mirror of
https://github.com/certd/certd.git
synced 2026-04-25 05:07:25 +08:00
Merge branch 'v2-dev' into v2_admin_mode
This commit is contained in:
@@ -3,6 +3,25 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.38.10](https://github.com/certd/certd/compare/v1.38.9...v1.38.10) (2026-02-15)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 修复1panel 请求失败的bug ([0283662](https://github.com/certd/certd/commit/0283662931ff47d6b5d49f91a30c4a002fe1d108))
|
||||
* 修复保存站点监控dns设置,偶尔无法保存成功的bug ([8387fe0](https://github.com/certd/certd/commit/8387fe0d5b2e77b8c2788a10791e5389d97a3e41))
|
||||
* 修复任务步骤标题过长导致错位的问题 ([9fb9805](https://github.com/certd/certd/commit/9fb980599f96ccbf61bd46019411db2f13c70e57))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* 监控设置支持逗号分割 ([c23d1d1](https://github.com/certd/certd/commit/c23d1d11b58a6cdfe431a7e8abbd5d955146c38d))
|
||||
* 列表中支持下次执行时间显示 ([a3cabd5](https://github.com/certd/certd/commit/a3cabd5f36ed41225ad418098596e9b2c44e31a1))
|
||||
* 模版编辑页面,hover反色过亮问题优化 ([e55a3a8](https://github.com/certd/certd/commit/e55a3a82fc6939b940f0c3be4529d74a625f6f4e))
|
||||
* 所有授权增加测试按钮 ([7a3e68d](https://github.com/certd/certd/commit/7a3e68d656c1dcdcd814b69891bd2c2c6fe3098a))
|
||||
* 优化网络测试页面,夜间模式显示效果 ([305da86](https://github.com/certd/certd/commit/305da86f97d918374819ecd6c50685f09b94ea59))
|
||||
* 支持next-terminal ([6f3fd78](https://github.com/certd/certd/commit/6f3fd785e77a33c72bdf4115dc5d498e677d1863))
|
||||
* 主题默认跟随系统颜色(自动切换深色浅色模式) ([32c3ce5](https://github.com/certd/certd/commit/32c3ce5c9868569523901a9a939ca5b535ec3277))
|
||||
* http校验方式支持scp上传 ([4eb940f](https://github.com/certd/certd/commit/4eb940ffe765a0330331bc6af8396315e36d4e4a))
|
||||
|
||||
## [1.38.9](https://github.com/certd/certd/compare/v1.38.8...v1.38.9) (2026-02-09)
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@certd/ui-client",
|
||||
"version": "1.38.9",
|
||||
"version": "1.38.10",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "vite --open",
|
||||
@@ -106,8 +106,8 @@
|
||||
"zod-defaults": "^0.1.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@certd/lib-iframe": "^1.38.9",
|
||||
"@certd/pipeline": "^1.38.9",
|
||||
"@certd/lib-iframe": "^1.38.10",
|
||||
"@certd/pipeline": "^1.38.10",
|
||||
"@rollup/plugin-commonjs": "^25.0.7",
|
||||
"@rollup/plugin-node-resolve": "^15.2.3",
|
||||
"@types/chai": "^4.3.12",
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 5.4 KiB |
@@ -13,6 +13,7 @@
|
||||
import { ComponentPropsType, doRequest } from "/@/components/plugins/lib";
|
||||
import { ref, inject } from "vue";
|
||||
import { Form } from "ant-design-vue";
|
||||
import { getInputFromForm } from "./utils";
|
||||
|
||||
defineOptions({
|
||||
name: "ApiTest",
|
||||
@@ -45,13 +46,15 @@ const doTest = async () => {
|
||||
message.value = "";
|
||||
hasError.value = false;
|
||||
loading.value = true;
|
||||
const { input, record } = getInputFromForm(form, pluginType);
|
||||
try {
|
||||
const res = await doRequest(
|
||||
{
|
||||
type: pluginType,
|
||||
typeName: form.type,
|
||||
action: props.action,
|
||||
input: pluginType === "plugin" ? form.input : form,
|
||||
input,
|
||||
record,
|
||||
},
|
||||
{
|
||||
onError(err: any) {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
import { ComponentPropsType, doRequest } from "/@/components/plugins/lib";
|
||||
import { defineComponent, inject, ref, useAttrs, watch, Ref } from "vue";
|
||||
import { PluginDefine } from "@certd/pipeline";
|
||||
import { getInputFromForm } from "./utils";
|
||||
|
||||
defineOptions({
|
||||
name: "RemoteAutoComplete",
|
||||
@@ -48,18 +49,6 @@ const message = ref("");
|
||||
const hasError = ref(false);
|
||||
const loading = ref(false);
|
||||
|
||||
function getInputFromForm(form: any, pluginType: string) {
|
||||
let input: any = {};
|
||||
if (pluginType === "plugin") {
|
||||
input = form?.input || {};
|
||||
} else if (pluginType === "access") {
|
||||
input = form?.access || {};
|
||||
} else {
|
||||
input = form || {};
|
||||
}
|
||||
return input;
|
||||
}
|
||||
|
||||
const getOptions = async () => {
|
||||
if (loading.value) {
|
||||
return;
|
||||
@@ -75,7 +64,7 @@ const getOptions = async () => {
|
||||
}
|
||||
const pluginType = getPluginType();
|
||||
const { form } = getScope();
|
||||
const input = getInputFromForm(form, pluginType);
|
||||
const { input, record } = getInputFromForm(form, pluginType);
|
||||
for (let key in define.input) {
|
||||
const inWatches = props.watches?.includes(key);
|
||||
const inputDefine = define.input[key];
|
||||
@@ -99,6 +88,7 @@ const getOptions = async () => {
|
||||
action: props.action,
|
||||
input,
|
||||
data: {},
|
||||
record,
|
||||
},
|
||||
{
|
||||
onError(err: any) {
|
||||
@@ -140,7 +130,7 @@ watch(
|
||||
() => {
|
||||
const pluginType = getPluginType();
|
||||
const { form, key } = getScope();
|
||||
const input = getInputFromForm(form, pluginType);
|
||||
const { input, record } = getInputFromForm(form, pluginType);
|
||||
const watches: any = {};
|
||||
if (props.watches && props.watches.length > 0) {
|
||||
for (const key of props.watches) {
|
||||
|
||||
@@ -9,6 +9,7 @@ import { doRequest } from "/@/components/plugins/lib";
|
||||
import { inject, ref, useAttrs } from "vue";
|
||||
import { useFormWrapper } from "@fast-crud/fast-crud";
|
||||
import { notification } from "ant-design-vue";
|
||||
import { getInputFromForm } from "./utils";
|
||||
|
||||
defineOptions({
|
||||
name: "RemoteInput",
|
||||
@@ -71,15 +72,18 @@ const doPluginFormSubmit = async (data: any) => {
|
||||
}
|
||||
|
||||
loading.value = true;
|
||||
|
||||
try {
|
||||
const pluginType = getPluginType();
|
||||
const { form } = getScope();
|
||||
const { input, record } = getInputFromForm(form, pluginType);
|
||||
const res = await doRequest({
|
||||
type: pluginType,
|
||||
typeName: form.type,
|
||||
action: props.action,
|
||||
input: pluginType === "plugin" ? form.input : form,
|
||||
input,
|
||||
data: data,
|
||||
record,
|
||||
});
|
||||
//获取返回值 填入到input中
|
||||
emit("update:modelValue", res);
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
import { ComponentPropsType, doRequest } from "/@/components/plugins/lib";
|
||||
import { defineComponent, inject, ref, useAttrs, watch, Ref } from "vue";
|
||||
import { PluginDefine } from "@certd/pipeline";
|
||||
import { getInputFromForm } from "./utils";
|
||||
|
||||
defineOptions({
|
||||
name: "RemoteSelect",
|
||||
@@ -79,17 +80,6 @@ const getPluginType: any = inject("get:plugin:type", () => {
|
||||
return "plugin";
|
||||
});
|
||||
|
||||
function getInputFromForm(form: any, pluginType: string) {
|
||||
let input: any = {};
|
||||
if (pluginType === "plugin") {
|
||||
input = form?.input || {};
|
||||
} else if (pluginType === "access") {
|
||||
input = form?.access || {};
|
||||
} else {
|
||||
input = form || {};
|
||||
}
|
||||
return input;
|
||||
}
|
||||
const searchKeyRef = ref("");
|
||||
const optionsRef = ref([]);
|
||||
const message = ref("");
|
||||
@@ -115,7 +105,7 @@ const getOptions = async () => {
|
||||
}
|
||||
const pluginType = getPluginType();
|
||||
const { form } = getScope();
|
||||
const input = getInputFromForm(form, pluginType);
|
||||
const { input, record } = getInputFromForm(form, pluginType);
|
||||
|
||||
for (let key in define.input) {
|
||||
const inWatches = props.watches?.includes(key);
|
||||
@@ -141,6 +131,7 @@ const getOptions = async () => {
|
||||
typeName: form.type,
|
||||
action: props.action,
|
||||
input,
|
||||
record,
|
||||
data: {
|
||||
searchKey: props.search ? searchKeyRef.value : "",
|
||||
pageNo,
|
||||
@@ -211,7 +202,7 @@ watch(
|
||||
() => {
|
||||
const pluginType = getPluginType();
|
||||
const { form, key } = getScope();
|
||||
const input = getInputFromForm(form, pluginType);
|
||||
const { input, record } = getInputFromForm(form, pluginType);
|
||||
const watches: any = {};
|
||||
if (props.watches && props.watches.length > 0) {
|
||||
for (const key of props.watches) {
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
import { ComponentPropsType, doRequest } from "/@/components/plugins/lib";
|
||||
import { defineComponent, inject, ref, useAttrs, watch, Ref } from "vue";
|
||||
import { PluginDefine } from "@certd/pipeline";
|
||||
import { getInputFromForm } from "./utils";
|
||||
|
||||
defineOptions({
|
||||
name: "RemoteTreeSelect",
|
||||
@@ -67,7 +68,7 @@ const getOptions = async () => {
|
||||
}
|
||||
const pluginType = getPluginType();
|
||||
const { form } = getScope();
|
||||
const input = (pluginType === "plugin" ? form?.input : form) || {};
|
||||
const { input, record } = getInputFromForm(form, pluginType);
|
||||
|
||||
for (let key in define.input) {
|
||||
const inWatches = props.watches?.includes(key);
|
||||
@@ -98,6 +99,7 @@ const getOptions = async () => {
|
||||
pageNo,
|
||||
pageSize,
|
||||
},
|
||||
record,
|
||||
},
|
||||
{
|
||||
onError(err: any) {
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
import { cloneDeep } from "lodash-es";
|
||||
|
||||
export function getInputFromForm(form: any, pluginType: string) {
|
||||
form = cloneDeep(form);
|
||||
let input: any = {};
|
||||
const record: any = form;
|
||||
if (pluginType === "plugin") {
|
||||
input = form?.input || {};
|
||||
delete form.input;
|
||||
} else if (pluginType === "access") {
|
||||
input = form?.access || {};
|
||||
delete form.access;
|
||||
} else if (pluginType === "notification") {
|
||||
input = form?.body || {};
|
||||
delete form.body;
|
||||
} else if (pluginType === "addon") {
|
||||
input = form?.body || {};
|
||||
delete form.body;
|
||||
} else {
|
||||
throw new Error(`pluginType ${pluginType} not support`);
|
||||
}
|
||||
return {
|
||||
input,
|
||||
record,
|
||||
};
|
||||
}
|
||||
@@ -20,6 +20,7 @@ export const Dicts = {
|
||||
uploaderTypeDict: dict({
|
||||
data: [
|
||||
{ label: "SFTP", value: "sftp" },
|
||||
{ label: "SCP", value: "scp" },
|
||||
{ label: "FTP", value: "ftp" },
|
||||
{ label: "阿里云OSS", value: "alioss" },
|
||||
{ label: "腾讯云COS", value: "tencentcos" },
|
||||
|
||||
@@ -12,11 +12,12 @@ export type RequestHandleReq<T = any> = {
|
||||
action: string;
|
||||
data?: any;
|
||||
input: T;
|
||||
record?: any;
|
||||
};
|
||||
|
||||
export async function doRequest(req: RequestHandleReq, opts: any = {}) {
|
||||
const url = `/pi/handle/${req.type}`;
|
||||
const { typeName, action, data, input } = req;
|
||||
const { typeName, action, data, input, record } = req;
|
||||
const res = await request({
|
||||
url,
|
||||
method: "post",
|
||||
@@ -25,6 +26,7 @@ export async function doRequest(req: RequestHandleReq, opts: any = {}) {
|
||||
action,
|
||||
data,
|
||||
input,
|
||||
record,
|
||||
},
|
||||
...opts,
|
||||
});
|
||||
|
||||
@@ -160,6 +160,7 @@ export default {
|
||||
updateTime: "Update Time",
|
||||
triggerType: "Trigger Type",
|
||||
pipelineId: "Pipeline Id",
|
||||
nextRunTime: "Next Run Time",
|
||||
projectName: "Project",
|
||||
adminId: "Admin",
|
||||
},
|
||||
|
||||
@@ -167,6 +167,7 @@ export default {
|
||||
updateTime: "更新时间",
|
||||
triggerType: "触发类型",
|
||||
pipelineId: "流水线Id",
|
||||
nextRunTime: "下次运行时间",
|
||||
projectName: "项目",
|
||||
adminId: "管理员",
|
||||
},
|
||||
|
||||
@@ -117,3 +117,4 @@ span.fs-icon-svg {
|
||||
margin: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
@import "./fix-windicss.less";
|
||||
@import "./antdv4.less";
|
||||
@import "./certd.less";
|
||||
@import "./dark.less";
|
||||
|
||||
html,
|
||||
body {
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
.dark{
|
||||
.fs-page-header{
|
||||
.title {
|
||||
color: #d5d5d5 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -94,7 +94,7 @@ const defaultPreferences: Preferences = {
|
||||
colorPrimary: "hsl(212 100% 45%)",
|
||||
colorSuccess: "hsl(144 57% 58%)",
|
||||
colorWarning: "hsl(42 84% 61%)",
|
||||
mode: "light",
|
||||
mode: "auto",
|
||||
radius: "0.5",
|
||||
semiDarkHeader: false,
|
||||
semiDarkSidebar: false,
|
||||
|
||||
@@ -67,7 +67,10 @@ export function getCommonColumnDefine(crudExpose: any, typeRef: any, api: any) {
|
||||
set(form, key, column.value);
|
||||
}
|
||||
//字段配置赋值
|
||||
columnsRef.value[key] = column;
|
||||
if (columnsRef.value) {
|
||||
columnsRef.value[key] = column;
|
||||
}
|
||||
|
||||
console.log("form", columnsRef.value);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
</a-form-item>
|
||||
<a-form-item :label="t('certd.monitor.setting.dnsServer')" :name="['dnsServer']">
|
||||
<div class="flex">
|
||||
<a-select v-model:value="formState.dnsServer" mode="tags" :open="false" />
|
||||
<a-select v-model:value="formState.dnsServer" :token-separators="[' ', ',', ',', '、', '|']" mode="tags" :open="false" />
|
||||
</div>
|
||||
<div class="helper">{{ t("certd.monitor.setting.dnsServerHelper") }}</div>
|
||||
</a-form-item>
|
||||
@@ -75,7 +75,7 @@ async function loadUserSettings() {
|
||||
|
||||
loadUserSettings();
|
||||
const doSave = async (form: any) => {
|
||||
await utils.sleep(1);
|
||||
await utils.sleep(300);
|
||||
await api.SiteMonitorSettingsSave({
|
||||
...formState,
|
||||
});
|
||||
|
||||
@@ -358,6 +358,7 @@ export default function ({ crudExpose, context: { selectedRowKeys, openCertApply
|
||||
column: {
|
||||
align: "center",
|
||||
width: 120,
|
||||
show: false,
|
||||
sorter: true,
|
||||
},
|
||||
form: {
|
||||
@@ -471,6 +472,18 @@ export default function ({ crudExpose, context: { selectedRowKeys, openCertApply
|
||||
align: "center",
|
||||
},
|
||||
},
|
||||
nextRunTime: {
|
||||
title: t("certd.fields.nextRunTime"),
|
||||
type: "datetime",
|
||||
form: {
|
||||
show: false,
|
||||
},
|
||||
column: {
|
||||
sorter: true,
|
||||
width: 150,
|
||||
align: "center",
|
||||
},
|
||||
},
|
||||
disabled: {
|
||||
title: t("certd.fields.enabled"),
|
||||
type: "dict-switch",
|
||||
|
||||
@@ -885,6 +885,7 @@ export default defineComponent({
|
||||
saveLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const edit = () => {
|
||||
pipeline.value = cloneDeep(currentPipeline.value);
|
||||
currentHistory.value = null;
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
<a-collapse v-if="detail?.template?.pipelineId > 0" v-model:active-key="activeKey">
|
||||
<a-collapse-panel v-for="(step, stepId) in steps" :key="stepId" class="step-item" :header="step.title">
|
||||
<div class="step-inputs flex flex-wrap">
|
||||
<div v-for="(input, key) of step.input" :key="key" class="hover:bg-gray-100 p-5 w-full xl:w-[50%]">
|
||||
<div v-for="(input, key) of step.input" :key="key" class="hover:bg-gray-100 dark:hover:bg-[#2d2d2d] p-5 w-full xl:w-[50%]">
|
||||
<div class="flex flex-between" :title="input.define.helper">
|
||||
<div class="flex flex-1 overflow-hidden mr-5">
|
||||
<span style="min-width: 140px" class="bas">
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { get, set } from "lodash-es";
|
||||
import { computed, reactive, ref, defineProps } from "vue";
|
||||
import { computed, reactive, ref } from "vue";
|
||||
import { useStepHelper } from "./utils";
|
||||
import { usePluginStore } from "/@/store/plugin";
|
||||
|
||||
|
||||
@@ -221,14 +221,12 @@ onMounted(() => {
|
||||
border: 1px solid #e8e8e8;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
background-color: #fff;
|
||||
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 12px 16px;
|
||||
background-color: #fafafa;
|
||||
border-bottom: 1px solid #e8e8e8;
|
||||
}
|
||||
|
||||
@@ -245,13 +243,11 @@ onMounted(() => {
|
||||
.input-form {
|
||||
margin-bottom: 12px;
|
||||
padding: 12px;
|
||||
background-color: #fafafa;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.domain-info {
|
||||
padding: 5.5px 12px;
|
||||
background-color: #f0f0f0;
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
@@ -272,7 +268,6 @@ onMounted(() => {
|
||||
.summary {
|
||||
margin-top: 16px;
|
||||
padding: 12px;
|
||||
background-color: #f8f9fa;
|
||||
border-radius: 4px;
|
||||
.summary-text {
|
||||
}
|
||||
|
||||
@@ -110,7 +110,6 @@ onMounted(() => {
|
||||
}
|
||||
|
||||
.info-item {
|
||||
background-color: #fafafa;
|
||||
border-radius: 4px;
|
||||
padding: 12px;
|
||||
|
||||
|
||||
@@ -138,7 +138,6 @@ const resultError = computed(() => {
|
||||
.port-info {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
background-color: #f0f0f0;
|
||||
padding: 2px 6px;
|
||||
border-radius: 3px;
|
||||
margin-right: 8px;
|
||||
@@ -154,7 +153,6 @@ const resultError = computed(() => {
|
||||
.error-message,
|
||||
.object-result,
|
||||
.text-result {
|
||||
background-color: #f8f8f8;
|
||||
padding: 8px 10px;
|
||||
border-radius: 3px;
|
||||
overflow-x: auto;
|
||||
@@ -170,7 +168,6 @@ const resultError = computed(() => {
|
||||
}
|
||||
|
||||
.test-log {
|
||||
background-color: #f8f8f8;
|
||||
padding: 8px 10px;
|
||||
border-radius: 3px;
|
||||
overflow-x: auto;
|
||||
|
||||
@@ -30,7 +30,6 @@ import ServerInfoCard from "./ServerInfoCard.vue";
|
||||
.page-sys-nettest {
|
||||
.nettest-container {
|
||||
padding: 16px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.test-areas {
|
||||
|
||||
Reference in New Issue
Block a user