Browse Source

fix

- 修复 路由切换页面不刷新的问题
feat
JinxChen 1 year ago
parent
commit
f1dcaa1953
56 changed files with 2977 additions and 4819 deletions
  1. +2
    -2
      .env.development
  2. +1
    -1
      .env.production
  3. +2
    -2
      .env.test
  4. +0
    -32
      .postcssrc.js
  5. +161
    -107
      README.md
  6. +0
    -36
      antpay_frontend_web_run.sh
  7. +2
    -2
      babel.config.js
  8. +37
    -0
      h5_frontend_web_run.sh
  9. +700
    -37
      package-lock.json
  10. +8
    -4
      package.json
  11. +3
    -3
      public/index.html
  12. +0
    -152
      public/schedule.html
  13. +11
    -12
      setup_development.sh
  14. +9
    -10
      setup_production.sh
  15. +9
    -9
      setup_test.sh
  16. +0
    -70
      src/api/alipay.js
  17. +79
    -0
      src/api/core.js
  18. +57
    -0
      src/api/pay.js
  19. +49
    -0
      src/api/wx.js
  20. +115
    -32
      src/assets/css/public.scss
  21. +323
    -0
      src/assets/css/reset.scss
  22. BIN
      src/assets/img/ssjl.jpg
  23. +0
    -144
      src/components/AgreementDialog.vue
  24. +0
    -76
      src/components/Checkbox.vue
  25. +0
    -13
      src/config/customize.js
  26. +0
    -49
      src/config/map/index.js
  27. +0
    -13
      src/config/map/models.js
  28. +1
    -1
      src/config/models.js
  29. +70
    -0
      src/http/java_api.js
  30. +1
    -1
      src/http/request.js
  31. +58
    -0
      src/http/webapi.js
  32. +87
    -56
      src/main.js
  33. +0
    -18
      src/pages/schedule/Schedule.vue
  34. +0
    -10
      src/pages/schedule/schedule.js
  35. +6
    -28
      src/router/index.js
  36. +64
    -37
      src/store/index.js
  37. +5
    -4
      src/store/prefix.js
  38. +0
    -269
      src/views/AliPayForm.vue
  39. +0
    -425
      src/views/AliPayFormNew.vue
  40. +0
    -535
      src/views/AliPayIndex.vue
  41. +0
    -36
      src/views/AliPayRedirect.vue
  42. +0
    -171
      src/views/AliPayResult.vue
  43. +0
    -636
      src/views/AlipayIndexNew.vue
  44. +0
    -50
      src/views/ComponentsTest.vue
  45. +0
    -338
      src/views/alipay-dealers/AlipayFormDealers.vue
  46. +0
    -231
      src/views/alipay-dealers/AlipayIndexDealers.vue
  47. +0
    -501
      src/views/chunyu/AliPayForm.vue
  48. +0
    -416
      src/views/gaode-demo/PointInRing.vue
  49. +0
    -96
      src/views/htmlCanvas/htmlCanvasDemo.vue
  50. +28
    -0
      src/views/index.vue
  51. +117
    -0
      src/views/package-home/index.vue
  52. +563
    -0
      src/views/package-list/index.vue
  53. +0
    -32
      src/views/page-not-found/index.vue
  54. +386
    -0
      src/views/pay-result/index.vue
  55. +0
    -120
      src/views/websocket/websocket-demo.vue
  56. +23
    -2
      vue.config.js

+ 2
- 2
.env.development View File

@@ -1,4 +1,4 @@
NODE_ENV= development
# base api
VUE_APP_BASE_API = 'https://id.ssjlai.com/telpopay'
#VUE_APP_BASE_API = 'https://ai.ssjlai.com/telpopay'
VUE_APP_BASE_API = 'https://id.ssjlai.com/'
#VUE_APP_BASE_API = 'https://ai.ssjlai.com/'

+ 1
- 1
.env.production View File

@@ -1,3 +1,3 @@
NODE_ENV= production
# base api
VUE_APP_BASE_API = 'https://ai.ssjlai.com/telpopay'
VUE_APP_BASE_API = 'https://ai.ssjlai.com/'

+ 2
- 2
.env.test View File

@@ -1,4 +1,4 @@
NODE_ENV= test
# base api
VUE_APP_BASE_API = 'https://id.ssjlai.com/telpopay'
#VUE_APP_BASE_API = 'https://ai.ssjlai.com/telpopay'
VUE_APP_BASE_API = 'https://id.ssjlai.com/'
#VUE_APP_BASE_API = 'https://ai.ssjlai.com/'

+ 0
- 32
.postcssrc.js View File

@@ -1,32 +0,0 @@
/*
* @Date: 2022-01-19 10:10:50
* @LastEditors: JinxChen
* @LastEditTime: 2022-01-21 15:57:33
* @FilePath: \alipay-scan-code-front-end\.postcssrc.js
* @description:
*/
const path = require("path");

module.exports = ({ webpack }) => {
const designWidth = webpack.resourcePath.includes(path.join("node_modules", "vant")) ? 375 : 375;
return {
plugins: {
autoprefixer: {},
"postcss-px-to-viewport": {
unitToConvert: "px",
viewportWidth: designWidth,
unitPrecision: 6,
propList: ["*"],
viewportUnit: "vw",
fontViewportUnit: "vw",
selectorBlackList: [],
minPixelValue: 1,
mediaQuery: true,
exclude: [],
landscape: false,
landscapeUnit: 'vw', // 横屏时使用的单位
landscapeWidth: 1125 // 横屏时使用的视口宽度
}
}
};
};

+ 161
- 107
README.md View File

@@ -1,136 +1,190 @@
<!--
* @Date: 2022-01-19 10:08:58
* @Date: 2022-08-17 16:19:13
* @LastEditors: JinxChen
* @LastEditTime: 2022-08-31 16:39:10
* @FilePath: \AntpayFrontEnd\README.md
* @description: 项目说明文档
* @LastEditTime: 2023-02-24 18:49:37
* @FilePath: \TelpoH5FrontendWeb\README.md
* @description: 项目说明
-->
# alipay-scan-code-front-end
## 项目说明
## 这是一个通过支付宝二维码进入的h5
## 项目依赖安装
# telpo-h5-template

## Project setup
```
npm install
```

### 项目运行
### Compiles and hot-reloads for development
```
npm run dev
```

### 项目打包
### Compiles and minifies for production
```
npm run build
```

### 项目本地调试
### Run your tests
```
npm run test
```

### Lints and fixes files
```
运行成功后 本地调试首次进入会进入到 http://localhost:8080/#/404 404页面
因为当前url还没有参数, 此时需要手动在url后面添加需要的参数,
例子: http://localhost:8080/#/index?goodsNo=889&userId=1
其中 goodsNo是商品的no, userId是用户的id, 这两个参数后面接口都会用到
以上在线上环境不需要配置,因为二维码会自动把这两个参数添加上去
npm run lint
```

### 项目代码编写规范(暂时想到这些,后面根据项目情况补充说明)
- css类名: 小写驼峰 中间用 - 隔开
- js函数方法: 开头小写后面开头大写驼峰
- .vue 文件命名: 统一大写驼峰
- 常量命名: 全部大写 以_拼接, 具体例子见: /src/config/models下的文件


### 项目分支管理
- master: 不可在此分支做任何修改, 只能合并develop分支, git merge --no-ff develop ; 且部署上线时对应production环境,不可混肴
- develop: 平时开发使用此分支, 需另开分支并说明是做什么的, 比如fix bug, git checkout -b fix-xxxx, 开发完成自测无问题后合并到develop分支,
- test: 如不必要不在此分支做任何修改, 合并develpo分支, git merge --no-ff develop ; 部署上线时对应test环境,不可混肴

### git 提交规范
- feature 新增一个功能
- bugfix 修复一个
- Bugdocs 文档变更
- style 代码格式(不影响功能,例如空格、分号等格式修正)
- refactor 代码重构
- perf 改善性能
- test 测试
- build 变更项目构建或外部依赖(例如 scopes: webpack、gulp、npm 等)
- ci 更改持续集成软件的配置文件和 package 中的 scripts 命令,例如 scopes: Travis, Circle 等
- chore 变更构建流程或辅助工具
- revert 代码回退

### 版本控制以及版本迭代说明

### v1.0.0
`2022.02.23`
build
- 初版发布
- 完成 项目搭建
- 完成 项目迁移 从documentFrontEndWeb 到 AntpayFrontEnd
- 增加 docker部署脚本
- 增加 环境设置脚本
- 增加 nginx.conf文件
### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).

# 本项目为天波H5项目
## 版本号管理
- 版本格式:主版本号.次版本号.修订号
1.主版本号:当你做了不兼容的 API 修改( 一般项目发生重大功能改变)
2.次版本号:当你做了向下兼容的功能性新增,
3.修订号:当你做了向下兼容的问题修正。
例如:
- V #1.0.0

##git提交为以下类别
- 1.fix 修复 xxx问题
- 2.feat 增加 xxx功能
- 3.docs 文档变更
- 4.style 代码格式(不影响代码运行的变动)
- 5.perf 性能优化
- 提交格式,比如:
-start---------------
- 版本号 v#1.0.0
- 2022.08.06
fix
- 修复 路由history模式原因引起的页面空白的问题

### v1.0.1
`2022.02.25`
feature
- 增加 非支付宝浏览环境下扫码切换支付宝弹窗提示
- 增加 android和ios设备支付宝下载链接
- 增加 android设备复制粘贴下载链接功能


### v1.0.2
`2022.03.04`
feature
- 增加 春雨个性化定制 '@/views/chunyu/AliPayForm'
- 增加 Checkbox 组件, '@/components/checkbox'
- 增加 AgreementDialog 组件, '@/components/AgreementDialog'

### v1.0.3
`2022.05.09`
feature
- 增加 支付宝花呗支付页面

### v1.0.4
`2022.05.10`
feature
- 增加 一个高德demo 判断一个点是否在一个多边形围栏内
- 增加 引入高德地图api
- 增加 圆形围栏判断 一个点是否在圆形围栏内
- 增加 坐标点显示
- 修改文件名称
- fix 修复了 xxx问题
...

- 后续可根据项目需要更新或者改进
-end------------------------

## v1.0.0
`2022.8.8`
feat
- 增加 项目基本配置

## v1.0.1
`2022.8.18`
feat
- card-form
- 增加 一个表单录入页

## v1.0.2
`2022.8.19`
style
- card-form
- 修改 页面样式

## v1.0.3
`2022.8.19`
feat
- card-form
- 增加 接口

## v1.0.4
`2022.8.20`
feat
- card-form
- 增加 保存失败错误提示

## v1.0.5
`2022.8.20`
fix
- card-form
- 修复 保存iccId参数多出来一个的问题

## v1.0.6
`2022.8.23`
feat
- card-form
- 增加 亲情号码六个字段

## v1.0.7
`2022.8.24`
feat
- card-form
- 增加 备注字段

## v1.0.8
`2022.8.25`
feat
- card-form
- 增加 学校名称字段
- 修改 学校名称字段最大长度为30

## v1.0.9
`2022.8.30`
feat
- card-form
- 修复 保存字段错误的问题

## v1.0.10
`2022.8.31`
feat
- card-form
- 增加 年级/班级下拉选择


## v1.0.11
`2022.9.9`
feat
- card-form
- 修改 保存接口传参

## v1.0.12
`2022.10.11`
feat
- card-form
- 修改 班级参数

-------------分割线,以下是2023年的readme----------

## v1.0.13
`2023.2.24`
feat
- package-list
- 增加 一个话费套餐购买页面



## v1.0.14
`2023.2.24`
feat
- package-home
- 增加 一个微信授权获取code的首页


## v1.0.15
`2023.2.24`
fix
- package-home
- 修复 微信网页授权重定向错误的问题

## v1.0.16
`2023.2.24`
fix
- package-home
- 修复 微信网页获取openId失败的问题

### v1.0.5
`2022.05.11`
## v1.0.17
`2023.2.24`
feature
- 增加 多页面配置

- pay-result
- 增加 一个微信支付结果查询页面

### v1.0.6
`2022.05.23`
ci
- 删除 多页面配置

## v1.0.18
`2023.2.24`
feature
- 增加 一个判断点是否在多个围栏单页面
- 修复 路由切换页面不刷新的问题

### v1.0.7
`2022.06.17`
feature
- PointInRing
- 增加 圆形或者marker拖拽


### v1.0.8
`2022.07.21`
feature
- websocket-demo
- 增加 一个websocket的demo


`2022.08.31`
feature
- html-canvas-demo
- 增加 一个htmlCanvas2demo
## v1.0.19
`2023.2.25`
fix
- 修复 路由切换页面不刷新的问题

+ 0
- 36
antpay_frontend_web_run.sh View File

@@ -1,36 +0,0 @@
#!/bin/bash
###
# @Date: 2021-11-15 09:37:49
# @LastEditors: JinxChen
# @LastEditTime: 2022-03-04 10:47:47
# @FilePath: \AntpayFrontEnd\antpay_frontend_web_run.sh
# @description: docker部署脚本, 根据项目具体情况来 修改 docker run -p 8804:80
###
environment=$1
version=$2
echo "环境变量为${environment},版本为$version!"
if [[ ${environment} = 'production' ]]; then
echo "开始远程构建容器"
docker stop antpay_frontend_web || true;
docker rm antpay_frontend_web || true;
docker rmi -f $(docker images | grep registry.cn-shanghai.aliyuncs.com/gps_card/antpay_frontend_web | awk '{print $3}')
#docker login --username=telpo_linwl@1111649216405698 --password=telpo#1234 registry.cn-shanghai.aliyuncs.com;
docker login --username=rzl_wangjx@1111649216405698 --password=telpo.123 registry.cn-shanghai.aliyuncs.com
docker pull registry.cn-shanghai.aliyuncs.com/gps_card/antpay_frontend_web:$version
docker run -p 8804:80 -d --restart=always --name antpay_frontend_web registry.cn-shanghai.aliyuncs.com/gps_card/antpay_frontend_web:$version;
#删除产生的None镜像
docker rmi -f $(docker images | grep none | awk '{print $3}')
docker ps -a

elif [[ ${environment} == 'test' ]]; then
echo "开始在测试环境远程构建容器"
docker stop antpay_frontend_web || true
docker rm antpay_frontend_web || true
docker rmi -f $(docker images | grep 139.224.254.18:5000/antpay_frontend_web | awk '{print $3}')
docker pull 139.224.254.18:5000/antpay_frontend_web:$version
docker run -p 8804:80 -d --restart=always --name antpay_frontend_web 139.224.254.18:5000/antpay_frontend_web:$version;
#删除产生的None镜像
docker rmi -f $(docker images | grep none | awk '{print $3}')
docker ps -a

fi

+ 2
- 2
babel.config.js View File

@@ -1,8 +1,8 @@
/*
* @Date: 2022-01-19 10:08:26
* @LastEditors: JinxChen
* @LastEditTime: 2022-01-19 10:56:39
* @FilePath: \alipay-scan-code-front-end\babel.config.js
* @LastEditTime: 2023-02-25 15:43:27
* @FilePath: \TelpoH5FrontendWeb\babel.config.js
* @description:
*/
module.exports = {


+ 37
- 0
h5_frontend_web_run.sh View File

@@ -0,0 +1,37 @@
#!/bin/bash
###
# @Date: 2022-08-18 09:19:07
# @LastEditors: JinxChen
# @LastEditTime: 2022-08-18 10:06:40
# @FilePath: \TelpoH5FrontendWeb\h5_frontend_web_run.sh
# @description: 部署脚本
###

environment=$1
version=$2
echo "环境变量为${environment},版本为$version!"
if [[ ${environment} = 'production' ]];
then
echo "开始远程构建容器"
docker stop h5_frontend_web || true;
docker rm h5_frontend_web || true;
docker rmi -f $(docker images | grep registry.cn-shanghai.aliyuncs.com/tolpo_platform/h5_frontend_web | awk '{print $3}')
#docker login --username=telpo_linwl@1111649216405698 --password=telpo#1234 registry.cn-shanghai.aliyuncs.com;
#docker login --username=telpo_fengjj@1111649216405698 --password=PWDaliyun123 registry.cn-shanghai.aliyuncs.com
docker login --username=rzl_wangjx@1111649216405698 --password=telpo.123 registry.cn-shanghai.aliyuncs.com
docker pull registry.cn-shanghai.aliyuncs.com/tolpo_platform/h5_frontend_web:$version
docker run -p 8075:80 -d --restart=always --name h5_frontend_web registry.cn-shanghai.aliyuncs.com/tolpo_platform/h5_frontend_web:$version;
#删除产生的None镜像
docker rmi -f $(docker images | grep none | awk '{print $3}')
docker ps -a
else
echo "开始在测试环境远程构建容器"
docker stop h5_frontend_web || true
docker rm h5_frontend_web || true
docker rmi -f $(docker images | grep 139.224.254.18:5000/h5_frontend_web | awk '{print $3}')
docker pull 139.224.254.18:5000/h5_frontend_web:$version
docker run -p 8075:80 -d --restart=always --name h5_frontend_web 139.224.254.18:5000/h5_frontend_web:$version;
#删除产生的None镜像
docker rmi -f $(docker images | grep none | awk '{print $3}')
docker ps -a
fi

+ 700
- 37
package-lock.json View File

@@ -1,22 +1,25 @@
{
"name": "alipay-scan-code-front-end",
"name": "h5frontend",
"version": "0.1.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "alipay-scan-code-front-end",
"name": "h5frontend",
"version": "0.1.0",
"dependencies": {
"@vant/area-data": "^1.2.2",
"amfe-flexible": "^2.2.1",
"axios": "^0.26.0",
"core-js": "^3.6.5",
"html2canvas": "^1.4.1",
"nprogress": "^0.2.0",
"rxjs": "^7.8.0",
"vant": "^2.12.39",
"vue": "^2.6.11",
"vue-router": "^3.2.0",
"vuex": "^3.4.0"
"vuex": "^3.4.0",
"weixin-js-sdk": "^1.6.0"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^4.5.0",
@@ -27,11 +30,12 @@
"@vue/test-utils": "^1.0.3",
"babel-eslint": "^10.1.0",
"babel-plugin-import": "^1.13.3",
"compression-webpack-plugin": "^5.0.0",
"eslint": "^6.7.2",
"eslint-plugin-prettier": "^3.3.1",
"eslint-plugin-vue": "^6.2.2",
"lint-staged": "^9.5.0",
"postcss-px-to-viewport": "^1.1.1",
"postcss-pxtorem": "^5.1.1",
"prettier": "^2.2.1",
"sass": "^1.26.5",
"sass-loader": "^8.0.2",
@@ -1676,6 +1680,12 @@
"node": ">=0.1.95"
}
},
"node_modules/@gar/promisify": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz",
"integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==",
"dev": true
},
"node_modules/@hapi/address": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz",
@@ -2046,6 +2056,90 @@
"node": ">= 8"
}
},
"node_modules/@npmcli/fs": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz",
"integrity": "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==",
"dev": true,
"dependencies": {
"@gar/promisify": "^1.0.1",
"semver": "^7.3.5"
}
},
"node_modules/@npmcli/fs/node_modules/lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
"dev": true,
"dependencies": {
"yallist": "^4.0.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/@npmcli/fs/node_modules/semver": {
"version": "7.3.8",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
"integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
"dev": true,
"dependencies": {
"lru-cache": "^6.0.0"
},
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/@npmcli/fs/node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"dev": true
},
"node_modules/@npmcli/move-file": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz",
"integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==",
"deprecated": "This functionality has been moved to @npmcli/fs",
"dev": true,
"dependencies": {
"mkdirp": "^1.0.4",
"rimraf": "^3.0.2"
},
"engines": {
"node": ">=10"
}
},
"node_modules/@npmcli/move-file/node_modules/mkdirp": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
"dev": true,
"bin": {
"mkdirp": "bin/cmd.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/@npmcli/move-file/node_modules/rimraf": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
"dev": true,
"dependencies": {
"glob": "^7.1.3"
},
"bin": {
"rimraf": "bin.js"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/@popperjs/core": {
"version": "2.11.2",
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.2.tgz",
@@ -3394,6 +3488,11 @@
"integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=",
"dev": true
},
"node_modules/amfe-flexible": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/amfe-flexible/-/amfe-flexible-2.2.1.tgz",
"integrity": "sha512-L2VfvDzoETBjhRptg5u/IUuzHSuxm22JpSRb404p/TBGeRfwWmmNEbB+TFPIP/sS/+pbM18bCFH9QnMojLuPNw=="
},
"node_modules/ansi-colors": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz",
@@ -5481,6 +5580,127 @@
"node": ">= 0.8.0"
}
},
"node_modules/compression-webpack-plugin": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/compression-webpack-plugin/-/compression-webpack-plugin-5.0.2.tgz",
"integrity": "sha512-F2G4cQfsMZ6CiPlG22Q5EDUCqnfyZqTjyJP5cMgNYUbBg/dUzV3hto8yTFFIogDCTWooVbePHQE0qL6FrJUSsA==",
"dev": true,
"dependencies": {
"cacache": "^15.0.5",
"find-cache-dir": "^3.3.1",
"schema-utils": "^2.7.0",
"serialize-javascript": "^4.0.0",
"webpack-sources": "^1.4.3"
},
"engines": {
"node": ">= 10.13.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
},
"peerDependencies": {
"webpack": "^4.0.0 || ^5.0.0"
}
},
"node_modules/compression-webpack-plugin/node_modules/cacache": {
"version": "15.3.0",
"resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz",
"integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==",
"dev": true,
"dependencies": {
"@npmcli/fs": "^1.0.0",
"@npmcli/move-file": "^1.0.1",
"chownr": "^2.0.0",
"fs-minipass": "^2.0.0",
"glob": "^7.1.4",
"infer-owner": "^1.0.4",
"lru-cache": "^6.0.0",
"minipass": "^3.1.1",
"minipass-collect": "^1.0.2",
"minipass-flush": "^1.0.5",
"minipass-pipeline": "^1.2.2",
"mkdirp": "^1.0.3",
"p-map": "^4.0.0",
"promise-inflight": "^1.0.1",
"rimraf": "^3.0.2",
"ssri": "^8.0.1",
"tar": "^6.0.2",
"unique-filename": "^1.1.1"
},
"engines": {
"node": ">= 10"
}
},
"node_modules/compression-webpack-plugin/node_modules/chownr": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
"integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
"dev": true,
"engines": {
"node": ">=10"
}
},
"node_modules/compression-webpack-plugin/node_modules/lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
"dev": true,
"dependencies": {
"yallist": "^4.0.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/compression-webpack-plugin/node_modules/mkdirp": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
"dev": true,
"bin": {
"mkdirp": "bin/cmd.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/compression-webpack-plugin/node_modules/p-map": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
"integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==",
"dev": true,
"dependencies": {
"aggregate-error": "^3.0.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/compression-webpack-plugin/node_modules/rimraf": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
"dev": true,
"dependencies": {
"glob": "^7.1.3"
},
"bin": {
"rimraf": "bin.js"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/compression-webpack-plugin/node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"dev": true
},
"node_modules/compression/node_modules/bytes": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
@@ -8388,6 +8608,18 @@
"node": ">=6 <7 || >=8"
}
},
"node_modules/fs-minipass": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
"integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
"dev": true,
"dependencies": {
"minipass": "^3.0.0"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/fs-write-stream-atomic": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz",
@@ -9468,6 +9700,18 @@
"node": ">=8"
}
},
"node_modules/inquirer/node_modules/rxjs": {
"version": "6.6.7",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz",
"integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==",
"dev": true,
"dependencies": {
"tslib": "^1.9.0"
},
"engines": {
"npm": ">=2.0.0"
}
},
"node_modules/inquirer/node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@@ -9480,6 +9724,12 @@
"node": ">=8"
}
},
"node_modules/inquirer/node_modules/tslib": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
"dev": true
},
"node_modules/internal-ip": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz",
@@ -12106,6 +12356,24 @@
"node": ">=4"
}
},
"node_modules/listr/node_modules/rxjs": {
"version": "6.6.7",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz",
"integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==",
"dev": true,
"dependencies": {
"tslib": "^1.9.0"
},
"engines": {
"npm": ">=2.0.0"
}
},
"node_modules/listr/node_modules/tslib": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
"dev": true
},
"node_modules/load-json-file": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz",
@@ -12764,12 +13032,67 @@
"node": ">=8"
}
},
"node_modules/minipass-collect": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz",
"integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==",
"dev": true,
"dependencies": {
"minipass": "^3.0.0"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/minipass-flush": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz",
"integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==",
"dev": true,
"dependencies": {
"minipass": "^3.0.0"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/minipass-pipeline": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz",
"integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==",
"dev": true,
"dependencies": {
"minipass": "^3.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/minipass/node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"dev": true
},
"node_modules/minizlib": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
"integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
"dev": true,
"dependencies": {
"minipass": "^3.0.0",
"yallist": "^4.0.0"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/minizlib/node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"dev": true
},
"node_modules/mississippi": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz",
@@ -14651,14 +14974,13 @@
"integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
"dev": true
},
"node_modules/postcss-px-to-viewport": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/postcss-px-to-viewport/-/postcss-px-to-viewport-1.1.1.tgz",
"integrity": "sha512-2x9oGnBms+e0cYtBJOZdlwrFg/mLR4P1g2IFu7jYKvnqnH/HLhoKyareW2Q/x4sg0BgklHlP1qeWo2oCyPm8FQ==",
"node_modules/postcss-pxtorem": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/postcss-pxtorem/-/postcss-pxtorem-5.1.1.tgz",
"integrity": "sha512-uvgIujL/pn0GbZ+rczESD2orHsbXrrCqi+q9wJO8PCk3ZGCoVVtu5hZTbtk+tbZHZP5UkTfCvqOrTZs9Ncqfsg==",
"dev": true,
"dependencies": {
"object-assign": ">=4.0.1",
"postcss": ">=5.0.2"
"postcss": "^7.0.27"
}
},
"node_modules/postcss-reduce-initial": {
@@ -15673,15 +15995,11 @@
}
},
"node_modules/rxjs": {
"version": "6.6.7",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz",
"integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==",
"dev": true,
"version": "7.8.0",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.0.tgz",
"integrity": "sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==",
"dependencies": {
"tslib": "^1.9.0"
},
"engines": {
"npm": ">=2.0.0"
"tslib": "^2.1.0"
}
},
"node_modules/safe-buffer": {
@@ -17254,6 +17572,59 @@
"node": ">=6"
}
},
"node_modules/tar": {
"version": "6.1.13",
"resolved": "https://registry.npmjs.org/tar/-/tar-6.1.13.tgz",
"integrity": "sha512-jdIBIN6LTIe2jqzay/2vtYLlBHa3JF42ot3h1dW8Q0PaAG4v8rm0cvpVePtau5C6OKXGGcgO9q2AMNSWxiLqKw==",
"dev": true,
"dependencies": {
"chownr": "^2.0.0",
"fs-minipass": "^2.0.0",
"minipass": "^4.0.0",
"minizlib": "^2.1.1",
"mkdirp": "^1.0.3",
"yallist": "^4.0.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/tar/node_modules/chownr": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
"integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
"dev": true,
"engines": {
"node": ">=10"
}
},
"node_modules/tar/node_modules/minipass": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.1.tgz",
"integrity": "sha512-KS4CHIsDfOZetnT+u6fwxyFADXLamtkPxkGScmmtTW//MlRrImV+LtbmbJpLQ86Hw7km/utbfEfndhGBrfwvlA==",
"dev": true,
"engines": {
"node": ">=8"
}
},
"node_modules/tar/node_modules/mkdirp": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
"dev": true,
"bin": {
"mkdirp": "bin/cmd.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/tar/node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"dev": true
},
"node_modules/terser": {
"version": "4.8.0",
"resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz",
@@ -17702,10 +18073,9 @@
}
},
"node_modules/tslib": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
"dev": true
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz",
"integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg=="
},
"node_modules/tty-browserify": {
"version": "0.0.0",
@@ -19230,6 +19600,11 @@
"node": ">=0.8.0"
}
},
"node_modules/weixin-js-sdk": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/weixin-js-sdk/-/weixin-js-sdk-1.6.0.tgz",
"integrity": "sha512-3IYQH7aalJGFJrwdT3epvTdR1MboMiH7vIZ5BRL2eYOJ12BNah7csoMkmSZzkq1+l92sSq29XdTCVjCJoK2sBQ=="
},
"node_modules/whatwg-encoding": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz",
@@ -20773,6 +21148,12 @@
"minimist": "^1.2.0"
}
},
"@gar/promisify": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz",
"integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==",
"dev": true
},
"@hapi/address": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz",
@@ -21082,6 +21463,69 @@
"fastq": "^1.6.0"
}
},
"@npmcli/fs": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz",
"integrity": "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==",
"dev": true,
"requires": {
"@gar/promisify": "^1.0.1",
"semver": "^7.3.5"
},
"dependencies": {
"lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
"dev": true,
"requires": {
"yallist": "^4.0.0"
}
},
"semver": {
"version": "7.3.8",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
"integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
}
},
"yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"dev": true
}
}
},
"@npmcli/move-file": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz",
"integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==",
"dev": true,
"requires": {
"mkdirp": "^1.0.4",
"rimraf": "^3.0.2"
},
"dependencies": {
"mkdirp": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
"dev": true
},
"rimraf": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
"dev": true,
"requires": {
"glob": "^7.1.3"
}
}
}
},
"@popperjs/core": {
"version": "2.11.2",
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.2.tgz",
@@ -22239,6 +22683,11 @@
"integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=",
"dev": true
},
"amfe-flexible": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/amfe-flexible/-/amfe-flexible-2.2.1.tgz",
"integrity": "sha512-L2VfvDzoETBjhRptg5u/IUuzHSuxm22JpSRb404p/TBGeRfwWmmNEbB+TFPIP/sS/+pbM18bCFH9QnMojLuPNw=="
},
"ansi-colors": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz",
@@ -23957,6 +24406,92 @@
}
}
},
"compression-webpack-plugin": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/compression-webpack-plugin/-/compression-webpack-plugin-5.0.2.tgz",
"integrity": "sha512-F2G4cQfsMZ6CiPlG22Q5EDUCqnfyZqTjyJP5cMgNYUbBg/dUzV3hto8yTFFIogDCTWooVbePHQE0qL6FrJUSsA==",
"dev": true,
"requires": {
"cacache": "^15.0.5",
"find-cache-dir": "^3.3.1",
"schema-utils": "^2.7.0",
"serialize-javascript": "^4.0.0",
"webpack-sources": "^1.4.3"
},
"dependencies": {
"cacache": {
"version": "15.3.0",
"resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz",
"integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==",
"dev": true,
"requires": {
"@npmcli/fs": "^1.0.0",
"@npmcli/move-file": "^1.0.1",
"chownr": "^2.0.0",
"fs-minipass": "^2.0.0",
"glob": "^7.1.4",
"infer-owner": "^1.0.4",
"lru-cache": "^6.0.0",
"minipass": "^3.1.1",
"minipass-collect": "^1.0.2",
"minipass-flush": "^1.0.5",
"minipass-pipeline": "^1.2.2",
"mkdirp": "^1.0.3",
"p-map": "^4.0.0",
"promise-inflight": "^1.0.1",
"rimraf": "^3.0.2",
"ssri": "^8.0.1",
"tar": "^6.0.2",
"unique-filename": "^1.1.1"
}
},
"chownr": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
"integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
"dev": true
},
"lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
"dev": true,
"requires": {
"yallist": "^4.0.0"
}
},
"mkdirp": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
"dev": true
},
"p-map": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
"integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==",
"dev": true,
"requires": {
"aggregate-error": "^3.0.0"
}
},
"rimraf": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
"dev": true,
"requires": {
"glob": "^7.1.3"
}
},
"yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"dev": true
}
}
},
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@@ -26249,6 +26784,15 @@
"universalify": "^0.1.0"
}
},
"fs-minipass": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
"integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
"dev": true,
"requires": {
"minipass": "^3.0.0"
}
},
"fs-write-stream-atomic": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz",
@@ -27087,6 +27631,15 @@
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true
},
"rxjs": {
"version": "6.6.7",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz",
"integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==",
"dev": true,
"requires": {
"tslib": "^1.9.0"
}
},
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@@ -27095,6 +27648,12 @@
"requires": {
"has-flag": "^4.0.0"
}
},
"tslib": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
"dev": true
}
}
},
@@ -29019,6 +29578,23 @@
"listr-verbose-renderer": "^0.5.0",
"p-map": "^2.0.0",
"rxjs": "^6.3.3"
},
"dependencies": {
"rxjs": {
"version": "6.6.7",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz",
"integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==",
"dev": true,
"requires": {
"tslib": "^1.9.0"
}
},
"tslib": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
"dev": true
}
}
},
"listr-silent-renderer": {
@@ -29705,6 +30281,51 @@
}
}
},
"minipass-collect": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz",
"integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==",
"dev": true,
"requires": {
"minipass": "^3.0.0"
}
},
"minipass-flush": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz",
"integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==",
"dev": true,
"requires": {
"minipass": "^3.0.0"
}
},
"minipass-pipeline": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz",
"integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==",
"dev": true,
"requires": {
"minipass": "^3.0.0"
}
},
"minizlib": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
"integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
"dev": true,
"requires": {
"minipass": "^3.0.0",
"yallist": "^4.0.0"
},
"dependencies": {
"yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"dev": true
}
}
},
"mississippi": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz",
@@ -31273,14 +31894,13 @@
}
}
},
"postcss-px-to-viewport": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/postcss-px-to-viewport/-/postcss-px-to-viewport-1.1.1.tgz",
"integrity": "sha512-2x9oGnBms+e0cYtBJOZdlwrFg/mLR4P1g2IFu7jYKvnqnH/HLhoKyareW2Q/x4sg0BgklHlP1qeWo2oCyPm8FQ==",
"postcss-pxtorem": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/postcss-pxtorem/-/postcss-pxtorem-5.1.1.tgz",
"integrity": "sha512-uvgIujL/pn0GbZ+rczESD2orHsbXrrCqi+q9wJO8PCk3ZGCoVVtu5hZTbtk+tbZHZP5UkTfCvqOrTZs9Ncqfsg==",
"dev": true,
"requires": {
"object-assign": ">=4.0.1",
"postcss": ">=5.0.2"
"postcss": "^7.0.27"
}
},
"postcss-reduce-initial": {
@@ -32078,12 +32698,11 @@
}
},
"rxjs": {
"version": "6.6.7",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz",
"integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==",
"dev": true,
"version": "7.8.0",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.0.tgz",
"integrity": "sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==",
"requires": {
"tslib": "^1.9.0"
"tslib": "^2.1.0"
}
},
"safe-buffer": {
@@ -33390,6 +34009,46 @@
"integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==",
"dev": true
},
"tar": {
"version": "6.1.13",
"resolved": "https://registry.npmjs.org/tar/-/tar-6.1.13.tgz",
"integrity": "sha512-jdIBIN6LTIe2jqzay/2vtYLlBHa3JF42ot3h1dW8Q0PaAG4v8rm0cvpVePtau5C6OKXGGcgO9q2AMNSWxiLqKw==",
"dev": true,
"requires": {
"chownr": "^2.0.0",
"fs-minipass": "^2.0.0",
"minipass": "^4.0.0",
"minizlib": "^2.1.1",
"mkdirp": "^1.0.3",
"yallist": "^4.0.0"
},
"dependencies": {
"chownr": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
"integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
"dev": true
},
"minipass": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.1.tgz",
"integrity": "sha512-KS4CHIsDfOZetnT+u6fwxyFADXLamtkPxkGScmmtTW//MlRrImV+LtbmbJpLQ86Hw7km/utbfEfndhGBrfwvlA==",
"dev": true
},
"mkdirp": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
"dev": true
},
"yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"dev": true
}
}
},
"terser": {
"version": "4.8.0",
"resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz",
@@ -33750,10 +34409,9 @@
}
},
"tslib": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
"dev": true
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz",
"integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg=="
},
"tty-browserify": {
"version": "0.0.0",
@@ -35007,6 +35665,11 @@
"integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==",
"dev": true
},
"weixin-js-sdk": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/weixin-js-sdk/-/weixin-js-sdk-1.6.0.tgz",
"integrity": "sha512-3IYQH7aalJGFJrwdT3epvTdR1MboMiH7vIZ5BRL2eYOJ12BNah7csoMkmSZzkq1+l92sSq29XdTCVjCJoK2sBQ=="
},
"whatwg-encoding": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz",


+ 8
- 4
package.json View File

@@ -1,5 +1,5 @@
{
"name": "alipay-scan-code-front-end",
"name": "h5frontend",
"version": "0.1.0",
"private": true,
"scripts": {
@@ -12,15 +12,18 @@
"test:unit": "vue-cli-service test:unit"
},
"dependencies": {
"amfe-flexible": "^2.2.1",
"@vant/area-data": "^1.2.2",
"axios": "^0.26.0",
"core-js": "^3.6.5",
"html2canvas": "^1.4.1",
"nprogress": "^0.2.0",
"rxjs": "^7.8.0",
"vant": "^2.12.39",
"vue": "^2.6.11",
"vue-router": "^3.2.0",
"vuex": "^3.4.0"
"vuex": "^3.4.0",
"weixin-js-sdk": "^1.6.0"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^4.5.0",
@@ -35,11 +38,12 @@
"eslint-plugin-prettier": "^3.3.1",
"eslint-plugin-vue": "^6.2.2",
"lint-staged": "^9.5.0",
"postcss-px-to-viewport": "^1.1.1",
"prettier": "^2.2.1",
"sass": "^1.26.5",
"sass-loader": "^8.0.2",
"vue-template-compiler": "^2.6.11"
"vue-template-compiler": "^2.6.11",
"postcss-pxtorem": "^5.1.1",
"compression-webpack-plugin": "^5.0.0"
},
"gitHooks": {
"pre-commit": "lint-staged"


+ 3
- 3
public/index.html View File

@@ -1,8 +1,8 @@
<!--
* @Date: 2022-01-19 10:08:26
* @LastEditors: JinxChen
* @LastEditTime: 2022-05-11 10:41:39
* @FilePath: \AntpayFrontEnd\public\index.html
* @LastEditTime: 2023-02-25 15:03:02
* @FilePath: \TelpoH5FrontendWeb\public\index.html
* @description:
-->
<!DOCTYPE html>
@@ -12,7 +12,7 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>电子学生证订购服务</title>
<title></title>
</head>
<body>
<noscript>


+ 0
- 152
public/schedule.html View File

@@ -1,152 +0,0 @@
<!doctype html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
<title>高德地图demo</title>
<link rel="stylesheet" href="https://a.amap.com/jsapi_demos/static/demo-center/css/demo-center.css" type="text/css">
<script type="text/javascript" src="https://webapi.amap.com/maps?v=1.4.15&key=6e4a6c39ea6d18b8dd3151baa3a7c0d5"></script>
<script type="text/javascript" src="https://cache.amap.com/lbs/static/addToolbar.js"></script>
<style>
html,body,#container{
height: 100%
}
.info {
height: 100px;
width: 250px;
z-index: 9999;
position: absolute;
top: 20px;
left: 20%;
background-color: wheat;
text-align: center;
}
</style>
</head>
<body>
<div id="container"></div>
<div class='info'>
<p>拖动marker可调整位置</p>
<input type="text" id="text"/>
</div>
<script script type="text/javascript">

/* var textBox = new AMap.Text({
map: map,
position: new AMap.LngLat(116.40109,39.919728),
offset: new AMap.Pixel(-20, -40),
style:{
'background-color':'yellow',
'border':'solid 1px #0088ff',
'padding':'10px 20px'
}
}) */
// 获取url的参数
function getQueryString() {
var url = window.location.hash;
console.log(url); //获取url中"?"符后的字串
let theRequest = new Object();
if (url.indexOf("?") != -1) {
let str = url.substr(8);
console.log("str", str);
strs = str.split("&");
for(let i = 0; i < strs.length; i ++) {
theRequest[strs[i].split("=")[0]]=unescape(strs[i].split("=")[1]);
}
}
return theRequest;
}
var params = getQueryString();
console.log(params.polygon);
var polyLnglAtList = params.polygon.split(';').map(item => {
return item.split(',');
});
var radius = Number(params.radius);
console.log("radius", radius);
var center = params.center.split(',');
var map = new AMap.Map("container", {
resizeEnable: true,
zoom: 13,
center: center
});
console.log("polyLnglAtList", polyLnglAtList);
var marker = new AMap.Marker({
map: map,
draggable:true,
position: center
});
function createPoly() {
// 创建地图
// 判断是多边形还是圆形 数组length为1 是圆形
if (polyLnglAtList.length === 1) {
// 创建点
var polygon = new AMap.Circle({
center: center,
radius: radius, //半径
borderWeight: 3,
strokeColor: "red",
strokeWeight: 6,
strokeOpacity: 0.5,
fillOpacity: 0.4,
strokeStyle: 'dashed',
strokeDasharray: [10, 10],
// 线样式还支持 'dashed'
fillColor: 'green',
zIndex: 50,
});
map.add(polygon)
return polygon
} else {
// 否则是多边形
var polygon = new AMap.Polygon({
map: map,
fillOpacity: 0.4,
path: polyLnglAtList
});
return polygon
}
};
// 绑定拖拽事件
function compute() {
var point = marker.getPosition();
console.log("当前坐标点::", point);
/* var isPointInRing = AMap.GeometryUtil.isPointInRing(point,polyLnglAtList); */
var newPolygon = createPoly();
console.log("newPolygon", newPolygon);
var isPointInRing = newPolygon.contains(point);
marker.setLabel({
content: isPointInRing ? '在内部'+ point : '在外部' + point,
offset:new AMap.Pixel(20,0)
});
// 双向绑定
var input = document.querySelector("#text");
var data = {};
Object.defineProperty(data, "name", {
configurable: true,
get: function(){
return input.value
},
set: function(newValue){
//this.value = newValue;
input.value = newValue;
}
})
data.name = point.toString();
input.onchange = function(){
data.name = data.name;
};
let divBox = document.createElement('span');
divBox.innerHTML = isPointInRing;
divBox.className = 'fence';
document.body.appendChild(divBox);
console.log("该点是否在围栏内::", isPointInRing);
}
createPoly();
compute();
marker.on('dragging',compute)
map.setFitView();
</script>
<div id="schedule"></div>
</body>
</html>

+ 11
- 12
setup_development.sh View File

@@ -1,27 +1,26 @@
#!/bin/bash
###
# @Author: your name
# @Date: 2020-07-02 10:34:00
# @LastEditTime: 2022-02-25 15:01:41
# @Date: 2022-08-18 09:19:07
# @LastEditors: JinxChen
# @Description: In User Settings Edit
# @FilePath: \AntpayFrontEnd\setup_development.sh
# @LastEditTime: 2022-08-18 10:06:17
# @FilePath: \TelpoH5FrontendWeb\setup_development.sh
# @description:
###
#!/bin/bash
npm -v
npm config set registry https://registry.npm.taobao.org
npm install
npm run build-dev
image_version=`date +%Y%m%d%H%M`;
docker stop antpay_frontend_web || true;
docker rm antpay_frontend_web || true;
docker stop h5_frontend_web || true;
docker rm h5_frontend_web || true;
# 删除镜像
docker rmi -f $(docker images | grep telpo/antpay_frontend_web | awk '{print $3}')
docker rmi -f $(docker images | grep telpo/h5_frontend_web | awk '{print $3}')
# 构建telpo/mrp:$image_version镜像
docker build --no-cache . -t telpo/antpay_frontend_web:$image_version;
docker build --no-cache . -t telpo/h5_frontend_web:$image_version;
#删除产生的None镜像
docker rmi -f $(docker images | grep none | awk '{print $3}')
# 查看镜像列表
docker images;
docker run -p 8804:80 -d --restart=always --name antpay_frontend_web telpo/antpay_frontend_web:$image_version;
docker run -p 8075:80 -d --restart=always --name h5_frontend_web telpo/h5_frontend_web:$image_version;
# 查看日志
docker logs antpay_frontend_web;
docker logs h5_frontend_web;

+ 9
- 10
setup_production.sh View File

@@ -1,28 +1,27 @@
#!/bin/bash
###
# @Author: your name
# @Date: 2020-07-02 10:34:59
# @LastEditTime: 2022-02-25 15:01:53
# @Date: 2022-08-18 09:19:07
# @LastEditors: JinxChen
# @Description: In User Settings Edit
# @FilePath: \AntpayFrontEnd\setup_production.sh
# @LastEditTime: 2022-08-18 09:29:15
# @FilePath: \TelpoH5FrontendWeb\setup_production.sh
# @description:
###
#!/bin/bash
npm -v
npm config set registry https://registry.npm.taobao.org
npm install
npm run build
image_version=$version;
# 删除镜像
docker rmi -f $(docker images | grep registry.cn-shanghai.aliyuncs.com/tolpo_platform/antpay_frontend_web | awk '{print $3}')
docker rmi -f $(docker images | grep registry.cn-shanghai.aliyuncs.com/tolpo_platform/h5_frontend_web | awk '{print $3}')
# 构建telpo/mrp:$image_version镜像
docker build --no-cache . -t telpo/antpay_frontend_web:$image_version;
docker build --no-cache . -t telpo/h5_frontend_web:$image_version;
#TODO:推送镜像到阿里仓库
echo '=================开始推送镜像======================='
#docker login --username=telpo_linwl@1111649216405698 --password=telpo#1234 registry.cn-shanghai.aliyuncs.com
#docker login --username=telpo_fengjj@1111649216405698 --password=PWDaliyun123 registry.cn-shanghai.aliyuncs.com
docker login --username=rzl_wangjx@1111649216405698 --password=telpo.123 registry.cn-shanghai.aliyuncs.com
docker tag telpo/antpay_frontend_web:$image_version registry.cn-shanghai.aliyuncs.com/tolpo_platform/antpay_frontend_web:$image_version
docker push registry.cn-shanghai.aliyuncs.com/tolpo_platform/antpay_frontend_web:$image_version
docker tag telpo/h5_frontend_web:$image_version registry.cn-shanghai.aliyuncs.com/tolpo_platform/h5_frontend_web:$image_version
docker push registry.cn-shanghai.aliyuncs.com/tolpo_platform/h5_frontend_web:$image_version
echo '=================推送镜像完成======================='
#删除产生的None镜像
docker rmi -f $(docker images | grep none | awk '{print $3}')


+ 9
- 9
setup_test.sh View File

@@ -1,10 +1,10 @@

###
# @Author: your name
# @Date: 2020-07-02 10:34:59
# @LastEditTime: 2022-02-25 15:02:07
# @Date: 2022-08-18 09:19:07
# @LastEditors: JinxChen
# @Description: In User Settings Edit
# @FilePath: \AntpayFrontEnd\setup_test.sh
# @LastEditTime: 2022-08-18 09:29:35
# @FilePath: \TelpoH5FrontendWeb\setup_test.sh
# @description:
###
#!/bin/bash
npm -v
@@ -14,14 +14,14 @@ npm run build-test
image_version=$version;
# 删除镜像
docker rmi -f $(
docker images | grep 139.224.254.18:5000/antpay_frontend_web | awk '{print $3}'
docker images | grep 139.224.254.18:5000/h5_frontend_web | awk '{print $3}'
)
# 构建telpo/mrp:$image_version镜像
docker build --no-cache . -t telpo/antpay_frontend_web:$image_version;
docker build --no-cache . -t telpo/h5_frontend_web:$image_version;
#TODO:推送镜像到私有仓库
echo '=================开始推送镜像======================='
docker tag telpo/antpay_frontend_web:$image_version 139.224.254.18:5000/antpay_frontend_web:$image_version
docker push 139.224.254.18:5000/antpay_frontend_web:$image_version
docker tag telpo/h5_frontend_web:$image_version 139.224.254.18:5000/h5_frontend_web:$image_version
docker push 139.224.254.18:5000/h5_frontend_web:$image_version
echo '=================推送镜像完成======================='
#删除产生的None镜像
docker rmi -f $(docker images | grep none | awk '{print $3}')


+ 0
- 70
src/api/alipay.js View File

@@ -1,70 +0,0 @@
/*
* @Date: 2022-02-14 15:18:50
* @LastEditors: JinxChen
* @LastEditTime: 2022-04-13 17:08:21
* @FilePath: \AntpayFrontEnd\src\api\alipay.js
* @description: axios封装
*/
import request from '../http/request';

export const APIAlipay = {
getGoodsDetails, //首页获取商品数据
getAlipayForm, // 调起支付宝收银台
getAlipayResult, //获取支付结果
getUserTemplate, //获取用户模板
getQRCode, //获取商品二维码图片
};
export default APIAlipay;

// post请求
function getGoodsDetails(goodsNo, userId) {
return request({
url: '/api/get/goods',
method: 'get',
params: {
goodsNo,
userId
},
});
}

function getAlipayForm(params) {
return request({
url: '/webpage/alipay',
method: 'post',
data: params,
});
}

function getAlipayResult(params) {
return request({
url: '/api/order/detail/callback',
method: 'post',
data: params,
});
}
function getUserTemplate (userId) {
return request({
url: '/api/get/goodsTemplate',
method: 'get',
params: {userId},
});
}

function getQRCode (userId, spuId) {
return request({
url: 'api/get/QRCodeImageUrl',
method: 'get',
params: {userId, spuId},
});
}

// get请求 示例
/* function getPolygonFence(serialNo) {
return request({
url: '/api/Geofence/GetPolygonFence',
method: 'get',
headers: { AuthKey: 'key1' },
params: { serialNo },
})
} */

+ 79
- 0
src/api/core.js View File

@@ -0,0 +1,79 @@
/*
* @Date: 2021-12-18 15:49:01
* @LastEditors: JinxChen
* @LastEditTime: 2023-02-24 10:03:15
* @FilePath: \TelpoH5FrontendWeb\src\api\core.js
* @description:
* b端的接口, 每次调用前先获取token
*/
import axios from 'axios';
import prefix from '@/store/prefix'
const baseUrl = process.env.VUE_APP_BASE_API + 'gateway';
const service = axios.create({
baseURL: baseUrl,
});
service.interceptors.request.use(
request => {
if (localStorage.getItem(prefix + 'gatewayToken')) {
request.headers.AccessToken = localStorage.getItem(prefix + 'gatewayToken');
}
return request;
},
);
export const APICore = {
areaAlarmDetail, //获取告警详情
getAuth, //获取b端接口token
changeAlarmStatus, //修改非法区域告警推送状态
QueryLiveBasePackage, //获取基本套餐
payLiveBaseDevice, //微信统一下单
GpsDeviceFence, //围栏 redis
}
/* const headerAuth = this.$store.getters.gatewayToken; */
// 获取告警详情
function areaAlarmDetail(data) {
return service({
url: `${baseUrl}/core/api/v1/Fence/AreaAlarmDetail`,
method: 'get',
params: data,
})
}
// 获取告警授权token
function getAuth(params) {
return service({
url: `${baseUrl}/core/api/v1/Ability/study_ai/terminal/auth`,
method: 'post',
data: params
})
}
function changeAlarmStatus(params) {
return service({
url: `${baseUrl}/core/api/v1/Fence/AddAreaUserFilter`,
method: 'post',
data: params
})
}
function GpsDeviceFence(params) {
return service({
url: `${baseUrl}/core/api/v1/Redis/GpsDeviceFence`,
method: 'post',
data: params
})
}
// 获取基本套餐信息
function QueryLiveBasePackage(params) {
return service({
url: `${baseUrl}/core/api/v1/Device/QueryLiveBasePackage`,
method: 'post',
data: params
});
}
// 统一下单
// 获取基本套餐信息
function payLiveBaseDevice(params) {
return service({
url: `${baseUrl}/core/api/v1/Device/PayLiveBaseDevice`,
method: 'post',
data: params
});
}
export default APICore;

+ 57
- 0
src/api/pay.js View File

@@ -0,0 +1,57 @@
import javaRequest from '@/http/java_api';

export const APIPay = {
getToken, //获取token
getOpenId, // 获取openId
getPolAlipayForm, //获取聚合码支付宝form
getPolWx, //获取聚合码微信
getWxPayResult, //获取微信支付结果
getAlipayResult,
};
export default APIPay;

function getToken(manufacturerNo) {
return javaRequest({
url: '/authorization/get/token',
method: 'get',
params: {manufacturerNo},
});
}
function getOpenId(code) {
return javaRequest({
url: '/polymerization/get/openid',
method: 'get',
params: {code},
});
}

function getPolAlipayForm(params) {
return javaRequest({
url: '/polymerization/alipay',
method: 'post',
data: params,
});
}

function getPolWx(params) {
return javaRequest({
url: '/polymerization/wxpay',
method: 'post',
data: params,
});
}

function getWxPayResult(params) {
return javaRequest({
url: '/api/wx/order/callback',
method: 'post',
data: params,
});
}
function getAlipayResult(params) {
return javaRequest({
url: '/api/order/detail/callback',
method: 'post',
data: params,
});
}

+ 49
- 0
src/api/wx.js View File

@@ -0,0 +1,49 @@
/*
* @Date: 2021-06-30 14:29:56
* @LastEditors: JinxChen
* @LastEditTime: 2023-02-25 10:44:01
* @FilePath: \TelpoH5FrontendWeb\src\api\wx.js
* @description: 功能
*/
import request from '@/http/webapi';


const APIWx = {
createJSSDK,
checkIsNewCustomer, //获取微信用户是否首次关注,即是否是新用户
ocr, //ocr识别
Effective, //激活接口
}
export default APIWx;
function createJSSDK({ userId, sUrl, appId }) {
return request({
url: '/api/WX/CreateJsSdk',
method: 'get',
params: { userId, sUrl, appId },
})
}
function checkIsNewCustomer(params) {
return request({
url: '/api/User/getOpenId',
method: 'post',
headers: { AuthKey: 'key1' },
data: params,
})
}

function ocr(params) {
return request({
url: '/api/WX/ocr',
method: 'post',
headers: { AuthKey: 'key1' },
data: params,
})
}
// 中亿SIM自动激活接口
function Effective(params) {
return request({
url: '/api/Command/Effective',
method: 'post',
data: params,
});
}

+ 115
- 32
src/assets/css/public.scss View File

@@ -1,42 +1,125 @@
$designWidth: 750;
$blue: #2599ff;
$next: #8bc6fa;
$red: #ff8c8c;
$background: #f2f4f5;
$border_color: #d1d1d1;
/* 绑定时选择人物关系图片head.png */
$spriteWidthHead: 180;
$spriteHeightHead: 330;
$iconWidthHead: 80;
$iconHeightHead: 80;
/* 雪碧图 */
$spriteWidth: 400;
$spriteHeight: 400;
/* tabbar */
$tabbarH: 60px;
/* navbar */
$navbarH: 46px;

/* @function px2rem($px) {
@return $px*320/$designWidth/20+rem;
} */

// 公共css样式
@-webkit-keyframes rotation {
from {
-webkit-transform: rotate(0deg);
}

// 24号字体
.font-24 {
font-size: 24px;
to {
-webkit-transform: rotate(360deg);
}
}
// 16号字体
.font-16 {
font-size: 16px;

@mixin colorAndFont($color, $fontSize) {
color: $color;
font-size: ($fontSize)px;
}

@mixin center {
display: flex;
justify-content: center;
align-items: center;
}

@mixin boxShadow($color...) {
@if $color {
box-shadow: 0 0 10px $color;
} @else {
box-shadow: 0 0 10px rgba(185, 185, 185, .9);
}
}

@mixin avatarShadow {
box-shadow: 0 0 1px 1px rgba(185, 185, 185, 0.4);
}

@mixin avatarActiveShadow {
box-shadow: 0 0 5px 1px rgba(185, 185, 185, 0.4);
}
// 红色字体
.font-red {
color: red;
@mixin avatarOnlineShadow {
box-shadow: 0 0 1px 1px rgba(95, 204, 14, 0.4);
}
// 蓝色字体
.font-blue {
color: #1989fa;
@mixin avatarActiveOnlineShadow {
box-shadow: 0 0 5px 1px rgba(95, 204, 14, 0.4);
}
// 白色字体
.font-white {
color: #fff;

@mixin border {
position: absolute;
box-sizing: border-box;
content: ' ';
pointer-events: none;
top: -50%;
right: -50%;
bottom: -50%;
left: -50% !important;
border-bottom: 1px solid $border_color;
-webkit-transform: scale(.5);
transform: scale(.5);
}
// 居中flex-column布局
.pos-flex-cen-column {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;

// 雪碧图位置的处理
@mixin bgPosition(
$spriteWidth,
$spriteHeight,
$iconWidth,
$iconHeight,
$iconX,
$iconY
) {
background-position: (
($iconX / ($spriteWidth - $iconWidth)) * 100% ($iconY / ($spriteHeight - $iconHeight)) * 100%
);
}
// 居中flex无column布局
.pos-flex-cen {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;

// 雪碧图
@mixin icon_position($iconWidth, $iconHeight, $iconX, $iconY) {
@include bgPosition(
$spriteWidth,
$spriteHeight,
$iconWidth,
$iconHeight,
$iconX,
$iconY
);
}

// 雪碧图路径
@mixin icon($spriteUrl, $iconW, $iconH, $containerW, $containerH) {
background: transparent url($spriteUrl) no-repeat;
background-size: (400 * $iconW / $containerW)px (400 * $iconH / $containerH)px;
}

// 绑定时选择人物关系图片head.png
@mixin head_position($iconX, $iconY) {
@include bgPosition(
$spriteWidthHead,
$spriteHeightHead,
$iconWidthHead,
$iconHeightHead,
$iconX,
$iconY
);
}
// 下划线
.underline {
text-decoration: underline;
}

+ 323
- 0
src/assets/css/reset.scss View File

@@ -0,0 +1,323 @@
* {
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
-webkit-tap-highlight-color: transparent;
}

html {
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
}

body,
html {
-webkit-user-select: none;
user-select: none;
width: 100vw;
height: 100vh;
}

address,
applet,
article,
aside,
audio,
blockquote,
body,
canvas,
caption,
dd,
details,
div,
dl,
dt,
embed,
figcaption,
figure,
footer,
h1,
h2,
h3,
h4,
h5,
h6,
header,
html,
iframe,
li,
mark,
menu,
nav,
object,
ol,
output,
p,
pre,
progress,
ruby,
section,
summary,
table,
tbody,
td,
tfoot,
th,
thead,
time,
tr,
ul,
video {
margin: 0;
padding: 0;
border: 0;
vertical-align: baseline;
}

a {
color: #444444;
background-color: transparent;
text-decoration: none;
-webkit-touch-callout: none;
outline: none;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}

a.active,
a.link,
a.hover {
color: #444444;
}

li {
list-style: none;
}

article,
aside,
details,
figcaption,
figure,
footer,
header,
main,
menu,
nav,
section,
summary {
display: block;
}

audio,
canvas,
progress,
video {
display: inline-block;
}

audio:not([controls]) {
display: none;
height: 0;
}

[hidden],
template {
display: none;
}

a:active,
a:hover {
outline: 0;
}

b,
strong {
font-weight: 700;
}

small {
font-size: 80%;
}

sub,
sup {
position: relative;
vertical-align: baseline;
font-size: 75%;
line-height: 0;
}

sup {
top: -0.5em;
}

sub {
bottom: -0.25em;
}

img {
border: 0;
-webkit-touch-callout: none;
}

svg:not(:root) {
overflow: hidden;
}

hr {
box-sizing: content-box;
height: 0;
}

pre {
overflow: auto;
}

code,
kbd,
pre,
samp {
font-size: 1em;
font-family: monospace;
}

a,
button,
input,
optgroup,
select,
textarea {
-webkit-tap-highlight-color: transparent;
}

button,
input,
optgroup,
select,
textarea {
margin: 0;
outline: 0;
color: inherit;
font: inherit;
line-height: normal;
-webkit-appearance: none;
}

button {
overflow: visible;
}

button,
select {
text-transform: none;
}

button,
html input[type='button'],
input[type='reset'],
input[type='submit'] {
cursor: pointer;
-webkit-appearance: button;
}

button[disabled],
html input[disabled] {
cursor: default;
}

button::-moz-focus-inner,
input::-moz-focus-inner {
padding: 0;
border: 0;
}

input {
line-height: normal;
}

input[type='checkbox'],
input[type='radio'] {
box-sizing: border-box;
padding: 0;
}

input[type='number']::-webkit-inner-spin-button,
input[type='number']::-webkit-outer-spin-button {
height: auto;
}

input[type='search'] {
box-sizing: content-box;
-webkit-appearance: textfield;
}

input[type='search']::-webkit-search-cancel-button,
input[type='search']::-webkit-search-decoration {
-webkit-appearance: none;
}

fieldset {
margin: 0 2px;
padding: 0.35em 0.625em 0.75em;
border: 1px solid silver;
}

legend {
padding: 0;
border: 0;
}

textarea {
overflow: auto;
}

optgroup {
font-weight: 700;
}

table {
border-collapse: collapse;
border-spacing: 0;
}

td,
th {
padding: 0;
}

.fl,
.leftArea {
float: left;
}

.fr,
.rightArea {
float: right;
}

.clearFix:after {
clear: both;
display: block;
visibility: hidden;
height: 0;
content: '.';
}

input {
border: none;
}

button,
input,
select,
textarea {
outline: 0;
}

textarea {
overflow: hidden;
border: none;
resize: none;
}

img[src=''], img:not([src]) {
opacity: 0;
}

BIN
src/assets/img/ssjl.jpg View File

Before After
Width: 300  |  Height: 300  |  Size: 15KB

+ 0
- 144
src/components/AgreementDialog.vue View File

@@ -1,144 +0,0 @@
<!--
* @Date: 2022-02-26 16:40:02
* @LastEditors: JinxChen
* @LastEditTime: 2022-02-28 17:00:19
* @FilePath: \AntpayFrontEnd\src\components\AgreementDialog.vue
* @description: 协议弹窗组件
-->
<template>
<div>
<van-dialog
class="agreement-container"
v-model="show"
:title="title"
confirm-button-color="#1989fa"
:show-confirm-button="false"
>
<div class="agreement-content">
<h5>一.开通需知及承诺</h5>
<p v-show="isNewCustom">1.感谢用户使用支付宝花呗分期功能。</p>
<p v-show="isNewCustom">
2.用户自愿开通4G电子学生证资费套餐服务({{count}}
<!-- 24 -->
期)每月自动通过支付宝花呗分期支付资费(话费+流量)套餐费{{(price/count).toFixed(2)}}元/月。
</p>
<p v-show="isNewCustom">3.用户需连续使用该资费套餐24期,可据此领取4G电子学生证1台、电话卡1张。</p>
<p style="white-space: pre-wrap">
<span v-show="isNewCustom">4.</span>
{{description}}
</p>
<p v-show="isOldCustom">5.协议期内,电子学生证非人为损坏或进水按“三包”政策进行免费维修或更换。如丢失或人为损坏,按优惠价重新购买。</p>
<p v-show="isOldCustom">6.北京随手精灵科技有限公司接受电子学生证运营销售商委托采用支付宝花呗分期付代收业务货款。</p>
<h5>二.用户承诺</h5>
<p>1.用户已充分了解支付宝花呗付款条款(含支付宝花呗相关规则),充分阅读及理解本协议。</p>
<p>2.用户已经签署业务订购回执,自愿购买并同意签署本协议。</p>
<h5>三.法律适用与管辖</h5>
<p>本协议之效力、解释、变更、执行与争议解决均适用中华人民共和国法律。因本协议产生的争议,均应依照中华人民共和国法律予以处理。</p>
<p v-show="!isButtonShow">{{countDown}}秒后显示按钮</p>
<div class="agreement-button" v-show="isButtonShow">
<van-button type="warning" @click="onDisAgree" round>不同意</van-button>
<van-button type="info" @click="onAgree" round>同意</van-button>
</div>
</div>
</van-dialog>
</div>
</template>

<script>
export default {
name:'agreement-dialog',
props: {
show: {
default: true,
type: Boolean
},
title: {
default: '',
type: String
},
isNewCustom: {
default: true,
type: Boolean
},
isOldCustom: {
default: false,
type: Boolean
},
count: {
default: null,
type: Number
},
price: {
default: null,
type: Number
},
description: {
default: '',
type: String
},
countDown: {
default: 3,
type: Number
},
isButtonShow: {
default: false,
type: Boolean
},
},
data(){
return {
}
},
methods: {
// 不同意
onDisAgree() {
this.$bus.$emit('getCheckStatus', false);
this.$bus.$emit('closeButton', false);
this.resetCountDown();
},
// 同意
onAgree() {
this.$bus.$emit('getCheckStatus', true);
this.$bus.$emit('closeButton', false);
this.resetCountDown();
},
// 重置倒计时和关闭弹窗
resetCountDown() {
this.countDown = 3;
},
}

}
</script>

<style scoped lang="scss">
.agreement-container {
.agreement-content {
height: 500px;
padding: 5px 10px;
border-top: 0.5px soild;
border-bottom: 0.5px soild;
text-align: left;
overflow: scroll;
h5 {
padding: 5px;
}
p {
padding: 5px;
font-size: 14px;
line-height: 20px;
}
.agreement-button {
padding: 10px;
display: flex;
justify-content: space-around;
align-items: center;
.van-button {
height: 30px;
width: 120px;
border-radius: 10px;
}
}
}
}
</style>

+ 0
- 76
src/components/Checkbox.vue View File

@@ -1,76 +0,0 @@
<!--
* @Date: 2022-02-26 09:26:04
* @LastEditors: JinxChen
* @LastEditTime: 2022-03-04 11:40:00
* @FilePath: \AntpayFrontEnd\src\components\Checkbox.vue
* @description: 单选框组件
-->
<template>
<div class="checkbox-container">
<van-checkbox v-model="checked" shape="square" @change="onCheckChange">
<strong >已阅读协议并确认</strong>
</van-checkbox>
</div>
</template>

<script>
export default {
name:'checkbox',
mounted() {
this.getDialogData();
},
data(){
return {
checked: false,
}
},
methods: {
// 获取从dialog组件传过来的参数
getDialogData() {
this.$bus.$on('getCheckStatus', (data) => {
this.checked = data;
})
},
// 单选框值发生变化时
onCheckChange(value) {
this.checked = value;
this.$emit('SendCheckStatus', value);
},
}
}
</script>

<style scoped lang="scss">
.checkbox-container {
margin: 5px 0;
.agreement-container {
.agreement-content {
height: 500px;
padding: 5px 10px;
border-top: 0.5px soild;
border-bottom: 0.5px soild;
text-align: left;
overflow: scroll;
h5 {
padding: 5px;
}
p {
padding: 5px;
font-size: 14px;
line-height: 20px;
}
.agreement-button {
padding: 10px;
display: flex;
justify-content: space-around;
align-items: center;
.van-button {
height: 30px;
width: 120px;
border-radius: 10px;
}
}
}
}
}
</style>

+ 0
- 13
src/config/customize.js View File

@@ -1,13 +0,0 @@
/*
* @Date: 2022-02-26 15:09:25
* @LastEditors: JinxChen
* @LastEditTime: 2022-03-04 10:58:12
* @FilePath: \AntpayFrontEnd\src\config\customize.js
* @description: 个性化定制, 根据不同的商家定制个性化的界面
* 注意: 后期可以根据接口来实现
*/
import store from '../store/index';

export const CUSTOMIZE_SERVICE = {
isChunyu:() => store.getters.goodsNo === 889,
};

+ 0
- 49
src/config/map/index.js View File

@@ -1,49 +0,0 @@
/*
* @Date: 2022-01-14 09:15:21
* @LastEditors: JinxChen
* @LastEditTime: 2022-05-10 10:24:06
* @FilePath: \AntpayFrontEnd\src\config\map\index.js
* @description:
*/
import { AMapKey, AMapJsCode } from './models';

/**
* @param isSync 异步加载
* @param plugins 字符串数组格式 [ 'AMap.Geocoder', ... ]
* @returns {Promise}
* @constructor
*/
export default function MapLoader(isSync = false, plugins = []) {
return new Promise((resolve, reject) => {
try {
if (window.AMap && (plugins === null || plugins === undefined || plugins.length === 0)) {
resolve(window.AMap)
} else {
let script = document.createElement('script');
script.type = 'text/javascript';
script.async = !isSync;
script.src = `https://webapi.amap.com/maps?v=1.4.15&callback=initAMap&key=${AMapKey}&plugin=AMap.BezierCurveEditor${plugins ? ',' + plugins.join(',') : ''}`;
script.onerror = reject;
document.head.appendChild(script);

let script1 = document.createElement('script');
script1.type = 'text/javascript';
script1.async = false;
script1.src = 'https://webapi.amap.com/ui/1.0/main.js?v=1.0.11';
script1.onerror = reject;
if (isSync) {
document.head.appendChild(script1);
}
}
window.initAMap = () => resolve(window.AMap);

// JSAPI key搭配静态安全密钥以明文设置, 详情见: https://lbs.amap.com/api/jsapi-v2/guide/abc/load
window._AMapSecurityConfig = {
securityJsCode: `${AMapJsCode}`,
}
} catch (e) {
console.log(e);
}

})
}

+ 0
- 13
src/config/map/models.js View File

@@ -1,13 +0,0 @@
/*
* @Date: 2021-04-12 16:29:30
* @LastEditors: JinxChen
* @LastEditTime: 2022-05-09 14:16:46
* @FilePath: \AntpayFrontEnd\src\config\map\models.js
* @description:
*/
// 高德key
export const AMapKey = /* 'f7bc7e76645d2e84aa6bc62fdc5498a0' */ '6e4a6c39ea6d18b8dd3151baa3a7c0d5';


//高德jscode
export const AMapJsCode = '6a421e1233cd12dd4899e373e11bb641';

+ 1
- 1
src/config/models.js View File

@@ -5,7 +5,7 @@
* @FilePath: \AntpayFrontEnd\src\config\models.js
* @description:
*/
export const VERSION_MODEL = '1.0.8'; //版本号
export const VERSION_MODEL = '1.0.19F'; //版本号
export const IMAGE_URL = {
production: 'http://zfb.ssjlai.com/web/',
test: 'http://zfb.ssjlai.com/web/',


+ 70
- 0
src/http/java_api.js View File

@@ -0,0 +1,70 @@
/*
* @Author: linwl
* @Date: 2020-04-13 14:47:59
* @LastEditTime: 2023-02-24 14:54:19
* @LastEditors: JinxChen
* @Description: axios请求配置
* @FilePath: \TelpoH5FrontendWeb\src\http\requestPolymer.js
*/
import axios from 'axios';
import prefix from '@/store/prefix';
const httpProxyPrefix = process.env.VUE_APP_BASE_API + 'telpopay/';

// create an axios instance axios.create创建一个实例
const service = axios.create({
// baseURL: process.env.VUE_APP_BASE_API,
baseURL: httpProxyPrefix,
// timeout: 5000 // request timeout
});

const errorHandler = (error) => {
// const status = get(error, 'response.status');
const status = error.response.status;
console.log(status);
switch (status) {
case 400: error.message = '请求错误'; break;
case 401: error.message = '未授权,请登录'; break;
case 403: error.message = '拒绝访问'; break;
case 404: error.message = '请求地址出错'; break;
case 408: error.message = '请求超时'; break;
case 500: error.message = '服务器内部错误'; break;
case 501: error.message = '服务未实现'; break;
case 502: error.message = '网关错误'; break;
case 503: error.message = '服务器不可用'; break;
case 504: error.message = '网关超时'; break;
case 505: error.message = 'HTTP版本不受支持'; break;
default: break;
}
return Promise.reject(error);
};

// 请求拦截器,增加 token interceptors拦截
service.interceptors.request.use(
request => {
/* if (localStorage.getItem('token')) {

} */
if (localStorage.getItem(prefix + 'token')) {
request.headers.token = localStorage.getItem(prefix + 'token');
}
console.log(localStorage.getItem(prefix + 'token'));
return request;
},
errorHandler
);

// response interceptor
service.interceptors.response.use(
response => {
// const res = response.data
/* if (response.data.message !== null && response.data.message.indexOf('无效的Access Token') >= 0) { // 登录过期,未建立统一错误码,用 message 暂代
// 登录过期
NotifyService.notify({ type: 'warning', message: `请重新登录,${response.data.message}` });
setTimeout(() => router.push('/login'), 1500);
} */
return response;
},
errorHandler
);

export default service;

+ 1
- 1
src/http/request.js View File

@@ -6,7 +6,7 @@
* @description: 封装axios
*/

import axios from 'axios'
import axios from 'axios';
const httpRequestUrl = process.env.VUE_APP_BASE_API;

// create an axios instance axios.create创建一个实例


+ 58
- 0
src/http/webapi.js View File

@@ -0,0 +1,58 @@
/*
* @Author: linwl
* @Date: 2020-04-13 14:47:59
* @LastEditTime: 2023-02-24 10:47:44
* @LastEditors: JinxChen
* @Description: axios请求配置
* @FilePath: \TelpoH5FrontendWeb\src\http\webapi.js
*/
import axios from 'axios';
const httpProxyPrefix = process.env.VUE_APP_BASE_API + 'webapi';

// create an axios instance axios.create创建一个实例
const service = axios.create({
baseURL: httpProxyPrefix,
});

const errorHandler = (error) => {
// const status = get(error, 'response.status');
const status = error.response.status;
console.log(status);
switch (status) {
case 400: error.message = '请求错误'; break;
case 401: error.message = '未授权,请登录'; break;
case 403: error.message = '拒绝访问'; break;
case 404: error.message = '请求地址出错'; break;
case 408: error.message = '请求超时'; break;
case 500: error.message = '服务器内部错误'; break;
case 501: error.message = '服务未实现'; break;
case 502: error.message = '网关错误'; break;
case 503: error.message = '服务器不可用'; break;
case 504: error.message = '网关超时'; break;
case 505: error.message = 'HTTP版本不受支持'; break;
default: break;
}
return Promise.reject(error);
};

// 请求拦截器,增加 token interceptors拦截
service.interceptors.request.use(
request => {
/* if (localStorage.getItem('webapiToken')) {

} */
request.headers.AuthToken = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJVc2VySW5mbyI6eyJVc2VySWQiOiJjZTQzOWU1Yy03NWVjLTRhMTEtYWJmMC02YTdhM2IzY2UwMGQiLCJMb2dpbk5hbWUiOiIxODI3NzQyNjcxMiIsIkxvZ2luVHlwZSI6MX0sIkV4cCI6MTY4NDg5NTk5ODg4NS4wfQ.VK_fNU0QrCJwsc_Dxa_lPP1dvnxo73TfKzV_bJquqxU';
return request;
},
errorHandler
);

// response interceptor
service.interceptors.response.use(
response => {
return response;
},
errorHandler
);

export default service;

+ 87
- 56
src/main.js View File

@@ -1,84 +1,115 @@
/*
* @Date: 2022-01-19 10:08:26
* @LastEditors: JinxChen
* @LastEditTime: 2022-05-11 14:24:55
* @FilePath: \AntpayFrontEnd\src\main.js
* @LastEditTime: 2023-02-25 15:44:55
* @FilePath: \TelpoH5FrontendWeb\src\main.js
* @description:
*/
import Vue from "vue";
import 'amfe-flexible/index.js';
import App from "./App.vue";
import router from "./router";
import store from "./store";
import './assets/reset.scss'; //配置全局清除样式
import '@/assets/css/reset.scss';
// ui库按需引入
import 'vant/lib/index.css';
import {
Button,
Tab,
Tabs,
Image as VanImage,
Calendar,
Cell,
CellGroup,
RadioGroup,
Radio,
DropdownMenu,
DropdownItem,
Checkbox,
CheckboxGroup,
Col,
Row,
DatetimePicker,
Dialog,
Card,
Form,
Field,
Sku,
Divider,
Empty,
Notify,
Field,
Form,
Icon,
Image,
Lazyload,
List,
Loading,
Toast,
Popup,
Area,
Cascader,
Picker,
NavBar,
NoticeBar,
Icon,
ImagePreview,
Notify,
Overlay,
Picker,
Popup,
PullRefresh,
Radio,
RadioGroup,
Row,
Slider,
Swipe,
SwipeCell,
SwipeItem,
Switch,
Tag,
Tab,
Tabbar,
TabbarItem,
Tabs,
Toast,
} from 'vant'; //按需加载vant组件

Vue
.use(Button)
.use(Tab)
.use(VanImage)
.use(Cell)
.use(CellGroup)
.use(RadioGroup)
.use(Radio)
.use(DropdownMenu)
.use(DropdownItem)
.use(Checkbox)
.use(CheckboxGroup)
.use(Col)
.use(Row)
.use(Dialog)
.use(Card)
.use(Form)
.use(Field)
.use(Sku)
.use(Empty)
.use(Notify)
.use(Loading)
.use(Toast)
.use(Area)
.use(Popup)
.use(Picker)
.use(Cascader)
.use(Tag)
.use(NoticeBar)
.use(Icon)
.use(ImagePreview)
.use(Switch)
.use(Tabs);
.use(Button)
.use(Calendar)
.use(Checkbox)
.use(CheckboxGroup)
.use(Cell)
.use(CellGroup)
.use(Col)
.use(DatetimePicker)
.use(Dialog)
.use(Divider)
.use(Empty)
.use(Icon)
.use(Image)
.use(Form)
.use(Field)
.use(Lazyload)
.use(List)
.use(Loading)
.use(NavBar)
.use(NoticeBar)
.use(Notify)
.use(Overlay)
.use(Picker)
.use(Popup)
.use(PullRefresh)
.use(Radio)
.use(RadioGroup)
.use(Row)
.use(Slider)
.use(Swipe)
.use(SwipeCell)
.use(SwipeItem)
.use(Switch)
.use(Tab)
.use(Tabbar)
.use(TabbarItem)
.use(Tabs)
.use(Toast)

Vue.config.productionTip = false;
Vue.config.devtools = true;
// 全局配置 loading
Toast.setDefaultOptions('success', {
duration: 1500,
forbidClick: true,
});
Toast.setDefaultOptions('loading', {
duration: 0,
forbidClick: true,
});
Dialog.setDefaultOptions({
confirmButtonColor: "#3296fa",
cancelButtonColor: "#999",
showCancelButton: false
});
Vue.config.productionTip = false;
Vue.prototype.$bus = new Vue();
new Vue({


+ 0
- 18
src/pages/schedule/Schedule.vue View File

@@ -1,18 +0,0 @@
<template>
<div id="schedule"></div>
</template>

<script>
export default {
name:'',
data(){
return {

}
}
}
</script>

<style scoped>

</style>

+ 0
- 10
src/pages/schedule/schedule.js View File

@@ -1,10 +0,0 @@
import Vue from 'vue';
import Schedule from './Schedule.vue';
import router from '../../router';
import store from '../../store';
Vue.config.productionTip = false;
new Vue({
router,
store,
render: (h) => h(Schedule),
}).$mount("#schedule");

+ 6
- 28
src/router/index.js View File

@@ -1,8 +1,8 @@
/*
* @Date: 2022-01-19 10:08:26
* @LastEditors: JinxChen
* @LastEditTime: 2022-08-31 16:16:31
* @FilePath: \AntpayFrontEnd\src\router\index.js
* @LastEditTime: 2023-02-25 15:56:31
* @FilePath: \TelpoH5FrontendWeb\src\router\index.js
* @description:
*/
import Vue from "vue";
@@ -13,32 +13,10 @@ import "nprogress/nprogress.css";
Vue.use(VueRouter);
const routes = [
{ path: '/', redirect: 'index' },
{ path: '/index', name: 'index', component: resolve => require(['@/views/AliPayIndex'], resolve) },
{ path: '/form', name: 'form', component: resolve => require(['@/views/AliPayForm'], resolve) },
{ path: '/redirect', name: 'redirect', component: resolve => require(['@/views/AliPayRedirect'], resolve) },
{ path: '/result', name: 'result', component: resolve => require(['@/views/AliPayResult'], resolve) },
{ path: '/404', name: 'page-not-found', component: resolve => require(['@/views/page-not-found/index'], resolve) },
// 春雨
{ path: '/chunyuForm', name: 'chunyuForm', component: resolve => require(['@/views/chunyu/AliPayForm'], resolve) },
// 组件测试页面
{ path: '/compTest', name: 'compTest', component: resolve => require(['@/views/ComponentsTest'], resolve) },
// 新首页
{ path: '/index-new', name: 'index-new', component: resolve => require(['@/views/AlipayIndexNew'], resolve) },
{ path: '/form-new', name: 'form-new', component: resolve => require(['@/views/AliPayFormNew'], resolve) },

// 分销商模式- 首页
{ path: '/index-dealers', name: 'index-dealers', component: resolve => require(['@/views/alipay-dealers/AlipayIndexDealers'], resolve) },

// 分销商模式- 信息录入
{ path: '/form-dealers', name: 'form-dealers', component: resolve => require(['@/views/alipay-dealers/AlipayFormDealers'], resolve) },

// 高德地图测试demo
{ path: '/gaode-point-in-ring', name: 'gaode-point-in-ring', component: resolve => require(['@/views/gaode-demo/PointInRing'], resolve),},
// webSocketDemo
{ path: '/websocket-demo', name: 'websocket-demo', component: resolve => require(['@/views/websocket/websocket-demo'], resolve),},
// htmlCnavas demo
{ path: '/html-canvas-demo', name: 'html-canvas-demo', component: resolve => require(['@/views/htmlCanvas/htmlCanvasDemo'], resolve),},

{ path: '/index', name: 'index', component: resolve => require(['@/views/index'], resolve) },
{ path: '/packageHome', name: 'packageHome', component: resolve => require(['@/views/package-home'], resolve) },
{ path: '/packageList', name: 'packageList', component: resolve => require(['@/views/package-list'], resolve) },
{ path: '/payResult', name: 'payResult', component: resolve => require(['@/views/pay-result'], resolve) },

];



+ 64
- 37
src/store/index.js View File

@@ -1,59 +1,86 @@
/*
* @Date: 2022-01-19 10:08:26
* @Date: 2022-08-17 16:18:02
* @LastEditors: JinxChen
* @LastEditTime: 2022-02-14 15:29:30
* @FilePath: \alipay-scan-code-front-end\src\store\index.js
* @description: 配置store
* @LastEditTime: 2023-02-25 15:23:43
* @FilePath: \TelpoH5FrontendWeb\src\store\index.js
* @description:
*/
import Vue from 'vue';
import Vuex from 'vuex';
/* import prefix from '@/store/prefix'; */
import { isNotNull } from "../utils/index"

import prefix from '@/store/prefix';
import { isNotNull } from '@/utils';
Vue.use(Vuex);
export default new Vuex.Store({
state: {
goodsNo: '',
userId: '',
price: '',
count: '',
},
imei: '', //例子
gatewayToken: '', //gateway接口token
token: '',
wxAuthCode: '',
openId: '',
appId: '',
isFromWx: null
},
mutations: {
goodsNo(state, goodsNo) {
state.goodsNo = goodsNo;
window.localStorage[ 'goodsNo' ] = goodsNo;
imei(state, imei) {
state.imei = imei;
window.localStorage[ prefix + 'imei' ] = imei;
},
gatewayToken(state, gatewayToken) {
state.gatewayToken = gatewayToken;
window.localStorage[prefix + 'gatewayToken'] = gatewayToken;
},
token(state, token) {
state.token = token;
window.localStorage[prefix + 'token'] = token;
},
userId(state, userId) {
state.userId = userId;
window.localStorage[ 'userId' ] = userId;
wxAuthCode(state, wxAuthCode) {
state.wxAuthCode = wxAuthCode;
window.localStorage[prefix + 'wxAuthCode'] = wxAuthCode;
},
price(state, price) {
state.price = price;
window.localStorage[ 'price' ] = price;
openId(state, openId) {
state.openId = openId;
window.localStorage[prefix + 'openId'] = openId;
},
count(state, count) {
state.count = count;
window.localStorage[ 'count' ] = count;
appId(state, appId) {
state.appId = appId;
window.localStorage[prefix + 'appId'] = appId;
},
isFromWx(state, isFromWx) {
state.isFromWx = isFromWx;
window.localStorage[prefix + 'isFromWx'] = isFromWx;
},
},
getters: {
goodsNo: state => {
if (isNotNull(state.goodsNo)) return state.goodsNo;
else return window.localStorage[ 'goodsNo' ] == null ? '' : window.localStorage[ 'goodsNo' ];
imei: state => {
if (isNotNull(state.imei)) return state.imei;
else return window.localStorage[ prefix + 'imei' ] == null ? '' : window.localStorage[ prefix + 'imei' ];
},
gatewayToken: state => {
if (state.gatewayToken != '') return state.gatewayToken;
return window.localStorage[prefix + 'gatewayToken'] == null ? '' : window.localStorage[prefix + 'gatewayToken'];
},
token: state => {
if (state.token != '') return state.token;
return window.localStorage[prefix + 'token'] == null ? '' : window.localStorage[prefix + 'token'];
},
userId: state => {
if (isNotNull(state.userId)) return state.userId;
else return window.localStorage[ 'userId' ] == null ? '' : window.localStorage[ 'userId' ];
wxAuthCode: state => {
if (state.wxAuthCode != '') return state.wxAuthCode;
return window.localStorage[prefix + 'wxAuthCode'] == null ? '' : window.localStorage[prefix + 'wxAuthCode'];
},
price: state => {
if (isNotNull(state.price)) return state.price;
else return window.localStorage[ 'price' ] == null ? '' : window.localStorage[ 'price' ];
openId: state => {
if (state.openId != '') return state.openId;
return window.localStorage[prefix + 'openId'] == null ? '' : window.localStorage[prefix + 'openId'];
},
count: state => {
if (isNotNull(state.count)) return state.count;
else return window.localStorage[ 'count' ] == null ? '' : window.localStorage[ 'count' ];
appId: state => {
if (state.appId != '') return state.appId;
return window.localStorage[prefix + 'appId'] == null ? '' : window.localStorage[prefix + 'appId'];
},
isFromWx: state => {
if (state.isFromWx != '') return state.isFromWx;
return window.localStorage[prefix + 'isFromWx'] == null ? '' : window.localStorage[prefix + 'isFromWx'];
},
},

actions: {},
modules: {}
})
});

+ 5
- 4
src/store/prefix.js View File

@@ -1,9 +1,10 @@
/*
* @Date: 2022-01-19 16:37:44
* @Date: 2022-08-17 17:30:25
* @LastEditors: JinxChen
* @LastEditTime: 2022-02-23 17:36:21
* @FilePath: \AlipayFrontEnd\src\store\prefix.js
* @LastEditTime: 2023-02-25 15:23:55
* @FilePath: \TelpoH5FrontendWeb\src\store\prefix.js
* @description:
*/
const prefix = 'alipay_front_end_web_';
// 多个前端项目在一个域名底下,故缓存需要明确根据项目分类
const prefix = 'telpo_h5_';
export default prefix;

+ 0
- 269
src/views/AliPayForm.vue View File

@@ -1,269 +0,0 @@
<!--
* @Date: 2022-01-19 16:53:16
* @LastEditors: JinxChen
* @LastEditTime: 2022-04-12 15:53:34
* @FilePath: \AntpayFrontEnd\src\views\AliPayForm.vue
* @description: 春雨个性化表单
-->
<template>
<div class="form-container">
<!-- 头部 -->
<div class="form-header">
<div class="img-left">
<van-image :src="goodsData.imgPath" height="120"></van-image>
</div>
<div class="content-right">
<p>
<span>套餐名字:</span>
</p>
<p>{{goodsData.mainTitle}}</p>

<p>
<span>月套餐费:</span>
</p>
<p>
<span>¥{{ (goodsData.price/goodsData.count).toFixed(2) }}</span> x
<span>{{goodsData.count}}期</span>
<span v-show="goodsData.isAmountShow">=¥{{goodsData.price}}</span>
</p>
</div>
</div>
<!-- 中部表单 -->
<div class="form-body">
<van-form @submit="onSubmit" @failed="onFailed">
<div class="form-box">
<van-field
v-model="form.phoneNumber"
name="phoneNumber"
label="电话"
type="tel"
placeholder="必填"
maxlength="11"
required
clearable
:rules="[{ required: true, message: '请填写电话' }]"
/>
<van-field
v-model="form.schoolName"
name="schoolName"
label="学校"
placeholder="必填"
maxlength="30"
required
clearable
:rules="[{ required: true, message: '请填写学校' }]"
/>
<van-field
v-model="form.className"
name="className"
label="班级"
placeholder="必填"
maxlength="10"
required
clearable
:rules="[{ required: true, message: '请填写班级' }]"
/>
<van-field
v-model="form.userName"
name="userName"
label="学生"
placeholder="必填"
maxlength="10"
required
clearable
:rules="[{ required: true, message: '请填写学生' }]"
/>
</div>
<!-- '请知悉' 提示, -->
<div class="know-tips">
<h5>请知悉!</h5>
<p>点击以下按钮,启动支付宝页面"立即支付"</p>
<p>成功后,将分期每月从你的余额扣{{ (goodsData.price/goodsData.count).toFixed(2) }}元</p>
</div>
<div class="form-footer">
<van-button
native-type="onSubmit"
>{{submitText}}</van-button>
</div>
</van-form>
</div>
</div>
</template>

<script>
import { APIAlipay } from "../api/alipay";
import { IMAGE_URL } from '../config/models';
export default {
name:'alipay-form',
data(){
return {
goodsData: {
imgPath: '',
price: null,
count: null,
isAmountShow: '',
mainTitle: '',
title: '4G电子学生证资费套餐开通服务协议',
}, //接收从首页传过来的数据
form: {
phoneNumber: '',
schoolName: '',
className: '',
userName: '',
deviceImei: ''
}, //输入的表单数据
alipayForm: '', //接收支付宝接口返回的表单
submitText: '办理支付宝分期业务', //submit标题
}
},
mounted() {
this.getGoodsDetails();

},
methods: {
// 根据商品编号获取商品详情
getGoodsDetails() {
APIAlipay.getGoodsDetails(this.$store.getters.goodsNo)
.then(res => {
if(res.data.code === 20000) {
let good = res.data.data.goods;
console.log("good", good);
// 图片路径
this.goodsData.imgPath = IMAGE_URL[ process.env.NODE_ENV ] + good.goodsImg;
// 价格
this.goodsData.price = good.price;
// 是否是老用户
this.isOld = good.descriptionText === '' ? true : false;
// 商品名称
this.goodsData.mainTitle = good.mainTitle;
// 分期数
let count = good.periodizationJson.substring(1, good.periodizationJson.length - 1).split(',');
// 是否显示金额总数, todo 后期需从接口获取
this.goodsData.isAmountShow = JSON.parse(this.$route.query.isAmountShow);
this.goodsData.count = Math.max(...count);
this.goodsData.goodDefCount = Math.max(...count).toString();
}
})
},
// 办理支付宝分期业务表单校验通过后
onSubmit() {
let reg = /^1[3456789]\d{9}$/; //手机号码正则验证
if(!reg.test(this.form.phoneNumber)) {
this.$notify({
message: '请输入正确的手机号码',
type: 'warning',
duration: 1500
})
} else {
let reqBody = {
username: this.form.userName,
deviceImei: this.form.deviceImei === '' ? '123' : this.form.deviceImei,
schoolName: this.form.schoolName,
className: this.form.className,
phoneNumber: this.form.phoneNumber,
periodizationNum: Number(this.goodsData.count),
goodsNo: this.$store.getters.goodsNo,
alipayStateType: Number(this.goodsData.payType),
userId: this.$store.getters.userId,
}
APIAlipay.getAlipayForm(reqBody)
.then(res => {
this.alipayForm = res.data;
this.$store.commit('price', Number(this.goodsData.price));
this.$store.commit('count', Number(this.goodsData.count));
// 跳转到一个中转页 form,再通过这个中转页来调起支付宝的收银台
this.$router.push({path: 'redirect', query: {alipayForm: this.alipayForm}});
})
.catch(error => {
console.log(error);
})
}
},
// 表单不通过时
onFailed() {
console.log("表单输入不完整!");
},
}
}
</script>

<style scoped lang="scss">
.form-container {
height: 100vh;
width: 100vw;
display: flex;
flex-direction: column;
overflow: hidden;
/* padding: 5px;
border-radius: 20px; */
background-color: #f7f8fa;
.form-header {
height: 25vh;
display: flex;
justify-content: center;
align-items: center;
padding: 10px;
box-shadow: rgba(50, 50, 93, 0.25) 0px 2px 5px -1px,
rgba(0, 0, 0, 0.3) 0px 1px 3px -1px;
background-color: rgba(235, 233, 229, 0.726);
.img-left {
width: 120px;
}
.content-right {
flex: 1;
p {
font-size: 14px;
text-align: left;
padding: 5px 10px;
strong {
text-align: left;
}
}
}
}
.form-body {
flex: 1;
position: relative;
overflow: scroll;
/* padding: 10px; */
box-shadow: rgba(50, 50, 93, 0.25) 0px 2px 5px -1px,
rgba(0, 0, 0, 0.3) 0px 1px 3px -1px;
.know-tips {
height: 120px;
width: 100%;
padding: 10px;
h5 {
font-size: 16px;
text-align: left;
padding: 5px;
color: red;
}
p {
font-size: 14px;
padding: 5px;
text-align: left;
}
}
}
.form-footer {
height: 15vh;
width: 100%;
position: absolute;
padding: 10px;
bottom: 10px;
left: 0;
display: flex;
justify-content: center;
flex-direction: column;
.van-button {
height: 40px;
background-color: #1989fa;
color: white;
border-radius: 5px;
&.notSubmit {
background-color: rgba(150, 150, 146, 0.904);
}
}
}
}
</style>

+ 0
- 425
src/views/AliPayFormNew.vue View File

@@ -1,425 +0,0 @@
<!--
* @Date: 2022-01-19 16:53:16
* @LastEditors: JinxChen
* @LastEditTime: 2022-05-06 15:18:53
* @FilePath: \AntpayFrontEnd\src\views\AliPayFormNew.vue
* @description: 表单信息录入
-->
<template>
<div class="form-container">
<!-- 头部 -->
<div class="form-header">
<div class="img-left">
<van-image :src="goods.imgPath" height="120" @click="onPreview"></van-image>
<van-image-preview v-model="Imgshow" :images="images" @change="onChange"></van-image-preview>
</div>
<div class="content-right">
<p>
<span>套餐名字:</span>
</p>
<p>{{goods.mainTitle}}</p>
<p>
<span>{{ goods.amountTitle }}:</span>
</p>
<p v-if="goods.isAntPay">
<span class="font-red font-24">¥{{ (goods.price/goods.count).toFixed(2) }}</span> x
<span>{{goods.count}}期</span>
<span v-show="userTemplate.isShowMoney">=¥{{goods.price}}</span>
</p>
<p v-if="!goods.isAntPay">
<span class="font-red font-24">¥{{ goods.price }}</span>
</p>
</div>
</div>
<!-- 中部表单 -->
<div class="form-body pos-flex-cen">
<van-form ref="form" >
<van-field
v-model="form.schoolName"
v-if="userTemplate.isShowSchool"
name="学校名称"
label="学校名称:"
required
maxlength="50"
left-icon="wap-home-o"
clearable
:rules="[{ required: true, message: '请填写学校名称' }]"
/>
<van-field
v-model="form.className"
v-if="userTemplate.isShowClass"
name="年级班级"
label="年级班级:"
required
maxlength="20"
left-icon="description"
clearable
:rules="[{ required: true, message: '请填写年级班级' }]"
/>
<van-field
v-model="form.studentName"
v-if="userTemplate.isShowStudentName"
name="学生姓名"
label="学生姓名:"
required
maxlength="10"
left-icon="manager-o"
clearable
:rules="[{ required: true, message: '请填写学生姓名' }]"
/>
<van-field
v-model="form.parentName"
v-if="userTemplate.isShowParentName"
name="家长姓名"
label="家长姓名:"
required
maxlength="10"
left-icon="friends-o"
clearable
:rules="[{ required: true, message: '请填写家长姓名' }]"
/>

<van-field
v-model="form.contactsManName"
v-if="userTemplate.isShowContactsManName"
name="联系人"
label="联系人:"
required
maxlength="10"
left-icon="contact"
clearable
:rules="[{ required: true, message: '请填写联系人' }]"
/>
<van-field
v-model="form.contactsTelephone"
v-if="userTemplate.isShowContactsTelephone"
name="联系电话"
label="联系电话:"
required
maxlength="11"
left-icon="phone-o"
clearable
:rules="[{ required: true, message: '请填写联系电话' }]"
/>

<van-field
v-model="form.familyNumber"
v-if="userTemplate.isShowFamilyNumber"
type="textarea"
:autosize="true"
name="亲情号码"
label="亲情号码:"
placeholder="每个亲情号码用 , 隔开,最多可支持4个"
required
maxlength="50"
left-icon="phone-circle-o"
clearable
:rules="[{ required: true, message: '请填写亲情号码' }]"
/>

<van-field
v-model="form.studentCard"
v-if="userTemplate.isShowStudentCard"
name="学生身份证"
label="学生身份证:"
required
maxlength="20"
left-icon="idcard"
clearable
:rules="[{ required: true, message: '请填写学生身份证' }]"
/>
<van-field
v-model="form.receivingAddress"
v-if="userTemplate.isShowReceivingAddress"
name="收货地址"
label="收货地址:"
type="textarea"
:autosize="{ maxHeight: 100, minHeight: 25 }"
required
maxlength="50"
left-icon="location-o"
clearable
:rules="[{ required: true, message: '请填写收货地址' }]"
></van-field>
<van-cell :center="true" v-if="userTemplate.isShowReceivingAddress">
<div class="switch-address">
<div class="left">
<van-switch v-model="checked" />
</div>
<div class="rigth">
<van-icon name="warning" color="#1989fa" />
<span>点击切换到商家配送</span>
</div>
</div>
</van-cell>
</van-form>
</div>
<!-- 底部按钮 -->
<div class="form-footer">
<div class="know-tips">
<p class="font-red font-big">
<van-icon name="warning" size="15" color="#1989fa" />
<span class="font-16">请知悉:</span>
</p>
<p v-if="goods.isAntPay">每月从您的支付宝余额扣除{{(goods.price / goods.count).toFixed(2)}}元</p>
<p v-if="!goods.isAntPay">即将从您的余额扣除{{goods.price}}元</p>
</div>
<van-button :class="['van-button', {notSubmit: !canSubmit }]" block @click="onSubmit">
<span class="font-white">{{submitText}}</span>
</van-button>
</div>
</div>
</template>

<script>
import { APIAlipay } from "../api/alipay";
import { isNotNull } from "../utils/index";
import { IMAGE_URL } from '../config/models';
export default {
name:'alipay-form',
data(){
return {
goods: {
imgPath: '',
price: '',
count: '',
type: '',
userId: '',
goodsNo: '',
isAmountShow: '',
mainTitle: '',
amountTitle: '',
isAntPay: null,
}, //接收从首页传过来的数据
form: {
studentName: '',
parentName: '',
schoolName: '',
className: '',
studentCard: '',
receivingAddress: '到店自提',
contactsManName: '',
contactsTelephone: '',
}, //输入的表单数据
userTemplate: {
isShowMoney: null,
isShowClass: true,
isShowContactsManName: null,
isShowContactsTelephone: true,
isShowFamilyNumber: null,
isShowParentName: null,
isShowReceivingAddress: null,
isShowSchool: true,
isShowStudentCard: null,
isShowStudentName: true,
},
alipayForm: '', //接收支付宝接口返回的表单
submitText: '办理支付宝分期业务', //submit标题
Imgshow: false, //相片预览
images: [
'https://img01.yzcdn.cn/vant/apple-1.jpg',
], //预览图片数组
canSubmit: false, //是否可以提交, 默认false
checked: false, //地址选择开关

}
},
created() {
this.getGoodsDetails();
this.initQueryData();
this.getUserTemplate();
},
methods: {
// 根据商品编号获取商品详情
getGoodsDetails() {
APIAlipay.getGoodsDetails(this.$store.getters.goodsNo, this.$store.getters.userId)
.then(res => {
if(res.data.code === 20000) {
let good = res.data.data.goods;
console.log("good", good);
// 图片路径
this.goods.imgPath = IMAGE_URL[ process.env.NODE_ENV ] + good.goodsImg;
// 价格
// 是否是老用户
this.isOld = good.descriptionText === '' ? true : false;
// 商品名称
this.goods.mainTitle = good.mainTitle;
// 是否显示金额总数, todo 后期需从接口获取
/* this.goods.isAmountShow = JSON.parse(this.$route.query.isAmountShow); */
}
})
},
// initQueryData 初始化路由传过来的数据
initQueryData() {
let query = this.$route.query;
this.goods.price = query.price;
this.goods.count = JSON.parse(query.count);
this.goods.type = JSON.parse(query.type);
this.goods.mainTitle = query.mainTitle;
this.goods.userId = JSON.parse(query.userId);
this.goods.goodsNo = JSON.parse(query.goodsNo);
this.goods.amountTitle = JSON.parse(query.type) === 2 ? '月套餐费' : '支付总额';
this.goods.isAntPay = JSON.parse(query.type) === 2;
},
// getUserTemplate 根据用户id 获取用户模板信息 判断页面组件是否需要渲染
getUserTemplate() {
APIAlipay.getUserTemplate(this.goods.userId)
.then(res => {
if(res.data.code === 20000) {
let data = res.data.data.goodsTemplate;
console.log("用户模板", data);
if(isNotNull(data)) {
this.userTemplate.isShowMoney = data.isShowMoney === 1;
this.userTemplate.isShowClass = data.isShowClass === 1;
this.userTemplate.isShowContactsManName = data.isShowContactsManName === 1;
this.userTemplate.isShowContactsTelephone = data.isShowContactsTelephone === 1;
this.userTemplate.isShowFamilyNumber = data.isShowFamilyNumber === 1;
this.userTemplate.isShowReceivingAddress = data.isShowReceivingAddress === 1;
this.userTemplate.isShowSchool = data.isShowSchool === 1;
this.userTemplate.isShowStudentCard = data.isShowStudentCard === 1;
this.userTemplate.isShowStudentName = data.isShowStudentName === 1;
}
}
})
},
// 办理支付宝分期业务表单校验通过后
onSubmit() {
if (!this.isCanSubmit(this.form)) {return};
let reg = /^1[3456789]\d{9}$/; //手机号码正则验证
if(!reg.test(this.form.phoneNumber)) {
this.$notify({
message: '请输入正确的手机号码',
type: 'warning',
duration: 1500
})
} else {
let reqBody = {
username: this.form.userName,
deviceImei: this.form.deviceImei === '' ? '123' : this.form.deviceImei,
schoolName: this.form.schoolName,
className: this.form.className,
phoneNumber: this.form.phoneNumber,
periodizationNum: Number(this.goods.count),
goodsNo: this.$store.getters.goodsNo,
alipayStateType: Number(this.goods.payType),
userId: this.$store.getters.userId,
}
APIAlipay.getAlipayForm(reqBody)
.then(res => {
this.alipayForm = res.data;
this.$store.commit('price', Number(this.goods.price));
this.$store.commit('count', Number(this.goods.count));
// 跳转到一个中转页 form,再通过这个中转页来调起支付宝的收银台
this.$router.push({path: 'redirect', query: {alipayForm: this.alipayForm}});
})
.catch(error => {
console.log(error);
})
}
},
// 表单不通过时
isCanSubmit(form) {
console.log(form);
},
// 图片预览
onChange() {

},
// 点击图片预览大图
onPreview() {
this.Imgshow = true;
}
}
}
</script>
<style lang="scss">
.van-form {
overflow: scroll;
border-radius: 10px;
}
</style>
<style scoped lang="scss">
.form-container {
height: 100vh;
width: 100vw;
display: flex;
flex-direction: column;
overflow: hidden;
padding: 20px;
.form-header {
height: 25vh;
display: flex;
justify-content: center;
align-items: center;
padding: 10px 0 10px 10px;
border-top-left-radius: 10px;
border-top-right-radius: 10px;
box-shadow: rgb(38, 57, 77) 0px 10px 20px -10px;
background-color: #fff;
/* background: linear-gradient(to bottom right, rgb(96, 141, 238), 60%, rgb(154, 213, 252)); */
.img-left {
width: 120px;
}
.content-right {
flex: 1;
p {
font-size: 14px;
text-align: left;
padding: 5px 10px;
strong {
text-align: left;
}
}
}
}
.form-body {
flex: 1;
width: 100%;
overflow: scroll;
margin: 20px 0 10px 0;
padding: 0;
box-shadow: rgb(38, 57, 77) 0px 10px 20px -10px;
border-bottom-left-radius: 10px;
border-bottom-right-radius: 10px;
background-color: #fafafa;
/* background: linear-gradient(to bottom right, rgb(154, 213, 252), 70%, rgb(96, 141, 238)); */
.switch-address {
display: flex;
justify-content: flex-start;
align-items: center;
.rigth {
padding-left: 10px;
}
}
}
.form-footer {
height: 20vh;
width: 100%;
padding: 0 10px;
display: flex;
justify-content: flex-end;
align-items: center;
flex-direction: column;
.know-tips {
width: 100%;
display: flex;
justify-content: flex-start;
align-items: flex-start;
flex-direction: column;
margin-bottom: 10px;
border-radius: 10px;
p {
padding: 5px;
}
}
.van-button {
background-color: #1989fa;
color: white;
border: none;
&.notSubmit {
background-color: rgb(150, 196, 241);
}
}
}
}
</style>

+ 0
- 535
src/views/AliPayIndex.vue View File

@@ -1,535 +0,0 @@
<!--
* @Date: 2022-01-19 16:52:21
* @LastEditors: JinxChen
* @LastEditTime: 2022-04-08 10:28:58
* @FilePath: \AntpayFrontEnd\src\views\AliPayIndex.vue
* @description:
-->
<template>
<div class="index-container">
<!-- 头部banner -->
<div class="index-banner">
<img class="img-contanier" :src="goodsData.imgPath"/>
</div>
<!-- 中间内容 -->
<div class="index-body">
<p class="set-meal-title">月套餐费: <span class="set-meal-price">¥{{ (goodsData.price/goodsData.count).toFixed(2) }}</span> x <span>{{goodsData.count}}期</span> <span v-show='isAmountShow'> = ¥{{goodsData.price}}</span></p>
<p class="index-tips">{{switchPayType}}:</p>
<!-- 花呗or支付宝 -->
<van-radio-group class="radio-group" v-model="radio" @change="onRadioChange">
<van-cell-group>
<!-- 支付宝 -->
<van-cell title="" clickable @click="radio = '1'" v-show="isAlipayShow">
<template #icon>
<img :src="alipayIconPath" alt="" class="pay-icon">
</template>
<template #right-icon>
<span class="radio-group-span">支付宝</span>
<van-radio name="1" />
</template>
</van-cell>
<!-- 花呗 -->
<van-cell title="" clickable @click="radio = '2'">
<template #icon>
<img :src="antpayIconpath" alt="" class="pay-icon">
</template>
<template #right-icon>
<span class="radio-group-span">花呗<label>(推荐)</label></span>
<van-radio name="2" />
</template>
</van-cell>
<!-- 花呗分期 -->
<div class="antpay-container" v-show="isAntpay">
<van-row>
<van-col span="6" class="antpay-row-col-6"><p>花呗分期:</p></van-col>
<van-col span="18" class="antpay-row-col-18">
<van-radio-group v-model="antPayRadio" @change="onChange">
<van-button type="default" size="mini" v-for="(item) in countList" :key="item.value">
<van-radio :name="item.value">
<p>分{{item.value}}期</p>
<p>每期{{ (goodsData.price/item.value).toFixed(2) }}元</p>
</van-radio>
</van-button>
</van-radio-group>
</van-col>
</van-row>
</div>
</van-cell-group>
</van-radio-group>
<!-- 我要开通花呗 -->
<p class="open-antpay" @click="onOpenAntpay">我要开通花呗</p>
<!-- 协议 -->
<p class="agreement" @click="onOpenAgreement">{{agreement.title}}</p>
<!-- 协议内容 -->
<van-dialog
class="agreement-container"
v-model="agreement.show"
:title="agreement.title"
confirm-button-color="#1989fa"
:show-confirm-button="false"
>
<div class="agreement-content">
<h5>一.开通需知及承诺</h5>
<p v-show="isNewCustom">1.感谢用户使用支付宝花呗分期功能。</p>
<p v-show="isNewCustom">2.用户自愿开通4G电子学生证资费套餐服务({{goodsData.count}}<!-- 24 -->期)每月自动通过支付宝花呗分期支付资费(话费+流量)套餐费{{(goodsData.price/goodsData.count).toFixed(2)}}元/月。</p>
<p v-show="isNewCustom">3.用户需连续使用该资费套餐24期,可据此领取4G电子学生证1台、电话卡1张。</p>
<p style="white-space: pre-wrap"><span v-show="isNewCustom">4.</span>{{goodsData.description}}</p>
<p v-show="isOldCustom">5.协议期内,电子学生证非人为损坏或进水按“三包”政策进行免费维修或更换。如丢失或人为损坏,按优惠价重新购买。</p>
<p v-show="isOldCustom">6.北京随手精灵科技有限公司接受电子学生证运营销售商委托采用支付宝花呗分期付代收业务货款。</p>
<h5>二.用户承诺</h5>
<p>1.用户已充分了解支付宝花呗付款条款(含支付宝花呗相关规则),充分阅读及理解本协议。</p>
<p>2.用户已经签署业务订购回执,自愿购买并同意签署本协议。</p>
<h5>三.法律适用与管辖</h5>
<p>本协议之效力、解释、变更、执行与争议解决均适用中华人民共和国法律。因本协议产生的争议,均应依照中华人民共和国法律予以处理。</p>
<p v-show="!agreement.isButtonShow">{{agreement.countDown}}秒后显示按钮</p>
<div class="agreement-button" v-show="agreement.isButtonShow">
<van-button type="warning" @click="onDisAgree" round>不同意</van-button>
<van-button type="info" @click="onAgree" round>同意</van-button>
</div>
</div>
</van-dialog>
</div>
<!-- 底部 -->
<div class="index-footer-out">
<div class="index-footer">
<div class="checkbox-container" v-show="!isChunyu">
<van-checkbox v-model="checked" shape="square" @change="onCheckChange"><strong>已阅读协议并确认</strong></van-checkbox>
</div>
<div class="footer-button">
<van-button :class="['van-button', {notSubmit: !checked && !isChunyu}]" block @click="onSubmit">{{submitText}}</van-button>
</div>
</div>
</div>
<!-- 非支付宝浏览器提示弹窗 -->
<van-dialog v-model="isAlipayBrowser" title="提示您切换支付宝扫码!"
:show-cancel-button="false"
:show-confirm-button="false"
confirm-button-color="#1989fa"
className="alipay-dialog"
:close-on-click-overlay="true">
<p>1.如果已安装支付宝,请打开支付宝扫码。</p>
<p>2.如果未安装支付宝,请到应用商店下载。
<span v-show="!isAndroid" @click="onDownAlipay" class="down">点击前往应用商店下载</span>
<span v-show="isAndroid">或复制 {{alipayDownUrl.android}}
[<span @click="onCopy" class="copy-span">点击复制
</span>],粘贴到浏览器打开下载页面。</span></p>
<p class="close-text">点击屏幕任意地方关闭弹窗</p>
</van-dialog>
</div>
</template>

<script>
import { isNotNull, isAlipayBrowser, isAndroid } from "../utils/index";
import { APIAlipay } from "../api/alipay";
import { IMAGE_URL, USER_AGENT, ALIPAY_DOWN_URL} from '../config/models';
/* import { CUSTOMIZE_SERVICE } from '../config/customize'; */
export default {
name:'alipay-index',
data(){
return {
// 商品数据
goodsData: {
imgPath: null /* || require('../assets/banner_03.jpg') */, //首页图片路径
price: null, //价格
count: null, //分期数
defCount: null, //默认分期数
amount: 480, //总数
isOld: null, //是否是老用户
description: null, //商品描述
defDescription: '电子学生证套餐两年内(24个月)内含每月200分钟通话和1.5G流量,超出通话或流量部分,由用户自行交费。', //默认协议内容
payType: null, //支付类型, 2是花呗, 1 是支付宝
name: null, //商品名称
},
radio: '2', //单选框的值,默认是 '2', 2是花呗, 1支付宝
antPayRadio: '', //花呗分期,默认24期
antpayIconpath: require('../assets/antpay.png'), //花呗支付图片
alipayIconPath: require('../assets/alipay.png'), //支付宝图片
checked: false, //是否已经勾选协议
isAlipayShow: true, //是否显示支付宝选项
goodsNo: '', //商品id
countList: null, //分期数数组
isAmountShow: true, //是否显示总数, 默认显示,部分客户不需要显示则false
isAntpay: true, //单选是否是花呗, 默认是花呗,否则是支付宝
agreement: {
title: '4G电子学生证资费套餐开通服务协议', //协议标题
show: false, //是否显示协议内容,默认不显示
isButtonShow: false, //是否显示按钮
timer: '', //定义一个倒计时
countDown: 3, //同意/不同意按钮显示倒计时
},
isNewCustom: true, //是否是新用户
isOldCustom: false, //是否是新用户
checkCount: 0, //首次点击同意协议单选框
isAlipayBrowser: !isAlipayBrowser(USER_AGENT), //是否是支付宝浏览器
isAndroid: isAndroid(USER_AGENT), //用户设备是否是android
alipayDownUrl: ALIPAY_DOWN_URL, //支付宝app下载链接
isChunyu: null, //是否是春雨
submitText: '一键下单' , //submit文字, 默认 一键下单, 可根据客户需求变化
switchPayType: '可切换支付方式', //默认 可切换支付方式, 可根据客户需求变化

}
},
mounted() {
this.storeQueryParams();
this.getGoodsDetails();
},
methods: {

// 缓存通过扫码得到的商品id
storeQueryParams() {
let params = this.$route.query;
this.initDealContent(params.goodsNo);
console.log("扫码传过来的参数", params);
if(isNotNull(params.goodsNo)) {
this.goodsNo = params.goodsNo;
this.$store.commit('goodsNo', params.goodsNo);
this.$store.commit('userId', params.userId);
} else {
this.$router.push({path: '/404'})
}
},
// 初始化协议内容,根据不同客户的商品id显示不同的协议内容
initDealContent(goodsNo) {
if(goodsNo === '1452515524181975040') {
this.isAlipayShow = true;
} else if(goodsNo === '1462964210433548288' || goodsNo === '1472882092902715392' || goodsNo === '1479390914305277952') {
this.isAmountShow = false;
} else if (goodsNo === '1483687825375969280') { //翼校云定制的商品id
this.agreement.title = '电子学生证AI套餐开通服务协议';
this.isNewCustom = false;
this.isAmountShow = true;
} else if (goodsNo === '889') {
this.isChunyu = false;
this.submitText = '下一步';
this.switchPayType = '支付方案'
}
else {
this.isAmountShow = true;
}
},
// 根据商品id获取商品详情
getGoodsDetails() {
APIAlipay.getGoodsDetails(this.goodsNo)
.then(res => {
if(res.data.code === 20000) {
let good = res.data.data.goods;
console.log("good", good);
// 图片路径
this.goodsData.imgPath = IMAGE_URL[ process.env.NODE_ENV ] + good.goodsImg;
// 价格
this.goodsData.price = good.price;
// 是否是老用户
this.isOld = good.descriptionText === '' ? true : false;
// 商品名称
this.goodsData.name = good.mainTitle;
//商品描述 根据\n换行符来把数据进行换行
this.goodsData.description = good.descriptionText === '' ? this.goodsData.defDescription : good.descriptionText.replace(/\\n/g,"<br/>");
// 分期数
let goodCount = good.periodizationJson.substring(1, good.periodizationJson.length - 1).split(',');
this.goodsData.goodCount = Math.max(...goodCount);
this.goodsData.defCount = Math.max(...goodCount).toString();
this.antPayRadio = Math.max(...goodCount).toString();
this.countList = goodCount.map(g => {
return {
value: g,
label: g
}
}).reverse();
console.log("this.countList", this.countList);
} else {
this.$notify({
message: '系统出现错误,请联系管理员!',
type: 'warning',
duration: 1000
});
}
})
},
// 单选支付宝花呗发生变化时
onRadioChange(values) {
this.isAntpay = values === '2' ? true : false;
this.radio = values;
this.goodsData.payType = Number(values);
},
// 选择分期数改变时
onChange(values) {
this.goodsData.count = values;
},
// 我要开通花呗弹窗
onOpenAntpay() {
this.$dialog.confirm({
title: '如何开通花呗?',
message: `
<p>进入支付宝APP-右下角【我的】-【花呗】,点击后按页面提示操作开通即可。</p>
`,
showCancelButton: false,
messageAlign: 'center',
confirmButtonColor: '#1989fa'
})
},
// 打开协议
onOpenAgreement() {
this.agreement.show = true;
this.checkCount ++;
if(this.checkCount <= 1) {
this.agreement.timer = setInterval(() =>{
this.agreement.countDown --;
if(this.agreement.countDown === 0) {
this.agreement.isButtonShow = true;
clearInterval(this.agreement.timer);
this.agreement.countDown = 3;
}
},1000)
} else if(this.checkCount >= 2){
this.agreement.isButtonShow = true;
}
},
// 复选框绑定值变化时
onCheckChange() {
if(this.checkCount < 1) {
// 首次选择复选框自动打开协议
this.onOpenAgreement();
this.checkCount ++;
} else if (this.checkCount >= 2) {
this.agreement.isButtonShow = true;
}
},

// 不同意
onDisAgree() {
this.checked = false;
this.resetCountDown();
},
// 同意
onAgree() {
this.checked = true;
this.resetCountDown();
},
// 重置倒计时和关闭弹窗
resetCountDown() {
this.agreement.show = false;
this.agreement.isButtonShow = false;
clearInterval(this.agreement.timer);
this.agreement.countDown = 3;
},
// 一键下单提交按钮
onSubmit() {
if(this.checked === false && !this.isChunyu) {
this.$notify({
message: `请阅读并勾选同意${this.agreement.title}`,
type: 'warning',
duration: 1500
})
}else if( this.isChunyu ) {
this.$router.push({path: 'chunyuForm', query: {isAmountShow: this.isAmountShow}})
}
else {
this.$router.push({path: 'form', query: {isAmountShow: this.isAmountShow}})
}
},
// 点击下载支付宝app
onDownAlipay() {
window.location.href = this.alipayDownUrl.ios;
},
// 复制网址
onCopy() {
let oInput = document.createElement('input');
oInput.value = this.alipayDownUrl.android;
document.body.appendChild(oInput);
oInput.select(); // 选择对象;
console.log(oInput.value)
document.execCommand("Copy"); // 执行浏览器复制命令
this.$toast.success('已复制到粘贴板!');
oInput.remove()
}
}
}
</script>

<style scoped lang="scss">
.index-container {
height: 100vh;
width: 100vw;
display: flex;
flex-direction: column;
overflow: hidden;
box-shadow: rgba(241, 241, 245, 0.932) 0px 30px 60px -12px inset, rgba(239, 242, 243, 0.884) 0px 18px 36px -18px inset;
.index-banner{
height: 40vh;
width: 100vw;
/* padding: 5px 5px 0 5px; */
.img-contanier {
height: 40vh;
width: 100vw;
}
}
.index-body {
flex: 1;
/* margin: 0 5px 5px 5px; */
padding: 0 10px 10px 10px;
overflow: scroll;
box-shadow: rgba(0, 0, 0, 0.09) 0px 2px 1px, rgba(0, 0, 0, 0.09) 0px 4px 2px, rgba(0, 0, 0, 0.09) 0px 8px 4px, rgba(0, 0, 0, 0.09) 0px 16px 8px, rgba(0, 0, 0, 0.09) 0px 32px 16px;
.set-meal-title {
font-size: 16px;
text-align: left;
padding: 5px 0 5px 0;
.set-meal-price {
font-size: 24px;
color: red;
}
}
.index-tips {
font-size: 16px;
text-align: left;
margin: 5px 0;
}
.van-cell {
height: 45px;
line-height: 45px;
padding: 0;
border: 0.5px solid #dcdee2;
border-radius: 10px;
margin-top: 10px;
}
.radio-group {
.radio-group-span {
padding-right: 5px;
label {
color: red;
}
}
.antpay-container {
height: 50px;
line-height: 50px;
/* padding: 5px 0; */
background-color: white;
}
.van-row, .antpay-row-col-18{
height: 50px;
line-height: 50px;
.antpay-row-col-6 {
p {
text-align: left;
font-size: 16px;
}
}
.antpay-row-col-18 {
display: flex;
/* justify-content: center;
align-items: center; */
line-height: 40px;
.van-radio-group {
overflow-x: auto;
white-space: nowrap;
}
.van-radio-group::-webkit-scrollbar {
display: none;
}
.van-button {
height: 40px;
width: 120px;
display: inline-block;
border-radius: 5px;
}
}
}
}
.open-antpay, .agreement {
height: 20px;
line-height: 20px;
text-decoration:underline;
text-align: left;
font-size: 14px;
margin: 5px 0px;
}
.open-antpay {
color: red;
}
.agreement {
margin: 5px 0px;
}
.agreement-container {
.agreement-content {
height: 500px;
padding: 5px 10px;
border-top: .5px soild;
border-bottom: .5px soild;
text-align: left;
overflow: scroll;
h5 {
padding: 5px;
}
p {
padding: 5px;
font-size: 14px;
line-height: 20px;

}
.agreement-button {
padding: 10px;
display: flex;
justify-content: space-around;
align-items: center;
.van-button {
height: 30px;
width: 120px;
border-radius: 10px;
}
}
}
}
.pay-icon {
height: 30px;
width: 30px;
margin: 5px;
}
}
.index-footer-out, .index-footer {
height: 15vh;
width: 100vw;
padding: 10px 10px ;
.index-footer {
position: absolute;
left: 0;
bottom: 0;
z-index: 999;
display: flex;
justify-content: center;
flex-direction: column;
.checkbox-container {
margin: 5px 0;
}
.footer-button {
/* box-shadow: rgb(217, 218, 219) 0 20px 30px -15px; */
.van-button {
background-color: #1989fa;
color: white;
border-radius: 5px;
&.notSubmit {
background-color: rgba(150, 150, 146, 0.904);
}
}
}
}
}
.alipay-dialog {
p {
padding: 10px;
line-height: 20px;
text-align: left;
font-size: 14px;
}
.down {
display: block;
color: #1989fa;
text-decoration: #1989fa;
}
.copy-span {
color: red;
}
.close-text {
text-align: center;
}
}
}
</style>

+ 0
- 36
src/views/AliPayRedirect.vue View File

@@ -1,36 +0,0 @@
<!--
* @Date: 2022-01-19 16:54:08
* @LastEditors: JinxChen
* @LastEditTime: 2022-03-04 10:26:29
* @FilePath: \AntpayFrontEnd\src\views\AliPayRedirect.vue
* @description:
-->
<template>
<div></div>
</template>

<script>
export default {
name:'alipay-redirect',
data(){
return {
queryData: this.$route.query.alipayForm, //接收上一个页面传过来的支付宝表单文件
}
},
mounted() {
this.createAlipayPage();
},
methods: {
createAlipayPage() {
const div = document.createElement('div'); //在当前页面创建一个div的节点
div.innerHTML = this.queryData; //将支付宝的form表单数据添加到div里面
document.body.appendChild(div); //把这个节点添加到页面的body里面去
document.forms[0].submit(); //自动调用form表单的submit方法正式调起支付宝的收银台界面
}
}
}
</script>

<style scoped lang="scss">

</style>

+ 0
- 171
src/views/AliPayResult.vue View File

@@ -1,171 +0,0 @@
<!--
* @Date: 2022-01-19 16:55:03
* @LastEditors: JinxChen
* @LastEditTime: 2022-04-12 18:16:42
* @FilePath: \AntpayFrontEnd\src\views\AliPayResult.vue
* @description:
注意:本地调试需要手动在url添加参数
?out_trade_no=2021112316151201&trade_no=2021112322001402891436965855
-->

<template>
<div class="pay-result-container">
<!-- 接口轮询时加载动画以及空状态 -->
<van-empty v-show="isResultBack" image="https://img01.yzcdn.cn/vant/custom-empty-image.png" />
<van-loading v-show="isResultBack" type="spinner" color="black">获取结果中...</van-loading>
<!-- 接口轮询完成后 -->
<div class="pay-result-content" v-show="!isResultBack">
<div class="result-header">
<p v-if="isPaySuccess" class="font-red font-24"><van-icon name="checked" color="green"/>{{ checkSuccess.tips }}</p>
<p v-if="isPaySuccess" class="font-red font-24"><van-icon name="checked" color="green"/>{{ checkSuccess.title }}</p>
<p v-if="!isPaySuccess" class="font-white font-24"><van-icon name="info-o" />{{checkFail.tips}}</p>
<p v-if="isPaySuccess">接下来将按分期每月从你的支付宝余额扣{{(price/count).toFixed(2)}}元。</p>
<p>{{isPaySuccess ? checkSuccess.content : checkFail.content}}</p>
</div>
<!-- 页脚 -->
<div class="result-footer">
<p>商家订单号: </p>
<p class="font-white">{{alipayOrder.outradeNo}}</p>
<p>请保存好该订单号截图,方便售后服务。</p>

</div>
</div>

</div>
</template>

<script>
import { isNotNull } from "../utils/index";
import { APIAlipay } from "../api/alipay";
export default {
name:'alipay-result',
data(){
return {
alipayOrder: {
outradeNo: '',
tradeNo: '',
}, //支付宝返回的订单号
timer: "", //计时器
num: 1, //轮询次数
price: this.$store.getters.price,
count: this.$store.getters.count,
isPaySuccess: null, //是否支付成功
isResultBack: false, //是否有结果返回
checkSuccess: {
tips: "恭喜你!",
title: '支付宝分期业务办理成功!',
content: "可进入支付宝-->我的-->花呗-->我的账单,查询详情。"
}, //查询支付结果成功时
checkFail: {
tips: "查询交易信息失败!",
content: "请进入支付宝-->我的-->花呗-->我的账单,查询详情。"
}, //查询支付结果失败时

}
},
mounted() {
this.getParamsData();
this.closeTime();
},
methods: {
// 获取url拼接的params
getParamsData() {
let params = this.$route.query;
console.log("支付宝返回的信息", params);
if (isNotNull(params)) {
this.alipayOrder.outradeNo = params.out_trade_no;
this.alipayOrder.tradeNo = params.trade_no;
this.getPayResult();
}
},
// 根据订单号轮询获取订单结果和状态
getPayResult() {
let that = this;
let reqBody = {
outTradeNo: this.alipayOrder.outradeNo,
tradeNo: this.alipayOrder.tradeNo
};
if(that.num > 30 ) {
if(that.timer){
clearInterval(that.timer);
}
} else {
that.timer = setInterval(() => {
that.num ++;
APIAlipay.getAlipayResult(reqBody)
.then(res => {
if(res.data.code === 20000) {
this.isResultBack = false;
this.isPaySuccess = true;
if(that.timer) {
clearInterval(that.timer)
}
}
}).catch(e => {
console.log(e)
})
}, 2000)
}
},
// 30秒后关闭轮询
closeTime() {
setTimeout(() => {
clearInterval(this.timer);
console.log("即将关闭轮询");
if(this.isPaySuccess === null && this.isResultBack === true) {
this.isResultBack = false;
this.isPaySuccess = false;
}
}, 30000);
},
}
}
</script>

<style scoped lang="scss">
.pay-result-container {
height: 100vh;
width: 100%;
padding: 20px;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
background: linear-gradient(to bottom right, rgb(154, 213, 252), 65%, rgb(96, 141, 238) );
.pay-result-content {
height: 100vh;
width: 100%;
.result-header, .result-footer {
display: flex;
justify-content: center;
flex-direction: column;
}
.result-header {
align-items: flex-start;
height: 50vh;
p {
text-align: left;
padding: 10px;
}
h5 {
font-size: 24px;
text-align: left;
padding: 10px;
}
}
.result-footer {
height: 50vh;
width: 100%;
border-top: 1px solid white;
align-items: center;
p {
/* font-size: 16px; */
padding: 10px;
}
p:nth-child(2) {
padding: 20px;
}
}
}
}
</style>

+ 0
- 636
src/views/AlipayIndexNew.vue View File

@@ -1,636 +0,0 @@
<!--
* @Date: 2022-04-08 10:53:53
* @LastEditors: JinxChen
* @LastEditTime: 2022-05-06 15:08:17
* @FilePath: \AntpayFrontEnd\src\views\AlipayIndexNew.vue
* @description:
-->
<template>
<div class="index-container">
<!-- banner -->
<div class="banner pos-flex-cen">
<van-image
:src="goods.bannerImg"
radius="10"
cover
/>
</div>
<!-- main -->
<div class="main pos-flex-cen-column">
<div class="main-container">
<div class="pay-choose">
<!-- 支付宝和花呗 选择-->
<div class="pay-header">
<p class="pay-plan">支付方案:</p>
<van-radio-group v-model="radio" @change="onRadioChange">
<van-cell-group>
<!-- 支付宝 -->
<van-cell clickable v-if="isShowAlipay" @click="onCell('1')">
<template #title>
<div class="pay-item">
<van-image :src="alipayIconPath" height="30" width="30"></van-image><span>支付宝</span>
</div>
</template>
<template #right-icon>
<van-radio name="1" />
</template>
</van-cell>
<!-- 支付宝end -->
<!-- 花呗 -->
<van-cell clickable v-if="isShowAntpay" @click="onCell('2')">
<template #title>
<div class="pay-item">
<van-image :src="antpayIconpath" height="30" width="30"></van-image><span>花呗分期<span class="font-red">(推荐)</span></span>
</div>
</template>
<template #right-icon>
<van-radio name="2" />
</template>
</van-cell>
<!-- 花呗分期下拉选择 -->
<van-dropdown-menu v-show="isAntPay" >
<van-dropdown-item v-model="goods.value" :options="goods.option" @change="onChange"/>
</van-dropdown-menu>
<!-- 花呗分期下拉选择 end-->
<!-- 花呗end -->
</van-cell-group>
</van-radio-group>
</div>
<!-- 花呗分期数选择 有12 24 支付宝默分期认 传1 此模块只有花呗分期使用-->
</div>
<!-- 套餐信息 -->
<div class="set-meal">
<!-- 套餐价格 -->
<div class="set-meal-price" v-if="isAntPay">
<span>{{ amountTitle }}:</span>
<span class="font-red price-big">¥{{ isAntPay ? (goods.price/goods.count).toFixed(2) : goods.price}}</span>
<span v-if="isAntPay"> x </span>
<span v-if="isAntPay"> {{ goods.count }}期 </span>
<!-- 花呗分期 -->
<span v-if="userTemplate.isShowMoney"> = </span>
<span v-if="userTemplate.isShowMoney"> ¥{{ goods.price }} </span>
</div>
<div class="set-meal-price" v-if="!isAntPay">
<span>{{ amountTitle }}:</span>
<span class="font-red price-big">¥{{ isAntPay ? (goods.price/goods.count).toFixed(2) : goods.price}}</span>
</div>
</div>
<!-- 其它内容 -->
<div class="others">
<!-- 开通花呗 -->
<div class="open-ant">
<p v-if="isAntPay"><van-icon name="warning" size="15" color="#1989fa" /><span class="underline font-red" @click="onOpenWay">如何开通花呗 ?</span></p>
<p v-if="userTemplate.isShowAgreement"><van-icon name="todo-list" size="15" color="#1989fa" /><span class="underline" @click="onOpenAgreement">智能学生证开通协议</span></p>
<p v-if="userTemplate.isShowAgreement"><van-checkbox v-model="checked" @change="onCheckChange" shape="square"><span>我已阅读协议并确认</span></van-checkbox></p>
</div>
</div>
</div>
</div>
<!-- footer -->
<div class="footer pos-flex-cen">
<van-button :class="['van-button', {notSubmit: !checked }]" block @click="onSubmit">{{submitText}}</van-button>
</div>

<!-- agreement 协议 -->
<van-dialog
v-model="isAgreementShow"
:title="goods.agreementTitle"
show-cancel-button
confirm-button-text="同意"
cancel-button-text="不同意"
confirm-button-color="green"
@confirm="onConfirm"
@cancel="onCancel"
>
<div class="deal-content" v-show="!custom.isCustomDeal">
<h5>一.开通需知及承诺</h5>
<p v-show="goods.isCustom">1.感谢用户使用支付宝花呗分期功能。</p>
<p v-show="goods.isCustom">2.用户自愿开通4G电子学生证<span v-show="!custom.isGuangan">资费</span>套餐服务(24期)每月自动通过支付宝花呗分期支付<span v-show="!custom.isGuangan">资费</span>(话费+流量)套餐费<span>{{(goods.price/goods.count).toFixed(2)}}元/月。</span></p>
<p v-show="goods.isCustom">3.用户需连续使用该<span v-show="!custom.isGuangan">资费</span>套餐24期,可据此领取4G电子学生证1台、电话卡1张。</p>
<p style="white-space: pre-wrap"><span v-show="goods.isCustom"></span>4.{{goods.description}}</p>
<p v-show="goods.isOld">5.协议期内,电子学生证非人为损坏或进水按“三包”政策进行免费维修或更换。如丢失或人为损坏,按优惠价重新购买。</p>
<p v-show="goods.isOld">6.北京随手精灵科技有限公司接受电子学生证运营销售商委托采用支付宝花呗分期付代收业务货款。</p>
<h5>二.用户承诺</h5>
<p>1.用户已充分了解支付宝花呗付款条款(含支付宝花呗相关规则),充分阅读及理解本协议。</p>
<p v-show="custom.isCanShow">2.用户已经签署业务订购回执,自愿购买并同意签署本协议。</p>
<h5>三.法律适用与管辖</h5>
<p>本协议之效力、解释、变更、执行与争议解决均适用中华人民共和国法律。因本协议产生的争议,均应依照中华人民共和国法律予以处理。</p>
</div>

<!-- 协议需要根据某一个客户自定义时,todo后面需要从接口获取 -->
<div class="deal-content" v-show="custom.isCustomDeal">
<h5>一.开通须知</h5>
<ol v-show="goods.isCustom">1.自愿开通测温版智能电子学生证配套资费套餐服务(24期)每月自动通过支付宝花呗分期支付资费(话费+流量)套餐费29元/月。</ol>
<ol v-show="goods.isCustom">2.需连续使用该资费套餐24期,可免费使用测温版智能电子学生证1台、电话卡一张。</ol>
<ol v-show="goods.isCustom">3.非人为损坏按照“三包”政策免费维修或更换,如丢失或人为损坏,请按价购买。</ol>
<h5>二.用户承诺</h5>
<ol>用户已充分了解支付宝花呗付款条款(含支付宝花呗相关规则),充分阅读及理解本协议。</ol>
<h5>三.法律适用</h5>
<ol>本协议之效力、解释、变更、执行与争议解决均适用中华人民共和国法律。</ol>
</div>
</van-dialog>

<!-- 非在支付宝浏览器弹窗 -->
<van-dialog
v-model="isAipayBrowser"
title="请切换支付宝扫码支付!"
:show-confirm-button="false"
:close-on-click-overlay="true"
>
<div class="browser-tips">

<p>
步骤如下:
</p>
<p>1、<a @click="onDownCode($event)" class="font-blue">点击下载</a>付款码,再长按码保存到手机相册。</p>
<p>
2、打开支付宝,如果未安装支付宝请到应用商店下载;<a v-show="isIos" @click="onDownAlipay" class="font-blue">请点击前往应用商店下载</a><span v-show="!isIos">或<span @click="onCopy" style="color: red">复制链接</span>,粘贴到浏览器打开并下载。</span>
</p>
<p>
3、支付宝扫码,然后从扫描页的【相册】中选择刚下载的付款码。
</p>
<p>点击屏幕任意地方关闭弹窗</p>
</div>
</van-dialog>
</div>
</template>

<script>
import { isNotNull, /* isAlipayBrowser, isAndroid */intCount, isShowAlipay, isShowAntpay } from "../utils/index";
import { APIAlipay } from "../api/alipay";
import { IMAGE_URL, USER_AGENT, ALIPAY_DOWN_URL} from '../config/models';
export default {
name:'',
data(){
return {
radio: "", //支付选项 默认花呗分期 1 是支付宝全额 , 2 是花呗分期
isShowAlipay: null, // 是否显示支付宝
isShowAntpay: null, //是否显示花呗
isAntPay: null, //是否是花呗支付
antpayIconpath: require('../assets/antpay.png'), //花呗支付图片
alipayIconPath: require('../assets/alipay.png'), //支付宝图片
submitText: '下一步', //submit文字
checked: false, //复选框 默认是false
goods: {
bannerImg: '' || require('@/assets/banner_03.jpg'), // banner图片
goodsNo: '', //商品id
userId: '', //用户id
description: '', //商品协议
mainTitle: '', //商品标题
price: '', //商品价格
count: '', //商品分期数
defDescription: '电子学生证套餐两年内(24个月)内含每月200分钟通话和1.5G流量,超出通话或流量部分,由用户自行交费。', //默认协议内容
isDistribution: null, //是否是分销模式 1是分销商模式 其它是代理商
agreementTitle: '', //协议标题
isOld: null, //是否是老用户
isCustom: true, //是否是新用户
value: '', //下拉框默认的值
option: [], //下拉选项
qrCodeImg: '', //商品二维码下载链接

}, //商品数据
userTemplate: {
isShowMoney: null, //是否需要显示总额
isShowAgreement: null, //是否需要显示协议

}, //用户模板
isAgreementShow: false, //弹窗协议, 默认不显示
checkoutCount: 0, //点击复选框或者协议次数
custom: {
isCanShow: false, //特殊客户不显示协议中某一个协议
isGuangan: false, //广安客户 协议个性定制
isAnjiao: false, //安教客户 协议个性定制
isCustomDeal: false, //客户个性化定制协议, 与默认协议区别大 故另起一个协议
},
isAipayBrowser: null, //是否是支付宝内核浏览器
isIos: null, //是否是ios
alipayDownUrl: '', //支付宝app下载链接
}
},
computed: {
amountTitle: {
get() {
return this.isAntPay ? '月套餐费' : '支付总额';
},
set(value) {
return value;
}
}
},
created() {
this.checkBrowser();
this.checkIosOrAndroid();
this.getParams();
},
methods: {
// checkBrowser 检查浏览器内核 非支付宝浏览器弹窗提示
checkBrowser() {
if (/AlipayClient/.test(USER_AGENT)) {
console.log("alipay");
this.isAipayBrowser = false;
} else {
this.isAipayBrowser = true;
}
},
// checkIosOrAndroid 检查当前用户设备是安卓还是ios 以方便跳转下载支付宝app 商店
checkIosOrAndroid() {
if (USER_AGENT.indexOf('Android') > -1 || USER_AGENT.indexOf('Linux') > -1) {
this.alipayDownUrl = ALIPAY_DOWN_URL.android;
this.isIos = false;
} else if (USER_AGENT.indexOf('iPhone') > -1) {
this.alipayDownUrl = ALIPAY_DOWN_URL.ios;
this.isIos = true;
}
},
// onDownCode 下载二维码
onDownCode($e) {
$e.stopPropagation();
// 定义下载链接, 从接口获取
// todo 待接口完成, 接口返回空则使用banner图片作为测试
const URL = this.goods.qrCodeImg;
window.open(URL);
},
// onDownAlipay 下载支付宝app
onDownAlipay() {
window.location = this.alipayDownUrl;
},
// onCopy 复制粘贴
onCopy() {
let url = 'https://d.alipay.com';
let oInput = document.createElement('input');
oInput.value = url;
document.body.appendChild(oInput);
oInput.select(); // 选择对象;
document.execCommand("Copy"); // 执行浏览器复制命令
this.$toast.success('已复制到粘贴板!');
oInput.remove()
},
// getParams 获取二维码url携带的参数
getParams() {
let params = this.$route.query;
// 根据不同商品的id初始化协议内容 注: 有些客户 需要显示不同的协议内容
this.initDealContent(params.goodsNo);
console.log("扫码传过来的参数", params);
if(isNotNull(params.goodsNo)) {
this.goods.goodsNo = params.goodsNo;
this.goods.userId = params.userId;
this.$store.commit('goodsNo', params.goodsNo);
this.$store.commit('userId', params.userId);
this.getGoodsDetails();
this.getUserTemplate();
this.getQRCodeImageUrl(params.userId, params.goodsNo);
} else {
this.$router.push({path: '/404'})
}
},
// initDealContent 初始化部分协议内容
initDealContent(goodsNo) {
console.log("goodsNo", goodsNo);
switch(goodsNo) {
case '1483687825375969280':
// do something
this.goods.agreementTitle = '电子学生证AI套餐开通服务协议';
break;
case '1499199301461164032':
// do something
this.goods.agreementTitle = '4G电子学生证套餐开通服务协议';
this.custom.isGuangan = true;
break;
case '1500295698449121280':
// do something
this.custom.isAnjiao = true;
this.checked = true;
break;
case '1500296054570696704':
// do something
this.custom.isAnjiao = true;
this.amountTitle = '费用总计';
this.isShowAlipay = true;
this.checked = true;
break;
case '1509442747413250048':
// do something
this.custom.isCanShow = false;
this.custom.isCustomDeal = true;
break;

}
},
// getGoodsDetails 根据商品No 和 用户id获取该商品的详情
getGoodsDetails() {
this.$toast.loading({
message: '加载中',
})
APIAlipay.getGoodsDetails(this.goods.goodsNo, this.goods.userId)
.then(res => {
let data = res.data;
console.log("商品数据::", data);
if (data.code === 20000) {
let good = data.data.goods;
console.log("goods", data.data.goods);
this.goods.bannerImg = IMAGE_URL[ process.env.NODE_ENV ] + good.goodsImg;
this.goods.description = good.descriptionText === '' ? this.goods.defDescription : good.descriptionText.replace(/\\n/g,"<br/>");
this.goods.isOld = good.descriptionText === '';
this.goods.price = good.price;
this.goods.count = good.count;
this.goods.mainTitle = good.mainTitle;
this.goods.agreementTitle = good.agreementTitle || '智能学生证套餐开通服务协议';
this.goods.isDistribution = good.patternNum === '1' ? true: false; // 分销模式1:分销模式;2 代理商模式
// 初始化 分期数 由于接口返回的分期数不符合页面填充的数据 我们要重组
let payCount = good.periodizationJson.substring(1, good.periodizationJson.length - 1).split(',');
let newCountList = intCount(payCount);
this.radio = newCountList.length === 0 ? '1' : '2'; //有一种情况, 只有支付宝全额支付时, 需默认支付方式为1
this.goods.count = newCountList.length === 0 ? 1 : Math.max(...newCountList); //有一种情况, 只有支付宝全额支付时, 需默认分期数为1
this.goods.value = Math.max(...newCountList).toString();
this.goods.option = newCountList.map(g => {
return {
text: `可分${g}期, ${(good.price/g).toFixed(2)}元/期`,
value: g
}
});
this.isShowAlipay = isShowAlipay(payCount); //单选是否显示支付宝
this.isShowAntpay = isShowAntpay(newCountList); //单选是否显示花呗
this.isAntPay = this.isShowAntpay; //花呗默认显示内容
this.redirectDealers(good.patternNum); //重定向 到分销商与代理商
} else {
this.$router.push({path: '/404'});
this.$dialog.confirm({
title: '出错了',
message: data.message || '请联系管理员!'
})
}
})
.catch(error => {
this.$dialog.confirm({
title: '出错了',
message: error,
})
})
.finally(() => {
this.$toast.clear();
})
},
// getUserTemplate 根据用户id 获取用户模板信息 判断页面组件是否需要渲染
getUserTemplate() {
APIAlipay.getUserTemplate(this.goods.userId)
.then(res => {
if(res.data.code === 20000) {
let data = res.data.data.goodsTemplate;
console.log("用户模板", data);
if(isNotNull(data)) {
// 处理协议单选框的默认值, 当不需要显示协议时为ture
this.checked = data.isShowAgreement === 0;
this.userTemplate.isShowMoney = data.isShowMoney === 1;
this.userTemplate.isShowAgreement = data.isShowAgreement === 1;
}
}
})
},
// getQRCodeImageUrl 获取商品二维码下载链接
getQRCodeImageUrl(userId, spuId) {
APIAlipay.getQRCode(userId, spuId)
.then(res => {
this.goods.qrCodeImg = res.data.data.QRCodeUrl;
})
.catch(error => {
console.log("error", error);
})
},
// onSubmit
onSubmit() {
if (!this.checked) {
this.$dialog.confirm({
title: '温馨提示',
message: `请您阅读并勾选同意\n${this.goods.agreementTitle}`,
showCancelButton: false
})
} else {
let queryData = {
price: this.goods.price,
count: this.radio === '1' ? 1 : this.goods.count,
type: this.radio, // '1' 是支付宝 '2'是花呗分期
userId: this.goods.userId,
goodsNo: this.goods.goodsNo,
mainTitle: this.goods.mainTitle,
}
this.$router.push({name: 'form-new', query: queryData});
}
},
// onRadio 选择支付方式
onRadioChange(value) {
console.log("选择的支付方式是::", value);
},
// onCell 点击 cell
onCell(value) {
console.log("选择的cell是", value);
this.radio = value;
this.isAntPay = value === '2';
console.log("this.isAntPay", this.isAntPay);
},
// onChange 花呗分期选择
onChange(value) {
this.goods.count = Number(value);
console.log("选择了", typeof value);
console.log("此时花呗的分期数是", this.goods.count);
},
// onOpenWay 如何开通花呗弹窗
onOpenWay() {
this.$dialog.confirm({
title: '如何开通花呗',
message: '请进入支付宝APP-右下角【我的】-【花呗】,点击后按页面提示操作开通即可。',
showCancelButton: false
});
},
// onOpenAgreement 打开协议弹窗
onOpenAgreement( ) {
this.isAgreementShow = true;
this.checkoutCount ++;
},
// onConfirm 协议弹窗 -同意
onConfirm() {
this.isAgreementShow = false;
this.checked = true;
},
// onCancel 协议弹窗 不同意
onCancel() {
this.isAgreementShow = false;
this.checked = false;
},
// onCheckChange 复选框
onCheckChange() {
if(this.checkoutCount < 1) {
this.onOpenAgreement();
this.checkoutCount ++;
}
},
// redirectDealers 重定向路由到 分销商首页
redirectDealers(patternNum) {
if( patternNum === '1') {
this.$router.push({name: 'index-dealers', query: {goodsNo: this.goods.goodsNo, userId: this.goods.userId,}})
}
},
}
}
</script>

// 此处不加 scoped是为了修改vant的默认样式
<style lang="scss">
.van-dropdown-item {
position: fixed;
right: 6%;
left: 6%;
width: 88%;
z-index: 10;
overflow: hidden;
}
.van-dropdown-menu__item {
display: flex;
justify-content: flex-start;
align-items: center;
}
/* .van-overlay {
position: fixed;
top: 0;
left: 0;
z-index: 1;
width: 100%;
height: 0;
background-color: rgba(0,0,0,.7);
} */
</style>
<style scoped lang="scss">
.index-container {
height: 100vh;
width: 100%;
padding: 20px 20px 0 20px;
overflow: hidden;
.banner {
height: 40vh;
width: 100%;
box-shadow: rgb(38, 57, 77) 0px 20px 30px -10px;
border-radius: 10px;
.van-image {
flex: 1;
width: 100%;
}
}
.main {
flex: 1;
min-height: 45vh;
width: 100%;
margin-top: 10px;
padding: 5px 20px;
border-radius: 10px;
background-color: #fafafa;
box-shadow: rgb(38, 57, 77) 0px 20px 30px -10px;
overflow: scroll;
.main-container {
width: 100%;
.pay-choose {
flex: 1;
width: 100%;
margin: 10px 0 0 0;
text-align: left;
.pay-header {
.pay-plan {
padding-left: 5px;
line-height: 20px;
}
p {
padding: 5px 0;
}
.pay-item {
display: flex;
justify-content: flex-start;
align-items: center;
span {
padding-left: 10px;
}
}
}
.van-cell {
padding: 5px 0;
}
.antpay-dropdown {
width: 80%;
left: 15px;
}
.van-dropdown-item {
width: 80% !important;
margin: 0 20px !important;
}
}
.set-meal {
height: 30px;
width: 100%;
margin: 10px 0;
display: flex;
justify-content: flex-start;
align-items: center;
span {
font-size: 14px;
}
.set-meal-price {
line-height: 30px;
.price-big {
font-size: 24px;
padding-left: 10px
}
}
}
.others {
flex: 1;
width: 100%;
.open-ant {
width: 100%;
text-align: left;
display: flex;
justify-content: center;
align-items: flex-start;
flex-direction: column;
p {
padding: 5px 0;

}
span {
padding-left: 5px;
}
}
}
}
}
.footer {
height: 10vh;
width: 100%;
padding: 0 20px;
position: absolute;
left: 0;
bottom: 5px;
display: flex;
justify-content: center;
align-items: flex-end;
.van-button {
background-color: #1989fa;
color: white;
border: none;
&.notSubmit {
background-color: rgb(150, 196, 241);
}
}
}
.deal-content, .browser-tips {
width: 100%;
overflow: scroll;
padding: 10px;
text-align: left;
p {
font-size: 14px;
padding: 5px;
line-height: 20px;
}
}
.deal-content {
height: 50vh;
}
}
</style>

+ 0
- 50
src/views/ComponentsTest.vue View File

@@ -1,50 +0,0 @@
<!--
* @Date: 2022-02-28 09:46:25
* @LastEditors: JinxChen
* @LastEditTime: 2022-03-31 16:23:27
* @FilePath: \AntpayFrontEnd\src\views\ComponentsTest.vue
* @description: 组件测试页面
-->
<template>
<div>
<AgreementDialog
:title="title"
:show="false"
:count="count"
:price="price"
:description="description"/>
<div class="flex-ct-x box">浮动布局</div>
</div>
</template>

<script>
import AgreementDialog from '../components/AgreementDialog'
export default {
name:'components-test',
components: { AgreementDialog },
data(){
return {
title: '标题',
description: 'description',
count: 24,
price: 240

}
},
mounted() {
this.getGoodsDetails();
},
methods: {
getGoodsDetails() {

}
}
}
</script>

<style scoped lang="scss">
.box {
height: 400px;
width: 400px;
}
</style>

+ 0
- 338
src/views/alipay-dealers/AlipayFormDealers.vue View File

@@ -1,338 +0,0 @@
<!--
* @Date: 2022-01-19 16:53:16
* @LastEditors: JinxChen
* @LastEditTime: 2022-04-13 14:26:06
* @FilePath: \AntpayFrontEnd\src\views\alipay-dealers\AlipayFormDealers.vue
* @description: 表单信息录入
-->
<template>
<div class="form-container">
<!-- 头部 -->
<div class="form-header pos-flex-cen">
<van-image radius="10" :src="goodsData.imgPath" @click="onPreview"></van-image>
</div>
<!-- 中部表单 -->
<div class="form-body pos-flex-cen">
<div class="tips">
<span class="font-red font-16"><van-icon name="warning" size="15" color="#1989fa" />友情提醒:</span>此处填写的联系电话,必须与“随手精灵0元购”下单时填写的电话为同一个。
</div>
<van-form>
<van-field
v-model="form.schoolName"
v-if="false"
name="学校名称"
label="学校名称:"
required
maxlength="50"
left-icon="wap-home-o"
clearable
:rules="[{ required: true, message: '请填写学校名称' }]"
/>
<van-field
v-model="form.className"
v-if="false"
name="年级班级"
label="年级班级:"
required
maxlength="20"
left-icon="description"
clearable
:rules="[{ required: true, message: '请填写年级班级' }]"
/>
<van-field
v-model="form.studentName"
v-if="false"
name="学生姓名"
label="学生姓名:"
required
maxlength="10"
left-icon="manager-o"
clearable
:rules="[{ required: true, message: '请填写学生姓名' }]"
/>
<van-field
v-model="form.parentName"
v-if="false"
name="家长姓名"
label="家长姓名:"
required
maxlength="10"
left-icon="friends-o"
clearable
:rules="[{ required: true, message: '请填写家长姓名' }]"
/>

<van-field
v-model="form.contactsManName"
v-if="true"
name="联系人"
label="联系人:"
required
maxlength="10"
left-icon="contact"
clearable
:rules="[{ required: true, message: '请填写联系人' }]"
/>
<van-field
v-model="form.contactsTelephone"
v-if="true"
name="联系电话"
label="联系电话:"
required
maxlength="11"
left-icon="phone-o"
clearable
:rules="[{ required: true, message: '请填写联系电话' }]"
/>


<van-field
v-model="form.familyNumber"
v-if="false"
type="textarea"
:autosize="true"
name="亲情号码"
label="亲情号码:"
placeholder="每个亲情号码用 , 隔开,最多可支持4个"
required
maxlength="50"
left-icon="phone-circle-o"
clearable
:rules="[{ required: true, message: '请填写亲情号码' }]"
/>

<van-field
v-model="form.studentCard"
v-if="false"
name="学生身份证"
label="学生身份证:"
placeholder="学生身份证"
required
maxlength="20"
left-icon="idcard"
clearable
:rules="[{ required: true, message: '请填写学生身份证' }]"
/>
<van-field
v-model="form.receivingAddress"
v-if="false"
name="收货地址"
label="收货地址:"
type="textarea"
:autosize="{ maxHeight: 100, minHeight: 25 }"
required
maxlength="50"
left-icon="location-o"
clearable
:rules="[{ required: true, message: '请填写收货地址' }]"
>
</van-field>
<van-cell :center="true" v-if="false">
<div class="switch-address ">
<div class="left"><van-switch v-model="checked" /></div>
<div class="rigth"><van-icon name="warning" color="#1989fa"/><span>点击切换到商家配送</span></div>
</div>
</van-cell>
</van-form>
</div>
<!-- 底部按钮 -->
<div class="form-footer">
<div class="know-tips">
<p class="font-red font-big"><van-icon name="warning" size="15" color="#1989fa" /><span class="font-16">友情提醒:</span></p>
<p>每月从您的支付宝余额扣除{{(goodsData.price / goodsData.count).toFixed(2)}}元</p>
<p>即将从您的余额扣除{{goodsData.price}}元</p>
</div>
<van-button :disabled="!canSubmit" block @click="onSubmit"><span class="font-white">{{submitText}}</span></van-button>
</div>
</div>
</template>

<script>
import { APIAlipay } from "../../api/alipay";
/* import { IMAGE_URL } from '../../config/models'; */
export default {
name:'alipay-form',
data(){
return {
goodsData: {
imgPath: '' || require('@/assets/img/dealers_form_banner.jpg'),
price: JSON.parse(this.$route.query.price) || '',
count: JSON.parse(this.$route.query.count) || 24,
isAmountShow: '',
mainTitle: '',
title: '4G电子学生证资费套餐开通服务协议',
}, //接收从首页传过来的数据
form: {
studentName: '',
parentName: '',
schoolName: '',
className: '',
studentCard: '',
receivingAddress: '到店自提',
contactsManName: '',
contactsTelephone: '',
}, //输入的表单数据
alipayForm: '', //接收支付宝接口返回的表单
submitText: '办理支付宝分期业务', //submit标题
Imgshow: false, //相片预览
images: [
'https://img01.yzcdn.cn/vant/apple-1.jpg',
], //预览图片数组
canSubmit: true, //是否可以提交, 默认false
checked: false, //地址选择开关

}
},
created() {
this.getGoodsDetails();

},
methods: {
// 根据商品编号获取商品详情
getGoodsDetails() {
APIAlipay.getGoodsDetails(this.$store.getters.goodsNo, this.$store.getters.userId)
.then(res => {
if(res.data.code === 20000) {
let good = res.data.data.goods;
console.log("good", good);
// 图片路径
/* this.goodsData.imgPath = IMAGE_URL[ process.env.NODE_ENV ] + good.goodsImg; */
// 价格
// 是否是老用户
this.isOld = good.descriptionText === '' ? true : false;
// 商品名称
this.goodsData.mainTitle = good.mainTitle;
// 是否显示金额总数, todo 后期需从接口获取
/* this.goodsData.isAmountShow = JSON.parse(this.$route.query.isAmountShow); */
}
})
},
// 办理支付宝分期业务表单校验通过后
onSubmit() {
let reg = /^1[3456789]\d{9}$/; //手机号码正则验证
if(!reg.test(this.form.phoneNumber)) {
this.$notify({
message: '请输入正确的手机号码',
type: 'warning',
duration: 1500
})
} else {
let reqBody = {
username: this.form.userName,
deviceImei: this.form.deviceImei === '' ? '123' : this.form.deviceImei,
schoolName: this.form.schoolName,
className: this.form.className,
phoneNumber: this.form.phoneNumber,
periodizationNum: Number(this.goodsData.count),
goodsNo: this.$store.getters.goodsNo,
alipayStateType: Number(this.goodsData.payType),
userId: this.$store.getters.userId,
}
APIAlipay.getAlipayForm(reqBody)
.then(res => {
this.alipayForm = res.data;
this.$store.commit('price', Number(this.goodsData.price));
this.$store.commit('count', Number(this.goodsData.count));
// 跳转到一个中转页 form,再通过这个中转页来调起支付宝的收银台
this.$router.push({path: 'redirect', query: {alipayForm: this.alipayForm}});
})
.catch(error => {
console.log(error);
})
}
},
// 表单不通过时
onFailed() {
console.log("表单输入不完整!");
},
// 图片预览
onChange() {

},
// 点击图片预览大图
onPreview() {
this.Imgshow = true;
}
}
}
</script>
<style lang="scss">
.van-form {
overflow: scroll;
border-radius: 10px;
}
</style>
<style scoped lang="scss">
.form-container {
height: 100vh;
width: 100vw;
display: flex;
flex-direction: column;
overflow: hidden;
padding: 10px;
.form-header {
height: 45vh;
width: 100%;
background-color: sandybrown;
border-top-left-radius: 10px;
border-top-right-radius: 10px;
box-shadow: rgb(38, 57, 77) 0px 10px 20px -10px;
background: linear-gradient(to bottom right, rgb(253, 198, 232), 60%, rgba(162, 94, 207, 0.952));
.van-image {
flex: 1;
width: 100%;
}
}
.form-body {
flex: 1;
width: 100%;
overflow: scroll;
margin: 20px 0 10px 0;
/* box-shadow: rgb(38, 57, 77) 0px 10px 20px -10px; */
border-bottom-left-radius: 10px;
border-bottom-right-radius: 10px;
/* background: linear-gradient(to bottom right, rgb(154, 213, 252), 40%, rgb(96, 141, 238)); */
/* background: linear-gradient(to bottom right, rgb(253, 198, 232), 40%, rgb(165, 108, 211)); */
.tips {
height: 60px;
width: 100%;
padding: 0 20px 20px 20px;
line-height: 20px;
text-align: left;

}
.switch-address {
display: flex;
justify-content: flex-start;
align-items: center;
.rigth {
padding-left: 10px;
}
}
}
.form-footer {
height: 20vh;
width: 100%;
padding: 0 10px;
display: flex;
justify-content: center;
align-items:flex-start;
flex-direction: column;
.know-tips {
width: 100%;
display: flex;
justify-content: flex-start;
align-items: flex-start;
flex-direction: column;
margin-bottom: 10px;
border-radius: 10px;
p {
padding: 5px;
}
}
.van-button {
background: linear-gradient(to bottom right, rgb(154, 213, 252), 40%, rgb(96, 141, 238));
}
}
}
</style>

+ 0
- 231
src/views/alipay-dealers/AlipayIndexDealers.vue View File

@@ -1,231 +0,0 @@
<!--
* @Date: 2022-04-08 10:53:53
* @LastEditors: JinxChen
* @LastEditTime: 2022-04-13 11:03:38
* @FilePath: \AntpayFrontEnd\src\views\alipay-dealers\AlipayIndexDealers.vue
* @description:
-->
<template>
<div class="index-container">
<!-- banner -->
<div class="banner pos-flex-cen">
<van-image
:src="bannerImg"
radius="10"
cover
/>
</div>
<!-- main -->
<div class="main pos-flex-cen-column">
<div class="pay-header">
<!-- 友情提醒-->
<div class="pay-tips">
<p><van-icon name="warning" size="15" color="#1989fa" /><span class="font-red">友情提醒:</span>您已提交“随手精灵0元购”订单,请点击“一键办理”在此完成每月话费缴纳。</p>
</div>
</div>
<!-- 套餐信息 -->
<div class="set-meal">
<!-- 套餐价格 -->
<div class="set-meal-price">
<span>月套餐费:</span>
<span class="font-red price-big">¥25.00</span>
<span> x </span>
<span> 24期 </span>
<span> = </span>
<span> ¥600 </span>
</div>
</div>
<!-- 其它内容 -->
<div class="others">
<!-- 开通花呗 -->
<div class="open-ant">
<p class="ant-img"><van-image :src="antpayIconpath" height="30" width="30"></van-image><span>花呗分期</span><van-icon name="warning" size="15" color="#1989fa" /><span class="underline">如何开通花呗?</span></p>
</div>
</div>
</div>
<!-- footer -->
<div class="footer pos-flex-cen">
<div class="footer-argeement">
<van-row>
<van-col :span="11">
<van-checkbox v-model="checked" shape="square"><span>我已阅读协议并确认</span></van-checkbox>
</van-col>
<van-col :span="13">
<van-icon name="todo-list" size="15" color="#1989fa" /><span class="underline">智能学生证开通协议</span>
</van-col>
</van-row>
</div>
<van-button type="info" :disabled="!checked" block @click="onSubmit">{{submitText}}</van-button>
</div>

</div>
</template>

<script>
export default {
name:'',
data(){
return {
bannerImg: require('@/assets/banner_03.jpg'),
radio: "1",
antpayIconpath: require('../../assets/antpay.png'), //花呗支付图片
alipayIconPath: require('../../assets/alipay.png'), //支付宝图片
submitText: '一键办理', //submit文字
radioCount: '1', //分期数
checked: false, //单选框 默认是false
value1: 24,
option1: [
{ text: '可分24期,20元/期', value: 24 },
{ text: '可分24期,40元/期', value: 12 },
],
}
},
mounted() {

},
methods: {


// submit
onSubmit() {
this.$router.push({name: 'form-new', query: { price: 480, count: 24}});
}
}
}
</script>

// 此处不加 scoped是为了修改vant的默认样式
<style lang="scss">
.van-dropdown-item {
position: fixed;
right: 5%;
left: 5%;
width: 90%;
z-index: 10;
overflow: hidden;
}
.van-dropdown-menu__item {
display: flex;
justify-content: flex-start;
align-items: center;
}
.van-overlay {
position: fixed;
top: 0;
left: 0;
z-index: 1;
width: 100%;
height: 0;
background-color: rgba(0,0,0,.7);
}
</style>
<style scoped lang="scss">
.index-container {
height: 100vh;
width: 100%;
padding: 10px 10px 0 10px;
overflow: hidden;
.banner {
height: 50vh;
width: 100%;
background-color: sandybrown;
box-shadow: rgb(38, 57, 77) 0px 20px 30px -10px;
border-top-left-radius: 10px;
border-top-right-radius: 10px;
.van-image {
flex: 1;
width: 100%;
}
}
.main {
/* flex: 1; */
height: 30vh;
width: 100%;
margin-top: 10px;
padding: 5px 20px;
border-bottom-left-radius: 10px;
border-bottom-right-radius: 10px;
background-color: #fff;
box-shadow: rgb(38, 57, 77) 0px 20px 30px -10px;
.pay-header {
flex: 1;
width: 100%;
margin: 10px 0 0 0;
text-align: left;
.pay-tips {
p {
padding: 5px;
line-height: 20px;
}
}
}
.set-meal {
flex: 1;
width: 100%;
padding: 10px 0;
display: flex;
justify-content: flex-start;
align-items: center;
span {
font-size: 14px;
}
.set-meal-price {
.price-big {
font-size: 24px;
}
}
}
.others {
height: 40px;
width: 100%;
.open-ant {
width: 100%;
text-align: left;
display: flex;
justify-content: center;
align-items: flex-start;
flex-direction: column;
.ant-img {
height: 40px;
display: flex;
justify-content: flex-start;
align-items: center;
margin-right: 10px;
.van-icon {
margin-left: 5px;
}
}
p {
padding: 5px 0;

}
span {
padding-left: 5px;
}
}
}
}
.footer {
height: 15vh;
width: 100%;
padding: 0 10px;
position: absolute;
left: 0;
bottom: 5px;
display: flex;
justify-content: center;
align-items: flex-start;
.footer-argeement {
width: 100%;
.van-row {
height: 40px;
width: 100%;
display: flex;
justify-content: flex-start;
align-items: center;
text-align: left;
}
}
}
}
</style>

+ 0
- 501
src/views/chunyu/AliPayForm.vue View File

@@ -1,501 +0,0 @@
<!--
* @Date: 2022-01-19 16:53:16
* @LastEditors: JinxChen
* @LastEditTime: 2022-03-04 15:48:09
* @FilePath: \AntpayFrontEnd\src\views\chunyu\AliPayForm.vue
* @description: 春雨个性化表单
-->
<template>
<div class="form-container">
<!-- 头部 -->
<div class="form-header">
<div class="img-left">
<van-image :src="goodsData.imgPath" height="120"></van-image>
</div>
<div class="content-right">
<p>
<strong>套餐名字:</strong>
</p>
<p>{{goodsData.mainTitle}}</p>
<p>
<strong>月套餐费:</strong>
</p>
<p>
<span>¥{{ (goodsData.price/goodsData.count).toFixed(2) }}</span> x
<span>{{goodsData.count}}期</span>
<span v-show="goodsData.isAmountShow">=¥{{goodsData.price}}</span>
</p>
</div>
</div>
<!-- 中部表单 -->
<div class="form-body">
<van-form @submit="onSubmit" @failed="onFailed">
<div class="form-box">
<!-- <van-field
v-model="form.phoneNumber"
name="phoneNumber"
label="电话"
type="tel"
placeholder="必填"
maxlength="11"
required
clearable
:rules="[{ required: true, message: '请填写电话' }]"
/>
<van-field
v-model="form.schoolName"
name="schoolName"
label="学校"
placeholder="必填"
maxlength="30"
required
clearable
:rules="[{ required: true, message: '请填写学校' }]"
/>
<van-field
v-model="form.className"
name="className"
label="班级"
placeholder="必填"
maxlength="10"
required
clearable
:rules="[{ required: true, message: '请填写班级' }]"
/>
<van-field
v-model="form.studentName"
name="studentName"
label="学生"
placeholder="必填"
maxlength="10"
required
clearable
:rules="[{ required: true, message: '请填写学生' }]"
/> -->
<!-- 省市区选择详情见 https://vant-contrib.gitee.io/vant/v2/#/zh-CN/area -->
<van-field
readonly
clickable
name="area"
:value="form.address"
label="地区:"
placeholder="点击选择省市区"
@click="showArea = true"
required
:rules="[{ validator}]"
/>
<van-popup v-model="showArea" position="bottom">
<van-area
:area-list="areaList"
@confirm="onConfirmAddress"
@cancel="showArea = false"
/>
</van-popup>
<!-- 请选择学校 -->
<van-field
readonly
clickable
name="school"
:value="form.schoolName"
label="学校:"
placeholder="点击选择学校"
@click="showSchool = true"
required
:rules="[{ validator}]"
/>
<van-popup v-model="showSchool" position="bottom">
<van-picker
show-toolbar
:columns="schoolColumns"
@confirm="onConfirmSchool"
@cancel="showSchool = false"
/>
</van-popup>
<!-- 选择年级班级 -->
<van-field
readonly
clickable
name="class"
:value="form.className"
label="年级班级:"
placeholder="点击选择年级班级"
@click="showClass = true"
required
:rules="[{ validator}]"
/>
<van-popup v-model="showClass" round position="bottom">
<van-cascader
v-model="form.className"
title="请选择年级班级"
:options="classOptions"
@close="showClass = false"
@finish="onClassFinish"
/>
</van-popup>

<!-- 请选择学生名字 -->
<van-field
readonly
clickable
name="school"
:value="form.studentName"
label="学生:"
placeholder="点击选择学生"
@click="showStudent = true"
required
:rules="[{ validator}]"
/>
<van-popup v-model="showStudent" position="bottom">
<van-picker
show-toolbar
:columns="studentColumns"
@confirm="onConfirmStudent"
@cancel="showStudent = false"
/>
</van-popup>

<!-- 请选择家长手机号码 -->
<van-field
readonly
clickable
name="school"
:value="form.phoneNumber"
label="手机号码:"
placeholder="点击选择家长手机号码"
@click="showPhone = true"
required
:rules="[{ pattern, message: '请输入正确的手机号码' }]"
/>
<van-popup v-model="showPhone" position="bottom">
<van-picker
show-toolbar
:columns="phoneColumns"
@confirm="onConfirmPhone"
@cancel="showPhone = false"
/>
</van-popup>

</div>
<!-- '请知悉' 提示, -->
<div class="know-tips">
<h5>请知悉!</h5>
<p>点击以下按钮,启动支付宝页面"立即支付"</p>
<p>成功后,将分期每月从你的余额扣{{ (goodsData.price/goodsData.count).toFixed(2) }}元</p>
</div>
<div class="form-footer">
<Checkbox @SendCheckStatus="SendCheckStatus" />
<AgreementDialog
:show="goodsData.isShow"
:title="goodsData.title"
:count="goodsData.count"
:price="goodsData.price"
:description="goodsData.description"
:countDown="goodsData.countDown"
:isButtonShow="goodsData.isButtonShow"
/>
<van-button
:class="['van-button', {notSubmit: !goodsData.newChecked}]"
native-type="onSubmit"
>{{submitText}}</van-button>
</div>
</van-form>
</div>
</div>
</template>

<script>
import { APIAlipay } from "../../api/alipay";
import Checkbox from "../../components/Checkbox";
import AgreementDialog from "../../components/AgreementDialog";
import { IMAGE_URL } from '../../config/models';
//Vant 官方提供了一份默认的省市区数据,可以通过 @vant/area-data 引入:
import { areaList } from '@vant/area-data';
import { isNotNull } from '../../utils';
export default {
name:'alipay-form',
components: { Checkbox, AgreementDialog },
data(){
return {
goodsData: {
imgPath: '', //图片地址
price: null, //价格
count: null, //分期数
isAmountShow: '', //是否显示金额总数, 目前根据首页商品来控制是否需要显示, 后期可根据接口来控制
mainTitle: '', //商品mainTitle
description: '', //协议说明
title: '4G电子学生证资费套餐开通服务协议',
newChecked: false, //单选框的值
checkCount: 0, //点击单选框的次数
isButtonShow: false, //显示协议组件里面的同意不同意按钮是否需要显示
countDown: 3, //协议按钮倒计时
timer: '', //定时器
isShow: false, //是否显示协议弹窗
}, //接收从首页传过来的数据
form: {
phoneNumber: '', //手机号码
schoolName: '', //学校名字
className: '', //班级名字
studentName: '', //学生名字
deviceImei: '', //设备Imei, 接口参数, 可为空,
address: '', //地址, todo, 接口暂时没有这个字段,待接口实现
}, //输入的表单数据
alipayForm: '', //接收支付宝接口返回的表单
submitText: '一键下单', //submit标题
showArea: false,
// todo 以下数据以接口实际数据为准
areaList, //省市区数据
showSchool: false,
schoolColumns: ['学校1', '学校2', '学校3', '学校4', '学校5'], //学校数据
showClass: false,
classOptions: [
{
text: '高一',
value: '1',
children: [
{ text: '一班', value: '1' },
{ text: '二班', value: '1' },
{ text: '三班', value: '1' }
],
},
{
text: '高二',
value: '2',
children: [
{ text: '一班', value: '2' },
{ text: '二班', value: '2' },
{ text: '三班', value: '2' },
],
},
],
showStudent: false,
studentColumns: [
'学生1', '学生2', '学生3', '学生4', '学生5'
],
showPhone: false,
phoneColumns: [
'18277426712', '18277426712', '18277426712', '18277426712', '18277426712'
],
pattern: /^1[3456789]\d{9}$/,




}
},
mounted() {
this.getGoodsDetails();
this.getCheckStatus();

},
methods: {
// 获取从协议弹窗传过来的单选框状态
getCheckStatus() {
this.$bus.$on('getCheckStatus', (data) => {
this.goodsData.newChecked = data;
this.goodsData.isShow = false;
})
},
// 根据商品编号获取商品详情
getGoodsDetails() {
APIAlipay.getGoodsDetails(this.$store.getters.goodsNo)
.then(res => {
if(res.data.code === 20000) {
let good = res.data.data.goods;
console.log("good", good);
// 图片路径
this.goodsData.imgPath = IMAGE_URL[ process.env.NODE_ENV ] + good.goodsImg;
// 价格
this.goodsData.price = good.price;
// 是否是老用户
this.isOld = good.descriptionText === '' ? true : false;
// 商品名称
this.goodsData.mainTitle = good.mainTitle;
//商品描述 根据\n换行符来把数据进行换行
this.goodsData.description = good.descriptionText === '' ? this.goodsData.defGoodDescription : good.descriptionText.replace(/\\n/g,"<br/>");
// 分期数
let count = good.periodizationJson.substring(1, good.periodizationJson.length - 1).split(',');
// 是否显示金额总数 todo 后期需从接口获取
this.goodsData.isAmountShow = JSON.parse(this.$route.query.isAmountShow);
this.goodsData.count = Math.max(...count);
this.goodsData.goodDefCount = Math.max(...count).toString();
}
})
},
// 办理支付宝分期业务表单校验通过后
onSubmit(values) {
if(this.goodsData.newChecked === false) {
this.$notify({
message: `请阅读并勾选同意${this.goodsData.title}`,
type: 'warning',
duration: 1500
});
} else if( values ) {
let reqBody = {
username: this.form.studentName,
deviceImei: this.form.deviceImei === '' ? '123' : this.form.deviceImei,
schoolName: this.form.schoolName,
className: this.form.className,
phoneNumber: this.form.phoneNumber,
periodizationNum: Number(this.goodsData.count),
goodsNo: this.$store.getters.goodsNo,
alipayStateType: Number(this.goodsData.payType),
userId: this.$store.getters.userId,
}
APIAlipay.getAlipayForm(reqBody)
.then(res => {
this.alipayForm = res.data;
this.$store.commit('price', Number(this.goodsData.price));
this.$store.commit('count', Number(this.goodsData.count));
// 跳转到一个中转页 form,再通过这个中转页来调起支付宝的收银台
this.$router.push({path: 'redirect', query: {alipayForm: this.alipayForm}});
})
.catch(error => {
console.log(error);
})
}
},
// 表单不通过时
onFailed() {
console.log("表单输入不完整!");
},
// 接收 checkbox 组件的SendCheckStatus事件
SendCheckStatus(value) {
//通知 checkbox 组件改变。
this.goodsData.newChecked = value;
this.goodsData.isShow = value;
this.initAgreement();

},
// 初始化协议组件内容
initAgreement() {
this.goodsData.checkCount ++;
if(this.goodsData.checkCount <= 1) {
this.goodsData.timer = setInterval(() =>{
this.goodsData.countDown --;
if(this.goodsData.countDown === 0) {
this.goodsData.isButtonShow = true;
clearInterval(this.goodsData.timer);
this.goodsData.countDown = 3;
}
},1000)
} else if(this.goodsData.checkCount >= 2){
this.goodsData.isButtonShow = true;
this.goodsData.isShow = false;
}
},
// 选择省市区
onConfirmAddress(values) {
this.form.address = values
.filter((item) => !!item)
.map((item) => item.name)
.join('/');
this.showArea = false;
},
// 选择学校
onConfirmSchool(values) {
this.form.schoolName = values;
this.showSchool = false;
},
// 选择年级班级
onClassFinish({ selectedOptions }) {
this.showClass = false;
this.form.className = selectedOptions.map((option) => option.text).join('/');
},
// 选择学生
onConfirmStudent(values) {
this.form.studentName = values;
this.showStudent = false;
},
// 选择家长手机号码
onConfirmPhone(values) {
this.form.phoneNumber = Number(values);
this.showPhone = false;
},
// 校验不为空
validator(value) {
return isNotNull(value);
},
}
}
</script>

<style scoped lang="scss">
.form-container {
height: 100vh;
width: 100vw;
display: flex;
flex-direction: column;
overflow: hidden;
/* padding: 5px;
border-radius: 20px; */
background-color: #f7f8fa;
.form-header {
height: 25vh;
display: flex;
justify-content: center;
align-items: center;
padding: 10px;
box-shadow: rgba(50, 50, 93, 0.25) 0px 2px 5px -1px,
rgba(0, 0, 0, 0.3) 0px 1px 3px -1px;
background-color: rgba(235, 233, 229, 0.726);
.img-left {
width: 120px;
}
.content-right {
flex: 1;
p {
font-size: 14px;
text-align: left;
padding: 5px 10px;
strong {
text-align: left;
}
}
}
}
.form-body {
flex: 1;
position: relative;
overflow: scroll;
/* padding: 10px; */
box-shadow: rgba(50, 50, 93, 0.25) 0px 2px 5px -1px,
rgba(0, 0, 0, 0.3) 0px 1px 3px -1px;
.know-tips {
height: 120px;
width: 100%;
padding: 10px;
h5 {
font-size: 16px;
text-align: left;
padding: 5px;
color: red;
}
p {
font-size: 14px;
padding: 5px;
text-align: left;
}
}
}
.form-footer {
height: 15vh;
width: 100%;
position: absolute;
padding: 10px;
bottom: 10px;
left: 0;
display: flex;
justify-content: center;
flex-direction: column;
.van-button {
height: 40px;
background-color: #1989fa;
color: white;
border-radius: 5px;
&.notSubmit {
background-color: rgba(150, 150, 146, 0.904);
}
}
}
}
</style>

+ 0
- 416
src/views/gaode-demo/PointInRing.vue View File

@@ -1,416 +0,0 @@
<template>
<div id="map" ref="mapContainer">
<div class="tips" v-if="isShowTips">
<!-- <p>{{this.tips}}</!--> -->
<p>当前点坐标:</p>
<van-field v-model="map.center"></van-field>
<p>当前点在围栏内的围栏id有:</p>
<div class="id-container">
<span v-for="(item, index) in polyIdList" :key="index">{{item}},</span>
</div>
</div>
</div>
</template>

<script>
import MapLoader from '@/config/map';
import { isNotNull } from "@/utils/index";
export default {
name:'point-in-ring',
data(){
return {
map: {
instance: null,
zoom: 13,
center: null /* || [113.121586,23.021351] */, //
marker: null,
polygon: null,
radius: '',
polygonCircle: [], //
}, //创建地图参数
polyLnglAtList: '', //绘制多边形围栏数据数组

isPointInRing: null, //是否在围栏内
isShowTips: false, //是否显示tips, 默认false,等到围栏加载完才显示
fenceList: [],
polygonList: [],
gence: '',
reqList: [

],
polyIdList: '', //点在围栏内的围栏id
circlePolygon: {
center: '',
radius: '',
},
fence: '',
circle: '',
currentCircle: ''


}
},
computed: {
tips() {
return this.isPointInRing ? '该点在围栏内' : '该点在围栏外';
},
},
created() {
this.getMap();
this.getParams();
},
mounted() {
},
methods: {
// getMap 创建地图
getMap() {
console.log("地图加载重");
const plugins = [
'AMap.Geocoder',
'AMap.GraspRoad',
'AMap.GeometryUtil',
'AMap.CitySearch',
'AMap.ToolBar',
];
MapLoader(false, plugins).then(
AMap => {
// 地图实例
let that = this;
that.map.instance = new AMap.Map('map', {
center: that.map.center,
resizeEnable: true,
zoom: that.map.zoom,
});
const toolBar = new AMap.ToolBar({ offset: new AMap.Pixel(10, 310), position: 'LT' });
this.map.instance.addControl(toolBar);
this.createPolygon();
this.createMarker();
this.computeMarker();
this.createCircle();
this.computeCircle();
},
e => {
console.log("加载地图失败,下面是报错数据");
console.log(e);
}
)

},
// 获取url的参数
getParams() {
if( isNotNull(this.$route.query) ) {
let params = this.$route.query;
let centerList = params.center.split(',');
this.map.center = params.center.split(',').slice(0, 2);
this.circlePolygon.center = params.center.split(',').slice(0, 2);
this.circlePolygon.radius = Number(params.center.split(',').slice(2, 3)[0]);
console.log("center", this.map.center);
console.log("this.circlePolygon.radius", this.circlePolygon.radius);
this.polyLnglAtList = params.polygon.split(';').map(item => {
return item.split(',');
});
}
},
// 创建围栏
createPolygon() {
// 多边形围栏
this.gence = this.polyLnglAtList.filter(item => {
return item.length > 4
}).map(item => {
return {
id: item[item.length - 2],
radius: item[item.length - 1],
center: item.splice(0, item.length - 2)
}
});
this.fenceList.push(this.gence);
this.gence.forEach(item => {
let fenceItem = this.gence.map(item => {
return item;
}).map(item => {
return item.center.map(item => {
return item.replace('-', ',').split(',')
})
})
console.log("fenceItem", fenceItem);
// 绘制多边形围栏
this.map.polygon = new AMap.Polygon({
map: this.map.instance,
fillOpacity: 0.1,
path: fenceItem
});
});
let circleItem = this.polyLnglAtList.filter(item => {
return item.length === 4;
});
let circleCenter = circleItem.map(item => {
return item
});
let circleCenterNew = circleCenter.map(item => {
return {
id: item[2],
radius: item[3],
center: item.splice(0, item.length - 2),
}
});
this.fenceList.push(circleCenterNew);
// 绘制圆形围栏
this.polygonList = circleCenterNew.map((item, index) => {
this.map.polygonCircle = new AMap.Circle({
center: item.center,
radius: item.radius,
borderWeight: 3,
strokeColor: "red",
strokeWeight: 6,
strokeOpacity: 0.5,
fillOpacity: 0.4,
strokeStyle: 'dashed',
strokeDasharray: [10, 10],
fillColor: 'green',
zIndex: 50,
});
this.polygonList.push(this.map.polygonCircle);
this.map.instance.add(this.map.polygonCircle);
return {
id: item.id,
content: this.map.polygonCircle,
/* radius: item.radius,
center: item.center */
}
})
},
// 创建marker
createMarker() {
let content = `
<div class="marker_avatar">
<div class="avatar">
<img src="//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-red.png" />

</div>
</div>`;
let center = this.map.center;
this.map.marker = new AMap.Marker({
position: center,
draggable: true,

});
// 注册拖拽事件
this.map.marker.on('dragging', this.computeMarker);
this.map.instance.add(this.map.marker);
this.map.instance.setCenter(center);
this.isShowTips = true;
},
// 创建圆形
createCircle() {
console.log("this.map.center", this.map.center);
if(this.currentCircle) {
this.map.instance.remove(this.currentCircle)
}
this.currentCircle = new AMap.Circle({
center: this.map.center.toString().split(','),
radius: this.circlePolygon.radius,
borderWeight: 3,
strokeColor: "red",
strokeWeight: 6,
strokeOpacity: 0.5,
fillOpacity: 0.4,
strokeStyle: 'dashed',
strokeDasharray: [10, 10],
fillColor: 'red',
draggable: true,
});
this.map.instance.add(this.currentCircle);
this.currentCircle.on('dragging', this.computeCircle);

},
// 推拽圆
computeCircle() {
let point = this.currentCircle.getCenter();
//this.map.center = point;
if(this.map.marker) {
this.map.instance.remove(this.map.marker)
}
this.map.center = point.toString().split(',')
this.createMarker();
/* console.log("circleCenter", circleCenter); */
let polygonCircleListMap = this.polygonList.map(item => {
return {
id: item.id,
content: item.content,
/* center: item.center,
radius: item.radius */
};
});
this.gence.forEach(item => {
let fenceItem = this.gence.map(item => {
return item;
}).map(item => {
return {
id: item.id,
center: item.center.map(item => {
return item.replace('-', ',').split(',')
})
}
})
this.checkIsPointInRing(fenceItem, polygonCircleListMap)
});
},
// 拖拽marker
computeMarker() {
let point = this.map.marker.getPosition();
this.map.center = point.toString().split(',');
this.createCircle();
/* console.log("circleCenter", circleCenter); */
let polygonCircleListMap = this.polygonList.map(item => {
return {
id: item.id,
content: item.content,
/* center: item.center,
radius: item.radius */
};
});
console.log("this.polygonList", this.polygonList);
console.log("polygonCircleListMap", polygonCircleListMap);
// 大
let path1 = [
[ 113.105056, 23.04447],
[113.129805, 23.052107],
[113.14218, 23.01336],
[113.106867, 23.012665]
];
// 小
let path2 = [
[113.102037,23.041415],
[113.137954,23.045997],
[113.142029,23.016554],
[113.121586,23.021351]
];
this.gence.forEach(item => {
let fenceItem = this.gence.map(item => {
return item;
}).map(item => {
return {
id: item.id,
center: item.center.map(item => {
return item.replace('-', ',').split(',')
})
}
})
this.checkIsPointInRing(fenceItem, polygonCircleListMap)
});

},
// 检查点是否在圆形围栏或者多边形围栏内
checkIsPointInRing(fenceList, circlePolygon) {
let point = this.map.marker.getPosition();
this.map.center = point.toString();
this.fence = fenceList.map(item => {
return {
id: item.id,
isPointInRing: AMap.GeometryUtil.isPointInRing(point, item.center),
/* lngLat: item.center */
};
})
console.log("this.fence", this.fence);
this.circle = circlePolygon.map(item => {
return {
id: item.id,
isPointInRing: item.content.contains(point),
};
})
this.reqList = [...this.fence, ...this.circle]
this.polyIdList = this.reqList.filter(item => {
return item.isPointInRing === true;
}).map(item => {
return item.id
});
let isPointInPolygon = this.reqList.some(item => {
return item.isPointInRing === true;
});
// 如果不存在,再通过算法判断
if(!isPointInPolygon) {
this.checkPointInPolygon();
}
console.log("reqList", this.reqList)
},
// 判断该点是否有一个在围栏内,如果有就正常返回,如果没有则创建一个圆形,通过圆形点到线段,两点之间距离分别判断是否跟多边形,圆形相交
checkPointInPolygon() {
// 1. 首先判断是否有圆形围栏,有通过计算两点之间距离判断是否交集,没有则下一步对比多边形围栏
if(this.circle.length > 0 || this.fence.length > 0) {
/* let mapCenter = this.map.center.split(',');
let mapRadius = Number(this.map.radius); */
let circleCenter = this.circlePolygon.center;
let circleRadius =Number(this.circlePolygon.radius);
// 获取圆形围栏的半径(radius),中心点(center)
this.polygonList.forEach(item => {
let center = item.content.getCenter();
let radius = item.content.getRadius();
/* let markerDistance = this.calculateDRealistance(mapCenter, center, mapRadius, radius); */
let circleDistance = this.calculateDRealistance(circleCenter, center, circleRadius, radius);
/* console.log("markerDistance", markerDistance); */
console.log("circleDistance", circleDistance);
});
console.log("fenceList", this.fenceList[0]);
if(this.fenceList[0].length > 0) {
let fenceLngLat = this.fenceList[0].map(item => {
return item.center;
}).map(item => {
return item.map(item => {
return item.replace('-', ',').split(',');
})
});
// 循环多边形围栏数组, 得到点到 线段 所需的数据
fenceLngLat.forEach(item => {

})
console.log("fenceLngLat", fenceLngLat);
}
}
},
// 计算两点之间的实际距离
calculateDRealistance(point1, point2, radius1, radius2) {
return Math.round(AMap.GeometryUtil.distance(point1, point2)) - Math.round(radius1 + radius2);
}
}
}
</script>

<style scoped lang="scss">
#map {
height: 100vh;
width: 100%;
z-index: 99;
.tips {
max-height: 20vh;
width: 90%;
padding: 5px;
overflow: scroll;
/* line-height: 80px; */
color: red;
background: wheat;
position: absolute;
top: 1vh;
left: 5%;
text-align: center;
font-size: 16px;
z-index: 9999;
p {
font-size: 12px;
padding: 10px;
}
}
.id-container {
height: 40px;
width: 100%;
background-color: white;
overflow: scroll;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
span {
margin: 5px;
}
}
}
</style>

+ 0
- 96
src/views/htmlCanvas/htmlCanvasDemo.vue View File

@@ -1,96 +0,0 @@
<!--
* @Date: 2022-08-31 16:13:39
* @LastEditors: JinxChen
* @LastEditTime: 2022-08-31 16:37:14
* @FilePath: \AntpayFrontEnd\src\views\htmlCanvas\htmlCanvasDemo.vue
* @description:
-->
<template>
<div class="htmlCanvas">
<van-button type="info" @click="onCreatPoster">生成海报</van-button>
<van-button type="info" @click="onSavePoster">保存海报</van-button>
<div id="poster" class="posterView">
<p>2421144211414</p>
</div>
<!-- 生成海报提示 -->
<div id="result" class="result" v-show="isShowResultImg"></div>
</div>
</template>

<script>
import html2canvas from 'html2canvas';
export default {
name:'',
data(){
return {
isShowResultImg: false
}
},
methods: {
onCreatPoster() {
this.isShowResultImg = true;
let options = {
useCORS: true,
ignoreElements:false,
scale: 7, //dpi 设置默认值,提高图片分辨率
};
let docItme = document.querySelector('#poster');
html2canvas(docItme, options)
.then(canvas => {
let url = canvas.toDataURL('image/png') //将canvas转成base64图片格式
document.querySelector('#result').innerHTML =
`<img src="${url}" alt="海报" width="100%" height="100%">`
})
},
onSavePoster() {
let that = this;
// let dpi = window.devicePixelRatio || 2
this.$dialog.confirm({
title: '温馨提示',
message: '是否保存ICCID截图'
}).then(() => {
that.downImage();
})
},
downImage() {
let options = {
useCORS:true, // 使用跨域
scale:6,
ignoreElements:(ele) =>{ //忽略的dom元素,保存海报就不会显示这个元素内容
if(ele.id === 'name'){
return true
}
}
};
html2canvas(document.querySelector('#poster'),options).then(canvas=>{
canvas.toBlob(function(blob){
var a = document.createElement('a')
var url = window.URL.createObjectURL(blob)
var filename = '海报.png'
a.href = url
a.download = filename
a.click()
// 当图片文件加载完成释放这个url
window.URL.revokeObjectURL(url)
})
})
}
}
}
</script>

<style scoped lang="scss">
.htmlCanvas {
.posterView {
height: 40px;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
p {
margin: 5px;
font-size: 24px;
}
}
}
</style>

+ 28
- 0
src/views/index.vue View File

@@ -0,0 +1,28 @@
<template>
<div @click="onClick">测试</div>
</template>

<script>
export default {
name:'',
data(){
return {

}
},
methods: {
onClick() {
this.$router.push({
name: 'packageList',
query: {
imei: '45555'
}
})
}
}
}
</script>

<style scoped>

</style>

+ 117
- 0
src/views/package-home/index.vue View File

@@ -0,0 +1,117 @@
<!--
* @Date: 2023-02-24 14:18:25
* @LastEditors: JinxChen
* @LastEditTime: 2023-02-24 15:39:49
* @FilePath: \TelpoH5FrontendWeb\src\views\package-home\index.vue
* @description:
-->
<template>
<div class="package-home"></div>
</template>

<script>
import { APIPay } from "@/api/pay";
import APICore from "@/api/core";
import { isNotNull } from "@/utils/index";
export default {
name: "",
data() {
return {
params: {

}
};
},
created() {
this.getParams();
this.getToken();
this.getAuth();
this.checkBrowser();
},
methods: {
// checkBrowser 检查扫码的浏览器内核
checkBrowser() {
const userAgent = window.navigator.userAgent;
console.log("浏览器内核", userAgent);
if (/AlipayClient/.test(userAgent)) {
console.log("alipay");
} else if (/MicroMessenger/.test(userAgent)) {
console.log("wx");
let url = window.location.href.split("?code=")[1];
console.log("获取授权code的url", url);
if (
isNotNull(url) ||
window.location.href.indexOf("code") > -1
) {
let timeStamp = new Date().getTime();
let code = url.split("&")[0];
if (isNotNull(code)) {
this.$store.commit("wxAuthCode", `${code}`);
/* this.getOpenId(); */
}
} else {
this.getWxCode();
console.log("获取token");
}
} else {
console.log("当前浏览器内核并非支付宝或者微信");
}
},
// 获取b端接口的token
getAuth() {
let manufactorId = "5bf13062-a41e-4d00-ba14-1101aad12650";
APICore.getAuth({ manufactorId: manufactorId }).then(res => {
this.$store.commit("gatewayToken", res.data.data);
});
},
// 获取token
getToken() {
let manufacturerNo = '9f166b07-ff83-4991-84dc-ca6ad4a6b95b';
APIPay.getToken(manufacturerNo).then(res => {
console.log("token的数据", res.data)
let data = res.data;
if(data.code === 20000) {
this.$store.commit("token", data.token);
console.log("token的数据", localStorage.getItem('token'))
}
})
},
// 根据code获取openId
getOpenId() {
let code = this.$store.getters.wxAuthCode;
APIPay.getOpenId(code).then(res => {
let data= res.data;
if(data.code === 20000) {
this.$store.commit("openId", data.data.openId);
}
})
},
// 获取微信code
getWxCode() {
let params = this.params;
let commonUrl = process.env.VUE_APP_BASE_API;
/* let testUrl = encodeURIComponent(`https://id.ssjlai.com/h5-frontendweb/#/${params.routerName}?imei=${params.imei}&appId=${params.appId}`);
let proUrl = encodeURIComponent(`https://ai.ssjlai.com/h5-frontendweb/#/${params.routerName}?imei=${params.imei}&appId=${params.appId}`); */
let redUrl = encodeURIComponent(`${commonUrl}/h5-frontendweb/#/${params.routerName}?imei=${params.imei}&appId=${params.appId}&iccid=${params.iccid}`);
console.log("redUrl", redUrl);
let url = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${params.appId}&redirect_uri=${redUrl}&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect`
window.location.href = url;
},
// 获取url传过来的参数
getParams() {
let params = this.$route.query;
if (params) {
console.log("params", params);
this.params = {...params};
this.$store.commit("appId", params.appId);
console.log("this.params", this.params);
}
},
}
};
</script>

<style scoped lang="scss">
.package-home {
}
</style>

+ 563
- 0
src/views/package-list/index.vue View File

@@ -0,0 +1,563 @@
<!--
* @Date: 2022-03-29 16:57:58
* @LastEditors: JinxChen
* @LastEditTime: 2023-02-25 15:52:29
* @FilePath: \TelpoH5FrontendWeb\src\views\package-list\index.vue
* @description: TODO 小台风充值h5
-->
<template>
<div class="package-list-container">
<van-nav-bar :left-arrow="false" :border="true">
<template #title>
<h5 style="font-size: 16px">{{topupTitle}}</h5>
</template>
</van-nav-bar>
<!-- 灰色线条 -->
<div class="gray-line"></div>
<!-- 套餐说明 -->
<div class="order-description" v-show="packageOrderList.length">
<h5>套餐说明:</h5>
<h5>每月200分钟通话时长,1G流量。</h5>
</div>
<!-- 套餐列表 -->
<div class="topup-container">
<div class="main">
<!-- <div class="tips" v-show="!isCanTopup">
<p>非本公司发行的SIM卡,</p>
<p>无此服务。</p>
<div class="cancel-button" @click="onNavBack">返回</div>
</div> -->
<!-- 无套餐时显示 -->
<div class="noData_container" v-show="packageOrderList.length === 0 && isShowNoData">
<p>暂无相关套餐数据,请您联系管理员~</p>
</div>
<!-- 套餐订购 -->
<div
class="package-order-container"

v-for="(item, index) in packageOrderList"
:key="index"
>
<!-- 推荐 -->
<div class="recom" v-show="index === 0">
<div class="shape"></div>
<div class="square">
<p>推荐</p>
</div>
</div>
<!-- 套餐内容 -->
<div class="order-content">
<div class="title">
<p>{{item.packageName}}<!-- :{{(item.packagePrice/item.packageIssue).toFixed(0)}}元/月 --></p>
</div>
<div class="details">
<p>
低至
<span
class="orange"
>{{(item.packagePrice/(item.packageIssue === 0 ? 1: item.packageIssue)).toFixed(0)}}</span>元/月
</p>
<p class="orange">
<span class="orange price">{{item.packagePrice}}元</span>
</p>
<div class="buy-btn" @click="onBuy(item)">
<p>话费充值</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>

<script>
import APIWx from "@/api/wx";
import { APIPay } from "@/api/pay";
let wx = require("weixin-js-sdk"); // TODO 再封装,可拦截错误提示等操作
import APICore from "@/api/core";
import axios from "axios";
import { isNotNull } from "@/utils/index";
export default {
name: "packageList",
data() {
return {
topupTitle: "请选择套餐充值激活电话卡",
wxItem: "",
packageOrderList: [],
outTradeNo: "", //订单号
price: "", //价格,
isShowNoData: false, //是否显示无套餐内容, 默认false
params: {
imei: '',
iccid: '',
manufactorId: '',
appId: '',

},
};
},
computed: {
isCanTopup() {
return this.$route.query.isCanTopup;
},
serialNo() {
return this.$route.query.serialNo;
}
},
created() {
this.getParams();
this.getWxAutograph();
this.getLiveBasePackage();
},
/* mounted() {
this.getParams();
this.getWxAutograph();
this.getLiveBasePackage();
}, */
methods: {
// 根据code获取openId
getOpenId() {
let code = this.$store.getters.wxAuthCode;
APIPay.getOpenId(code).then(res => {
let data= res.data;
if(data.code === 20000) {
this.$store.commit("openId", data.data.openId);
}
})
},
// 获取b端接口的token
getAuth() {
let manufactorId = "5bf13062-a41e-4d00-ba14-1101aad12650";
APICore.getAuth({ manufactorId: manufactorId }).then(res => {
this.$store.commit("gatewayToken", res.data.data);
});
},
// 获取url传过来的参数
getParams() {
let params = this.$route.query;
if (params) {
let url = window.location.href.split("?code=")[1];
if ( isNotNull(url) || window.location.href.indexOf("code") > -1) {
let timeStamp = new Date().getTime();
let code = url.split("&")[0];
if (isNotNull(code)) {
this.$store.commit("wxAuthCode", `${code}`);
this.getOpenId();
}
}
this.params = {...params};
}
},
// 获取基本套餐信息
getLiveBasePackage() {
this.$toast.loading({
message: "获取套餐中",
duration: 1500
});
let reqBody = {
imei: this.params.imei
}
APICore.QueryLiveBasePackage(reqBody)
.then(res => {
if (res.data.code === 106 || res.data.code === 104) {
// token过期
this.getAuth();
setTimeout(() => {
this.getLiveBasePackage();
}, 1500);
} else if (res.data.code === 0 && res.data.data === null) {
this.isShowNoData = true;
}else {
let data = res.data.data.packageList;
if(data === null) {
this.isShowNoData = true;
} else {
this.packageOrderList = data.reverse();
console.log("套餐数据::", data);
}
}
this.$toast.success({
message: "成功获取套餐",
duration: 1500
});
})
.catch(error => {
this.$dialog.confirm({
title: "获取套餐数据失败",
message: error
});
})
.finally(() => {
setTimeout(() => {
this.$toast.clear();
}, 1500);
});
},
// 返回
onNavBack() {
},
// 获取微信jssdk
getWxAutograph() {
let that = this;
return new Promise((resolve, reject) => {
APIWx.createJSSDK({
sUrl: window.location.href.split("#")[0],
userId: '',
appId: this.params.appId
})
.then(res => {
let item = res.data.data;
this.wxItem = res.data.data;
wx.config({
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: item.appId, // 必填,公众号的唯一标识
timestamp: item.timeStamp, // 必填,生成签名的时间戳
nonceStr: item.nonceStr, // 必填,生成签名的随机串
signature: item.signature, // 必填,签名
jsApiList: ["chooseWXPay"] // 必填,需要使用的JS接口列表
});

wx.ready(() => {
resolve(true);
/* that.canScan = true; */
});
})
.catch(err => {
reject(false);
console.log(err);
});
});
},
// 话费充值
onBuy(data) {
let payType = data.packagePayType;
this.price = data.packagePrice;
// 需要区分是要用微信支付还是支付宝花呗支付
if (payType === "支付宝花呗") {
this.aliPay(data);
} else {
this.wxPay(data);
}
},
// 微信支付
wxPay(data) {
this.$toast.loading({
message: "加载中"
});
let orderData = data;
let reqBody = {
openId: this.$store.getters.openId, //openId
imei: this.params.imei, //imei
productId: data.productId, //套餐id
packageName: data.productModel + ',' + data.packageName, //套餐名字
packagePayType: this.shiftType(data.packagePayType), //支付类型
packageIssue: data.packageIssue, //分期
packagePrice: process.env.NODE_ENV === "production" ? data.packagePrice * 100 : 1 //总金额单位为分,测试环境写死
};
APICore.payLiveBaseDevice(reqBody)
.then(res => {
this.$toast.clear();
if (res.data.code === 104 || res.data.code === 106) {
this.getAuth();
setTimeout(() => {
this.wxPay(orderData);
}, 1000);
}
let that = this;
let wxData = res.data.data;
that.outTradeNo = wxData.out_trade_no;
console.log("wxData", wxData);
// 本地测试
that.$router.push({
name: "payResult",
query: {
outTradeNo: that.outTradeNo,
price: that.price,
rechargeUrl: data.rechargeUrl || '',
iccid: this.params.iccid,
isAdmin: this.$route.query.isAdmin,
serialNo: this.params.imei,
routerName: this.params.routerName,
issue: data.packageIssue
}
});
wx.chooseWXPay({
timestamp: wxData.timeStamp, // 支付签名时间戳,注意微信 jssdk 中的所有使用 timestamp 字段均为小写。但最新版的支付后台生成签名使用的 timeStamp 字段名需大写其中的 S 字符
nonceStr: wxData.nonceStr, // 支付签名随机串,不长于 32 位
package: wxData.package, // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=\*\*\*)
signType: wxData.signType, // 微信支付V3的传入 RSA ,微信支付V2的传入格式与V2统一下单的签名格式保持一致
paySign: wxData.paySign, // 支付签名
success: function(res) {
// 支付成功后的回调函数
that.$router.push({
name: "payResult",
query: {
outTradeNo: that.outTradeNo,
price: that.price,
rechargeUrl: data.rechargeUrl,
iccid: that.params.iccid,
isAdmin: that.$route.query.isAdmin || false,
serialNo: that.$route.query.serialNo,
issue: data.packageIssue
}
});
console.log("微信支付成功::", res);
},
fail: err => {
console.log("支付出错了::", err);
this.$dialog.confirm({
title: "支付失败",
message: "出错了,请您重新进入"
});
},
cancel: function(err) {
// 用户取消支付
this.$dialog.confirm({
message: "您取消了支付"
});
console.log("用户取消了支付::", err);
}
});
})
.catch(error => {
console.log("error", error);
})
.finally(() => {
this.$toast.clear();
});
},
// 跳转到支付宝花呗外部链接
aliPay(data) {
console.log("选择了支付宝::", data);
this.$toast.loading({
message: "加载中"
});
let orderData = data;
let reqBody = {
openId: this.$store.getters.openId, //openId
imei: this.serialNo, //imei
productId: data.productId, //套餐id
packageName: data.productModel + ',' + data.packageName, //套餐名字
packagePayType: this.shiftType(data.packagePayType), //支付类型
packageIssue: data.packageIssue, //分期
packagePrice: process.env.NODE_ENV === "production" ? data.packagePrice * 100 : 1 //总金额单位为分,测试环境写死
};
this.$toast.clear();
APICore.payLiveBaseDevice(reqBody)
.then(res => {
if (res.data.code === 104 || res.data.code === 106) {
this.getAuth();
setTimeout(() => {
this.aliPay(orderData);
}, 1000);
}
let that = this;
let alipayData = res.data.data.xmlStrMap;
this.outTradeNo = alipayData.outTradeNo;
let alipayForm = decodeURI(alipayData.payXmlStr);
that.$store.commit("isFromWx", true);
let alipayUserId = process.env.NODE_ENV === "production" ? 42 : 18
this.$router.push({
name: "payResult",
query: {
rechargeUrl:
data.rechargeUrl ||
`https://id.ssjlai.com/frontend/#/alipay`,
outTradeNo: that.outTradeNo,
price: that.price,
alipayForm: alipayForm,
iccid: that.$route.query.iccid,
isAdmin: that.$route.query.isAdmin || false,
serialNo: that.$route.query.serialNo,
alipayUserId: alipayUserId,
productId: data.productId
}
});
})
.catch(error => {
console.log("error", error);
})
.finally(() => {
this.$toast.clear();
});
},
// 转换类型
shiftType(type) {
switch (type) {
case "微信":
return "1"
/* break; */
case "支付宝花呗":
return "2"
/* break; */
}
}
}
};
</script>
<style lang="scss">
.van-nav-bar__title {
max-width: 80% !important;
font-size: 16px;
}
</style>
<style lang="scss" scoped>
.package-list-container {
background-color: white;
height: 100vh;
.topup-container {
display: flex;
justify-content: space-between;
align-items: center;
flex-direction: column;
background-color: white;
overflow: scroll;
height: calc(100vh - 4rem);
.main {
padding: 0 10px;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
.tips {
padding: 10px;
}
.noData_container {
margin: 100px auto 0;
height: 120px;
/* background: url(../../../assets/img/news-noData.png) center no-repeat; */
background-size: 165px 120px;
display: flex;
justify-content: center;
align-items: flex-end;
font-size: 16px;
color: #999;
p {
font-size: 16px;
}
/* @include colorAndFont(#999, 28); */
}
p {
padding: 10px;
font-size: 16px;
}
.cancel-button {
width: 30vw;
border-radius: 5px;
background-color: #2599ff;
color: #fff;
min-height: 40px;
display: flex;
justify-content: center;
align-items: center;
font-size: 16px;
}
.package-order-container {
position: relative;
height: 120px;
width: 300px;
padding: 5px 20px;
margin: 10px 0;
z-index: 999;
box-shadow: rgba(14, 30, 37, 0.12) 0 3px 5px 0,
rgba(14, 30, 37, 0.32) 0 2px 16px 0;
.recom {
position: absolute;
top: -7px;
left: -26px;
border-style: solid;
border-width: 0 40px 40px;
border-color: transparent transparent red;
transform: rotate(-45deg);
text-align: center;
z-index: 9999;
p {
padding: 0;
color: white;
font-size: 14px;
}
.shape {
position: absolute;
top: -1px;
left: -21px;
border-style: solid;
border-width: 0 21px 21px;
border-color: transparent transparent white;
}
.square {
height: 15px;
width: 35px;
position: absolute;
top: 21px;
left: -20px;
background: red;
font-size: 14px;
}
}
.order-content {
padding-top: 25px;
.title {
display: flex;
justify-content: flex-start;
p {
font-size: 14px;
font-weight: bold;
}
}
.details {
display: flex;
justify-content: space-between;
align-items: center;
p {
font-size: 14px;
}
.orange {
color: orange;
}
.price {
font-size: 14px;
font-weight: bold;
padding-right: 5px;
}
.buy-btn {
height: 30px;
width: 90px;
display: flex;
justify-content: center;
align-items: center;
background: orange;
border-radius: 20px;
p {
padding: 0;
color: white;
}
}
}
}
.content {
font-size: 14px;
}
}
}
}
.gray-line {
height: 10px;
width: 100%;
background: #f2f4f5;

}
.order-description {
height: 60px;
display: flex;
justify-content: flex-start;
align-items: flex-start;
flex-direction: column;
padding: 5px 0 10px 25px;
h5 {
font-size: 14px;
padding: 10px 0 0 0;
}
}
}
</style>

+ 0
- 32
src/views/page-not-found/index.vue View File

@@ -1,32 +0,0 @@
<!--
* @Date: 2022-02-14 15:34:10
* @LastEditors: JinxChen
* @LastEditTime: 2022-04-14 11:33:22
* @FilePath: \AntpayFrontEnd\src\views\page-not-found\index.vue
* @description: 404
-->
<template>
<div class="page-not-found">
<van-empty description="商品数据异常!请您联系相关工作人员!" />
</div>
</template>

<script>
export default {
name:'page-not-found',
data(){
return {

}
}
}
</script>

<style scoped lang="scss">
.page-not-found {
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
</style>

+ 386
- 0
src/views/pay-result/index.vue View File

@@ -0,0 +1,386 @@
<!--
* @Date: 2023-02-24 16:47:33
* @LastEditors: JinxChen
* @LastEditTime: 2023-02-25 16:02:53
* @FilePath: \TelpoH5FrontendWeb\src\views\pay-result\index.vue
* @description:
-->
<!--
* @Date: 2022-05-29 10:23:28
* @LastEditors: JinxChen
* @LastEditTime: 2023-02-25 10:34:31
* @FilePath: \TelpoH5FrontendWeb\src\views\pay-result\index.vue
* @description:
-->
<template>
<div class="pay-result-container">
<div class="check-container" v-show="pageShow">
<van-nav-bar title="支付结果" :left-arrow="false" :border="true" ></van-nav-bar>
<!-- 头部 -->
<div class="header pos-center">
<img src="../../assets/img/ssjl.jpg" alt />
<p>随手精灵</p>
</div>
<!-- 详细 -->
<div class="details">
<div class="details-item">
<p class="left-text">订单状态</p>
<p>{{isPayStatus ? '支付成功' : '查询失败'}}</p>
</div>
<div class="details-item">
<p class="left-text">订单尾号</p>
<p>{{outTradeNo}}</p>
</div>
<div class="details-item price">
<p class="left-text">支付总额</p>
<p>¥ {{price}}元</p>
</div>
</div>
<!-- 返回 -->
<div class="footer pos-center">
<!-- <div class="back-btn" @click="onNavBack" v-show="!isPayStatus">
<p>返回重新选择套餐购买</p>
</div> -->
<div class="back-btn" @click="onNext" v-show="!isPayStatus">
<p>激活电话卡</p>
</div>
</div>
</div>
<!-- <div class="flush" v-show="isIos">
<div class="back-btn" @click="onFlush">
<p>查询</p>
</div>
</div> -->
</div>
</template>

<script>
import { isNotNull} from "@/utils/index";
import { APIPay } from "@/api/pay";
import APIWx from "@/api/wx";
import axios from "axios";
export default {
name: "payResult",
data() {
return {
pageShow: false,
count: 0,
timer: "", //定时器
isPayStatus: null,
price: this.$route.query.price,
outTradeNo: this.$route.query.outTradeNo,
isIos: null //是否是ios
};
},
created() {
this.checkParams();
this.closeTime();
},
mounted() {
//this.checkParams();
//this.closeTime();
},
methods: {
// checkIosOrAndroid
checkIosOrAndroid() {
let userAgent = navigator.userAgent;
if (userAgent.indexOf("iPhone") > -1) {
this.isIos = true;
}
},
onNavBack() {
this.$router.push({
name: "packageList",
query: {
serialNo: this.$route.query.serialNo,
isAdmin: this.$route.query.isAdmin,
iccid: this.$route.query.iccid,
routerName: this.$route.query.routerName,
}
});
},
// 下一步激活
onNext() {
console.log("激活", );
//this.$toast.loading("激活中");
this.effective();
},
// 激活接口
effective() {
this.$toast.loading('激活中,请稍候...');
let reqBody = {
imei: this.$route.query.serialNo,
iccid: this.$route.query.iccid || '',
issue: Number(this.$route.query.issue) || 0
};
APIWx.Effective(reqBody)
.then(res => {
console.log("res", res);
let data = res.data;
console.log("data", data);
this.$toast.clear();
if(data.stateCode !== 1) {
this.$dialog.confirm({
title: '温馨提示',
message: `${data.message}`,
showCancelButton: false
})
} else if(data.stateCode === 0 && data.message !== null) {
this.$dialog.confirm({
title: '温馨提示',
message: `电话卡激活失败!请进行实名认证与绑定SIM卡。如您已实名认证,请5分钟后,再进行设备绑定。`,
showCancelButton: false
})
/* Dialog.confirm({ title: "SIM卡激活失败", message: data.message, className: "device_confirm", }); */
} else if (data.stateCode === 1 && data.message !== 'ok') {

/* this.countDown(); */
this.$dialog.confirm({ title: "SIM卡激活成功", message: '卡激活成功,5分钟后则可正常使用。', showCancelButton: false});
} else if (data.stateCode === 1 && data.message === 'ok') {
this.$dialog.confirm({ title: "SIM卡激活成功", message: '卡激活成功,5分钟后则可正常使用。', showCancelButton: false});
}
})
.catch(error => {
console.log("出错了:;", error);
this.$dialog.confirm({
title: '温馨提示',
message: `${error.message}`,
showCancelButton: false
})
}).finally(() => {
this.$toast.clear();
})
},
// ios需要手动点击按钮查询
onFlush() {
this.isIos = false;
this.checkParams();
},
// storeParams
checkParams() {
let params = this.$route.query;
let isFromWx = this.$store.getters.isFromWx;
if (params.rechargeUrl && isFromWx === true) {
// 如果存在支付宝跳转链接,则打开外部浏览器跳到支付宝h5
console.log("支付宝");
this.$toast.loading({
message: "跳转中",
});
setTimeout(() => {
this.$store.commit("isFromWx", "");
let alipayForm = encodeURIComponent(params.alipayForm); //对接口返回的form进行编码
let url =
process.env.NODE_ENV === "production"
? `https://ai.ssjlai.com/frontend/#/alipay?goodsNo=${params.productId}&userId=${params.alipayUserId}&isWx=true&alipayForm=${alipayForm}`
: `https://id.ssjlai.com/frontend/#/alipay?goodsNo=${params.productId}&userId=${params.alipayUserId}&isWx=true&alipayForm=${alipayForm}`;
window.location.href = url;
}, 1500);
} else if (params.rechargeUrl && isFromWx === null) {
// todo 轮询支付宝的支付结果
let that = this;
console.log("支付宝结果");
this.$toast.loading({
message: "结果查询中"
});
let reqBody = {
outTradeNo: params.outTradeNo
};
let url =
process.env.NODE_ENV === "production"
? "https://ai.ssjlai.com/telpopay/alipay/order/detail/callback"
: "https://id.ssjlai.com/telpopay/alipay/order/detail/callback";
if (that.count >= 30) {
if (that.timer) {
clearInterval(that.timer);
this.isPayStatus = false;
this.pageShow = true;
this.$toast.clear();
console.log("关闭轮询1");
}
}
that.timer = setInterval(() => {
that.count++;
APIPay.getAlipayResult(reqBody)
.then(res => {
if (res.data.code === 20000) {
this.pageShow = true;
this.isPayStatus = true;
this.$toast.clear();
console.log("关闭轮询2");
if (that.timer) {
clearInterval(that.timer);
}
}
})
.catch(e => {
console.log(e);
});
}, 2000);
} else {
// todo 轮询微信支付的订单,支付成功则激活 (只有直播基地的imei才激活操作)
let that = this;
console.log("微信");
this.$toast.loading({message: "结果查询中"});
let reqBody = {
outTradeNo: params.outTradeNo
};
let url =
process.env.NODE_ENV === "production"
? " https://ai.ssjlai.com/telpopay/api/wx/order/callback"
: "https://id.ssjlai.com/telpopay/api/wx/order/callback";
if (that.count >= 30) {
if (that.timer) {
clearInterval(that.timer);
this.isPayStatus = false;
this.pageShow = true;
this.$toast.clear();
console.log("关闭轮询3");
}
}
that.timer = setInterval(() => {
that.count++;
APIPay.getWxPayResult(reqBody)
.then(res => {
if (res.data.code === 20000) {
this.pageShow = true;
this.isPayStatus = true;
this.$toast.clear();
console.log("关闭轮询4");
if (that.timer) {
clearInterval(that.timer);
}
}
})
.catch(e => {
console.log(e);
});
}, 2000);
}
},
// 获取微信支付接口
getWxPayResult() {
this.$toast.loading({
message: "正在获取支付结果",
duration: 3000
});
setTimeout(() => {
this.pageShow = true;
}, 3000);
},
closeTime() {
let params = this.$route.query;
let isFromWx = this.$store.getters.isFromWx;
setTimeout(() => {
clearInterval(this.timer);
console.log("即将关闭轮询");
this.$toast.clear();
if (this.pageShow === false) {
this.pageShow = true;
}
}, 31000);
}
}
};
</script>

<style scoped lang="scss">
.pay-result-container {
height: 100vh;
width: 100%;
display: flex;
justify-content: flex-start;
align-items: center;
flex-direction: column;
background-color: white;
overflow: scroll;
.check-container {
width: 100%;
}
.pos-center {
display: flex;
justify-content: flex-start;
align-items: center;
flex-direction: column;
}
.header {
width: 100%;
padding: 10px 0;
img {
height: 60px;
width: 60px;
margin: 10px 0;
border-radius: 50%;
}
p {
font-size: 18px;
}
}
.details {
padding: 20px 0;
width: 100%;
p {
font-size: 16px;
}
.details-item {
width: 80%;
display: flex;
justify-content: space-between;
align-items: center;
margin-left: 10%;
padding: 10px 0;
.left-text {
color: gray;
}
}
.price {
padding: 20px 0;
border-bottom: 5px solid $background;
.left-text {
color: gray;
}
}
.details-item:nth-child(2) {
border-bottom: 5px solid $background;
}
}
.footer {
height: 75px;
.back-btn {
height: 45px;
width: 275px;
display: flex;
justify-content: center;
align-items: center;
background: $blue;
border: 1px solid $blue;
border-radius: 25px;
p {
font-size: 18px;
padding: 0;
color: white;
}
}
}
}
.flush {
height: calc(100vh - 2.3784rem);
display: flex;
justify-content: center;
align-items: center;
.back-btn {
height: 45px;
width: 275px;
display: flex;
justify-content: center;
align-items: center;
background: $blue;
border: 1px solid $blue;
border-radius: 25px;
p {
font-size: 18px;
padding: 0;
color: white;
}
}
}
</style>

+ 0
- 120
src/views/websocket/websocket-demo.vue View File

@@ -1,120 +0,0 @@
<!--
* @Date: 2022-07-21 14:16:12
* @LastEditors: JinxChen
* @LastEditTime: 2022-08-09 15:11:38
* @FilePath: \AntpayFrontEnd\src\views\websocket\websocket-demo.vue
* @description: websocket 测试demo
-->
<template>
<div class="websocket-container">
<van-field v-model="socketData" label="socket数据" type="textarea" rows="1" autosize />
<van-button type="info" @click="onStartConnect">开始连接</van-button>
<van-button type="danger" @click="onStopConnect">停止连接</van-button>
</div>
</template>

<script>
export default {
name: 'websocket-demo',
data(){
return {
wsUrl: 'ws://id.ssjlai.com/realtime_pos/api/WebSocket/Acceptor',
websock: '',
socketData: '',
}
},
created() {},
destroyed() {
this.websocketClose(); //离开路由之后断开websocket连接
},
methods: {
// 开始连接
onStartConnect() {
this.initWebsocket();
},
// 关闭连接
onStopConnect() {
this.websocketClose()
},
// 初始化websocket连接
initWebsocket() {
this.$toast.loading({
message: '开始连接websocket',
})
if(typeof(WebSocket) === "undefined"){
this.$dialog.confirm({
title: '出错了',
message: '您的浏览器不支持websocket'
})
}else{
// 实例化socket
this.websock = new WebSocket(this.wsUrl);
// 获取webSocket返回的信息
this.websock.onmessage = this.websocketOnMessage;
// 打开连接
this.websock.onopen = this.websocketOnOpen;
// 连接出错
this.websock.onerror = this.websocketOnError;
// 关闭连接
this.websock.onclose = this.websocketClose;

}
},
// 打开websocket
websocketOnOpen() {
//连接建立之后执行send方法发送数据
let actions = '864316050104798';
this.websocketsend(actions);
this.$toast.loading({
message: '开始连接websocket',
})
console.log("开始连接");
},
// websocket出错
websocketOnError() {
//失败重连
//this.initWebSocket();
this.$toast.clear();
let that = this;
this.$dialog.confirm({
title: '出错了',
message: '是否重新连接websocket'
}).then(() => {
that.initWebsocket();
}).catch(() => {
that.websocketClose();
})
},
// 关闭websocket连接
websocketClose(e) {
this.websock.close();
if(e) {
console.log('断开连接',e);
};
console.log("关闭连接");
},
// 数据接收
websocketOnMessage(e) {
//this.$toast.clear();
const redata = JSON.parse(e.data);
console.log("获取到的数:;", redata);
},
// 发送数据
websocketsend(data){//数据发送
this.websock.send(data);
},
}
}
</script>

<style scoped lang="scss">
.websocket-container {
height: 100vh;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
padding: 0 20px;
}
</style>

+ 23
- 2
vue.config.js View File

@@ -1,11 +1,18 @@
/*
* @Author: your name
* @Date: 2020-04-15 10:00:32
* @LastEditTime: 2022-05-23 11:11:49
* @LastEditTime: 2023-02-25 15:35:15
* @LastEditors: JinxChen
* @Description: In User Settings Edit
* @FilePath: \AntpayFrontEnd\vue.config.js
* @FilePath: \TelpoH5FrontendWeb\vue.config.js
*/
const autoprefixer = require('autoprefixer'); // 根据屏幕动态改变根元素font-size

const pxtorem = require('postcss-pxtorem'); // 把代码中px转为rem

// const CompressionWebpackPlugin = require('compress-webpack-plugin');

const CompressionPlugin = require("compression-webpack-plugin");
const port = process.env.port || process.env.npm_config_port || 8080;/* 7788 */ // dev port

module.exports = {
@@ -38,6 +45,20 @@ module.exports = {
// 比如你可以这样向所有 Sass/Less 样式传入共享的全局变量
prependData: `@import "@/assets/css/public.scss";`
},
postcss: {
plugins: [
autoprefixer({
overrideBrowserslist: ["last 15 versions"]
}),
pxtorem({
rootValue: 37.5, // 换算的基数
// rootValue: 75, // 换算的基数
/* selectorBlackList: ["van"], */
propList: ["*"],
//exclude: /node_modules/
})
]
}
},
// Enable CSS modules for all css / pre-processor files. // This option does not affect *.vue files.
requireModuleExtension: true


Loading…
Cancel
Save