mirror of https://github.com/certd/certd
fix: 免费套餐支持购买
parent
fe4786e168
commit
f5ec9870fd
|
@ -122,12 +122,11 @@ export const useSettingStore = defineStore({
|
||||||
};
|
};
|
||||||
return vipLabelMap[this.plusInfo?.vipType || "free"];
|
return vipLabelMap[this.plusInfo?.vipType || "free"];
|
||||||
},
|
},
|
||||||
// @ts-ignore
|
getHeaderMenus(): { menus: any[] } {
|
||||||
getHeaderMenus() {
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
return this.headerMenus?.menus || { menus: [] };
|
return this.headerMenus?.menus || { menus: [] };
|
||||||
},
|
},
|
||||||
isSuiteEnabled() {
|
isSuiteEnabled(): boolean {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
return this.suiteSetting?.enabled === true;
|
return this.suiteSetting?.enabled === true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,6 +52,14 @@ export async function TradeCreate(form: TradeCreateReq) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function TradeCreateFree(form: TradeCreateReq) {
|
||||||
|
return await request({
|
||||||
|
url: "/suite/trade/createFree",
|
||||||
|
method: "POST",
|
||||||
|
data: form
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export async function GetPaymentTypes() {
|
export async function GetPaymentTypes() {
|
||||||
return await request({
|
return await request({
|
||||||
url: "/suite/trade/payments",
|
url: "/suite/trade/payments",
|
||||||
|
|
|
@ -35,6 +35,7 @@ import { ref } from "vue";
|
||||||
import * as api from "./api";
|
import * as api from "./api";
|
||||||
import ProductInfo from "/@/views/certd/suite/product-info.vue";
|
import ProductInfo from "/@/views/certd/suite/product-info.vue";
|
||||||
import OrderModal from "/@/views/certd/suite/order-modal.vue";
|
import OrderModal from "/@/views/certd/suite/order-modal.vue";
|
||||||
|
import { notification } from "ant-design-vue";
|
||||||
|
|
||||||
const suites = ref([]);
|
const suites = ref([]);
|
||||||
const addons = ref([]);
|
const addons = ref([]);
|
||||||
|
@ -48,6 +49,20 @@ async function loadProducts() {
|
||||||
loadProducts();
|
loadProducts();
|
||||||
const orderModalRef = ref<any>(null);
|
const orderModalRef = ref<any>(null);
|
||||||
async function doOrder(req: any) {
|
async function doOrder(req: any) {
|
||||||
|
if (req.price === 0) {
|
||||||
|
//如果是0,直接请求创建订单
|
||||||
|
await api.TradeCreateFree({
|
||||||
|
productId: req.productId,
|
||||||
|
duration: req.duration,
|
||||||
|
num: 1,
|
||||||
|
payType: "free"
|
||||||
|
});
|
||||||
|
notification.success({
|
||||||
|
message: "套餐购买成功"
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
await orderModalRef.value.open({
|
await orderModalRef.value.open({
|
||||||
...req
|
...req
|
||||||
});
|
});
|
||||||
|
|
|
@ -263,7 +263,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
userSuite: compute(({ row }) => {
|
userSuite: compute(({ row }) => {
|
||||||
return row;
|
return row;
|
||||||
}),
|
}),
|
||||||
currentSuite: context.detail
|
currentSuite: context.currentSuite
|
||||||
},
|
},
|
||||||
conditionalRender: {
|
conditionalRender: {
|
||||||
match() {
|
match() {
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onActivated, onMounted, ref } from "vue";
|
import { computed, onActivated, onMounted, ref } from "vue";
|
||||||
import { useFs } from "@fast-crud/fast-crud";
|
import { useFs } from "@fast-crud/fast-crud";
|
||||||
import createCrudOptions from "./crud";
|
import createCrudOptions from "./crud";
|
||||||
import api, { SuiteDetail } from "/@/views/certd/suite/mine/api";
|
import api, { SuiteDetail } from "/@/views/certd/suite/mine/api";
|
||||||
|
@ -25,7 +25,14 @@ defineOptions({
|
||||||
name: "MySuites"
|
name: "MySuites"
|
||||||
});
|
});
|
||||||
const detail = ref<SuiteDetail>({});
|
const detail = ref<SuiteDetail>({});
|
||||||
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: { detail } });
|
const currentSuite = computed(() => {
|
||||||
|
if (detail.value?.suites && detail.value.suites.length > 0) {
|
||||||
|
return detail.value.suites[0];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: { detail, currentSuite } });
|
||||||
|
|
||||||
async function loadSuiteDetail() {
|
async function loadSuiteDetail() {
|
||||||
detail.value = await api.SuiteDetailGet();
|
detail.value = await api.SuiteDetailGet();
|
||||||
|
|
|
@ -80,7 +80,7 @@ const productTypeDictRef = dict({
|
||||||
|
|
||||||
const emit = defineEmits(["order"]);
|
const emit = defineEmits(["order"]);
|
||||||
async function doOrder() {
|
async function doOrder() {
|
||||||
emit("order", { product: props.product, productId: props.product.id, duration: selected.value.duration });
|
emit("order", { product: props.product, productId: props.product.id, duration: selected.value.duration, price: selected.value.price });
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -162,7 +162,8 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
]
|
]
|
||||||
}),
|
}),
|
||||||
column: {
|
column: {
|
||||||
width: 100
|
width: 100,
|
||||||
|
align: "center"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
payType: {
|
payType: {
|
||||||
|
@ -173,14 +174,16 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
data: [
|
data: [
|
||||||
{ label: "聚合支付", value: "yizhifu" },
|
{ label: "聚合支付", value: "yizhifu" },
|
||||||
{ label: "支付宝", value: "alipay" },
|
{ label: "支付宝", value: "alipay" },
|
||||||
{ label: "微信", value: "wxpay" }
|
{ label: "微信", value: "wxpay" },
|
||||||
|
{ label: "免费", value: "free" }
|
||||||
]
|
]
|
||||||
}),
|
}),
|
||||||
column: {
|
column: {
|
||||||
width: 100,
|
width: 100,
|
||||||
component: {
|
component: {
|
||||||
color: "auto"
|
color: "auto"
|
||||||
}
|
},
|
||||||
|
align: "center"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
payTime: {
|
payTime: {
|
||||||
|
|
|
@ -36,8 +36,8 @@
|
||||||
</span>
|
</span>
|
||||||
<span>(<expires-time-text :value="item.expiresTime" />)</span>
|
<span>(<expires-time-text :value="item.expiresTime" />)</span>
|
||||||
</a-tag>
|
</a-tag>
|
||||||
<div class="flex-o ml-5">
|
<div v-if="detail.suites?.length === 0" class="flex-o ml-5">
|
||||||
暂无套餐 <a-button v-if="detail.suites?.length === 0" class="ml-5" type="primary" size="small" @click="goBuy">去购买</a-button>
|
暂无套餐 <a-button class="ml-5" type="primary" size="small" @click="goBuy">去购买</a-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a-popover>
|
</a-popover>
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
<div style="height: 400px">
|
<div style="height: 400px">
|
||||||
<ProductManager @refreshed="onTableRefresh"></ProductManager>
|
<ProductManager @refreshed="onTableRefresh"></ProductManager>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="helper">不建议设置免费套餐,可以在下方配置注册赠送套餐</div>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
|
||||||
<a-form-item label="注册赠送套餐" name="registerGift">
|
<a-form-item label="注册赠送套餐" name="registerGift">
|
||||||
|
|
|
@ -7,6 +7,10 @@ import { ref, watch } from "vue";
|
||||||
import { dict } from "@fast-crud/fast-crud";
|
import { dict } from "@fast-crud/fast-crud";
|
||||||
import { request } from "/@/api/service";
|
import { request } from "/@/api/service";
|
||||||
|
|
||||||
|
defineOptions({
|
||||||
|
name: "SuiteDurationSelector"
|
||||||
|
});
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
modelValue?: {
|
modelValue?: {
|
||||||
productId?: number;
|
productId?: number;
|
||||||
|
|
|
@ -155,7 +155,8 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
component: {
|
component: {
|
||||||
name: DurationValue,
|
name: DurationValue,
|
||||||
vModel: "modelValue"
|
vModel: "modelValue"
|
||||||
}
|
},
|
||||||
|
align: "center"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
amount: {
|
amount: {
|
||||||
|
@ -182,7 +183,8 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
]
|
]
|
||||||
}),
|
}),
|
||||||
column: {
|
column: {
|
||||||
width: 100
|
width: 100,
|
||||||
|
align: "center"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
payType: {
|
payType: {
|
||||||
|
@ -193,14 +195,16 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
data: [
|
data: [
|
||||||
{ label: "聚合支付", value: "yizhifu" },
|
{ label: "聚合支付", value: "yizhifu" },
|
||||||
{ label: "支付宝", value: "alipay" },
|
{ label: "支付宝", value: "alipay" },
|
||||||
{ label: "微信", value: "wxpay" }
|
{ label: "微信", value: "wxpay" },
|
||||||
|
{ label: "免费", value: "free" }
|
||||||
]
|
]
|
||||||
}),
|
}),
|
||||||
column: {
|
column: {
|
||||||
width: 100,
|
width: 100,
|
||||||
component: {
|
component: {
|
||||||
color: "auto"
|
color: "auto"
|
||||||
}
|
},
|
||||||
|
align: "center"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
payTime: {
|
payTime: {
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
import { request } from "/src/api/service";
|
import { request } from "/src/api/service";
|
||||||
|
|
||||||
export function createApi() {
|
const apiPrefix = "/sys/suite/user-suite";
|
||||||
const apiPrefix = "/sys/suite/user-suite";
|
export const sysUserSuiteApi = {
|
||||||
return {
|
|
||||||
async GetList(query: any) {
|
async GetList(query: any) {
|
||||||
return await request({
|
return await request({
|
||||||
url: apiPrefix + "/page",
|
url: apiPrefix + "/page",
|
||||||
|
@ -55,8 +54,12 @@ export function createApi() {
|
||||||
method: "post",
|
method: "post",
|
||||||
data: { ids }
|
data: { ids }
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
async PresentSuite(form: any) {
|
||||||
|
return await request({
|
||||||
|
url: apiPrefix + "/presentSuite",
|
||||||
|
method: "post",
|
||||||
|
data: form
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
export const pipelineGroupApi = createApi();
|
|
||||||
|
|
|
@ -1,15 +1,14 @@
|
||||||
import { AddReq, compute, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
import { AddReq, compute, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
||||||
import { pipelineGroupApi } from "./api";
|
import { sysUserSuiteApi } from "./api";
|
||||||
import { useRouter } from "vue-router";
|
import { useRouter } from "vue-router";
|
||||||
import SuiteValueEdit from "/@/views/sys/suite/product/suite-value-edit.vue";
|
import SuiteValueEdit from "/@/views/sys/suite/product/suite-value-edit.vue";
|
||||||
import SuiteValue from "/@/views/sys/suite/product/suite-value.vue";
|
import SuiteValue from "/@/views/sys/suite/product/suite-value.vue";
|
||||||
import DurationValue from "/@/views/sys/suite/product/duration-value.vue";
|
import DurationValue from "/@/views/sys/suite/product/duration-value.vue";
|
||||||
import dayjs from "dayjs";
|
|
||||||
import createCrudOptionsUser from "/@/views/sys/authority/user/crud";
|
import createCrudOptionsUser from "/@/views/sys/authority/user/crud";
|
||||||
import UserSuiteStatus from "/@/views/certd/suite/mine/user-suite-status.vue";
|
import UserSuiteStatus from "/@/views/certd/suite/mine/user-suite-status.vue";
|
||||||
|
import SuiteDurationSelector from "../setting/suite-duration-selector.vue";
|
||||||
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
||||||
const api = pipelineGroupApi;
|
const api = sysUserSuiteApi;
|
||||||
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
|
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
|
||||||
return await api.GetList(query);
|
return await api.GetList(query);
|
||||||
};
|
};
|
||||||
|
@ -26,7 +25,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
|
|
||||||
const addRequest = async (req: AddReq) => {
|
const addRequest = async (req: AddReq) => {
|
||||||
const { form } = req;
|
const { form } = req;
|
||||||
const res = await api.AddObj(form);
|
const res = await api.PresentSuite(form);
|
||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -57,16 +56,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
},
|
},
|
||||||
actionbar: {
|
actionbar: {
|
||||||
buttons: {
|
buttons: {
|
||||||
add: { show: false }
|
add: { text: "赠送套餐" }
|
||||||
// buy: {
|
|
||||||
// text: "购买",
|
|
||||||
// type: "primary",
|
|
||||||
// click() {
|
|
||||||
// router.push({
|
|
||||||
// path: "/certd/suite/buy"
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
toolbar: { show: false },
|
toolbar: { show: false },
|
||||||
|
@ -112,7 +102,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
show: true
|
show: true
|
||||||
},
|
},
|
||||||
form: {
|
form: {
|
||||||
rules: [{ required: true, message: "此项必填" }]
|
show: false
|
||||||
},
|
},
|
||||||
column: {
|
column: {
|
||||||
width: 200
|
width: 200
|
||||||
|
@ -143,6 +133,27 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
//赠送
|
||||||
|
presentSuiteId: {
|
||||||
|
title: "赠送套餐",
|
||||||
|
type: "dict-select",
|
||||||
|
column: { show: false },
|
||||||
|
addForm: {
|
||||||
|
component: {
|
||||||
|
name: SuiteDurationSelector,
|
||||||
|
vModel: "modelValue"
|
||||||
|
},
|
||||||
|
rules: [{ required: true, message: "请选择套餐" }]
|
||||||
|
},
|
||||||
|
valueResolve({ form, value }) {
|
||||||
|
if (value) {
|
||||||
|
const arr = value.splict("_");
|
||||||
|
form.productId = parseInt(arr[0]);
|
||||||
|
form.duration = parseInt(arr[1]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
form: { show: false }
|
||||||
|
},
|
||||||
productType: {
|
productType: {
|
||||||
title: "类型",
|
title: "类型",
|
||||||
type: "dict-select",
|
type: "dict-select",
|
||||||
|
@ -158,7 +169,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
]
|
]
|
||||||
}),
|
}),
|
||||||
form: {
|
form: {
|
||||||
rules: [{ required: true, message: "此项必填" }]
|
show: false
|
||||||
},
|
},
|
||||||
column: {
|
column: {
|
||||||
width: 80,
|
width: 80,
|
||||||
|
@ -179,6 +190,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
title: "域名数量",
|
title: "域名数量",
|
||||||
type: "text",
|
type: "text",
|
||||||
form: {
|
form: {
|
||||||
|
show: false,
|
||||||
key: ["content", "maxDomainCount"],
|
key: ["content", "maxDomainCount"],
|
||||||
component: {
|
component: {
|
||||||
name: SuiteValueEdit,
|
name: SuiteValueEdit,
|
||||||
|
@ -201,6 +213,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
title: "流水线数量",
|
title: "流水线数量",
|
||||||
type: "text",
|
type: "text",
|
||||||
form: {
|
form: {
|
||||||
|
show: false,
|
||||||
key: ["content", "maxPipelineCount"],
|
key: ["content", "maxPipelineCount"],
|
||||||
component: {
|
component: {
|
||||||
name: SuiteValueEdit,
|
name: SuiteValueEdit,
|
||||||
|
@ -223,6 +236,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
title: "部署次数",
|
title: "部署次数",
|
||||||
type: "text",
|
type: "text",
|
||||||
form: {
|
form: {
|
||||||
|
show: false,
|
||||||
key: ["content", "maxDeployCount"],
|
key: ["content", "maxDeployCount"],
|
||||||
component: {
|
component: {
|
||||||
name: SuiteValueEdit,
|
name: SuiteValueEdit,
|
||||||
|
@ -248,6 +262,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
title: "证书监控数量",
|
title: "证书监控数量",
|
||||||
type: "text",
|
type: "text",
|
||||||
form: {
|
form: {
|
||||||
|
show: false,
|
||||||
key: ["content", "maxMonitorCount"],
|
key: ["content", "maxMonitorCount"],
|
||||||
component: {
|
component: {
|
||||||
name: SuiteValueEdit,
|
name: SuiteValueEdit,
|
||||||
|
@ -269,7 +284,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
duration: {
|
duration: {
|
||||||
title: "时长",
|
title: "时长",
|
||||||
type: "text",
|
type: "text",
|
||||||
form: {},
|
form: { show: false },
|
||||||
column: {
|
column: {
|
||||||
component: {
|
component: {
|
||||||
name: DurationValue,
|
name: DurationValue,
|
||||||
|
@ -304,11 +319,17 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
type: "date",
|
type: "date",
|
||||||
column: {
|
column: {
|
||||||
width: 150
|
width: 150
|
||||||
|
},
|
||||||
|
form: {
|
||||||
|
show: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
expiresTime: {
|
expiresTime: {
|
||||||
title: "过期时间",
|
title: "过期时间",
|
||||||
type: "date",
|
type: "date",
|
||||||
|
form: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
column: {
|
column: {
|
||||||
width: 150,
|
width: 150,
|
||||||
component: {
|
component: {
|
||||||
|
@ -328,7 +349,8 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
]
|
]
|
||||||
}),
|
}),
|
||||||
form: {
|
form: {
|
||||||
value: true
|
value: true,
|
||||||
|
show: false
|
||||||
},
|
},
|
||||||
column: {
|
column: {
|
||||||
width: 100,
|
width: 100,
|
||||||
|
|
|
@ -11,10 +11,10 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { defineComponent, onActivated, onMounted } from "vue";
|
import { onActivated, onMounted } from "vue";
|
||||||
import { useFs } from "@fast-crud/fast-crud";
|
import { useFs } from "@fast-crud/fast-crud";
|
||||||
import createCrudOptions from "./crud";
|
import createCrudOptions from "./crud";
|
||||||
import { createApi } from "./api";
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: "UserSuites"
|
name: "UserSuites"
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue