mirror of https://github.com/certd/certd
feat: 支持微信支付
parent
67d762b6a5
commit
45d6347f5b
|
@ -1,4 +1,4 @@
|
||||||
export function isDev() {
|
export function isDev() {
|
||||||
const nodeEnv = process.env.NODE_ENV || '';
|
const nodeEnv = process.env.NODE_ENV || '';
|
||||||
return nodeEnv === 'development' || nodeEnv.indexOf('local') >= 0;
|
return nodeEnv === 'development' || nodeEnv.indexOf('local') >= 0 || nodeEnv.includes('dev');
|
||||||
}
|
}
|
||||||
|
|
|
@ -184,7 +184,7 @@ export abstract class AbstractTaskPlugin implements ITaskPlugin {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract execute(): Promise<void>;
|
abstract execute(): Promise<void | string>;
|
||||||
|
|
||||||
appendTimeSuffix(name?: string) {
|
appendTimeSuffix(name?: string) {
|
||||||
if (name == null) {
|
if (name == null) {
|
||||||
|
|
|
@ -56,6 +56,7 @@
|
||||||
"pinia": "2.1.7",
|
"pinia": "2.1.7",
|
||||||
"psl": "^1.9.0",
|
"psl": "^1.9.0",
|
||||||
"qiniu-js": "^3.4.2",
|
"qiniu-js": "^3.4.2",
|
||||||
|
"qrcode": "^1.5.4",
|
||||||
"sortablejs": "^1.15.2",
|
"sortablejs": "^1.15.2",
|
||||||
"vue": "^3.4.21",
|
"vue": "^3.4.21",
|
||||||
"vue-cropperjs": "^5.0.0",
|
"vue-cropperjs": "^5.0.0",
|
||||||
|
|
|
@ -1,39 +1,39 @@
|
||||||
<template>
|
<template>
|
||||||
<a-modal v-model:open="openRef" class="order-modal" title="订单确认" @ok="orderCreate">
|
<a-modal v-model:open="openRef" class="order-modal" title="订单确认" @ok="orderCreate">
|
||||||
<div v-if="product" class="order-box">
|
<div v-if="product" class="order-box">
|
||||||
<div class="flex-o mt-5">套餐:{{ product.title }}</div>
|
<div class="flex-o mt-5"><span class="label">套餐:</span>{{ product.title }}</div>
|
||||||
<div class="flex-o mt-5">说明:{{ product.intro }}</div>
|
<div class="flex-o mt-5"><span class="label">说明:</span>{{ product.intro }}</div>
|
||||||
<div class="flex-o mt-5">
|
<div class="flex-o mt-5">
|
||||||
<span class="flex-o">规格:</span>
|
<span class="label">规格:</span>
|
||||||
<span class="flex-o">流水线<suite-value class="ml-5" :model-value="product.content.maxPipelineCount" unit="条" />;</span>
|
<span class="flex-o">流水线<suite-value class="ml-5" :model-value="product.content.maxPipelineCount" unit="条" />;</span>
|
||||||
<span class="flex-o">域名<suite-value class="ml-5" :model-value="product.content.maxDomainCount" unit="个" />;</span>
|
<span class="flex-o">域名<suite-value class="ml-5" :model-value="product.content.maxDomainCount" unit="个" />;</span>
|
||||||
<span class="flex-o">部署次数<suite-value class="ml-5" :model-value="product.content.maxDeployCount" unit="次" />;</span>
|
<span class="flex-o">部署次数<suite-value class="ml-5" :model-value="product.content.maxDeployCount" unit="次" />;</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex-o mt-5">
|
<div class="flex-o mt-5">
|
||||||
时长:
|
<span class="label">时长:</span>
|
||||||
<duration-value v-model="formRef.duration"></duration-value>
|
<duration-value v-model="formRef.duration"></duration-value>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-o mt-5">价格: <price-input :edit="false" :model-value="durationSelected.price"></price-input></div>
|
<div class="flex-o mt-5"><span class="label">价格:</span> <price-input :edit="false" :model-value="durationSelected.price"></price-input></div>
|
||||||
|
|
||||||
<div class="flex-o mt-5">
|
<div class="flex-o mt-5">
|
||||||
支付方式:
|
<span class="label">支付方式:</span>
|
||||||
<fs-dict-select v-model:value="formRef.payType" :dict="paymentsDictRef" style="width: 200px"> </fs-dict-select>
|
<fs-dict-select v-model:value="formRef.payType" :dict="paymentsDictRef" style="width: 200px"> </fs-dict-select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="tsx">
|
||||||
import { ref } from 'vue';
|
import { ref } from "vue";
|
||||||
import { GetPaymentTypes, OrderModalOpenReq, TradeCreate } from '/@/views/certd/suite/api';
|
import { GetPaymentTypes, OrderModalOpenReq, TradeCreate } from "/@/views/certd/suite/api";
|
||||||
import SuiteValue from '/@/views/sys/suite/product/suite-value.vue';
|
import SuiteValue from "/@/views/sys/suite/product/suite-value.vue";
|
||||||
import PriceInput from '/@/views/sys/suite/product/price-input.vue';
|
import PriceInput from "/@/views/sys/suite/product/price-input.vue";
|
||||||
import { dict } from '@fast-crud/fast-crud';
|
import { dict } from "@fast-crud/fast-crud";
|
||||||
import { Modal, notification } from 'ant-design-vue';
|
import { Modal, notification } from "ant-design-vue";
|
||||||
import DurationValue from '/@/views/sys/suite/product/duration-value.vue';
|
import DurationValue from "/@/views/sys/suite/product/duration-value.vue";
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from "vue-router";
|
||||||
|
import qrcode from "qrcode";
|
||||||
const openRef = ref(false);
|
const openRef = ref(false);
|
||||||
|
|
||||||
const product = ref<any>(null);
|
const product = ref<any>(null);
|
||||||
|
@ -63,7 +63,6 @@ const paymentsDictRef = dict({
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
async function orderCreate() {
|
async function orderCreate() {
|
||||||
console.log("orderCreate", formRef.value);
|
|
||||||
if (!formRef.value.payType) {
|
if (!formRef.value.payType) {
|
||||||
notification.error({
|
notification.error({
|
||||||
message: "请选择支付方式"
|
message: "请选择支付方式"
|
||||||
|
@ -77,6 +76,13 @@ async function orderCreate() {
|
||||||
payType: formRef.value.payType
|
payType: formRef.value.payType
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function onPaid() {
|
||||||
|
openRef.value = false;
|
||||||
|
router.push({
|
||||||
|
path: "/"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
//跳转到对应的页面
|
//跳转到对应的页面
|
||||||
// http://pay.docmirror.cn/submit.php
|
// http://pay.docmirror.cn/submit.php
|
||||||
//易支付表单提交
|
//易支付表单提交
|
||||||
|
@ -87,7 +93,8 @@ async function orderCreate() {
|
||||||
doAlipay(paymentReq);
|
doAlipay(paymentReq);
|
||||||
} else if (formRef.value.payType === "wxpay") {
|
} else if (formRef.value.payType === "wxpay") {
|
||||||
//微信支付
|
//微信支付
|
||||||
doWxpay(paymentReq);
|
doWxpay(paymentReq.qrcode, onPaid);
|
||||||
|
return;
|
||||||
} else {
|
} else {
|
||||||
notification.error({
|
notification.error({
|
||||||
message: "暂不支持该支付方式"
|
message: "暂不支持该支付方式"
|
||||||
|
@ -99,10 +106,7 @@ async function orderCreate() {
|
||||||
title: "请在新页面完成支付",
|
title: "请在新页面完成支付",
|
||||||
content: "是否确认已完成支付",
|
content: "是否确认已完成支付",
|
||||||
onOk: async () => {
|
onOk: async () => {
|
||||||
openRef.value = false;
|
onPaid();
|
||||||
router.push({
|
|
||||||
path: "/"
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
cancelText: "取消支付",
|
cancelText: "取消支付",
|
||||||
okText: "已完成支付"
|
okText: "已完成支付"
|
||||||
|
@ -113,8 +117,29 @@ function doAlipay(paymentReq: any) {
|
||||||
window.open(paymentReq.api);
|
window.open(paymentReq.api);
|
||||||
}
|
}
|
||||||
|
|
||||||
function doWxpay(paymentReq: any) {
|
async function doWxpay(qrcodeText: string, onPaid: () => Promise<void>) {
|
||||||
window.open(paymentReq.api);
|
//展示微信支付二维码
|
||||||
|
const imageUrl = await qrcode.toDataURL(qrcodeText);
|
||||||
|
|
||||||
|
Modal.confirm({
|
||||||
|
wrapClassName: "modal-confirm-center",
|
||||||
|
title: "请微信扫码支付",
|
||||||
|
okText: "已完成支付",
|
||||||
|
cancelText: "取消支付",
|
||||||
|
icon() {
|
||||||
|
return "";
|
||||||
|
},
|
||||||
|
content: () => {
|
||||||
|
return (
|
||||||
|
<div style="text-align: center;">
|
||||||
|
<img src={imageUrl} style="width: 200px;height: 200px;display: initial;" />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
async onOk() {
|
||||||
|
await onPaid();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function doYizhifu(paymentReq: any) {
|
function doYizhifu(paymentReq: any) {
|
||||||
|
@ -161,3 +186,23 @@ defineExpose({
|
||||||
open
|
open
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
<style lang="less">
|
||||||
|
.order-box {
|
||||||
|
.label {
|
||||||
|
width: 80px;
|
||||||
|
text-align: right;
|
||||||
|
margin-right: 5px;
|
||||||
|
color: #686868;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-confirm-center {
|
||||||
|
.ant-modal-confirm-btns {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.ant-modal-confirm-content {
|
||||||
|
margin: 0 !important;
|
||||||
|
max-width: 100% !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
@ -53,6 +53,7 @@ CREATE TABLE "cd_user_suite"
|
||||||
"title" varchar(100),
|
"title" varchar(100),
|
||||||
"content" text,
|
"content" text,
|
||||||
"duration" integer,
|
"duration" integer,
|
||||||
|
"product_type" varchar(50),
|
||||||
"deploy_count_used" integer,
|
"deploy_count_used" integer,
|
||||||
"is_present" boolean,
|
"is_present" boolean,
|
||||||
"is_bootstrap" boolean,
|
"is_bootstrap" boolean,
|
||||||
|
|
|
@ -7,14 +7,14 @@
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "cross-env NODE_ENV=production node ./bootstrap.js",
|
"start": "cross-env NODE_ENV=production node ./bootstrap.js",
|
||||||
"dev": "cross-env NODE_ENV=local mwtsc --watch --run @midwayjs/mock/app",
|
"dev": "cross-env NODE_ENV=local mwtsc --watch --run @midwayjs/mock/app",
|
||||||
"commdev": "cross-env NODE_ENV=commdev mwtsc --watch --run @midwayjs/mock/app",
|
"dev-commlocal": "cross-env NODE_ENV=dev-commlocal mwtsc --watch --run @midwayjs/mock/app",
|
||||||
"commpro": "cross-env NODE_ENV=commpro mwtsc --watch --run @midwayjs/mock/app",
|
"dev-commpro": "cross-env NODE_ENV=dev-commpro mwtsc --watch --run @midwayjs/mock/app",
|
||||||
"pgdev": "cross-env NODE_ENV=pgdev mwtsc --watch --run @midwayjs/mock/app",
|
"dev-pgd": "cross-env NODE_ENV=dev-pgd mwtsc --watch --run @midwayjs/mock/app",
|
||||||
"mysqldev": "cross-env NODE_ENV=mysqldev mwtsc --watch --run @midwayjs/mock/app",
|
"dev-mysql": "cross-env NODE_ENV=dev-mysql mwtsc --watch --run @midwayjs/mock/app",
|
||||||
"local-plus": "cross-env NODE_ENV=localplus mwtsc --watch --run @midwayjs/mock/app",
|
"dev-localplus": "cross-env NODE_ENV=dev-localplus mwtsc --watch --run @midwayjs/mock/app",
|
||||||
"pgpl": "cross-env NODE_ENV=pgpl mwtsc --watch --run @midwayjs/mock/app",
|
"dev-pgpl": "cross-env NODE_ENV=dev-pgpl mwtsc --watch --run @midwayjs/mock/app",
|
||||||
"dev-new": "cross-env NODE_ENV=devnew mwtsc --watch --run @midwayjs/mock/app",
|
"dev-new": "cross-env NODE_ENV=dev-new mwtsc --watch --run @midwayjs/mock/app",
|
||||||
"rm-db-new": "rimraf ./data/db-new.sqlite",
|
"rm-newdb": "rimraf ./data/db-new.sqlite",
|
||||||
"test": "cross-env NODE_ENV=unittest mocha",
|
"test": "cross-env NODE_ENV=unittest mocha",
|
||||||
"cov": "cross-env c8 --all --reporter=text --reporter=lcovonly npm run test",
|
"cov": "cross-env c8 --all --reporter=text --reporter=lcovonly npm run test",
|
||||||
"lint": "mwts check",
|
"lint": "mwts check",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { App, Autoload, Config, Init, Inject, Scope, ScopeEnum } from '@midwayjs/core';
|
import { App, Autoload, Config, Init, Inject, Scope, ScopeEnum } from '@midwayjs/core';
|
||||||
import { getPlusInfo, isPlus } from '@certd/plus-core';
|
import { getPlusInfo, isPlus } from '@certd/plus-core';
|
||||||
import { logger } from '@certd/basic';
|
import { isDev, logger } from '@certd/basic';
|
||||||
|
|
||||||
import { SysInstallInfo, SysSettingsService } from '@certd/lib-server';
|
import { SysInstallInfo, SysSettingsService } from '@certd/lib-server';
|
||||||
import { getVersion } from '../../utils/version.js';
|
import { getVersion } from '../../utils/version.js';
|
||||||
|
@ -36,6 +36,18 @@ export class AutoZPrint {
|
||||||
}
|
}
|
||||||
logger.info('Certd已启动');
|
logger.info('Certd已启动');
|
||||||
logger.info('=========================================');
|
logger.info('=========================================');
|
||||||
|
if (isDev()) {
|
||||||
|
this.startHeapLog();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
startHeapLog() {
|
||||||
|
function format(bytes: any) {
|
||||||
|
return (bytes / 1024 / 1024).toFixed(2) + ' MB';
|
||||||
|
}
|
||||||
|
setInterval(() => {
|
||||||
|
logger.info(`heapUsed: ${format(process.memoryUsage().heapUsed)}`);
|
||||||
|
}, 60000);
|
||||||
}
|
}
|
||||||
|
|
||||||
async startHttpsServer() {
|
async startHttpsServer() {
|
||||||
|
|
Loading…
Reference in New Issue