feat(Auth): Compete auth-middleware
This commit is contained in:
parent
07143e2048
commit
d167cb7265
11
composables/user.ts
Normal file
11
composables/user.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
export async function getUserId() {
|
||||||
|
const auth = useCookie("auth");
|
||||||
|
return await $fetch("/api/user/auth", {
|
||||||
|
method: "GET",
|
||||||
|
query: {
|
||||||
|
auth: auth.value,
|
||||||
|
},
|
||||||
|
}).then((res: number) => {
|
||||||
|
return res;
|
||||||
|
});
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
export default defineNuxtRouteMiddleware(async (to, from) => {
|
||||||
|
if ((await getUserId()) != 1) {
|
||||||
|
ElMessage("禁止访问");
|
||||||
|
return navigateTo("/", { replace: true });
|
||||||
|
}
|
||||||
|
});
|
@ -4,24 +4,24 @@ export default defineNuxtRouteMiddleware(async (to, from) => {
|
|||||||
ElMessage("未登录或cookie未开启");
|
ElMessage("未登录或cookie未开启");
|
||||||
return navigateTo("/user/login", { replace: true });
|
return navigateTo("/user/login", { replace: true });
|
||||||
} else {
|
} else {
|
||||||
const { data: result } = await useFetch("/api/user/auth", {
|
const result = await $fetch("/api/user/auth", {
|
||||||
method: "post",
|
method: "post",
|
||||||
body: {
|
body: {
|
||||||
auth: auth.value,
|
auth: auth.value,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
if (!result.value?.login && to.path !== "/user/test") {
|
if (!result.login && to.path !== "/user/test") {
|
||||||
if (result.value?.code == 0) {
|
if (result.code == 0) {
|
||||||
ElMessage("未登录");
|
ElMessage("未登录");
|
||||||
} else if (result.value?.code == 2) {
|
} else if (result.code == 2) {
|
||||||
ElMessage("登录超时,请重新登录");
|
ElMessage("登录超时,请重新登录");
|
||||||
auth.value = undefined;
|
auth.value = undefined;
|
||||||
} else {
|
} else {
|
||||||
ElMessage(result.value?.code);
|
ElMessage("error" + result.code);
|
||||||
}
|
}
|
||||||
return navigateTo("/user/login");
|
return navigateTo("/user/login");
|
||||||
} else {
|
} else {
|
||||||
console.log(auth.value);
|
//console.log(auth.value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -5,26 +5,26 @@
|
|||||||
</Head>
|
</Head>
|
||||||
<client-only>
|
<client-only>
|
||||||
<el-table :data="tableData" style="width: 100%">
|
<el-table :data="tableData" style="width: 100%">
|
||||||
<el-table-column prop="appid" label="AppID" width="180" />
|
<el-table-column prop="id" label="AppID" width="180" />
|
||||||
<el-table-column prop="name" label="申请人" width="180" />
|
<el-table-column prop="applicant" label="申请人" width="180" />
|
||||||
<el-table-column prop="phone" label="手机号" width="180" />
|
<el-table-column prop="area" label="地区" width="180" />
|
||||||
<el-table-column label="配置" width="300">
|
<el-table-column label="配置" width="300">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-icon color="blue"><ElIcon-Cpu /></el-icon>
|
<el-icon color="blue"><ElIcon-Cpu /></el-icon>
|
||||||
{{ scope.row.resource.cpu }} Core
|
{{ scope.row.cpu }} Core
|
||||||
<el-icon color="green"><ElIcon-Stopwatch /></el-icon
|
<el-icon color="green"><ElIcon-Stopwatch /></el-icon
|
||||||
>{{ scope.row.resource.ram }} GB
|
>{{ scope.row.ram }} GB
|
||||||
<el-icon color="gray"><ElIcon-Memo /></el-icon>
|
<el-icon color="gray"><ElIcon-Memo /></el-icon>
|
||||||
{{ scope.row.resource.disk }} GB
|
{{ scope.row.disk }} GB
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="usage" label="用途" width="360" />
|
<el-table-column prop="desc" label="用途" width="360" />
|
||||||
<el-table-column label="状态" width="300">
|
<el-table-column label="状态" width="300">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-icon :color="scope.row.apply ? 'green' : 'orange'"
|
<el-icon :color="scope.row.deploy ? 'green' : 'orange'"
|
||||||
><ElIcon-Stamp
|
><ElIcon-Stamp
|
||||||
/></el-icon>
|
/></el-icon>
|
||||||
{{ scope.row.apply ? "通过" : "待审核" }}
|
{{ scope.row.deploy ? "通过" : "待审核" }}
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="操作">
|
<el-table-column label="操作">
|
||||||
@ -49,30 +49,7 @@
|
|||||||
</client-only>
|
</client-only>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
const tableData = [
|
import type { Application } from "~/types/Application";
|
||||||
{
|
const data: Application[] = await $fetch("/api/admin/applications");
|
||||||
appid: "1",
|
const tableData = ref(data);
|
||||||
name: "漩葵",
|
|
||||||
phone: 1922949224,
|
|
||||||
usage: "用于开展服务",
|
|
||||||
resource: {
|
|
||||||
cpu: 1,
|
|
||||||
ram: 2,
|
|
||||||
disk: 10,
|
|
||||||
},
|
|
||||||
apply: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
appid: "2",
|
|
||||||
name: "BrianLing",
|
|
||||||
phone: 1922949224,
|
|
||||||
usage: "用于开展服务",
|
|
||||||
resource: {
|
|
||||||
cpu: 1,
|
|
||||||
ram: 2,
|
|
||||||
disk: 10,
|
|
||||||
},
|
|
||||||
apply: true,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
</script>
|
</script>
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
>
|
>
|
||||||
<ClientOnly>
|
<ClientOnly>
|
||||||
<Vueform
|
<Vueform
|
||||||
|
@success="AppSuccess"
|
||||||
endpoint="/api/test"
|
endpoint="/api/test"
|
||||||
method="POST"
|
method="POST"
|
||||||
view="tabs"
|
view="tabs"
|
||||||
@ -28,49 +29,67 @@
|
|||||||
label="项目名称"
|
label="项目名称"
|
||||||
placeholder="项目名称"
|
placeholder="项目名称"
|
||||||
:columns="{ container: 4, label: 4, wrapper: 12 }"
|
:columns="{ container: 4, label: 4, wrapper: 12 }"
|
||||||
rules="required"
|
:rules="['required', isCreate]"
|
||||||
/>
|
/>
|
||||||
<SelectElement
|
<SelectElement
|
||||||
name="select"
|
name="area"
|
||||||
default="辽宁一区"
|
default="1"
|
||||||
label="地区"
|
label="地区"
|
||||||
:native="false"
|
:native="false"
|
||||||
:items="['辽宁一区', '辽宁二区', '江西一区']"
|
:items="{ 1: '辽宁一区', 2: '辽宁二区', 3: '江西一区' }"
|
||||||
:columns="{ container: 4, label: 3, wrapper: 12 }"
|
:columns="{ container: 4, label: 3, wrapper: 12 }"
|
||||||
rules="required"
|
rules="required"
|
||||||
/>
|
/>
|
||||||
<RadiogroupElement
|
<RadiogroupElement
|
||||||
default="2 Core"
|
default="2"
|
||||||
label="CPU核心数"
|
label="CPU核心数"
|
||||||
name="cpu"
|
name="cpu"
|
||||||
:items="['2 Core', '4 Core', '6 Core', 'More']"
|
:items="{ 2: '2 Core', 4: '4 Core', 6: '6 Core', 10: 'More' }"
|
||||||
view="tabs"
|
view="tabs"
|
||||||
/>
|
/>
|
||||||
<RadiogroupElement
|
<RadiogroupElement
|
||||||
default="2 GB"
|
default="2"
|
||||||
label="RAM容量"
|
label="RAM容量"
|
||||||
name="ram"
|
name="ram"
|
||||||
:items="['2 GB', '4 GB', '6 GB', 'More']"
|
:items="{ 2: '2 GB', 4: '4 GB', 6: '6 GB', 10: 'More' }"
|
||||||
view="tabs"
|
view="tabs"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<SliderElement
|
<SliderElement
|
||||||
|
sync
|
||||||
name="disk"
|
name="disk"
|
||||||
label="磁盘容量"
|
label="磁盘容量"
|
||||||
:default="5"
|
:default="5"
|
||||||
:min="1"
|
:min="1"
|
||||||
:max="40"
|
:max="40"
|
||||||
:format="(v: number) => v > 1 ? `${Math.round(v)} GB` : '1 GB'"
|
:format="(v: number) => v > 1 ? `${Math.round(v)} GB` : '1 GB'"
|
||||||
|
:columns="{ container: 12, label: 12, wrapper: 12 }"
|
||||||
:add-classes="{
|
:add-classes="{
|
||||||
ElementLayout: {
|
ElementLayout: {
|
||||||
innerWrapper: 'mt-12',
|
innerWrapper: 'mt-12',
|
||||||
},
|
},
|
||||||
}"
|
}"
|
||||||
/>
|
/>
|
||||||
|
<EditorElement
|
||||||
<EditorElement name="usage" label="用途说明" rules="required|max:500" />
|
name="desc"
|
||||||
|
label="用途说明"
|
||||||
|
rules="required|max:500"
|
||||||
|
:hide-tools="['attach']"
|
||||||
|
/>
|
||||||
|
<StaticElement
|
||||||
|
label="人机验证"
|
||||||
|
name="static"
|
||||||
|
:columns="{ container: 12, label: 12, wrapper: 12 }"
|
||||||
|
>
|
||||||
|
<DefaultSilderVerify
|
||||||
|
@success="sliderHandleSuccess"
|
||||||
|
@failed="sliderHandleError"
|
||||||
|
/>
|
||||||
|
</StaticElement>
|
||||||
|
<HiddenElement :default="uid" name="uid" />
|
||||||
|
<HiddenElement :default="auth" name="auth" />
|
||||||
<ButtonElement
|
<ButtonElement
|
||||||
|
:disabled="isBot"
|
||||||
name="submit"
|
name="submit"
|
||||||
button-label="提交申请"
|
button-label="提交申请"
|
||||||
align="center"
|
align="center"
|
||||||
@ -82,9 +101,43 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import PhoneElemen from "@vueform/vueform";
|
import { Validator } from "@vueform/vueform";
|
||||||
definePageMeta({
|
definePageMeta({
|
||||||
middleware: ["auth"],
|
middleware: ["auth"],
|
||||||
});
|
});
|
||||||
|
const uid: number = await getUserId();
|
||||||
|
const isBot = ref(true);
|
||||||
|
const auth = useCookie("auth");
|
||||||
|
function sliderHandleSuccess() {
|
||||||
|
ElMessage({ message: "人机验证已通过", type: "success" });
|
||||||
|
isBot.value = false;
|
||||||
|
}
|
||||||
|
function sliderHandleError() {
|
||||||
|
ElMessage({ message: "人机验证未通过", type: "warning" });
|
||||||
|
}
|
||||||
|
const isCreate = class extends Validator {
|
||||||
|
get msg() {
|
||||||
|
return "项目名已存在";
|
||||||
|
}
|
||||||
|
check(value: string) {
|
||||||
|
if (value == "") {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return $fetch("/api/application", {
|
||||||
|
method: "POST",
|
||||||
|
body: { name: value },
|
||||||
|
}).then((res) => {
|
||||||
|
return res.name;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
const form = ref();
|
const form = ref();
|
||||||
|
function AppSuccess(response: { data: { code: number; msg: string } }) {
|
||||||
|
if (response.data.code) {
|
||||||
|
ElMessage({ message: response.data.msg, type: "success" });
|
||||||
|
navigateTo("/");
|
||||||
|
} else {
|
||||||
|
ElMessage({ message: response.data.msg, type: "warning" });
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -4,10 +4,12 @@
|
|||||||
<Title>FreePotato Server</Title>
|
<Title>FreePotato Server</Title>
|
||||||
<Meta name="description" content="免费服务器~" />
|
<Meta name="description" content="免费服务器~" />
|
||||||
</Head>
|
</Head>
|
||||||
|
|
||||||
<ElRow :gutter="10" align="middle" style="height: 900px">
|
<ElRow :gutter="10" align="middle" style="height: 900px">
|
||||||
<ElCol :span="24"><IndexNewsCarouel /></ElCol>
|
<ElCol :span="24"><IndexNewsCarouel /></ElCol>
|
||||||
<ElCol :span="24"><IndexNewsStatus /></ElCol>
|
<ElCol :span="24"><IndexNewsStatus /></ElCol>
|
||||||
</ElRow>
|
</ElRow>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts"></script>
|
<script setup lang="ts">
|
||||||
|
const a = await getUserId();
|
||||||
|
console.info(a);
|
||||||
|
</script>
|
||||||
|
@ -1,11 +1,63 @@
|
|||||||
<template>
|
<template>
|
||||||
<Head>
|
<Head>
|
||||||
<Title>用户信息</Title>
|
<Title>个人界面</Title>
|
||||||
<Meta name="description" />
|
<Meta name="description" />
|
||||||
</Head>
|
</Head>
|
||||||
|
<client-only>
|
||||||
|
<el-table :data="tableData" style="width: 100%">
|
||||||
|
<el-table-column prop="id" label="AppID" width="180" />
|
||||||
|
<el-table-column prop="applicant" label="申请人" width="180" />
|
||||||
|
<el-table-column prop="area" label="地区" width="180" />
|
||||||
|
<el-table-column label="配置" width="300">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-icon color="blue"><ElIcon-Cpu /></el-icon>
|
||||||
|
{{ scope.row.cpu }} Core
|
||||||
|
<el-icon color="green"><ElIcon-Stopwatch /></el-icon
|
||||||
|
>{{ scope.row.ram }} GB
|
||||||
|
<el-icon color="gray"><ElIcon-Memo /></el-icon>
|
||||||
|
{{ scope.row.disk }} GB
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="desc" label="用途" width="360" />
|
||||||
|
<el-table-column label="状态" width="300">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-icon :color="scope.row.deploy ? 'green' : 'orange'"
|
||||||
|
><ElIcon-Stamp
|
||||||
|
/></el-icon>
|
||||||
|
{{ scope.row.deploy ? "通过" : "待审核" }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button
|
||||||
|
size="small"
|
||||||
|
type="success"
|
||||||
|
@click="ElMessage({ message: '查看', type: 'success' })"
|
||||||
|
>
|
||||||
|
查看
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
size="small"
|
||||||
|
type="danger"
|
||||||
|
@click="ElMessage({ message: '取消', type: 'warning' })"
|
||||||
|
>
|
||||||
|
取消
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</client-only>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script lang="ts" setup>
|
||||||
|
import type { Application } from "~/types/Application";
|
||||||
definePageMeta({
|
definePageMeta({
|
||||||
middleware: ["auth"],
|
middleware: ["auth"],
|
||||||
});
|
});
|
||||||
|
const data: Application[] = await $fetch("/api/user/application", {
|
||||||
|
method: "POST",
|
||||||
|
body: {
|
||||||
|
uid: await getUserId(),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const tableData = ref(data);
|
||||||
</script>
|
</script>
|
||||||
|
113
prisma/test.prisma
Normal file
113
prisma/test.prisma
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
// This is your Prisma schema file,
|
||||||
|
// learn more about it in the docs: https://pris.ly/d/prisma-schema
|
||||||
|
|
||||||
|
generator client {
|
||||||
|
provider = "prisma-client-js"
|
||||||
|
binaryTargets = ["native", "debian-openssl-3.0.x"]
|
||||||
|
}
|
||||||
|
|
||||||
|
datasource db {
|
||||||
|
provider = "sqlite"
|
||||||
|
url = env("DATABASE_URL")
|
||||||
|
}
|
||||||
|
|
||||||
|
model User {
|
||||||
|
id Int @id @default(autoincrement())
|
||||||
|
phone String @unique
|
||||||
|
username String?
|
||||||
|
password String
|
||||||
|
applications Application[]
|
||||||
|
loginlogs Loginlogs[]
|
||||||
|
Vm Vm[]
|
||||||
|
}
|
||||||
|
|
||||||
|
model Adminer {
|
||||||
|
id Int @id @default(autoincrement())
|
||||||
|
adminId Int
|
||||||
|
}
|
||||||
|
|
||||||
|
model Application {
|
||||||
|
id Int @id @default(autoincrement())
|
||||||
|
name String
|
||||||
|
area String
|
||||||
|
cpu Int
|
||||||
|
ram Int
|
||||||
|
disk Int
|
||||||
|
desc String
|
||||||
|
deploy Boolean @default(false)
|
||||||
|
applicant User @relation(fields: [applicantId], references: [id])
|
||||||
|
applicantId Int
|
||||||
|
}
|
||||||
|
model Register {
|
||||||
|
id Int @id @default(autoincrement())
|
||||||
|
phone String
|
||||||
|
deadline DateTime
|
||||||
|
code String
|
||||||
|
}
|
||||||
|
model Loginlogs {
|
||||||
|
id Int @id @default(autoincrement())
|
||||||
|
outtime DateTime
|
||||||
|
ip String
|
||||||
|
loginer User @relation(fields: [userid], references: [id])
|
||||||
|
userid Int
|
||||||
|
token String @unique
|
||||||
|
}
|
||||||
|
//Config
|
||||||
|
model Web {
|
||||||
|
ConfigId Int @id
|
||||||
|
ConfigName String
|
||||||
|
ConfigValue String
|
||||||
|
}
|
||||||
|
model Cluster {
|
||||||
|
ClusterId Int @id
|
||||||
|
Name String
|
||||||
|
Ip String
|
||||||
|
Username String
|
||||||
|
Password String
|
||||||
|
Gateway String
|
||||||
|
Resource String
|
||||||
|
Status String
|
||||||
|
Nodes Node[]
|
||||||
|
}
|
||||||
|
model Node {
|
||||||
|
NodeId Int @id
|
||||||
|
Cluster Cluster @relation(fields: [ClusterId], references: [ClusterId])
|
||||||
|
ClusterId Int
|
||||||
|
Resource String
|
||||||
|
Status String
|
||||||
|
Vms Vm[]
|
||||||
|
}
|
||||||
|
model Template {
|
||||||
|
TemplateId Int @id @default(autoincrement())
|
||||||
|
OS String
|
||||||
|
Type String
|
||||||
|
Path String
|
||||||
|
Cpu String
|
||||||
|
Ram String
|
||||||
|
Disk String
|
||||||
|
Ports String
|
||||||
|
Vm Vm[]
|
||||||
|
}
|
||||||
|
//datasource
|
||||||
|
model Ip {
|
||||||
|
Adress String @id
|
||||||
|
Vmid Int
|
||||||
|
Vm Vm @relation(fields: [Vmid], references: [Vmid])
|
||||||
|
}
|
||||||
|
model Port {
|
||||||
|
Port Int @id
|
||||||
|
Vmid Int
|
||||||
|
Vm Vm @relation(fields: [Vmid], references: [Vmid])
|
||||||
|
}
|
||||||
|
model Vm {
|
||||||
|
Vmid Int @id @default(autoincrement())
|
||||||
|
NodeId Int
|
||||||
|
Node Node @relation(fields: [NodeId], references: [NodeId])
|
||||||
|
TemplateId Int
|
||||||
|
Template Template @relation(fields: [TemplateId], references: [TemplateId])
|
||||||
|
UserId Int
|
||||||
|
User User @relation(fields: [UserId], references: [id])
|
||||||
|
Ip Ip[]
|
||||||
|
SshPort Int
|
||||||
|
Ports Port[]
|
||||||
|
}
|
51
server/api/admin/applications.ts
Normal file
51
server/api/admin/applications.ts
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
import { PrismaClient } from "@prisma/client";
|
||||||
|
import type { Application } from "~/types/Application";
|
||||||
|
const db = new PrismaClient();
|
||||||
|
type app = {
|
||||||
|
applicant: {
|
||||||
|
username: string | null;
|
||||||
|
};
|
||||||
|
} & {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
area: string;
|
||||||
|
cpu: number;
|
||||||
|
ram: number;
|
||||||
|
disk: number;
|
||||||
|
desc: string;
|
||||||
|
deploy: boolean;
|
||||||
|
applicantId: number;
|
||||||
|
};
|
||||||
|
function formatApplication(raw: app[]): Application[] {
|
||||||
|
var logs: Application[] = [];
|
||||||
|
raw.forEach((element: app) => {
|
||||||
|
logs.push({
|
||||||
|
id: element.id,
|
||||||
|
area: element.area,
|
||||||
|
name: element.name,
|
||||||
|
applicant: element.applicant.username || "none",
|
||||||
|
cpu: element.cpu,
|
||||||
|
ram: element.ram,
|
||||||
|
disk: element.disk,
|
||||||
|
desc: element.desc,
|
||||||
|
deploy: element.deploy,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return logs;
|
||||||
|
}
|
||||||
|
export default defineEventHandler(async (event) => {
|
||||||
|
const applications = await db.application.findMany({
|
||||||
|
orderBy: {
|
||||||
|
id: "desc", // 'asc' 表示升序,'desc' 表示降序
|
||||||
|
},
|
||||||
|
include: {
|
||||||
|
applicant: {
|
||||||
|
select: {
|
||||||
|
username: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
await db.$disconnect();
|
||||||
|
return formatApplication(applications);
|
||||||
|
});
|
6
server/api/application/create.post.ts
Normal file
6
server/api/application/create.post.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import { PrismaClient } from "@prisma/client";
|
||||||
|
const db = new PrismaClient();
|
||||||
|
export default defineEventHandler(async (event) => {
|
||||||
|
const body = await readBody(event);
|
||||||
|
return body;
|
||||||
|
});
|
15
server/api/application/index.ts
Normal file
15
server/api/application/index.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { PrismaClient } from "@prisma/client";
|
||||||
|
const db = new PrismaClient();
|
||||||
|
export default defineEventHandler(async (event) => {
|
||||||
|
const body = await readBody(event);
|
||||||
|
const res = {
|
||||||
|
name:
|
||||||
|
(await db.application.findFirst({
|
||||||
|
where: {
|
||||||
|
name: body.name,
|
||||||
|
},
|
||||||
|
})) == null,
|
||||||
|
};
|
||||||
|
await db.$disconnect();
|
||||||
|
return res;
|
||||||
|
});
|
@ -1,7 +1,66 @@
|
|||||||
import { PrismaClient } from "@prisma/client";
|
import { PrismaClient } from "@prisma/client";
|
||||||
|
|
||||||
const db = new PrismaClient();
|
const db = new PrismaClient();
|
||||||
|
export default defineEventHandler(async (event) => {
|
||||||
|
const body: {
|
||||||
|
name: string;
|
||||||
|
area: string;
|
||||||
|
cpu: string;
|
||||||
|
ram: string;
|
||||||
|
disk: string;
|
||||||
|
desc: string;
|
||||||
|
uid: string;
|
||||||
|
auth: string;
|
||||||
|
} = await readBody(event);
|
||||||
|
const isAuth: { login: boolean; code: number } = await $fetch(
|
||||||
|
"/api/user/auth",
|
||||||
|
{
|
||||||
|
method: "POST",
|
||||||
|
body: {
|
||||||
|
auth: body.auth,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if (isAuth.login) {
|
||||||
|
await db.application.create({
|
||||||
|
data: {
|
||||||
|
name: body.name,
|
||||||
|
area: body.area,
|
||||||
|
cpu: parseInt(body.cpu),
|
||||||
|
ram: parseInt(body.ram),
|
||||||
|
disk: parseInt(body.disk),
|
||||||
|
desc: body.desc,
|
||||||
|
applicantId: parseInt(body.uid),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
export default defineEventHandler((event) => {
|
await db.$disconnect();
|
||||||
return event;
|
return {
|
||||||
|
code: 1,
|
||||||
|
msg: "申请提交成功",
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
if (isAuth.code == 0) {
|
||||||
|
console.error(isAuth);
|
||||||
|
console.error(JSON.stringify(body));
|
||||||
|
return {
|
||||||
|
code: 0,
|
||||||
|
msg: "未登录",
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
code: 0,
|
||||||
|
msg: "登陆超时",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return body;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/* { name: '1231',
|
||||||
|
area: '1',
|
||||||
|
cpu: '2',
|
||||||
|
ram: '2',
|
||||||
|
disk: '5',
|
||||||
|
desc: '<div>12313</div>',
|
||||||
|
uid: '1',
|
||||||
|
auth: 'a19705902b2ba12fbe52930b34802ab1' } */
|
||||||
|
55
server/api/user/application.post.ts
Normal file
55
server/api/user/application.post.ts
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
import { PrismaClient } from "@prisma/client";
|
||||||
|
import type { Application } from "~/types/Application";
|
||||||
|
const db = new PrismaClient();
|
||||||
|
type app = {
|
||||||
|
applicant: {
|
||||||
|
username: string | null;
|
||||||
|
};
|
||||||
|
} & {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
area: string;
|
||||||
|
cpu: number;
|
||||||
|
ram: number;
|
||||||
|
disk: number;
|
||||||
|
desc: string;
|
||||||
|
deploy: boolean;
|
||||||
|
applicantId: number;
|
||||||
|
};
|
||||||
|
function formatApplication(raw: app[]): Application[] {
|
||||||
|
var logs: Application[] = [];
|
||||||
|
raw.forEach((element: app) => {
|
||||||
|
logs.push({
|
||||||
|
id: element.id,
|
||||||
|
area: element.area,
|
||||||
|
name: element.name,
|
||||||
|
applicant: element.applicant.username || "none",
|
||||||
|
cpu: element.cpu,
|
||||||
|
ram: element.ram,
|
||||||
|
disk: element.disk,
|
||||||
|
desc: element.desc,
|
||||||
|
deploy: element.deploy,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return logs;
|
||||||
|
}
|
||||||
|
export default defineEventHandler(async (event) => {
|
||||||
|
const body = await readBody(event);
|
||||||
|
const applications = await db.application.findMany({
|
||||||
|
where: {
|
||||||
|
applicantId: body.uid,
|
||||||
|
},
|
||||||
|
orderBy: {
|
||||||
|
id: "desc", // 'asc' 表示升序,'desc' 表示降序
|
||||||
|
},
|
||||||
|
include: {
|
||||||
|
applicant: {
|
||||||
|
select: {
|
||||||
|
username: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
await db.$disconnect();
|
||||||
|
return formatApplication(applications);
|
||||||
|
});
|
23
server/api/user/auth.get.ts
Normal file
23
server/api/user/auth.get.ts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import { PrismaClient } from "@prisma/client";
|
||||||
|
|
||||||
|
const db = new PrismaClient();
|
||||||
|
export default defineEventHandler(async (event) => {
|
||||||
|
const query: { auth: string } = getQuery(event);
|
||||||
|
let userid: number = 0;
|
||||||
|
userid = await db.loginlogs
|
||||||
|
.findFirst({
|
||||||
|
where: { token: query.auth },
|
||||||
|
select: {
|
||||||
|
userid: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
if (res != null) {
|
||||||
|
return res.userid;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
//console.info(userid);
|
||||||
|
return userid;
|
||||||
|
});
|
@ -4,7 +4,7 @@ const db = new PrismaClient();
|
|||||||
|
|
||||||
async function auth(auth: string) {
|
async function auth(auth: string) {
|
||||||
const res = await db.loginlogs.findFirst({
|
const res = await db.loginlogs.findFirst({
|
||||||
where: { token: auth.toString() },
|
where: { token: auth },
|
||||||
});
|
});
|
||||||
//return JSON.stringify((await res).values)
|
//return JSON.stringify((await res).values)
|
||||||
if (res == null) {
|
if (res == null) {
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
export type Application = {
|
export type Application = {
|
||||||
name: string
|
id: number;
|
||||||
area: string
|
name: string;
|
||||||
cpu: number
|
area: string;
|
||||||
ram: number
|
cpu: number;
|
||||||
disk: number
|
ram: number;
|
||||||
usage: string
|
disk: number;
|
||||||
applicantId: number
|
desc: string;
|
||||||
}
|
applicant: string;
|
||||||
|
deploy: boolean;
|
||||||
|
};
|
||||||
|
1
types/Application/index.d.ts
vendored
Normal file
1
types/Application/index.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
export { Application } from "./Application.ts";
|
Loading…
Reference in New Issue
Block a user