mirror of https://github.com/certd/certd
				
				
				
			chore: suite
							parent
							
								
									8057586dc1
								
							
						
					
					
						commit
						1c8e25beb3
					
				| 
						 | 
				
			
			@ -280,3 +280,7 @@ h1, h2, h3, h4, h5, h6 {
 | 
			
		|||
.fs-16{
 | 
			
		||||
    font-size: 16px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.w-50\%{
 | 
			
		||||
    width: 50%;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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: {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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>
 | 
			
		||||
| 
						 | 
				
			
			@ -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 });
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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>
 | 
			
		||||
| 
						 | 
				
			
			@ -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>
 | 
			
		||||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
| 
						 | 
				
			
			@ -23,34 +24,34 @@ CREATE TABLE "cd_product"
 | 
			
		|||
 | 
			
		||||
CREATE TABLE "cd_payment"
 | 
			
		||||
(
 | 
			
		||||
  "id"                  integer PRIMARY KEY AUTOINCREMENT NOT NULL,
 | 
			
		||||
  "type"                varchar(100),
 | 
			
		||||
  "title"               varchar(100),
 | 
			
		||||
  "setting"             text,
 | 
			
		||||
  "order"               integer,
 | 
			
		||||
  "disabled"            boolean  NOT NULL DEFAULT (false),
 | 
			
		||||
  "create_time"         datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP),
 | 
			
		||||
  "update_time"         datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP)
 | 
			
		||||
  "id"          integer PRIMARY KEY AUTOINCREMENT NOT NULL,
 | 
			
		||||
  "type"        varchar(100),
 | 
			
		||||
  "title"       varchar(100),
 | 
			
		||||
  "setting"     text,
 | 
			
		||||
  "order"       integer,
 | 
			
		||||
  "disabled"    boolean  NOT NULL DEFAULT (false),
 | 
			
		||||
  "create_time" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP),
 | 
			
		||||
  "update_time" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP)
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
CREATE TABLE "cd_order"
 | 
			
		||||
(
 | 
			
		||||
  "id"                  integer PRIMARY KEY AUTOINCREMENT NOT NULL,
 | 
			
		||||
  "user_id"             integer,
 | 
			
		||||
  "product_id"          integer,
 | 
			
		||||
  "title"               varchar(100),
 | 
			
		||||
  "count"               integer,
 | 
			
		||||
  "price"               integer,
 | 
			
		||||
  "amount"              integer,
 | 
			
		||||
  "remark"              varchar(100),
 | 
			
		||||
  "status"              varchar(100),
 | 
			
		||||
  "pay_id"              integer,
 | 
			
		||||
  "pay_time"            integer,
 | 
			
		||||
  "pay_type"            varchar(100),
 | 
			
		||||
  "pay_no"              varchar(100),
 | 
			
		||||
  "create_time"         datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP),
 | 
			
		||||
  "update_time"         datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP)
 | 
			
		||||
  "id"          integer PRIMARY KEY AUTOINCREMENT NOT NULL,
 | 
			
		||||
  "user_id"     integer,
 | 
			
		||||
  "product_id"  integer,
 | 
			
		||||
  "title"       varchar(100),
 | 
			
		||||
  "count"       integer,
 | 
			
		||||
  "price"       integer,
 | 
			
		||||
  "amount"      integer,
 | 
			
		||||
  "remark"      varchar(100),
 | 
			
		||||
  "status"      varchar(100),
 | 
			
		||||
  "pay_id"      integer,
 | 
			
		||||
  "pay_time"    integer,
 | 
			
		||||
  "pay_type"    varchar(100),
 | 
			
		||||
  "pay_no"      varchar(100),
 | 
			
		||||
  "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)
 | 
			
		||||
);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue