feat(.): Achieve the sms code send
This commit is contained in:
parent
d834378c1c
commit
8a04c4e72e
@ -7,14 +7,10 @@
|
||||
@select="handleSelect"
|
||||
>
|
||||
<el-menu-item index="/">
|
||||
<img
|
||||
style="width: 50px;"
|
||||
src="/logo.svg"
|
||||
alt="Element logo"
|
||||
/>
|
||||
<img style="width: 50px" src="/logo.svg" alt="Element logo" />
|
||||
</el-menu-item>
|
||||
<el-menu-item index="/apply">立即申请</el-menu-item>
|
||||
<el-menu-item index="/about">关于我们</el-menu-item>
|
||||
<el-menu-item index="/about" disabled>关于我们</el-menu-item>
|
||||
<el-menu-item index="/status" disabled>设备监控</el-menu-item>
|
||||
<el-sub-menu index="/area" disabled>
|
||||
<template #title>区域服务</template>
|
||||
@ -35,16 +31,14 @@
|
||||
<el-menu-item index="register">注册</el-menu-item>
|
||||
</el-menu>
|
||||
</client-only>
|
||||
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
||||
const activeIndex = ref('1')
|
||||
const activeIndex = ref("1");
|
||||
const handleSelect = (key: string, keyPath: string[]) => {
|
||||
console.log(key, keyPath)
|
||||
navigateTo(key)
|
||||
}
|
||||
console.log(key, keyPath);
|
||||
navigateTo(key);
|
||||
};
|
||||
</script>
|
||||
<style>
|
||||
.flex-grow {
|
||||
|
@ -1,8 +1,11 @@
|
||||
// https://nuxt.com/docs/api/configuration/nuxt-config
|
||||
export default defineNuxtConfig({
|
||||
devtools: { enabled: true },
|
||||
modules: [
|
||||
"@element-plus/nuxt",
|
||||
'@vueform/nuxt'
|
||||
],
|
||||
})
|
||||
runtimeConfig: {
|
||||
apiSecret: "",
|
||||
apiOpenid: "",
|
||||
apiApikey: "",
|
||||
apiSmsId: 0,
|
||||
},
|
||||
modules: ["@element-plus/nuxt", "@vueform/nuxt"],
|
||||
});
|
||||
|
@ -17,6 +17,7 @@
|
||||
"element-plus": "^2.7.4",
|
||||
"nuxt": "^3.11.2",
|
||||
"prisma": "^5.15.0",
|
||||
"quanmsms": "^1.0.2",
|
||||
"typescript": "^5.4.5",
|
||||
"vue": "^3.4.27",
|
||||
"vue-router": "^4.3.2"
|
||||
|
78
pages/admin/index.vue
Normal file
78
pages/admin/index.vue
Normal file
@ -0,0 +1,78 @@
|
||||
<template>
|
||||
<Head>
|
||||
<Title>管理界面</Title>
|
||||
<Meta name="description" />
|
||||
</Head>
|
||||
<client-only>
|
||||
<el-table :data="tableData" style="width: 100%">
|
||||
<el-table-column prop="appid" label="AppID" width="180" />
|
||||
<el-table-column prop="name" label="申请人" width="180" />
|
||||
<el-table-column prop="phone" label="手机号" width="180" />
|
||||
<el-table-column label="配置" width="300">
|
||||
<template #default="scope">
|
||||
<el-icon color="blue"><ElIcon-Cpu /></el-icon>
|
||||
{{ scope.row.resource.cpu }} Core
|
||||
<el-icon color="green"><ElIcon-Stopwatch /></el-icon
|
||||
>{{ scope.row.resource.ram }} GB
|
||||
<el-icon color="gray"><ElIcon-Memo /></el-icon>
|
||||
{{ scope.row.resource.disk }} GB
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="usage" label="用途" width="360" />
|
||||
<el-table-column label="状态" width="300">
|
||||
<template #default="scope">
|
||||
<el-icon :color="scope.row.apply ? 'green' : 'orange'"
|
||||
><ElIcon-Stamp
|
||||
/></el-icon>
|
||||
{{ scope.row.apply ? "通过" : "待审核" }}
|
||||
</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>
|
||||
<script lang="ts" setup>
|
||||
const tableData = [
|
||||
{
|
||||
appid: "1",
|
||||
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>
|
@ -2,30 +2,76 @@
|
||||
<!--立即申请页面-->
|
||||
<Head>
|
||||
<Title>立即申请</Title>
|
||||
<Meta name="description"/>
|
||||
<Meta name="description" />
|
||||
</Head>
|
||||
<div style="width:50%;margin:auto;" :style="{
|
||||
<div
|
||||
style="width: 50%; margin: auto"
|
||||
:style="{
|
||||
boxShadow: `var(--el-box-shadow-light)`,
|
||||
}">
|
||||
<ClientOnly >
|
||||
<Vueform endpoint="/api/test" method="POST" view="tabs" style="padding:30px" >
|
||||
<StaticElement tag="h4" align="center" content="个人信息" name="static" />
|
||||
<TextElement name="username" label="昵称" placeholder="昵称" :columns="{ container: 4, label: 3, wrapper: 12 }" rules="required|min:3"/>
|
||||
<PhoneElement name="phone" allow-incomplete unmask default="+86" :include="['cn']" label="手机号" placeholder="+86" :columns="{ container: 12, label: 1, wrapper: 4 }" rules="required"/>
|
||||
<TextElement name="code" label="验证码" placeholder="xxxxxx" :columns="{ container: 4, label: 3, wrapper: 12 }" rules="required"/>
|
||||
<ButtonElement name="button" :columns="{ container: 8, label: 3, wrapper: 12 }" button-label="发送验证码"/>
|
||||
<StaticElement tag="h4" align="center" content="项目详情" name="static" />
|
||||
<TextElement name="name" label="项目名称" placeholder="项目名称" :columns="{ container: 4, label: 4, wrapper: 12 }" rules="required"/>
|
||||
}"
|
||||
>
|
||||
<ClientOnly>
|
||||
<Vueform
|
||||
endpoint="/api/test"
|
||||
method="POST"
|
||||
view="tabs"
|
||||
style="padding: 30px"
|
||||
>
|
||||
<StaticElement
|
||||
tag="h4"
|
||||
align="center"
|
||||
content="个人信息"
|
||||
name="static"
|
||||
/>
|
||||
<TextElement
|
||||
name="username"
|
||||
label="昵称"
|
||||
placeholder="昵称"
|
||||
:columns="{ container: 4, label: 3, wrapper: 12 }"
|
||||
rules="required|min:3"
|
||||
/>
|
||||
<PhoneElement
|
||||
name="phone"
|
||||
allow-incomplete
|
||||
unmask
|
||||
default="+86"
|
||||
:include="['cn']"
|
||||
label="手机号"
|
||||
placeholder="+86"
|
||||
:columns="{ container: 12, label: 1, wrapper: 4 }"
|
||||
rules="required"
|
||||
/>
|
||||
<TextElement
|
||||
name="code"
|
||||
label="验证码"
|
||||
placeholder="xxxxxx"
|
||||
:columns="{ container: 4, label: 4, wrapper: 12 }"
|
||||
rules="required"
|
||||
/>
|
||||
<ButtonElement
|
||||
name="button"
|
||||
:columns="{ container: 8, label: 3, wrapper: 12 }"
|
||||
button-label="发送验证码"
|
||||
/>
|
||||
<StaticElement
|
||||
tag="h4"
|
||||
align="center"
|
||||
content="项目详情"
|
||||
name="static"
|
||||
/>
|
||||
<TextElement
|
||||
name="name"
|
||||
label="项目名称"
|
||||
placeholder="项目名称"
|
||||
:columns="{ container: 4, label: 4, wrapper: 12 }"
|
||||
rules="required"
|
||||
/>
|
||||
<SelectElement
|
||||
name="select"
|
||||
default="辽宁一区"
|
||||
label="地区"
|
||||
:native="false"
|
||||
:items="[
|
||||
'辽宁一区',
|
||||
'辽宁二区',
|
||||
'江西一区',
|
||||
]"
|
||||
:items="['辽宁一区', '辽宁二区', '江西一区']"
|
||||
:columns="{ container: 4, label: 3, wrapper: 12 }"
|
||||
rules="required"
|
||||
/>
|
||||
@ -33,14 +79,14 @@
|
||||
default="2 Core"
|
||||
label="CPU核心数"
|
||||
name="cpu"
|
||||
:items="['2 Core', '4 Core', '6 Core','More']"
|
||||
:items="['2 Core', '4 Core', '6 Core', 'More']"
|
||||
view="tabs"
|
||||
/>
|
||||
<RadiogroupElement
|
||||
default="2 GB"
|
||||
label="RAM容量"
|
||||
name="ram"
|
||||
:items="['2 GB', '4 GB', '6 GB','More']"
|
||||
:items="['2 GB', '4 GB', '6 GB', 'More']"
|
||||
view="tabs"
|
||||
/>
|
||||
|
||||
@ -53,24 +99,25 @@
|
||||
:format="(v: number) => v > 1 ? `${Math.round(v)} GB` : '1 GB'"
|
||||
:add-classes="{
|
||||
ElementLayout: {
|
||||
innerWrapper: 'mt-12'
|
||||
}
|
||||
innerWrapper: 'mt-12',
|
||||
},
|
||||
}"
|
||||
/>
|
||||
|
||||
<EditorElement
|
||||
name="usage"
|
||||
label="用途说明"
|
||||
rules="required|max:500"
|
||||
/>
|
||||
<EditorElement name="usage" label="用途说明" rules="required|max:500" />
|
||||
|
||||
<ButtonElement name="submit" button-label="提交申请" align="center" size="lg" submits/>
|
||||
<ButtonElement
|
||||
name="submit"
|
||||
button-label="提交申请"
|
||||
align="center"
|
||||
size="lg"
|
||||
submits
|
||||
/>
|
||||
</Vueform>
|
||||
</ClientOnly>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import PhoneElemen from '@vueform/vueform'
|
||||
const form = ref()
|
||||
import PhoneElemen from "@vueform/vueform";
|
||||
const form = ref();
|
||||
</script>
|
@ -2,14 +2,62 @@
|
||||
<!--登录界面-->
|
||||
<Head>
|
||||
<Title>登录界面</Title>
|
||||
<Meta name="description"/>
|
||||
<Meta name="description" />
|
||||
</Head>
|
||||
<div>
|
||||
<el-text class="mx-1" type="primary" >
|
||||
Primary
|
||||
</el-text>
|
||||
<div
|
||||
style="width: 25%; margin: auto"
|
||||
:style="{
|
||||
boxShadow: `var(--el-box-shadow-light)`,
|
||||
}"
|
||||
>
|
||||
<ClientOnly>
|
||||
<Vueform
|
||||
endpoint="/api/test"
|
||||
method="POST"
|
||||
view="tabs"
|
||||
style="padding: 30px"
|
||||
>
|
||||
<StaticElement tag="h4" align="center" content="登录" name="static" />
|
||||
<PhoneElement
|
||||
input-type="number"
|
||||
name="phone"
|
||||
allow-incomplete
|
||||
unmask
|
||||
default="+86"
|
||||
:include="['cn']"
|
||||
label="手机号"
|
||||
placeholder="+86"
|
||||
:columns="{ container: 12, label: 3, wrapper: 10 }"
|
||||
rules="required|min:14|max:14"
|
||||
/>
|
||||
<TextElement
|
||||
input-type="password"
|
||||
name="password"
|
||||
label="密码"
|
||||
rules="required|min:8|max:16|confirmed"
|
||||
:columns="{ container: 12, label: 3, wrapper: 10 }"
|
||||
/>
|
||||
<CheckboxElement
|
||||
name="policy"
|
||||
label="用户协议"
|
||||
rules="required"
|
||||
message="您必须同意用户政策才能继续"
|
||||
>
|
||||
已阅读并同意<ElLink href="/" target="_blank">《用户协议》</ElLink>
|
||||
</CheckboxElement>
|
||||
<CheckboxElement name="news"> 希望获取最新资讯 </CheckboxElement>
|
||||
<ButtonElement
|
||||
name="submit"
|
||||
button-label="登录"
|
||||
align="center"
|
||||
size="lg"
|
||||
submits
|
||||
/>
|
||||
</Vueform>
|
||||
</ClientOnly>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
|
||||
import PhoneElemen from "@vueform/vueform";
|
||||
const form = ref();
|
||||
</script>
|
@ -2,33 +2,210 @@
|
||||
<!--注册页面-->
|
||||
<Head>
|
||||
<Title>注册页面</Title>
|
||||
<Meta name="description"/>
|
||||
<Meta name="description" />
|
||||
</Head>
|
||||
<div style="width:50%;margin:auto;" :style="{
|
||||
<div
|
||||
style="width: 25%; margin: auto"
|
||||
:style="{
|
||||
boxShadow: `var(--el-box-shadow-light)`,
|
||||
}">
|
||||
<ClientOnly >
|
||||
<Vueform endpoint="/api/test" method="POST" view="tabs" style="padding:30px" >
|
||||
<StaticElement tag="h4" align="center" content="个人信息" name="static" />
|
||||
<TextElement name="username" allow-incomplete label="昵称" placeholder="昵称" :columns="{ container: 4, label: 3, wrapper: 8 }" rules="required|min:3|max:64"/>
|
||||
<PhoneElement input-type="number" name="phone" allow-incomplete unmask default="+86" :include="['cn']" label="手机号" placeholder="+86" :columns="{ container: 12, label: 1, wrapper: 4 }" rules="required|max:6|min:6"/>
|
||||
<TextElement name="code" label="验证码" placeholder="xxxxxx" :columns="{ container: 4, label: 3, wrapper: 12 }" rules="required"/>
|
||||
<ButtonElement name="button" :columns="{ container: 8, label: 3, wrapper: 12 }" button-label="发送验证码"/>
|
||||
<TextElement input-type="password" name="password" label="密码" rules="required|min:8|max:16|confirmed"/>
|
||||
<TextElement input-type="password" name="password_confirmation" label="确认密码" rules="required|min:8|max:16"/>
|
||||
<CheckboxElement name="policy" label="用户协议" rules="required" message="您必须同意用户政策才能继续">
|
||||
}"
|
||||
>
|
||||
<ClientOnly>
|
||||
<Vueform
|
||||
endpoint="/api/test"
|
||||
method="POST"
|
||||
view="tabs"
|
||||
:model-value="form"
|
||||
@update:model-value="form = $event"
|
||||
validate-on="change"
|
||||
style="padding: 30px"
|
||||
>
|
||||
<StaticElement tag="h4" align="center" content="注册" name="static" />
|
||||
<TextElement
|
||||
ref="username$"
|
||||
name="username"
|
||||
allow-incomplete
|
||||
label="昵称"
|
||||
placeholder="昵称"
|
||||
:columns="{ container: 12, label: 3, wrapper: 8 }"
|
||||
rules="required|min:3|max:64"
|
||||
@blur="Check()"
|
||||
/>
|
||||
<PhoneElement
|
||||
ref="phone$"
|
||||
input-type="number"
|
||||
name="phone"
|
||||
allow-incomplete
|
||||
unmask
|
||||
default="+86"
|
||||
:include="['cn']"
|
||||
label="手机号"
|
||||
placeholder="+86"
|
||||
:columns="{ container: 12, label: 3, wrapper: 10 }"
|
||||
rules="required|min:14|max:14"
|
||||
@blur="Check()"
|
||||
:disabled="phoneChecked"
|
||||
/>
|
||||
<TextElement
|
||||
name="code"
|
||||
label="验证码"
|
||||
placeholder="xxxxxx"
|
||||
rules="required|max:6|min:6"
|
||||
:columns="{ container: 8, label: 5, wrapper: 12 }"
|
||||
@blur="CheckCode()"
|
||||
:disabled="!codeBtnRef.disabled || phoneChecked"
|
||||
ref="code$"
|
||||
/>
|
||||
<ButtonElement
|
||||
name="button"
|
||||
:columns="{ container: 4, label: 3, wrapper: 12 }"
|
||||
@click="Send()"
|
||||
:button-label="codeBtnRef.text"
|
||||
:disabled="codeBtnRef.disabled || phoneChecked"
|
||||
/>
|
||||
<TextElement
|
||||
input-type="password"
|
||||
name="password"
|
||||
label="密码"
|
||||
rules="required|min:8|max:16|confirmed"
|
||||
:columns="{ container: 12, label: 3, wrapper: 10 }"
|
||||
/>
|
||||
<TextElement
|
||||
input-type="password"
|
||||
name="password_confirmation"
|
||||
label="确认密码"
|
||||
rules="required|min:8|max:16"
|
||||
:columns="{ container: 12, label: 3, wrapper: 10 }"
|
||||
/>
|
||||
<CheckboxElement
|
||||
name="policy"
|
||||
label="用户协议"
|
||||
rules="required"
|
||||
message="您必须同意用户政策才能继续"
|
||||
>
|
||||
已阅读并同意<ElLink href="/" target="_blank">《用户协议》</ElLink>
|
||||
</CheckboxElement>
|
||||
<CheckboxElement name="news">
|
||||
希望获取最新资讯
|
||||
</CheckboxElement>
|
||||
<ButtonElement name="submit" button-label="提交申请" align="center" size="lg" submits/>
|
||||
<CheckboxElement name="news"> 希望获取最新资讯 </CheckboxElement>
|
||||
<ButtonElement
|
||||
:disabled="canSubmit"
|
||||
name="submit"
|
||||
button-label="注册"
|
||||
align="center"
|
||||
size="lg"
|
||||
submits
|
||||
/><ButtonElement
|
||||
name="reset"
|
||||
danger
|
||||
button-label="重置"
|
||||
resets
|
||||
size="sm"
|
||||
/>
|
||||
</Vueform>
|
||||
</ClientOnly>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import PhoneElemen from '@vueform/vueform'
|
||||
const form = ref()
|
||||
</script>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import PhoneElemen from "@vueform/vueform";
|
||||
const form = ref({});
|
||||
const phoneChecked = ref(false);
|
||||
const codeBtnRef = ref({ text: "发送验证码", color: "", disabled: false });
|
||||
const username$ = ref(null);
|
||||
const phone$ = ref(null);
|
||||
const code$ = ref(null);
|
||||
const canSubmit = ref(false);
|
||||
function Check() {
|
||||
const query = {
|
||||
username: form.value.username,
|
||||
phone: form.value.phone.replace("+86", ""),
|
||||
};
|
||||
if (!/^(?!1(4|7)\d{9})1[3-9]\d{9}$/.test(query.phone)) {
|
||||
phone$.value.messageBag.clear("errors");
|
||||
phone$.value.messageBag.append("手机号格式错误" + query.phone);
|
||||
canSubmit.value = true;
|
||||
return;
|
||||
} else {
|
||||
phone$.value.messageBag = [];
|
||||
}
|
||||
$fetch("/api/test/reg", {
|
||||
method: "POST",
|
||||
body: query,
|
||||
}).then((res) => {
|
||||
if (!res.phone) {
|
||||
phone$.value.messageBag.append("手机号已经注册");
|
||||
canSubmit.value = true;
|
||||
} else {
|
||||
canSubmit.value = false;
|
||||
}
|
||||
if (!res.username) {
|
||||
username$.value.messageBag.append("昵称已存在");
|
||||
canSubmit.value = true;
|
||||
} else {
|
||||
canSubmit.value = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
function Send() {
|
||||
Check();
|
||||
if (!canSubmit.value) {
|
||||
$fetch("/api/test/sms", {
|
||||
method: "POST",
|
||||
body: {
|
||||
phone: form.value.phone.replace("+86", ""),
|
||||
},
|
||||
}).then((res) => {
|
||||
switch (res.code) {
|
||||
case 0:
|
||||
ElMessage({ message: res.msg + "\n" + res.error, type: "error" });
|
||||
break;
|
||||
case 1:
|
||||
ElMessage({ message: res.msg, type: "success" });
|
||||
codeBtnRef.value.disabled = true;
|
||||
codeBtnRef.value.text = "请查收";
|
||||
break;
|
||||
case 2:
|
||||
ElMessage({ message: res.msg, type: "warning" });
|
||||
codeBtnRef.value.disabled = true;
|
||||
codeBtnRef.value.text = "请查收";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
console.info(form.value.phone.replace("+86", ""));
|
||||
}
|
||||
function CheckCode() {
|
||||
if (!code$.value.invalid) {
|
||||
$fetch("/api/test/code", {
|
||||
method: "POST",
|
||||
body: {
|
||||
phone: form.value.phone.replace("+86", ""),
|
||||
code: form.value.code,
|
||||
},
|
||||
}).then((res) => {
|
||||
switch (res.code) {
|
||||
case 0:
|
||||
ElMessage({
|
||||
message: res.msg,
|
||||
type: "error",
|
||||
});
|
||||
break;
|
||||
case 1:
|
||||
ElMessage({ message: res.msg, type: "success" });
|
||||
codeBtnRef.value.disabled = true;
|
||||
codeBtnRef.value.text = "已验证";
|
||||
phoneChecked.value = ture;
|
||||
break;
|
||||
case 2:
|
||||
ElMessage({ message: res.msg, type: "warning" });
|
||||
codeBtnRef.value.disabled = false;
|
||||
codeBtnRef.value.text = "发送验证码";
|
||||
break;
|
||||
default:
|
||||
ElMessage({ message: res.msg, type: "warning" });
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
6
pages/user/index.vue
Normal file
6
pages/user/index.vue
Normal file
@ -0,0 +1,6 @@
|
||||
<template>
|
||||
<Head>
|
||||
<Title>用户信息</Title>
|
||||
<Meta name="description" />
|
||||
</Head>
|
||||
</template>
|
@ -18,6 +18,11 @@ model User {
|
||||
applications Application[]
|
||||
}
|
||||
|
||||
model Adminer {
|
||||
id Int @id @default(autoincrement())
|
||||
adminId Int
|
||||
}
|
||||
|
||||
model Application {
|
||||
id Int @id @default(autoincrement())
|
||||
name String
|
||||
@ -30,3 +35,9 @@ model Application {
|
||||
applicant User @relation(fields: [applicantId], references: [id])
|
||||
applicantId Int
|
||||
}
|
||||
model Register {
|
||||
id Int @id @default(autoincrement())
|
||||
phone String
|
||||
deadline DateTime
|
||||
code String
|
||||
}
|
27
server/api/test/code.ts
Normal file
27
server/api/test/code.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import { PrismaClient } from "@prisma/client";
|
||||
const db = new PrismaClient();
|
||||
export default defineEventHandler(async (event) => {
|
||||
const body = await readBody(event);
|
||||
const register = (await db.register.findFirst({
|
||||
where: {
|
||||
phone: body.phone,
|
||||
},
|
||||
orderBy: {
|
||||
deadline: "desc", // 'asc' 表示升序,'desc' 表示降序
|
||||
},
|
||||
})) || {
|
||||
deadline: new Date(),
|
||||
};
|
||||
const deadlineDate = new Date(register.deadline);
|
||||
const now = new Date();
|
||||
if (now > deadlineDate) {
|
||||
return { code: 2, msg: "验证码超时了,请重新发送" };
|
||||
} else if (register.code != body.code) {
|
||||
console.log(body.code + " phone " + register.phone + " " + register.code);
|
||||
return { code: 0, msg: "验证码错误" };
|
||||
} else if (register.code == body.code) {
|
||||
return { code: 1, msg: "验证码正确" };
|
||||
} else {
|
||||
return { code: -1, msg: "未知错误" };
|
||||
}
|
||||
});
|
@ -1,9 +1,38 @@
|
||||
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 = await readBody(event)
|
||||
console.info(body)
|
||||
return body
|
||||
})
|
||||
export default defineEventHandler(async (event) => {
|
||||
const body = await readBody(event);
|
||||
console.info(body);
|
||||
let isSend =
|
||||
(await db.register.findFirst({
|
||||
where: {
|
||||
phone: body.phone,
|
||||
},
|
||||
})) != null;
|
||||
if (isSend) {
|
||||
const register = (await db.register.findFirst({
|
||||
where: {
|
||||
phone: body.phone,
|
||||
},
|
||||
orderBy: {
|
||||
deadline: "desc", // 'asc' 表示升序,'desc' 表示降序
|
||||
},
|
||||
})) || {
|
||||
deadline: new Date(),
|
||||
};
|
||||
const deadlineDate = new Date(register.deadline);
|
||||
const now = new Date();
|
||||
if (now <= deadlineDate) {
|
||||
return { code: 2, msg: "三分钟内请勿重发送" };
|
||||
} else {
|
||||
return {
|
||||
code: -1,
|
||||
msg:
|
||||
"发送成功" + now + "<=" + deadlineDate + ":" + (now <= deadlineDate),
|
||||
};
|
||||
}
|
||||
}
|
||||
return isSend;
|
||||
});
|
||||
|
19
server/api/test/reg.ts
Normal file
19
server/api/test/reg.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import { PrismaClient } from "@prisma/client";
|
||||
const db = new PrismaClient();
|
||||
export default defineEventHandler(async (event) => {
|
||||
const body = await readBody(event);
|
||||
return {
|
||||
username:
|
||||
(await db.user.findFirst({
|
||||
where: {
|
||||
username: body.username,
|
||||
},
|
||||
})) == null,
|
||||
phone:
|
||||
(await db.user.findFirst({
|
||||
where: {
|
||||
phone: body.phone,
|
||||
},
|
||||
})) == null,
|
||||
};
|
||||
});
|
93
server/api/test/sms.ts
Normal file
93
server/api/test/sms.ts
Normal file
@ -0,0 +1,93 @@
|
||||
import { PrismaClient } from "@prisma/client";
|
||||
import qmAPI from "quanmsms";
|
||||
|
||||
const config = useRuntimeConfig();
|
||||
const smsApi = new qmAPI(config.apiOpenid.toString(), {
|
||||
sms: {
|
||||
apiKey: config.apiApikey,
|
||||
},
|
||||
});
|
||||
const db = new PrismaClient();
|
||||
function generateRandomCode(length: number) {
|
||||
let code = "";
|
||||
//const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';复杂验证码
|
||||
const possible = "0123456789";
|
||||
for (let i = 0; i < length; i++) {
|
||||
code += possible.charAt(Math.floor(Math.random() * possible.length));
|
||||
}
|
||||
return code;
|
||||
}
|
||||
function generateDeadline() {
|
||||
const now = new Date(); // 获取当前时间
|
||||
const threeMinutesLater = new Date(now.getTime() + 3.5 * 60 * 1000); // 加上3分钟
|
||||
return threeMinutesLater.toISOString(); // 转换为ISO格式字符串
|
||||
}
|
||||
|
||||
function send(telstr: string) {
|
||||
let tel = parseInt(telstr);
|
||||
const code = generateRandomCode(6);
|
||||
let param = {
|
||||
tel: tel,
|
||||
model_id: config.apiSmsId.toString(),
|
||||
model_args: {
|
||||
//模板id对应的变量key值,object格式,内部自动处理成平台要求的str
|
||||
code: code,
|
||||
// 如果你的模板没变量,该值可为空
|
||||
},
|
||||
};
|
||||
return smsApi
|
||||
.sendSMS(param)
|
||||
.then((response: { code: number; state: number }) => {
|
||||
if (response.state == 200) {
|
||||
db.register
|
||||
.create({
|
||||
data: {
|
||||
phone: telstr,
|
||||
deadline: generateDeadline(),
|
||||
code: code,
|
||||
},
|
||||
})
|
||||
.then((reg) => {
|
||||
if (reg.phone == telstr) {
|
||||
console.info(telstr + "发送成功");
|
||||
}
|
||||
});
|
||||
return { code: 1, msg: "发送成功" };
|
||||
} else {
|
||||
console.info(tel);
|
||||
return { code: 0, msg: "发送失败", error: response };
|
||||
}
|
||||
// 你的业务代码
|
||||
});
|
||||
}
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const body = await readBody(event);
|
||||
let isSend =
|
||||
(await db.register.findFirst({
|
||||
where: {
|
||||
phone: body.phone,
|
||||
},
|
||||
})) != null;
|
||||
if (isSend) {
|
||||
const register = (await db.register.findFirst({
|
||||
where: {
|
||||
phone: body.phone,
|
||||
},
|
||||
orderBy: {
|
||||
deadline: "desc", // 'asc' 表示升序,'desc' 表示降序
|
||||
},
|
||||
})) || {
|
||||
deadline: new Date(),
|
||||
};
|
||||
const deadlineDate = new Date(register.deadline);
|
||||
const now = new Date();
|
||||
if (now <= deadlineDate) {
|
||||
return { code: 2, msg: "三分钟内请勿重发送" };
|
||||
} else {
|
||||
return send(body.phone);
|
||||
}
|
||||
} else {
|
||||
return send(body.phone);
|
||||
}
|
||||
});
|
@ -4858,6 +4858,11 @@ proxy-from-env@^1.1.0:
|
||||
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
|
||||
integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==
|
||||
|
||||
quanmsms@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/quanmsms/-/quanmsms-1.0.2.tgz#8e7748329f87fd5f5550fe8eb94b6ab11a54ff90"
|
||||
integrity sha512-wY4A2tz5ZANlgJw4t3fTgmcRpXO6FkyAxSfipdWa8DZxtfbItjQ4BErlugiEmL0sB2cTwJG9P3w5NT7i56T11Q==
|
||||
|
||||
queue-microtask@^1.2.2:
|
||||
version "1.2.3"
|
||||
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
|
||||
|
Loading…
Reference in New Issue
Block a user