mirror of https://github.com/usual2970/certimate
				
				
				
			feat: rename `configType`/`providerType` to `provider`
							parent
							
								
									849e065bb2
								
							
						
					
					
						commit
						e695c8ee5c
					
				| 
						 | 
				
			
			@ -152,7 +152,7 @@ func Get(record *models.Record) (Applicant, error) {
 | 
			
		|||
		DisableFollowCNAME: applyConfig.DisableFollowCNAME,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return GetWithTypeOption(domain.AccessProviderType(access.GetString("configType")), option)
 | 
			
		||||
	return GetWithTypeOption(domain.AccessProviderType(access.GetString("provider")), option)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetWithApplyNode(node *domain.WorkflowNode) (Applicant, error) {
 | 
			
		||||
| 
						 | 
				
			
			@ -174,15 +174,15 @@ func GetWithApplyNode(node *domain.WorkflowNode) (Applicant, error) {
 | 
			
		|||
		DisableFollowCNAME: node.GetConfigBool("disableFollowCNAME"),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return GetWithTypeOption(domain.AccessProviderType(access.ConfigType), applyConfig)
 | 
			
		||||
	return GetWithTypeOption(domain.AccessProviderType(access.Provider), applyConfig)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetWithTypeOption(providerType domain.AccessProviderType, option *ApplyOption) (Applicant, error) {
 | 
			
		||||
func GetWithTypeOption(provider domain.AccessProviderType, option *ApplyOption) (Applicant, error) {
 | 
			
		||||
	/*
 | 
			
		||||
	  注意:如果追加新的常量值,请保持以 ASCII 排序。
 | 
			
		||||
	  NOTICE: If you add new constant, please keep ASCII order.
 | 
			
		||||
	*/
 | 
			
		||||
	switch providerType {
 | 
			
		||||
	switch provider {
 | 
			
		||||
	case domain.ACCESS_PROVIDER_ACMEHTTPREQ:
 | 
			
		||||
		return NewACMEHttpReqApplicant(option), nil
 | 
			
		||||
	case domain.ACCESS_PROVIDER_ALIYUN:
 | 
			
		||||
| 
						 | 
				
			
			@ -206,7 +206,7 @@ func GetWithTypeOption(providerType domain.AccessProviderType, option *ApplyOpti
 | 
			
		|||
	case domain.ACCESS_PROVIDER_VOLCENGINE:
 | 
			
		||||
		return NewVolcEngineApplicant(option), nil
 | 
			
		||||
	default:
 | 
			
		||||
		return nil, fmt.Errorf("unsupported applicant provider type: %s", providerType)
 | 
			
		||||
		return nil, fmt.Errorf("unsupported applicant provider type: %s", provider)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,11 +4,11 @@ import "time"
 | 
			
		|||
 | 
			
		||||
type Access struct {
 | 
			
		||||
	Meta
 | 
			
		||||
	Name       string    `json:"name" db:"name"`
 | 
			
		||||
	ConfigType string    `json:"configType" db:"configType"`
 | 
			
		||||
	Config     string    `json:"config" db:"config"`
 | 
			
		||||
	Usage      string    `json:"usage" db:"usage"`
 | 
			
		||||
	DeletedAt  time.Time `json:"deleted" db:"deleted"`
 | 
			
		||||
	Name      string    `json:"name" db:"name"`
 | 
			
		||||
	Provider  string    `json:"provider" db:"provider"`
 | 
			
		||||
	Config    string    `json:"config" db:"config"`
 | 
			
		||||
	Usage     string    `json:"usage" db:"usage"`
 | 
			
		||||
	DeletedAt time.Time `json:"deleted" db:"deleted"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type AccessProviderType string
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,10 +30,10 @@ func (a *AccessRepository) GetById(ctx context.Context, id string) (*domain.Acce
 | 
			
		|||
			CreatedAt: record.GetTime("created"),
 | 
			
		||||
			UpdatedAt: record.GetTime("updated"),
 | 
			
		||||
		},
 | 
			
		||||
		Name:       record.GetString("name"),
 | 
			
		||||
		ConfigType: record.GetString("configType"),
 | 
			
		||||
		Config:     record.GetString("config"),
 | 
			
		||||
		Usage:      record.GetString("usage"),
 | 
			
		||||
		Name:     record.GetString("name"),
 | 
			
		||||
		Provider: record.GetString("provider"),
 | 
			
		||||
		Config:   record.GetString("config"),
 | 
			
		||||
		Usage:    record.GetString("usage"),
 | 
			
		||||
	}
 | 
			
		||||
	return rs, nil
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -79,12 +79,12 @@ func (d *deployNode) Run(ctx context.Context) error {
 | 
			
		|||
		DeployConfig: domain.DeployConfig{
 | 
			
		||||
			Id:     d.node.Id,
 | 
			
		||||
			Access: access.Id,
 | 
			
		||||
			Type:   d.node.GetConfigString("providerType"),
 | 
			
		||||
			Type:   d.node.GetConfigString("provider"),
 | 
			
		||||
			Config: d.node.Config,
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	deploy, err := deployer.GetWithTypeAndOption(d.node.GetConfigString("providerType"), option)
 | 
			
		||||
	deploy, err := deployer.GetWithTypeAndOption(d.node.GetConfigString("provider"), option)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		d.AddOutput(ctx, d.node.Name, "获取部署对象失败", err.Error())
 | 
			
		||||
		return err
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,110 @@
 | 
			
		|||
package migrations
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
 | 
			
		||||
	"github.com/pocketbase/dbx"
 | 
			
		||||
	"github.com/pocketbase/pocketbase/daos"
 | 
			
		||||
	m "github.com/pocketbase/pocketbase/migrations"
 | 
			
		||||
	"github.com/pocketbase/pocketbase/models/schema"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	m.Register(func(db dbx.Builder) error {
 | 
			
		||||
		dao := daos.New(db);
 | 
			
		||||
 | 
			
		||||
		collection, err := dao.FindCollectionByNameOrId("4yzbv8urny5ja1e")
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// update
 | 
			
		||||
		edit_provider := &schema.SchemaField{}
 | 
			
		||||
		if err := json.Unmarshal([]byte(`{
 | 
			
		||||
			"system": false,
 | 
			
		||||
			"id": "hwy7m03o",
 | 
			
		||||
			"name": "provider",
 | 
			
		||||
			"type": "select",
 | 
			
		||||
			"required": false,
 | 
			
		||||
			"presentable": false,
 | 
			
		||||
			"unique": false,
 | 
			
		||||
			"options": {
 | 
			
		||||
				"maxSelect": 1,
 | 
			
		||||
				"values": [
 | 
			
		||||
					"acmehttpreq",
 | 
			
		||||
					"aliyun",
 | 
			
		||||
					"aws",
 | 
			
		||||
					"baiducloud",
 | 
			
		||||
					"byteplus",
 | 
			
		||||
					"cloudflare",
 | 
			
		||||
					"dogecloud",
 | 
			
		||||
					"godaddy",
 | 
			
		||||
					"huaweicloud",
 | 
			
		||||
					"k8s",
 | 
			
		||||
					"local",
 | 
			
		||||
					"namedotcom",
 | 
			
		||||
					"namesilo",
 | 
			
		||||
					"powerdns",
 | 
			
		||||
					"qiniu",
 | 
			
		||||
					"ssh",
 | 
			
		||||
					"tencentcloud",
 | 
			
		||||
					"volcengine",
 | 
			
		||||
					"webhook"
 | 
			
		||||
				]
 | 
			
		||||
			}
 | 
			
		||||
		}`), edit_provider); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
		collection.Schema.AddField(edit_provider)
 | 
			
		||||
 | 
			
		||||
		return dao.SaveCollection(collection)
 | 
			
		||||
	}, func(db dbx.Builder) error {
 | 
			
		||||
		dao := daos.New(db);
 | 
			
		||||
 | 
			
		||||
		collection, err := dao.FindCollectionByNameOrId("4yzbv8urny5ja1e")
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// update
 | 
			
		||||
		edit_provider := &schema.SchemaField{}
 | 
			
		||||
		if err := json.Unmarshal([]byte(`{
 | 
			
		||||
			"system": false,
 | 
			
		||||
			"id": "hwy7m03o",
 | 
			
		||||
			"name": "configType",
 | 
			
		||||
			"type": "select",
 | 
			
		||||
			"required": false,
 | 
			
		||||
			"presentable": false,
 | 
			
		||||
			"unique": false,
 | 
			
		||||
			"options": {
 | 
			
		||||
				"maxSelect": 1,
 | 
			
		||||
				"values": [
 | 
			
		||||
					"acmehttpreq",
 | 
			
		||||
					"aliyun",
 | 
			
		||||
					"aws",
 | 
			
		||||
					"baiducloud",
 | 
			
		||||
					"byteplus",
 | 
			
		||||
					"cloudflare",
 | 
			
		||||
					"dogecloud",
 | 
			
		||||
					"godaddy",
 | 
			
		||||
					"huaweicloud",
 | 
			
		||||
					"k8s",
 | 
			
		||||
					"local",
 | 
			
		||||
					"namedotcom",
 | 
			
		||||
					"namesilo",
 | 
			
		||||
					"powerdns",
 | 
			
		||||
					"qiniu",
 | 
			
		||||
					"ssh",
 | 
			
		||||
					"tencentcloud",
 | 
			
		||||
					"volcengine",
 | 
			
		||||
					"webhook"
 | 
			
		||||
				]
 | 
			
		||||
			}
 | 
			
		||||
		}`), edit_provider); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
		collection.Schema.AddField(edit_provider)
 | 
			
		||||
 | 
			
		||||
		return dao.SaveCollection(collection)
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -7,7 +7,7 @@ import { z } from "zod";
 | 
			
		|||
 | 
			
		||||
import AccessProviderSelect from "@/components/provider/AccessProviderSelect";
 | 
			
		||||
import { type AccessModel } from "@/domain/access";
 | 
			
		||||
import { ACCESS_PROVIDERS } from "@/domain/provider";
 | 
			
		||||
import { ACCESS_PROVIDERS, accessProvidersMap } from "@/domain/provider";
 | 
			
		||||
import { useAntdForm } from "@/hooks";
 | 
			
		||||
 | 
			
		||||
import AccessEditFormACMEHttpReqConfig from "./AccessEditFormACMEHttpReqConfig";
 | 
			
		||||
| 
						 | 
				
			
			@ -57,7 +57,7 @@ const AccessEditForm = forwardRef<AccessEditFormInstance, AccessEditFormProps>((
 | 
			
		|||
      .min(1, t("access.form.name.placeholder"))
 | 
			
		||||
      .max(64, t("common.errmsg.string_max", { max: 64 }))
 | 
			
		||||
      .trim(),
 | 
			
		||||
    configType: z.nativeEnum(ACCESS_PROVIDERS, { message: t("access.form.type.placeholder") }),
 | 
			
		||||
    provider: z.nativeEnum(ACCESS_PROVIDERS, { message: t("access.form.provider.placeholder") }),
 | 
			
		||||
    config: z.any(),
 | 
			
		||||
  });
 | 
			
		||||
  const formRule = createSchemaFieldRule(formSchema);
 | 
			
		||||
| 
						 | 
				
			
			@ -65,10 +65,10 @@ const AccessEditForm = forwardRef<AccessEditFormInstance, AccessEditFormProps>((
 | 
			
		|||
    initialValues: initialValues,
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  const [configType, setConfigType] = useState(initialValues?.configType);
 | 
			
		||||
  const [fieldProvider, setFieldProvider] = useState(initialValues?.provider);
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    setConfigType(initialValues?.configType);
 | 
			
		||||
  }, [initialValues?.configType]);
 | 
			
		||||
    setFieldProvider(initialValues?.provider);
 | 
			
		||||
  }, [initialValues?.provider]);
 | 
			
		||||
 | 
			
		||||
  const [configFormInst] = Form.useForm();
 | 
			
		||||
  const configFormName = useCreation(() => `accessEditForm_config${Math.random().toString(36).substring(2, 10)}${new Date().getTime()}`, []);
 | 
			
		||||
| 
						 | 
				
			
			@ -78,7 +78,7 @@ const AccessEditForm = forwardRef<AccessEditFormInstance, AccessEditFormProps>((
 | 
			
		|||
      NOTICE: If you add new child component, please keep ASCII order.
 | 
			
		||||
     */
 | 
			
		||||
    const configFormProps = { form: configFormInst, formName: configFormName, disabled: disabled, initialValues: initialValues?.config };
 | 
			
		||||
    switch (configType) {
 | 
			
		||||
    switch (fieldProvider) {
 | 
			
		||||
      case ACCESS_PROVIDERS.ACMEHTTPREQ:
 | 
			
		||||
        return <AccessEditFormACMEHttpReqConfig {...configFormProps} />;
 | 
			
		||||
      case ACCESS_PROVIDERS.ALIYUN:
 | 
			
		||||
| 
						 | 
				
			
			@ -118,7 +118,7 @@ const AccessEditForm = forwardRef<AccessEditFormInstance, AccessEditFormProps>((
 | 
			
		|||
      case ACCESS_PROVIDERS.WEBHOOK:
 | 
			
		||||
        return <AccessEditFormWebhookConfig {...configFormProps} />;
 | 
			
		||||
    }
 | 
			
		||||
  }, [disabled, initialValues, configType, configFormInst, configFormName]);
 | 
			
		||||
  }, [disabled, initialValues, fieldProvider, configFormInst, configFormName]);
 | 
			
		||||
 | 
			
		||||
  const handleFormProviderChange = (name: string) => {
 | 
			
		||||
    if (name === configFormName) {
 | 
			
		||||
| 
						 | 
				
			
			@ -128,8 +128,8 @@ const AccessEditForm = forwardRef<AccessEditFormInstance, AccessEditFormProps>((
 | 
			
		|||
  };
 | 
			
		||||
 | 
			
		||||
  const handleFormChange = (_: unknown, values: AccessEditFormFieldValues) => {
 | 
			
		||||
    if (values.configType !== configType) {
 | 
			
		||||
      setConfigType(values.configType);
 | 
			
		||||
    if (values.provider !== fieldProvider) {
 | 
			
		||||
      setFieldProvider(values.provider);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    onValuesChange?.(values);
 | 
			
		||||
| 
						 | 
				
			
			@ -160,12 +160,12 @@ const AccessEditForm = forwardRef<AccessEditFormInstance, AccessEditFormProps>((
 | 
			
		|||
          </Form.Item>
 | 
			
		||||
 | 
			
		||||
          <Form.Item
 | 
			
		||||
            name="configType"
 | 
			
		||||
            label={t("access.form.type.label")}
 | 
			
		||||
            name="provider"
 | 
			
		||||
            label={t("access.form.provider.label")}
 | 
			
		||||
            rules={[formRule]}
 | 
			
		||||
            tooltip={<span dangerouslySetInnerHTML={{ __html: t("access.form.type.tooltip") }}></span>}
 | 
			
		||||
            tooltip={<span dangerouslySetInnerHTML={{ __html: t("access.form.provider.tooltip") }}></span>}
 | 
			
		||||
          >
 | 
			
		||||
            <AccessProviderSelect disabled={preset !== "add"} placeholder={t("access.form.type.placeholder")} showSearch={!disabled} />
 | 
			
		||||
            <AccessProviderSelect disabled={preset !== "add"} placeholder={t("access.form.provider.placeholder")} showSearch={!disabled} />
 | 
			
		||||
          </Form.Item>
 | 
			
		||||
        </Form>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,6 +4,7 @@ import { useControllableValue } from "ahooks";
 | 
			
		|||
import { Modal, notification } from "antd";
 | 
			
		||||
 | 
			
		||||
import { type AccessModel } from "@/domain/access";
 | 
			
		||||
import { accessProvidersMap } from "@/domain/provider";
 | 
			
		||||
import { useTriggerElement, useZustandShallowSelector } from "@/hooks";
 | 
			
		||||
import { useAccessesStore } from "@/stores/access";
 | 
			
		||||
import { getErrMsg } from "@/utils/error";
 | 
			
		||||
| 
						 | 
				
			
			@ -48,24 +49,25 @@ const AccessEditModal = ({ data, loading, trigger, preset, onSubmit, ...props }:
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    try {
 | 
			
		||||
      let res: AccessModel;
 | 
			
		||||
      let temp: AccessModel = formRef.current!.getFieldsValue();
 | 
			
		||||
      temp.usage = accessProvidersMap.get(temp.provider)!.usage;
 | 
			
		||||
      if (preset === "add") {
 | 
			
		||||
        if (data?.id) {
 | 
			
		||||
          throw "Invalid props: `data`";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        res = await createAccess(formRef.current!.getFieldsValue() as AccessModel);
 | 
			
		||||
        temp = await createAccess(temp);
 | 
			
		||||
      } else if (preset === "edit") {
 | 
			
		||||
        if (!data?.id) {
 | 
			
		||||
          throw "Invalid props: `data`";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        res = await updateAccess({ ...data, ...formRef.current!.getFieldsValue() } as AccessModel);
 | 
			
		||||
        temp = await updateAccess({ ...data, ...temp });
 | 
			
		||||
      } else {
 | 
			
		||||
        throw "Invalid props: `preset`";
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      onSubmit?.(res);
 | 
			
		||||
      onSubmit?.(temp);
 | 
			
		||||
      setOpen(false);
 | 
			
		||||
    } catch (err) {
 | 
			
		||||
      notificationApi.error({ message: t("common.text.request_error"), description: getErrMsg(err) });
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -45,7 +45,7 @@ const AccessSelect = ({ filter, ...props }: AccessTypeSelectProps) => {
 | 
			
		|||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const provider = accessProvidersMap.get(access.configType);
 | 
			
		||||
    const provider = accessProvidersMap.get(access.provider);
 | 
			
		||||
    return (
 | 
			
		||||
      <Space className="max-w-full grow truncate" size={4}>
 | 
			
		||||
        <Avatar src={provider?.icon} size="small" />
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -41,7 +41,7 @@ const DeployProviderPicker = ({ className, style, onSelect }: DeployProviderPick
 | 
			
		|||
 | 
			
		||||
  return (
 | 
			
		||||
    <div className={className} style={style}>
 | 
			
		||||
      <Input.Search placeholder={t("workflow_node.deploy.search.provider_type.placeholder")} onChange={(e) => setKeyword(e.target.value.trim())} />
 | 
			
		||||
      <Input.Search placeholder={t("workflow_node.deploy.search.provider.placeholder")} onChange={(e) => setKeyword(e.target.value.trim())} />
 | 
			
		||||
 | 
			
		||||
      <div className="mt-4">
 | 
			
		||||
        <Show when={providers.length > 0} fallback={<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />}>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -52,7 +52,7 @@ const WorkflowElement = ({ node }: NodeProps) => {
 | 
			
		|||
      }
 | 
			
		||||
 | 
			
		||||
      case WorkflowNodeType.Deploy: {
 | 
			
		||||
        const provider = deployProvidersMap.get(node.config?.providerType as string);
 | 
			
		||||
        const provider = deployProvidersMap.get(node.config?.provider as string);
 | 
			
		||||
        return (
 | 
			
		||||
          <Space>
 | 
			
		||||
            <Avatar src={provider?.icon} size="small" />
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -163,7 +163,7 @@ const ApplyNodeForm = ({ node }: ApplyNodeFormProps) => {
 | 
			
		|||
                  </Button>
 | 
			
		||||
                }
 | 
			
		||||
                onSubmit={(record) => {
 | 
			
		||||
                  const provider = accessProvidersMap.get(record.configType);
 | 
			
		||||
                  const provider = accessProvidersMap.get(record.provider);
 | 
			
		||||
                  if (ACCESS_USAGES.ALL === provider?.usage || ACCESS_USAGES.APPLY === provider?.usage) {
 | 
			
		||||
                    formInst.setFieldValue("access", record.id);
 | 
			
		||||
                  }
 | 
			
		||||
| 
						 | 
				
			
			@ -176,7 +176,7 @@ const ApplyNodeForm = ({ node }: ApplyNodeFormProps) => {
 | 
			
		|||
          <AccessSelect
 | 
			
		||||
            placeholder={t("workflow_node.apply.form.access.placeholder")}
 | 
			
		||||
            filter={(record) => {
 | 
			
		||||
              const provider = accessProvidersMap.get(record.configType);
 | 
			
		||||
              const provider = accessProvidersMap.get(record.provider);
 | 
			
		||||
              return ACCESS_USAGES.ALL === provider?.usage || ACCESS_USAGES.APPLY === provider?.usage;
 | 
			
		||||
            }}
 | 
			
		||||
          />
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -55,9 +55,7 @@ const DeployNodeForm = ({ node }: DeployFormProps) => {
 | 
			
		|||
  const { hidePanel } = usePanel();
 | 
			
		||||
 | 
			
		||||
  const formSchema = z.object({
 | 
			
		||||
    providerType: z
 | 
			
		||||
      .string({ message: t("workflow_node.deploy.form.provider_type.placeholder") })
 | 
			
		||||
      .nonempty(t("workflow_node.deploy.form.provider_type.placeholder")),
 | 
			
		||||
    provider: z.string({ message: t("workflow_node.deploy.form.provider.placeholder") }).nonempty(t("workflow_node.deploy.form.provider.placeholder")),
 | 
			
		||||
    access: z
 | 
			
		||||
      .string({ message: t("workflow_node.deploy.form.provider_access.placeholder") })
 | 
			
		||||
      .nonempty(t("workflow_node.deploy.form.provider_access.placeholder")),
 | 
			
		||||
| 
						 | 
				
			
			@ -88,14 +86,14 @@ const DeployNodeForm = ({ node }: DeployFormProps) => {
 | 
			
		|||
    setPreviousOutput(rs);
 | 
			
		||||
  }, [node, getWorkflowOuptutBeforeId]);
 | 
			
		||||
 | 
			
		||||
  const fieldProviderType = Form.useWatch("providerType", { form: formInst, preserve: true });
 | 
			
		||||
  const fieldProvider = Form.useWatch("provider", { form: formInst, preserve: true });
 | 
			
		||||
 | 
			
		||||
  const formFieldsComponent = useMemo(() => {
 | 
			
		||||
    /*
 | 
			
		||||
      注意:如果追加新的子组件,请保持以 ASCII 排序。
 | 
			
		||||
      NOTICE: If you add new child component, please keep ASCII order.
 | 
			
		||||
     */
 | 
			
		||||
    switch (fieldProviderType) {
 | 
			
		||||
    switch (fieldProvider) {
 | 
			
		||||
      case DEPLOY_PROVIDERS.ALIYUN_ALB:
 | 
			
		||||
        return <DeployNodeFormAliyunALBFields />;
 | 
			
		||||
      case DEPLOY_PROVIDERS.ALIYUN_CLB:
 | 
			
		||||
| 
						 | 
				
			
			@ -143,26 +141,26 @@ const DeployNodeForm = ({ node }: DeployFormProps) => {
 | 
			
		|||
      case DEPLOY_PROVIDERS.WEBHOOK:
 | 
			
		||||
        return <DeployNodeFormWebhookFields />;
 | 
			
		||||
    }
 | 
			
		||||
  }, [fieldProviderType]);
 | 
			
		||||
  }, [fieldProvider]);
 | 
			
		||||
 | 
			
		||||
  const handleProviderTypePick = useCallback(
 | 
			
		||||
  const handleProviderPick = useCallback(
 | 
			
		||||
    (value: string) => {
 | 
			
		||||
      formInst.setFieldValue("providerType", value);
 | 
			
		||||
      formInst.setFieldValue("provider", value);
 | 
			
		||||
    },
 | 
			
		||||
    [formInst]
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  const handleProviderTypeSelect = (value: string) => {
 | 
			
		||||
    if (fieldProviderType === value) return;
 | 
			
		||||
  const handleProviderSelect = (value: string) => {
 | 
			
		||||
    if (fieldProvider === value) return;
 | 
			
		||||
 | 
			
		||||
    // 切换部署目标时重置表单,避免其他部署目标的配置字段影响当前部署目标
 | 
			
		||||
    if (node.config?.providerType === value) {
 | 
			
		||||
    if (node.config?.provider === value) {
 | 
			
		||||
      formInst.resetFields();
 | 
			
		||||
    } else {
 | 
			
		||||
      const oldValues = formInst.getFieldsValue();
 | 
			
		||||
      const newValues: Record<string, unknown> = {};
 | 
			
		||||
      for (const key in oldValues) {
 | 
			
		||||
        if (key === "providerType" || key === "access" || key === "certificate") {
 | 
			
		||||
        if (key === "provider" || key === "access" || key === "certificate") {
 | 
			
		||||
          newValues[key] = oldValues[key];
 | 
			
		||||
        } else {
 | 
			
		||||
          newValues[key] = undefined;
 | 
			
		||||
| 
						 | 
				
			
			@ -170,7 +168,7 @@ const DeployNodeForm = ({ node }: DeployFormProps) => {
 | 
			
		|||
      }
 | 
			
		||||
      formInst.setFieldsValue(newValues);
 | 
			
		||||
 | 
			
		||||
      if (deployProvidersMap.get(fieldProviderType)?.provider !== deployProvidersMap.get(value)?.provider) {
 | 
			
		||||
      if (deployProvidersMap.get(fieldProvider)?.provider !== deployProvidersMap.get(value)?.provider) {
 | 
			
		||||
        formInst.setFieldValue("access", undefined);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -178,14 +176,9 @@ const DeployNodeForm = ({ node }: DeployFormProps) => {
 | 
			
		|||
 | 
			
		||||
  return (
 | 
			
		||||
    <Form {...formProps} form={formInst} disabled={formPending} layout="vertical">
 | 
			
		||||
      <Show when={!!fieldProviderType} fallback={<DeployProviderPicker onSelect={handleProviderTypePick} />}>
 | 
			
		||||
        <Form.Item name="providerType" label={t("workflow_node.deploy.form.provider_type.label")} rules={[formRule]}>
 | 
			
		||||
          <DeployProviderSelect
 | 
			
		||||
            allowClear
 | 
			
		||||
            placeholder={t("workflow_node.deploy.form.provider_type.placeholder")}
 | 
			
		||||
            showSearch
 | 
			
		||||
            onSelect={handleProviderTypeSelect}
 | 
			
		||||
          />
 | 
			
		||||
      <Show when={!!fieldProvider} fallback={<DeployProviderPicker onSelect={handleProviderPick} />}>
 | 
			
		||||
        <Form.Item name="provider" label={t("workflow_node.deploy.form.provider.label")} rules={[formRule]}>
 | 
			
		||||
          <DeployProviderSelect allowClear placeholder={t("workflow_node.deploy.form.provider.placeholder")} showSearch onSelect={handleProviderSelect} />
 | 
			
		||||
        </Form.Item>
 | 
			
		||||
 | 
			
		||||
        <Form.Item className="mb-0">
 | 
			
		||||
| 
						 | 
				
			
			@ -201,7 +194,7 @@ const DeployNodeForm = ({ node }: DeployFormProps) => {
 | 
			
		|||
              </div>
 | 
			
		||||
              <div className="text-right">
 | 
			
		||||
                <AccessEditModal
 | 
			
		||||
                  data={{ configType: deployProvidersMap.get(fieldProviderType!)?.provider }}
 | 
			
		||||
                  data={{ provider: deployProvidersMap.get(fieldProvider!)?.provider }}
 | 
			
		||||
                  preset="add"
 | 
			
		||||
                  trigger={
 | 
			
		||||
                    <Button size="small" type="link">
 | 
			
		||||
| 
						 | 
				
			
			@ -210,7 +203,7 @@ const DeployNodeForm = ({ node }: DeployFormProps) => {
 | 
			
		|||
                    </Button>
 | 
			
		||||
                  }
 | 
			
		||||
                  onSubmit={(record) => {
 | 
			
		||||
                    const provider = accessProvidersMap.get(record.configType);
 | 
			
		||||
                    const provider = accessProvidersMap.get(record.provider);
 | 
			
		||||
                    if (ACCESS_USAGES.ALL === provider?.usage || ACCESS_USAGES.DEPLOY === provider?.usage) {
 | 
			
		||||
                      formInst.setFieldValue("access", record.id);
 | 
			
		||||
                    }
 | 
			
		||||
| 
						 | 
				
			
			@ -223,11 +216,11 @@ const DeployNodeForm = ({ node }: DeployFormProps) => {
 | 
			
		|||
            <AccessSelect
 | 
			
		||||
              placeholder={t("workflow_node.deploy.form.provider_access.placeholder")}
 | 
			
		||||
              filter={(record) => {
 | 
			
		||||
                if (fieldProviderType) {
 | 
			
		||||
                  return deployProvidersMap.get(fieldProviderType)?.provider === record.configType;
 | 
			
		||||
                if (fieldProvider) {
 | 
			
		||||
                  return deployProvidersMap.get(fieldProvider)?.provider === record.provider;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                const provider = accessProvidersMap.get(record.configType);
 | 
			
		||||
                const provider = accessProvidersMap.get(record.provider);
 | 
			
		||||
                return ACCESS_USAGES.ALL === provider?.usage || ACCESS_USAGES.APPLY === provider?.usage;
 | 
			
		||||
              }}
 | 
			
		||||
            />
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,8 +3,7 @@ import { type AccessUsageType } from "./provider";
 | 
			
		|||
// #region AccessModel
 | 
			
		||||
export interface AccessModel extends BaseModel {
 | 
			
		||||
  name: string;
 | 
			
		||||
  configType: string;
 | 
			
		||||
  usage: AccessUsageType;
 | 
			
		||||
  provider: string;
 | 
			
		||||
  config: /*
 | 
			
		||||
    注意:如果追加新的类型,请保持以 ASCII 排序。
 | 
			
		||||
    NOTICE: If you add new type, please keep ASCII order.
 | 
			
		||||
| 
						 | 
				
			
			@ -30,6 +29,7 @@ export interface AccessModel extends BaseModel {
 | 
			
		|||
      | VolcEngineAccessConfig
 | 
			
		||||
      | WebhookAccessConfig
 | 
			
		||||
    );
 | 
			
		||||
  usage: AccessUsageType;
 | 
			
		||||
}
 | 
			
		||||
// #endregion
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,9 +18,9 @@
 | 
			
		|||
 | 
			
		||||
  "access.form.name.label": "Name",
 | 
			
		||||
  "access.form.name.placeholder": "Please enter authorization name",
 | 
			
		||||
  "access.form.type.label": "Provider",
 | 
			
		||||
  "access.form.type.placeholder": "Please select a provider",
 | 
			
		||||
  "access.form.type.tooltip": "DNS provider: The provider that hosts your domain names and manages your DNS records.<br>Host provider: The provider that hosts your servers or cloud services for deploying certificates.<br><br><i>Cannot be edited after saving.</i>",
 | 
			
		||||
  "access.form.provider.label": "Provider",
 | 
			
		||||
  "access.form.provider.placeholder": "Please select a provider",
 | 
			
		||||
  "access.form.provider.tooltip": "DNS provider: The provider that hosts your domain names and manages your DNS records.<br>Host provider: The provider that hosts your servers or cloud services for deploying certificates.<br><br><i>Cannot be edited after saving.</i>",
 | 
			
		||||
  "access.form.acmehttpreq_endpoint.label": "Endpoint",
 | 
			
		||||
  "access.form.acmehttpreq_endpoint.placeholder": "Please enter endpoint",
 | 
			
		||||
  "access.form.acmehttpreq_endpoint.tooltip": "For more information, see <a href=\"https://go-acme.github.io/lego/dns/httpreq/\" target=\"_blank\">https://go-acme.github.io/lego/dns/httpreq/</a>",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -47,9 +47,9 @@
 | 
			
		|||
  "workflow_node.apply.form.disable_follow_cname.tooltip": "It determines whether to disable CNAME following during ACME DNS-01 authentication. If you don't understand this option, just keep it by default.<br><a href=\"https://letsencrypt.org/2019/10/09/onboarding-your-customers-with-lets-encrypt-and-acme/#the-advantages-of-a-cname\" target=\"_blank\">Learn more</a>.",
 | 
			
		||||
 | 
			
		||||
  "workflow_node.deploy.label": "Deployment",
 | 
			
		||||
  "workflow_node.deploy.search.provider_type.placeholder": "Search deploy target ...",
 | 
			
		||||
  "workflow_node.deploy.form.provider_type.label": "Deploy target",
 | 
			
		||||
  "workflow_node.deploy.form.provider_type.placeholder": "Please select deploy target",
 | 
			
		||||
  "workflow_node.deploy.search.provider.placeholder": "Search deploy target ...",
 | 
			
		||||
  "workflow_node.deploy.form.provider.label": "Deploy target",
 | 
			
		||||
  "workflow_node.deploy.form.provider.placeholder": "Please select deploy target",
 | 
			
		||||
  "workflow_node.deploy.form.provider_access.label": "Host provider authorization",
 | 
			
		||||
  "workflow_node.deploy.form.provider_access.placeholder": "Please select an authorization of host provider",
 | 
			
		||||
  "workflow_node.deploy.form.provider_access.tooltip": "Used to deploy certificates.",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,9 +18,9 @@
 | 
			
		|||
 | 
			
		||||
  "access.form.name.label": "名称",
 | 
			
		||||
  "access.form.name.placeholder": "请输入授权名称",
 | 
			
		||||
  "access.form.type.label": "提供商",
 | 
			
		||||
  "access.form.type.placeholder": "请选择提供商",
 | 
			
		||||
  "access.form.type.tooltip": "提供商分为两种类型:<br>【DNS 提供商】您的 DNS 托管方,通常等同于域名注册商,用于在申请证书时管理您的域名解析记录。<br>【主机提供商】您的服务器或云服务的托管方,用于部署签发的证书。<br><br>该字段保存后不可修改。",
 | 
			
		||||
  "access.form.provider.label": "提供商",
 | 
			
		||||
  "access.form.provider.placeholder": "请选择提供商",
 | 
			
		||||
  "access.form.provider.tooltip": "提供商分为两种类型:<br>【DNS 提供商】您的 DNS 托管方,通常等同于域名注册商,用于在申请证书时管理您的域名解析记录。<br>【主机提供商】您的服务器或云服务的托管方,用于部署签发的证书。<br><br>该字段保存后不可修改。",
 | 
			
		||||
  "access.form.acmehttpreq_endpoint.label": "服务端点",
 | 
			
		||||
  "access.form.acmehttpreq_endpoint.placeholder": "请输入服务端点",
 | 
			
		||||
  "access.form.acmehttpreq_endpoint.tooltip": "这是什么?请参阅 <a href=\"https://go-acme.github.io/lego/dns/httpreq/\" target=\"_blank\">https://go-acme.github.io/lego/dns/httpreq/</a>",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -47,9 +47,9 @@
 | 
			
		|||
  "workflow_node.apply.form.disable_follow_cname.tooltip": "在 ACME DNS-01 认证时是否禁止 CNAME 跟随。如果你不了解该选项的用途,保持默认即可。<br><a href=\"https://letsencrypt.org/2019/10/09/onboarding-your-customers-with-lets-encrypt-and-acme/#the-advantages-of-a-cname\" target=\"_blank\">点此了解更多</a>。",
 | 
			
		||||
 | 
			
		||||
  "workflow_node.deploy.label": "部署",
 | 
			
		||||
  "workflow_node.deploy.search.provider_type.placeholder": "搜索部署目标……",
 | 
			
		||||
  "workflow_node.deploy.form.provider_type.label": "部署目标",
 | 
			
		||||
  "workflow_node.deploy.form.provider_type.placeholder": "请选择部署目标",
 | 
			
		||||
  "workflow_node.deploy.search.provider.placeholder": "搜索部署目标……",
 | 
			
		||||
  "workflow_node.deploy.form.provider.label": "部署目标",
 | 
			
		||||
  "workflow_node.deploy.form.provider.placeholder": "请选择部署目标",
 | 
			
		||||
  "workflow_node.deploy.form.provider_access.label": "主机提供商授权",
 | 
			
		||||
  "workflow_node.deploy.form.provider_access.placeholder": "请选择主机提供商授权",
 | 
			
		||||
  "workflow_node.deploy.form.provider_access.tooltip": "用于部署证书,注意与申请阶段所需的 DNS 提供商相区分。",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -50,8 +50,8 @@ const AccessList = () => {
 | 
			
		|||
      render: (_, record) => {
 | 
			
		||||
        return (
 | 
			
		||||
          <Space className="max-w-full truncate" size={4}>
 | 
			
		||||
            <Avatar src={accessProvidersMap.get(record.configType)?.icon} size="small" />
 | 
			
		||||
            <Typography.Text ellipsis>{t(accessProvidersMap.get(record.configType)?.name ?? "")}</Typography.Text>
 | 
			
		||||
            <Avatar src={accessProvidersMap.get(record.provider)?.icon} size="small" />
 | 
			
		||||
            <Typography.Text ellipsis>{t(accessProvidersMap.get(record.provider)?.name ?? "")}</Typography.Text>
 | 
			
		||||
          </Space>
 | 
			
		||||
        );
 | 
			
		||||
      },
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -219,7 +219,7 @@ const SettingsSSLProvider = () => {
 | 
			
		|||
 | 
			
		||||
      const settings = await getSettings<SSLProviderSettingsContent>(SETTINGS_NAMES.SSL_PROVIDER);
 | 
			
		||||
      setSettings(settings);
 | 
			
		||||
      setFormProviderType(settings.content?.provider);
 | 
			
		||||
      setProviderType(settings.content?.provider);
 | 
			
		||||
 | 
			
		||||
      setLoading(false);
 | 
			
		||||
    };
 | 
			
		||||
| 
						 | 
				
			
			@ -227,7 +227,7 @@ const SettingsSSLProvider = () => {
 | 
			
		|||
    fetchData();
 | 
			
		||||
  }, []);
 | 
			
		||||
 | 
			
		||||
  const [providerType, setFormProviderType] = useState<SSLProviders>(SSLPROVIDERS.LETS_ENCRYPT);
 | 
			
		||||
  const [providerType, setProviderType] = useState<SSLProviders>(SSLPROVIDERS.LETS_ENCRYPT);
 | 
			
		||||
  const providerFormComponent = useMemo(() => {
 | 
			
		||||
    switch (providerType) {
 | 
			
		||||
      case SSLPROVIDERS.LETS_ENCRYPT:
 | 
			
		||||
| 
						 | 
				
			
			@ -245,7 +245,7 @@ const SettingsSSLProvider = () => {
 | 
			
		|||
    try {
 | 
			
		||||
      const resp = await saveSettings(settings);
 | 
			
		||||
      setSettings(resp);
 | 
			
		||||
      setFormProviderType(resp.content?.provider);
 | 
			
		||||
      setProviderType(resp.content?.provider);
 | 
			
		||||
 | 
			
		||||
      messageApi.success(t("common.text.operation_succeeded"));
 | 
			
		||||
    } catch (err) {
 | 
			
		||||
| 
						 | 
				
			
			@ -269,7 +269,7 @@ const SettingsSSLProvider = () => {
 | 
			
		|||
      <Show when={!loading} fallback={<Skeleton active />}>
 | 
			
		||||
        <Form form={formInst} disabled={formPending} layout="vertical" initialValues={{ provider: providerType }}>
 | 
			
		||||
          <Form.Item className="mb-2" name="provider" label={t("settings.sslprovider.form.provider.label")}>
 | 
			
		||||
            <CheckCard.Group className="w-full" onChange={(value) => setFormProviderType(value as SSLProviders)}>
 | 
			
		||||
            <CheckCard.Group className="w-full" onChange={(value) => setProviderType(value as SSLProviders)}>
 | 
			
		||||
              <CheckCard
 | 
			
		||||
                avatar={<img src={"/imgs/acme/letsencrypt.svg"} className="size-8" />}
 | 
			
		||||
                size="small"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,9 +25,9 @@ export const remove = async (record: MaybeModelRecordWithId<AccessModel>) => {
 | 
			
		|||
  record = { ...record, deleted: dayjs.utc().format("YYYY-MM-DD HH:mm:ss") };
 | 
			
		||||
 | 
			
		||||
  // TODO: 仅为兼容旧版本,后续迭代时删除
 | 
			
		||||
  if ("configType" in record && record.configType === "httpreq") record.configType = "acmehttpreq";
 | 
			
		||||
  if ("configType" in record && record.configType === "tencent") record.configType = "tencentcloud";
 | 
			
		||||
  if ("configType" in record && record.configType === "pdns") record.configType = "powerdns";
 | 
			
		||||
  if ("provider" in record && record.provider === "httpreq") record.provider = "acmehttpreq";
 | 
			
		||||
  if ("provider" in record && record.provider === "tencent") record.provider = "tencentcloud";
 | 
			
		||||
  if ("provider" in record && record.provider === "pdns") record.provider = "powerdns";
 | 
			
		||||
 | 
			
		||||
  await getPocketBase().collection(COLLECTION_NAME).update<AccessModel>(record.id!, record);
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue