checkout init

This commit is contained in:
rsgltzyd 2024-09-17 11:08:56 +08:00
parent 395829a029
commit 3837e9d3a7
10 changed files with 814 additions and 2 deletions

View File

@ -0,0 +1,76 @@
<script>
import { defineComponent } from 'vue';
import Post from '../utils/Post.js';
export default defineComponent({
props: {
post: { type: Post, required: true },
},
data() {
return {
childPost: {}
};
},
created() {
this.childPost = this.post;
},
});
</script>
<template>
<div class="card">
<div class="title">
<h2>{{ childPost.title }}</h2>
</div>
<div class="content">
<p>{{ childPost.content }}</p>
</div>
</div>
</template>
<style scoped>
.card {
box-sizing: border-box;
box-shadow: 0 0 10px 0 rgba(0, 0, 0, .24);
border-radius: 4px;
padding: 8px;
cursor: pointer;
margin: 10px 0;
/* height: 100px; */
}
.card .title {
/* height: 24px; */
line-height: 24px;
/* margin-bottom: 4px; */
padding-bottom: 4px;
border-bottom: 1px solid rgba(0, 0, 0, .24);
}
.card .title:hover {
color: burlywood;
}
.card .content {
padding: 4px;
/* height: 100%; */
/* max-height: calc(100% - 36px); */
}
.card .content p {
/* 单行显示 */
text-overflow: ellipsis;
overflow: hidden;
word-break: break-all;
white-space: nowrap;
/* 多行显示 */
/* word-break: break-all;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical; */
/* */
/* height: 100%; */
}
</style>

View File

@ -0,0 +1,78 @@
const weekDayNumber = 7;
const week_zh_cn = ["周日", "周一", "周二", "周三", "周四", "周五", "周六"];
const week_en_us = ["SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"];
class Day {
constructor(year, month, day, content, isCurrentMonth = false, isCurrentDay = false) {
this.year = year;
this.month = month;
this.day = day;
this.content = content;
this.isCurrentMonth = isCurrentMonth;
this.isCurrentDay = isCurrentDay
}
}
const defaultDate = new Date();
const defaultYear = defaultDate.getFullYear()
const defaultMonth = defaultDate.getMonth()
const defaultDay = defaultDate.getDate()
/**
* 初始化日历
* @param {[Day]} currentDays
* @param {number} [year = defaultYear]
* @param {number} [month = defaultMonth]
* @param {number} [day = defaultDay]
* @returns {[Day]}
*/
function initDay(currentDays = new Array(42), year = defaultYear, month = defaultMonth, day = defaultDay) {
if (!Array.isArray(currentDays)) {
currentDays = new Array(42);
} else if (currentDays.length != 42) {
console.log(currentDays);
throw new Error(currentDays)
} else {
currentDays = [...currentDays];
}
const days = currentDays;
const firstDayOfMonth = new Date(year, month, 1);
const lastDayOfMonth = new Date(year, month + 1, 0);
const currentDaysOfMonth = lastDayOfMonth.getDate();
for (let i = 0; i < firstDayOfMonth.getDay(); i++) {
days[i] = new Day('', '');
}
for (let i = 0; i < currentDaysOfMonth; i++) {
const weekDay = (firstDayOfMonth.getDay() + i) % weekDayNumber;
days[firstDayOfMonth.getDay() + i] = new Day(year, month, i + 1, week_zh_cn[weekDay], true);
if (i === day - 1) {
days[firstDayOfMonth.getDay() + i].isCurrentDay = true;
}
}
for (let i = currentDaysOfMonth + firstDayOfMonth.getDay(); i < days.length; i++) {
const extraDay = i - currentDaysOfMonth - firstDayOfMonth.getDay() + 1;
const weekDay = i % weekDayNumber;
days[i] = new Day(year, month + 1, extraDay, week_zh_cn[weekDay]);
}
return currentDays;
}
export { week_zh_cn, week_en_us, defaultYear, defaultMonth, defaultDay, initDay };

View File

@ -0,0 +1,126 @@
<script setup lang="js">
import { ref } from 'vue'
import { week_zh_cn, defaultYear, defaultMonth, defaultDay, initDay } from './CustomCalendar.js'
import IconCircleToTheRight from './icons/IconCircleToTheRight.vue'
import IconCircleToTheLeft from './icons/IconCircleToTheLeft.vue'
const weekTitle = ref(week_zh_cn)
let dayArray = ref(initDay())
const year = ref(defaultYear)
const month = ref(defaultMonth)
const day = ref(defaultDay)
const editMonth = {
add: () => {
month.value >= 11 ? ((month.value = 0), (year.value += 1)) : (month.value += 1)
dayArray.value = initDay(dayArray.value, year.value, month.value, day.value)
},
sub: () => {
month.value <= 0 ? ((month.value = 11), (year.value -= 1)) : (month.value -= 1)
dayArray.value = initDay(dayArray.value, year.value, month.value, day.value)
}
}
const handleDayClick = (date) => {
year.value = date.month >= 12 ? date.year + 1 : date.year
month.value = date.month % 12
day.value = date.day
dayArray.value = initDay(dayArray.value, year.value, month.value, day.value)
}
</script>
<template>
<div id="calendar">
<div class="title">
<button class="left" type="button" @click="editMonth.sub()">
<IconCircleToTheLeft />
</button>
<div>
<span>{{ year }}</span>
<span>{{ month + 1 }}</span>
<span>{{ day }}</span>
</div>
<button class="right" type="button" @click="editMonth.add()">
<IconCircleToTheRight />
</button>
</div>
<div class="content">
<div v-for="(title, index) in weekTitle" :key="index">
<span>{{ title }}</span>
</div>
<div v-for="(day, index) in dayArray" :key="index" @click="handleDayClick(day)">
<span v-if="day.isCurrentMonth && !day.isCurrentDay" class="day">
{{ day.day }}
</span>
<span v-else-if="day.isCurrentMonth && day.isCurrentDay" class="current_day">
{{ day.day }}
</span>
<span v-else>
{{ day.day }}
</span>
</div>
</div>
</div>
</template>
<style>
#calendar {
> .title {
display: flex;
justify-content: space-around;
width: 100%;
}
text-align: center;
}
#calendar .title {
> button {
height: 20px;
}
button svg {
width: 100%;
height: 100%;
}
}
.content {
display: grid;
grid-template-columns: repeat(7, 1fr);
> div {
outline: 1px solid;
display: flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
height: 100%;
}
}
@media screen and (max-width: 800px) {
#calendar {
width: 280px;
}
.content {
height: 240px;
}
}
@media screen and (min-width: 800px) {
#calendar {
max-width: 350px;
}
.content {
height: 300px;
}
}
.day {
color: #000000;
}
.current_day {
color: #880000;
}
</style>

View File

@ -0,0 +1,83 @@
<script>
import { defineComponent } from 'vue';
export default defineComponent({
props: {
poemTitle: {
type: String,
default: '雨霖铃·寒蝉凄切'
},
poemBody: {
type: Array,
default: () => [
'寒蝉凄切,对长亭晚,骤雨初歇。',
'都门帐饮无绪,留恋处,兰舟催发。',
'执手相看泪眼,竟无语凝噎。',
'念去去,千里烟波,暮霭沉沉楚天阔。',
'多情自古伤离别,更那堪,冷落清秋节!',
'今宵酒醒何处?杨柳岸,晓风残月。',
'此去经年,应是良辰好景虚设。',
'便纵有千种风情,更与何人说?'
],
}
},
data() {
return {
};
},
});
</script>
<template>
<div class="poem">
<h2 class="poem-title">
{{ this.poemTitle }}
</h2>
<ul class="poem-body">
<li v-for="{poem, index} in this.poemBody" :key="index">
{{ poem }}
</li>
</ul>
</div>
</template>
<style scoped>
* {
/* box-sizing: border-box; */
font-family: 'Ma Shan Zheng', cursive;
margin: 0;
padding: 0;
color: #000;
}
ol,
ul {
list-style: none;
}
.poem {
width: 280px;
border-radius: 4px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.4);
}
.poem-title {
text-align: center;
white-space: nowrap;
padding-top: 10px;
font-size: 24px;
width: 100%;
}
.poem-body {
text-align: center;
white-space: nowrap;
font-size: 16px;
padding: 10px 0;
>li {
margin: 5px auto;
}
}
</style>

View File

@ -0,0 +1,23 @@
<script>
import { defineComponent } from 'vue';
export default defineComponent({
props: {
},
data() {
return {
};
},
});
</script>
<template>
<div>
PersonInfoHHHHH
</div>
</template>
<style scoped>
</style>

View File

@ -0,0 +1,36 @@
<script>
import { defineComponent } from "vue";
export default defineComponent({
data() {
return {
test: ''
}
},
methods: {
testapi() {
fetch("http://127.0.0.1:3000/user")
.then(res => res.json())
.then(data => {
this.test = data;
})
.catch(err => console.log('Request Failed', err))
}
}
});
</script>
<template>
<button @click="testapi">测试接口调用</button>
<p v-if="this.test != ''">
{{ this.test[0].name }}<br>
{{ this.test[0].birth }}<br>
{{ this.test[0].gender }}<br>
{{ this.test[0].name }}<br>
{{ this.test[0].password }}<br>
{{ this.test[0].register_date }}<br>
{{ this.test[0].status }}<br>
</p>
</template>
<style></style>

View File

@ -0,0 +1,340 @@
<script>
import { defineComponent } from 'vue';
export default defineComponent({
props: {
welcome: {
type: String,
default: '你好',
},
url: {
type: String,
default: 'http://127.0.0.1:3000/login',
},
},
data() {
return {
showAccountError: false,
showPasswordError: false,
accountAbove: false,
passwordAbove: false,
accountShow: true,
passwordShow: true,
account: '',
password: '',
};
},
watch: {
account(val) {
val.length > 0 ? (this.showAccountError = false, this.accountShow = false) :
(this.showAccountError = false, this.accountShow = false);
},
password(val) {
val.length > 0 ? (this.showPasswordError = false, this.passwordShow = false) :
(this.showPasswordError = false, this.passwordShow = false);
},
},
methods: {
accountFocus() {
if (this.account.length <= 0) {
this.accountShow = true;
this.accountAbove = true;
this.showAccountError = true;
}
},
accountBlur() {
if (this.account.length <= 0) {
this.accountShow = false;
this.accountAbove = false;
this.showAccountError = false;
}
},
passwordFocus() {
if (this.password.length <= 0) {
this.passwordShow = true;
this.passwordAbove = true;
this.showPasswordError = true;
}
},
passwordBlur() {
if (this.password.length <= 0) {
this.passwordShow = false;
this.passwordAbove = false;
this.showPasswordError = false;
}
},
async login() {
const payload = {
account: this.account,
password: this.password
};
try {
console.log(this.url);
const response = await fetch(this.url, {
method: "POST",
mode: "cors",
cache: "default",
headers: {
'Content-Type': 'application/json; charset=utf-8'
},
credentials: 'include',
body: JSON.stringify(payload)
});
const data = await response.json();
console.log(data);
} catch (err) {
console.error(err);
}
}
}
})
</script>
<template>
<div class="login-from">
<p class="title">{{ welcome }}</p>
<form @submit.prevent="login">
<div class="account">
<div class="form-field" :class="{ 'form-field-error': showAccountError }">
<div class="form-control">
<div>
<input
v-model="account"
@focus="accountFocus"
@blur="accountBlur"
class="account-input"
type="text"
name="account"
id="account"
autocomplete="off"
required
/>
<label
class="floating-label"
:class="{ 'floating-label-above': accountAbove, 'floating-label-error': showAccountError }"
for="account"
>邮箱/手机号码</label
>
</div>
</div>
</div>
<div v-if="showAccountError" class="floating-label-error">请输入账号</div>
</div>
<div class="password">
<div class="form-field" :class="{ 'form-field-error': showPasswordError }">
<div class="form-control">
<div>
<input
v-model="password"
@focus="passwordFocus"
@blur="passwordBlur"
class="password-input"
type="password"
name="password"
id="password"
autocomplete="off"
required
/>
<label
class="floating-label"
:class="{ 'floating-label-above': passwordAbove, 'floating-label-error': showPasswordError }"
for="password"
>密码</label
>
</div>
</div>
</div>
<div v-if="showPasswordError" class="floating-label-error">请输入密码</div>
</div>
<div class="accept-terms">
<label for="agreement" class="accept">
<span class="agreement-checkbox">
<input
class="accept-checkbox-input"
type="checkbox"
name="agreement"
id="agreement"
/>
<span class="agreement-inner"></span>
</span>
<span class="accept-text"
>已阅读并同意小米账号<span>用户协议</span><span>隐私政策</span></span
>
</label>
</div>
<button class="login-button" type="submit">登录</button>
<div class="form-action">
<div class="form-action-start">忘记密码?</div>
<div class="form-action-end">手机号登录</div>
</div>
</form>
</div>
</template>
<style scoped>
* {
box-sizing: border-box;
}
.title {
color: #000;
text-align: center;
}
.login-from {
width: 400px;
padding: 20px;
border-radius: 4px;
box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.7);
}
.password,
.account {
width: 360px;
margin: 10px auto;
}
.password-input,
.account-input {
background-color: rgba(0, 0, 0, 0);
height: 60px;
width: 100%;
padding: 30px 20px 10px;
display: block;
border-width: 0;
}
.password-input:focus-visible,
.account-input:focus-visible {
outline-color: rgb(255, 92, 0);
}
.form-field {
background-color: rgb(249, 249, 249);
/* background-color: #000; */
position: relative;
border-radius: 4px;
overflow: hidden;
transform: all 0.1s ease;
}
.form-field-error {
background-color: rgb(252, 242, 243);
}
.form-control {
position: relative;
}
.floating-label {
position: absolute;
top: 20px;
left: 20px;
font-size: 17px;
height: 20px;
line-height: 20px;
transition: all 0.15s ease-in-out 0.15s;
}
.floating-label-above {
top: 10px;
font-size: 12px;
color: #aaa;
}
.floating-label-error {
color: red;
}
.form-helper {
font-size: 12px;
color: red;
}
.accept-terms {
height: 25px;
line-height: 20px;
}
.accept {
top: 20px;
color: #aaa;
font-size: 14px;
cursor: pointer;
line-height: 20px;
display: inline-flex;
}
.accept>span {
display: block;
}
.agreement-checkbox {
position: relative;
height: 20px;
width: 20px;
line-height: 1;
}
.accept-checkbox-input {
background-color: rgba(0, 0, 0, 0);
border-color: transparent;
position: absolute;
height: 100%;
width: 100%;
z-index: 1;
}
.agreement-inner {
position: absolute;
display: block;
/* height: 20px; */
width: 20px;
top: 0;
left: 0;
bottom: 0;
right: 0;
border: 1px solid #ddd;
border-radius: 4px;
}
.accept-text {
padding-left: 4px;
padding-right: 4px;
display: block;
}
.form-action {
display: block;
}
.form-action::after {
content: "";
display: block;
clear: both;
}
.form-action-start {
float: left;
}
.form-action-end {
float: right;
}
.login-button {
width: 100%;
padding: 10px;
height: 60px;
margin-top: 10px;
margin-bottom: 10px;
border-width: 0;
background-color: #ff5c02;
border-radius: 4px;
font-size: 18px;
color: rgba(255, 255, 255);
cursor: pointer;
}
.login-button:hover {
opacity: 0.9;
}
</style>

View File

@ -0,0 +1,25 @@
<template>
<svg
t="1726497206660"
class="icon"
viewBox="0 0 1032 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
p-id="1670"
width="200"
height="200"
>
<path
d="M606.901081 722.142411c-8.861629 0-17.763416-2.91818-25.192726-8.901787L361.854295 535.834033c-17.254742-13.934978-19.958743-39.208021-6.037152-56.47615 13.934978-17.268128 39.208021-19.958743 56.47615-6.037151l219.854059 177.406591c17.254742 13.921592 19.958743 39.208021 6.037152 56.476149-7.937984 9.825431-19.557159 14.938939-31.283423 14.938939z"
p-id="1671"
></path>
<path
d="M387.100566 544.709047c-12.181393 0-24.228924-5.528478-32.113364-16.00983-13.332601-17.723257-9.785273-42.902597 7.937985-56.235199l219.867445-165.479535c17.723257-13.332601 42.902597-9.785273 56.235199 7.937985 13.332601 17.723257 9.785273 42.902597-7.937984 56.235198L411.222401 536.637201a39.95363 39.95363 0 0 1-24.121835 8.071846z"
p-id="1672"
></path>
<path
d="M516.424121 1024c-69.648117 0-137.248154-13.520007-200.899277-40.198596-61.482568-25.768331-116.713806-62.647163-164.127534-109.632535-47.440501-46.998758-84.694145-101.761481-110.730199-162.735375C13.680641 648.2375 0 581.146136 0 511.993307S13.680641 375.749114 40.653725 312.566506c26.036054-60.987281 63.289698-115.736617 110.730199-162.735375 47.413729-46.971986 102.644966-83.864204 164.127534-109.632535C379.175968 13.520007 446.762618 0 516.424121 0s137.248154 13.520007 200.899277 40.198596c61.495954 25.768331 116.713806 62.647163 164.127535 109.632535 47.440501 46.998758 84.707531 101.761481 110.730198 162.735375 26.973084 63.182608 40.653725 130.273972 40.653725 199.426801s-13.680641 136.244193-40.653725 199.426801c-26.036054 60.987281-63.289698 115.736617-110.730198 162.735375-47.413729 46.971986-102.63158 83.864204-164.127535 109.632535-63.651124 26.678589-131.25116 40.198596-200.899277 40.198596z m0-943.683125C275.955397 80.316875 80.316875 273.974247 80.316875 511.993307s195.638522 431.676432 436.107246 431.676432 436.107246-193.657372 436.107246-431.676432S756.879459 80.316875 516.424121 80.316875z"
p-id="1673"
></path>
</svg>
</template>

View File

@ -0,0 +1,25 @@
<template>
<svg
t="1726496829251"
class="icon"
viewBox="0 0 1032 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
p-id="1515"
width="200"
height="200"
>
<path
d="M516.424121 1024c-69.648117 0-137.248154-13.520007-200.899277-40.198596-61.482568-25.768331-116.713806-62.647163-164.127534-109.632535-47.440501-46.998758-84.694145-101.761481-110.730199-162.735375C13.680641 648.2375 0 581.146136 0 511.993307S13.680641 375.749114 40.653725 312.566506c26.036054-60.987281 63.289698-115.736617 110.730199-162.735375 47.413729-46.971986 102.644966-83.864204 164.127534-109.632535C379.175968 13.520007 446.762618 0 516.424121 0s137.248154 13.520007 200.899277 40.198596c61.495954 25.768331 116.713806 62.647163 164.127535 109.632535 47.440501 46.998758 84.707531 101.761481 110.730198 162.735375 26.973084 63.182608 40.653725 130.273972 40.653725 199.426801s-13.680641 136.244193-40.653725 199.426801c-26.036054 60.987281-63.289698 115.736617-110.730198 162.735375-47.413729 46.971986-102.63158 83.864204-164.127535 109.632535-63.651124 26.678589-131.25116 40.198596-200.899277 40.198596z m0-943.683125C275.955397 80.316875 80.316875 273.974247 80.316875 511.993307s195.638522 431.676432 436.107246 431.676432 436.107246-193.657372 436.107246-431.676432S756.879459 80.316875 516.424121 80.316875z"
p-id="1516"
></path>
<path
d="M655.091206 557.225094c-8.861629 0-17.763416-2.91818-25.192726-8.901787L410.04442 370.916716c-17.254742-13.921592-19.958743-39.208021-6.037152-56.47615 13.934978-17.254742 39.208021-19.958743 56.47615-6.037151l219.854059 177.406591c17.254742 13.921592 19.958743 39.208021 6.037152 56.476149-7.937984 9.825431-19.557159 14.938939-31.283423 14.938939z"
p-id="1517"
></path>
<path
d="M435.304077 722.731401c-12.181393 0-24.228924-5.528478-32.113364-16.00983-13.332601-17.723257-9.785273-42.902597 7.937985-56.235199l219.867446-165.479535c17.723257-13.332601 42.902597-9.785273 56.235198 7.937984 13.332601 17.723257 9.785273 42.902597-7.937984 56.235199L459.425912 714.659555a39.95363 39.95363 0 0 1-24.121835 8.071846z"
p-id="1518"
></path>
</svg>
</template>

View File

@ -1,9 +1,9 @@
<script setup>
import TheWelcome from '../components/TheWelcome.vue'
import CustomCalendar from '../components/CustomCalendar.vue'
</script>
<template>
<main>
<TheWelcome />
<CustomCalendar />
</main>
</template>