mirror of https://github.com/certd/certd
				
				
				
			chore:
							parent
							
								
									cb27d4b490
								
							
						
					
					
						commit
						ffa4de6911
					
				| 
						 | 
				
			
			@ -231,6 +231,7 @@ function openUpgrade() {
 | 
			
		|||
      title: "基础版",
 | 
			
		||||
      desc: "社区免费版",
 | 
			
		||||
      type: "free",
 | 
			
		||||
      icon: "lucide:package-open",
 | 
			
		||||
      privilege: ["证书申请无限制", "域名数量无限制", "证书流水线数量无限制", "常用的主机、云平台、cdn等部署插件", "邮件、webhook通知方式"]
 | 
			
		||||
    },
 | 
			
		||||
    plus: {
 | 
			
		||||
| 
						 | 
				
			
			@ -244,6 +245,7 @@ function openUpgrade() {
 | 
			
		|||
          openStarModal();
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      icon: "stash:thumb-up",
 | 
			
		||||
      price: 29.9,
 | 
			
		||||
      get() {
 | 
			
		||||
        return (
 | 
			
		||||
| 
						 | 
				
			
			@ -259,6 +261,7 @@ function openUpgrade() {
 | 
			
		|||
      title: "商业版",
 | 
			
		||||
      desc: "商业授权,可对外运营",
 | 
			
		||||
      type: "comm",
 | 
			
		||||
      icon: "vaadin:handshake",
 | 
			
		||||
      privilege: ["拥有专业版所有特权", "允许商用,可修改logo、标题", "数据统计", "插件管理", "多用户无限制", "支持用户支付"],
 | 
			
		||||
      price: 399,
 | 
			
		||||
      get() {
 | 
			
		||||
| 
						 | 
				
			
			@ -293,8 +296,8 @@ function openUpgrade() {
 | 
			
		|||
        slots.push(
 | 
			
		||||
          <a-col span={8}>
 | 
			
		||||
            <div class={vipBlockClass}>
 | 
			
		||||
              <h3 class="block-header">
 | 
			
		||||
                <span>{item.title}</span>
 | 
			
		||||
              <h3 class="block-header ">
 | 
			
		||||
                <span class="flex-o">{item.title}</span>
 | 
			
		||||
                {item.trial && (
 | 
			
		||||
                  <span class="trial">
 | 
			
		||||
                    <a-tooltip title={item.trial.message}>
 | 
			
		||||
| 
						 | 
				
			
			@ -303,8 +306,11 @@ function openUpgrade() {
 | 
			
		|||
                  </span>
 | 
			
		||||
                )}
 | 
			
		||||
              </h3>
 | 
			
		||||
              <div style="color:green">{item.desc}</div>
 | 
			
		||||
              <ul class="flex-1">
 | 
			
		||||
              <div style="color:green" class="flex-o">
 | 
			
		||||
                <fs-icon icon={item.icon} class="fs-16 flex-o" />
 | 
			
		||||
                {item.desc}
 | 
			
		||||
              </div>
 | 
			
		||||
              <ul class="flex-1 privilege">
 | 
			
		||||
                {item.privilege.map((p: string) => (
 | 
			
		||||
                  <li class="flex-baseline">
 | 
			
		||||
                    <fs-icon class="color-green" icon="ion:checkmark-sharp" />
 | 
			
		||||
| 
						 | 
				
			
			@ -430,9 +436,13 @@ onMounted(() => {
 | 
			
		|||
    color: green;
 | 
			
		||||
  }
 | 
			
		||||
  .vip-type-vs {
 | 
			
		||||
    .privilege {
 | 
			
		||||
      .fs-icon {
 | 
			
		||||
        color: green;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    .fs-icon {
 | 
			
		||||
      margin-right: 5px;
 | 
			
		||||
      color: green;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
import Validator from "async-validator";
 | 
			
		||||
// 自定义验证器函数
 | 
			
		||||
export function isDomain(rule: any, value: any) {
 | 
			
		||||
  if (value == null) {
 | 
			
		||||
  if (value == null || value == "") {
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
  let domains: string[] = value;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -216,7 +216,7 @@ export const sysResources = [
 | 
			
		|||
            title: "用户套餐",
 | 
			
		||||
            name: "UserSuites",
 | 
			
		||||
            path: "/sys/suite/user-suite",
 | 
			
		||||
            component: "/certd/suite/user-suite/index.vue",
 | 
			
		||||
            component: "/sys/suite/user-suite/index.vue",
 | 
			
		||||
            meta: {
 | 
			
		||||
              show: () => {
 | 
			
		||||
                const settingStore = useSettingStore();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -59,7 +59,9 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
 | 
			
		|||
            order: 0,
 | 
			
		||||
            type: "link",
 | 
			
		||||
            text: null,
 | 
			
		||||
            title: "立即检查",
 | 
			
		||||
            tooltip: {
 | 
			
		||||
              title: "立即检查"
 | 
			
		||||
            },
 | 
			
		||||
            icon: "ion:play-sharp",
 | 
			
		||||
            click: async ({ row }) => {
 | 
			
		||||
              await api.DoCheck(row.id);
 | 
			
		||||
| 
						 | 
				
			
			@ -107,7 +109,10 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
 | 
			
		|||
          },
 | 
			
		||||
          type: "text",
 | 
			
		||||
          form: {
 | 
			
		||||
            rules: [{ required: true, message: "请输入域名" }]
 | 
			
		||||
            rules: [
 | 
			
		||||
              { required: true, message: "请输入域名" },
 | 
			
		||||
              { type: "domains", message: "请输入正确的域名" }
 | 
			
		||||
            ]
 | 
			
		||||
          },
 | 
			
		||||
          column: {
 | 
			
		||||
            width: 160,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -76,7 +76,7 @@ async function orderCreate() {
 | 
			
		|||
    payType: formRef.value.payType
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  function onPaid() {
 | 
			
		||||
  async function onPaid() {
 | 
			
		||||
    openRef.value = false;
 | 
			
		||||
    router.push({
 | 
			
		||||
      path: "/"
 | 
			
		||||
| 
						 | 
				
			
			@ -114,7 +114,7 @@ async function orderCreate() {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
function doAlipay(paymentReq: any) {
 | 
			
		||||
  window.open(paymentReq.api);
 | 
			
		||||
  window.open(paymentReq.url);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function doWxpay(qrcodeText: string, onPaid: () => Promise<void>) {
 | 
			
		||||
| 
						 | 
				
			
			@ -157,7 +157,7 @@ function doYizhifu(paymentReq: any) {
 | 
			
		|||
   * 签名类型	sign_type	是	String	MD5	默认为MD5
 | 
			
		||||
   */
 | 
			
		||||
  const form = document.createElement("form");
 | 
			
		||||
  form.action = paymentReq.api;
 | 
			
		||||
  form.action = paymentReq.url;
 | 
			
		||||
  form.method = "post";
 | 
			
		||||
  form.target = "_blank";
 | 
			
		||||
  // form.style.display = "none";
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,7 +11,7 @@
 | 
			
		|||
        <a-tab-pane key="register" tab="注册设置">
 | 
			
		||||
          <SettingRegister v-if="activeKey === 'register'" />
 | 
			
		||||
        </a-tab-pane>
 | 
			
		||||
        <a-tab-pane key="payment" tab="支付设置">
 | 
			
		||||
        <a-tab-pane v-if="settingsStore.isComm" key="payment" tab="支付设置">
 | 
			
		||||
          <SettingPayment v-if="activeKey === 'payment'" />
 | 
			
		||||
        </a-tab-pane>
 | 
			
		||||
      </a-tabs>
 | 
			
		||||
| 
						 | 
				
			
			@ -25,10 +25,11 @@ import SettingRegister from "/@/views/sys/settings/tabs/register.vue";
 | 
			
		|||
import SettingPayment from "/@/views/sys/settings/tabs/payment.vue";
 | 
			
		||||
import { useRoute, useRouter } from "vue-router";
 | 
			
		||||
import { ref } from "vue";
 | 
			
		||||
import { useSettingStore } from "/@/store/modules/settings";
 | 
			
		||||
defineOptions({
 | 
			
		||||
  name: "SysSettings"
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const settingsStore = useSettingStore();
 | 
			
		||||
const activeKey = ref("");
 | 
			
		||||
const route = useRoute();
 | 
			
		||||
const router = useRouter();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -68,7 +68,11 @@ const formState = reactive<
 | 
			
		|||
    alipay: PaymentItem;
 | 
			
		||||
    wxpay: PaymentItem;
 | 
			
		||||
  }>
 | 
			
		||||
>({});
 | 
			
		||||
>({
 | 
			
		||||
  yizhifu: { enabled: false },
 | 
			
		||||
  alipay: { enabled: false },
 | 
			
		||||
  wxpay: { enabled: false }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
async function loadSettings() {
 | 
			
		||||
  const data: any = await api.SettingGet();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -106,7 +106,9 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
 | 
			
		|||
            ]
 | 
			
		||||
          }),
 | 
			
		||||
          form: {
 | 
			
		||||
            rules: [{ required: true, message: "此项必填" }]
 | 
			
		||||
            value: "suite",
 | 
			
		||||
            rules: [{ required: true, message: "此项必填" }],
 | 
			
		||||
            helper: "目前没区别,重复购买可叠加数量"
 | 
			
		||||
          },
 | 
			
		||||
          column: {
 | 
			
		||||
            width: 80,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,7 +3,7 @@
 | 
			
		|||
    <template #header>
 | 
			
		||||
      <div class="title">
 | 
			
		||||
        套餐设置
 | 
			
		||||
        <span class="sub"> 需要<router-link to="/sys/settings" :query="{ tab: 'payment' }">开启至少一种支付方式</router-link></span>
 | 
			
		||||
        <span class="sub"> 需要<router-link :to="{ path: '/sys/settings', query: { tab: 'payment' } }">开启至少一种支付方式</router-link></span>
 | 
			
		||||
      </div>
 | 
			
		||||
    </template>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -31,6 +31,7 @@
 | 
			
		|||
 | 
			
		||||
        <a-form-item label=" " :colon="false">
 | 
			
		||||
          <loading-button type="primary" html-type="button" :click="onClick">保存</loading-button>
 | 
			
		||||
          <div class="helper">需要 <router-link :to="{ path: '/sys/settings', query: { tab: 'payment' } }">开启至少一种支付方式</router-link></div>
 | 
			
		||||
        </a-form-item>
 | 
			
		||||
      </a-form>
 | 
			
		||||
    </div>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
import { request } from "/src/api/service";
 | 
			
		||||
 | 
			
		||||
export function createApi() {
 | 
			
		||||
  const apiPrefix = "/sys/suite/userSuites";
 | 
			
		||||
  const apiPrefix = "/sys/suite/user-suite";
 | 
			
		||||
  return {
 | 
			
		||||
    async GetList(query: any) {
 | 
			
		||||
      return await request({
 | 
			
		||||
| 
						 | 
				
			
			@ -47,6 +47,14 @@ export function createApi() {
 | 
			
		|||
        url: apiPrefix + "/all",
 | 
			
		||||
        method: "post"
 | 
			
		||||
      });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    async GetSimpleUserByIds(ids: number[]) {
 | 
			
		||||
      return await request({
 | 
			
		||||
        url: "/sys/authority/user/getSimpleUserByIds",
 | 
			
		||||
        method: "post",
 | 
			
		||||
        data: { ids }
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -55,26 +55,26 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
 | 
			
		|||
      },
 | 
			
		||||
      actionbar: {
 | 
			
		||||
        buttons: {
 | 
			
		||||
          add: { show: false },
 | 
			
		||||
          buy: {
 | 
			
		||||
            text: "购买",
 | 
			
		||||
            type: "primary",
 | 
			
		||||
            click() {
 | 
			
		||||
              router.push({
 | 
			
		||||
                path: "/certd/suite/buy"
 | 
			
		||||
              });
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
          add: { show: false }
 | 
			
		||||
          // buy: {
 | 
			
		||||
          //   text: "购买",
 | 
			
		||||
          //   type: "primary",
 | 
			
		||||
          //   click() {
 | 
			
		||||
          //     router.push({
 | 
			
		||||
          //       path: "/certd/suite/buy"
 | 
			
		||||
          //     });
 | 
			
		||||
          //   }
 | 
			
		||||
          // }
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      rowHandle: {
 | 
			
		||||
        width: 200,
 | 
			
		||||
        fixed: "right",
 | 
			
		||||
        buttons: {
 | 
			
		||||
          view: { show: false },
 | 
			
		||||
          view: { show: true },
 | 
			
		||||
          copy: { show: false },
 | 
			
		||||
          edit: { show: false },
 | 
			
		||||
          remove: { show: false }
 | 
			
		||||
          remove: { show: true }
 | 
			
		||||
          // continue:{
 | 
			
		||||
          //   text:"续期",
 | 
			
		||||
          //   type:"link",
 | 
			
		||||
| 
						 | 
				
			
			@ -115,6 +115,17 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
 | 
			
		|||
            width: 200
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        userId: {
 | 
			
		||||
          title: "用户",
 | 
			
		||||
          type: "table-select",
 | 
			
		||||
          dict: dict({
 | 
			
		||||
            async getNodesByValues(ids: number[]) {
 | 
			
		||||
              return await api.GetSimpleUserByIds(ids);
 | 
			
		||||
            },
 | 
			
		||||
            value: "id",
 | 
			
		||||
            label: "nickName"
 | 
			
		||||
          })
 | 
			
		||||
        },
 | 
			
		||||
        productType: {
 | 
			
		||||
          title: "类型",
 | 
			
		||||
          type: "dict-select",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -39,14 +39,18 @@ export class SiteInfoController extends CrudController<SiteInfoService> {
 | 
			
		|||
  @Post('/add', { summary: Constants.per.authOnly })
 | 
			
		||||
  async add(@Body(ALL) bean: any) {
 | 
			
		||||
    bean.userId = this.getUserId();
 | 
			
		||||
    return await super.add(bean);
 | 
			
		||||
    const res = await this.service.add(bean);
 | 
			
		||||
    await this.service.check(res.id);
 | 
			
		||||
    return this.ok(res);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Post('/update', { summary: Constants.per.authOnly })
 | 
			
		||||
  async update(@Body(ALL) bean) {
 | 
			
		||||
    await this.service.checkUserId(bean.id, this.getUserId());
 | 
			
		||||
    delete bean.userId;
 | 
			
		||||
    return await super.update(bean);
 | 
			
		||||
    await this.service.update(bean);
 | 
			
		||||
    await this.service.check(bean.id);
 | 
			
		||||
    return this.ok();
 | 
			
		||||
  }
 | 
			
		||||
  @Post('/info', { summary: Constants.per.authOnly })
 | 
			
		||||
  async info(@Query('id') id: number) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,6 +4,7 @@ import { CrudController } from '@certd/lib-server';
 | 
			
		|||
import { RoleService } from '../../../modules/sys/authority/service/role-service.js';
 | 
			
		||||
import { PermissionService } from '../../../modules/sys/authority/service/permission-service.js';
 | 
			
		||||
import { Constants } from '@certd/lib-server';
 | 
			
		||||
import { In } from 'typeorm';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 系统用户
 | 
			
		||||
| 
						 | 
				
			
			@ -23,6 +24,24 @@ export class UserController extends CrudController<UserService> {
 | 
			
		|||
    return this.service;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Post('/getSimpleUserByIds', { summary: 'sys:auth:user:add' })
 | 
			
		||||
  async getSimpleUserByIds(@Body('ids') ids: number[]) {
 | 
			
		||||
    const users = await this.service.find({
 | 
			
		||||
      select: {
 | 
			
		||||
        id: true,
 | 
			
		||||
        username: true,
 | 
			
		||||
        nickName: true,
 | 
			
		||||
        mobile: true,
 | 
			
		||||
        phoneCode: true,
 | 
			
		||||
      },
 | 
			
		||||
      where: {
 | 
			
		||||
        id: In(ids),
 | 
			
		||||
      },
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    return this.ok(users);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Post('/page', { summary: 'sys:auth:user:view' })
 | 
			
		||||
  async page(
 | 
			
		||||
    @Body(ALL)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -51,7 +51,16 @@ export class SiteInfoService extends BaseService<SiteInfoEntity> {
 | 
			
		|||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return await this.repository.save(data);
 | 
			
		||||
    data.disabled = false;
 | 
			
		||||
    return await super.add(data);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async update(data: any) {
 | 
			
		||||
    if (!data.id) {
 | 
			
		||||
      throw new Error('id is required');
 | 
			
		||||
    }
 | 
			
		||||
    delete data.userId;
 | 
			
		||||
    await super.update(data);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async getUserMonitorCount(userId: number) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue