chore: suite

v2
xiaojunnuo 2024-12-18 09:07:52 +08:00
parent 8057586dc1
commit 1c8e25beb3
9 changed files with 270 additions and 80 deletions

View File

@ -280,3 +280,7 @@ h1, h2, h3, h4, h5, h6 {
.fs-16{
font-size: 16px;
}
.w-50\%{
width: 50%;
}

View File

@ -14,12 +14,12 @@ export async function GetLatestVersion() {
return latest;
}
const res = await request({
url: "https://registry.npmmirror.com/@certd/pipeline",
url: "/app/latest",
method: "GET",
unpack: false
unpack: true
});
try {
const latest = res["dist-tags"].latest;
const latest = res;
LocalStorage.set("latestVersion", latest, 60 * 60 * 24);
return latest;
} catch (e: any) {

View File

@ -1,11 +1,12 @@
import * as api from "./api";
import { useI18n } from "vue-i18n";
import { computed, Ref, ref } from "vue";
import { Ref, ref } from "vue";
import { useRouter } from "vue-router";
import { AddReq, compute, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes, utils } from "@fast-crud/fast-crud";
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
import { useUserStore } from "/@/store/modules/user";
import { useSettingStore } from "/@/store/modules/settings";
import { Modal } from "ant-design-vue";
import SuiteValue from "./suite-value.vue";
import SuiteValueEdit from "./suite-value-edit.vue";
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
const router = useRouter();
@ -63,6 +64,20 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
minWidth: 200,
fixed: "right"
},
form: {
group: {
groups: {
base: {
header: "基础信息",
columns: ["title", "type", "price", "originPrice", "duration", "isBootstrap", "intro"]
},
content: {
header: "套餐内容",
columns: ["maxDomainCount", "maxPipelineCount", "maxDeployCount", "siteMonitor"]
}
}
}
},
columns: {
id: {
title: "ID",
@ -78,11 +93,6 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
title: {
title: "套餐名称",
type: "text",
editForm: {
component: {
disabled: true
}
},
search: {
show: true
},
@ -93,77 +103,134 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
type: {
title: "类型",
type: "dict-select",
editForm: {
component: {
disabled: true
}
},
dict: dict({
data: [
{ label: "套餐", value: "suite" },
{ label: "加量包", value: "addon" }
]
})
}),
column: {
width: 100
}
},
maxDomainCount: {
title: "域名数量",
type: "number"
type: "number",
form: {
component: {
name: SuiteValueEdit,
vModel: "modelValue",
unit: "个"
}
},
column: {
width: 100,
component: {
name: SuiteValue
}
}
},
maxPipelineCount: {
title: "流水线数量",
type: "number"
type: "number",
form: {
component: {
name: SuiteValueEdit,
vModel: "modelValue",
unit: "条"
}
},
column: {
width: 100,
component: {
name: SuiteValue
}
}
},
maxDeployCount: {
title: "部署次数",
type: "number"
type: "number",
form: {
component: {
name: SuiteValueEdit,
vModel: "modelValue",
unit: "次"
}
},
column: {
width: 100,
component: {
name: SuiteValue
}
}
},
siteMonitor: {
title: "支持证书监控",
type: "dict-switch",
dict: dict({
data: [
{ label: "是", value: true, color: "success" },
{ label: "否", value: false, color: "error" }
]
}),
column: {
width: 120
}
},
isBootstrap: {
title: "是否初始套餐",
type: "dict-switch",
dict: dict({
data: [
{ label: "是", value: true, color: "success" },
{ label: "否", value: false, color: "error" }
]
}),
column: {
width: 120
}
},
price: {
title: "单价",
type: "number"
type: "number",
column: {
width: 100
}
},
originPrice: {
title: "原价",
type: "number"
type: "number",
column: {
width: 100
}
},
duration: {
title: "有效时长",
type: "number"
type: "dict-select",
column: {
width: 100
}
},
intro: {
title: "说明",
type: "textarea"
type: "textarea",
column: {
width: 200
}
},
order: {
title: "排序",
type: "number",
form: {
show: false
}
},
disabled: {
title: "禁用/启用",
type: "dict-switch",
dict: dict({
data: [
{ label: "启用", value: false, color: "success" },
{ label: "禁用", value: true, color: "error" }
]
}),
form: {
value: false
},
column: {
width: 100,
component: {
title: "点击可禁用/启用",
on: {
async click({ value, row }) {
Modal.confirm({
title: "提示",
content: `确定要${!value ? "禁用" : "启用"}吗?`,
onOk: async () => {
await api.SetDisabled(row.id, !value);
await crudExpose.doRefresh();
}
});
}
}
}
width: 100
}
},
createTime: {

View File

@ -0,0 +1,48 @@
<template>
<div class="cd-suite-value-edit flex-o">
<div class="flex- 1"><a-checkbox :checked="modelValue === -1" @update:checked="onCheckedChange">无限制</a-checkbox><span class="ml-5"></span></div>
<div class="ml-10 w-50%">
<a-input-number v-if="modelValue >= 0" :value="modelValue" class="ml-5" @update:value="onValueChange">
<template v-if="unit" #addonAfter>{{ unit }}</template>
</a-input-number>
</div>
</div>
</template>
<script lang="ts" setup>
import { Form } from "ant-design-vue";
import { dict } from "@fast-crud/fast-crud";
const props = defineProps<{
modelValue?: number;
}>();
const durationDict = dict({
data: [
{ label: "1年", value: 365 },
{ label: "2年", value: 730 },
{ label: "3年", value: 1095 },
{ label: "4年", value: 1460 },
{ label: "5年", value: 1825 },
{ label: "6年", value: 2190 },
{ label: "7年", value: 2555 },
{ label: "8年", value: 2920 },
{ label: "9年", value: 3285 },
{ label: "10年", value: 3650 },
{ label: "永久", value: -1 }
]
});
const formItemContext = Form.useInjectFormItemContext();
const emit = defineEmits(["update:modelValue"]);
const onCheckedChange = (checked: boolean) => {
const value = checked ? -1 : 1;
onValueChange(value);
};
function onValueChange(value: number) {
emit("update:modelValue", value);
formItemContext.onFieldChange();
}
</script>

View File

@ -2,11 +2,8 @@
<fs-page class="page-cert">
<template #header>
<div class="title">
CNAME服务配置
<span class="sub">
此处配置的域名作为其他域名校验的代理当别的域名需要申请证书时通过CNAME映射到此域名上来验证所有权好处是任何域名都可以通过此方式申请证书也无需填写AccessSecret
<a href="https://certd.docmirror.cn/guide/feature/cname/" target="_blank">CNAME功能原理及使用说明</a>
</span>
套餐管理
<span class="sub"> 必须设置一个初始套餐 </span>
</div>
</template>
<fs-crud ref="crudRef" v-bind="crudBinding">
@ -27,7 +24,7 @@ import { message, Modal } from "ant-design-vue";
import { DeleteBatch } from "./api";
defineOptions({
name: "CnameProvider"
name: "ProductManager"
});
const { crudBinding, crudRef, crudExpose, context } = useFs({ createCrudOptions });

View File

@ -0,0 +1,32 @@
<template>
<div class="cd-suite-value-edit flex-o">
<div class="flex- 1"><a-checkbox :checked="modelValue === -1" @update:checked="onCheckedChange">无限制</a-checkbox><span class="ml-5"></span></div>
<div class="ml-10 w-50%">
<a-input-number v-if="modelValue >= 0" :value="modelValue" class="ml-5" @update:value="onValueChange">
<template v-if="unit" #addonAfter>{{ unit }}</template>
</a-input-number>
</div>
</div>
</template>
<script lang="ts" setup>
import { Form } from "ant-design-vue";
const props = defineProps<{
modelValue?: number;
unit?: string;
}>();
const formItemContext = Form.useInjectFormItemContext();
const emit = defineEmits(["update:modelValue"]);
const onCheckedChange = (checked: boolean) => {
const value = checked ? -1 : 1;
onValueChange(value);
};
function onValueChange(value: number) {
emit("update:modelValue", value);
formItemContext.onFieldChange();
}
</script>

View File

@ -0,0 +1,38 @@
<template>
<div v-if="target" class="cd-suite-value">
<a-tag :color="target.color">{{ target.label }}</a-tag>
</div>
</template>
<script lang="ts" setup>
import { computed } from "vue";
const props = defineProps<{
modelValue: number;
}>();
const target = computed(() => {
if (!props.modelValue) {
return {};
}
if (props.modelValue === -1) {
return {
value: -1,
label: "无限制",
color: "green"
};
} else if (props.modelValue === 0) {
return {
value: 0,
label: "-",
color: "red"
};
} else {
return {
value: props.modelValue,
label: props.modelValue,
color: "blue"
};
}
});
</script>

View File

@ -9,11 +9,12 @@ CREATE TABLE "cd_product"
"max_deploy_count" integer,
"deploy_count_period" varchar(100),
"site_monitor" boolean,
"expires_time" integer,
"duration" integer,
"price" integer,
"origin_price" integer,
"intro" varchar(2048),
"order" integer,
"is_bootstrap" boolean,
"disabled" boolean NOT NULL DEFAULT (false),
"create_time" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP),
"update_time" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP)
@ -65,10 +66,12 @@ CREATE TABLE "cd_user_suite"
"max_domain_count" integer,
"max_pipeline_count" integer,
"max_deploy_count" integer,
"used_deploy_count" integer,
"deploy_count_period" varchar(100),
"site_monitor" boolean,
"duration" integer,
"used_deploy_count" integer,
"active_time" integer,
"expires_time" integer,
"disabled" boolean NOT NULL DEFAULT (false),
"create_time" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP),
"update_time" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP)
);

View File

@ -18,6 +18,7 @@ export class AppController extends BaseController {
const res = await http.request({
url: 'https://registry.npmmirror.com/@certd/pipeline',
method: 'get',
logRes: false,
});
try {
const latest = res['dist-tags'].latest;