commit
1eeb944be6
17 changed files with 806 additions and 0 deletions
@ -0,0 +1 @@ |
|||
unpackage |
@ -0,0 +1,46 @@ |
|||
<script lang="uts"> |
|||
let firstBackTime = 0 |
|||
export default { |
|||
onLaunch: function () { |
|||
console.log('App Launch') |
|||
}, |
|||
onShow: function () { |
|||
console.log('App Show') |
|||
}, |
|||
onHide: function () { |
|||
console.log('App Hide') |
|||
}, |
|||
// #ifdef APP-ANDROID |
|||
onLastPageBackPress: function () { |
|||
console.log('App LastPageBackPress') |
|||
if (firstBackTime == 0) { |
|||
uni.showToast({ |
|||
title: '再按一次退出应用', |
|||
position: 'bottom', |
|||
}) |
|||
firstBackTime = Date.now() |
|||
setTimeout(() => { |
|||
firstBackTime = 0 |
|||
}, 2000) |
|||
} else if (Date.now() - firstBackTime < 2000) { |
|||
firstBackTime = Date.now() |
|||
uni.exit() |
|||
} |
|||
}, |
|||
// #endif |
|||
onExit: function () { |
|||
console.log('App Exit') |
|||
}, |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
/*每个页面公共css */ |
|||
.uni-row { |
|||
flex-direction: row; |
|||
} |
|||
|
|||
.uni-column { |
|||
flex-direction: column; |
|||
} |
|||
</style> |
Binary file not shown.
@ -0,0 +1,6 @@ |
|||
|
|||
@font-face { |
|||
font-family: ZhanKuKuaiLeTi; |
|||
src: url('@/assets/fonts/ZhanKuKuaiLeTi2016XiuDingBan-1.ttf'); |
|||
} |
|||
|
@ -0,0 +1,85 @@ |
|||
<template> |
|||
<view class="x-navbar"> |
|||
<x-status-bar></x-status-bar> |
|||
<view class="x-navbar__content"></view> |
|||
<view class="x-navbar__fixed"> |
|||
<x-status-bar></x-status-bar> |
|||
<view class="x-navbar__content"> |
|||
<view class="x-navbar__content__left"> |
|||
<slot name="left"></slot> |
|||
</view> |
|||
<view class="x-navbar__content__title"> |
|||
<slot></slot> |
|||
</view> |
|||
<view class="x-navbar__content__right"> |
|||
<slot name="right"></slot> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script setup> |
|||
const res = uni.getSystemInfoSync() |
|||
const statusBarHeight = ref(res.statusBarHeight) |
|||
const xNavbarStyle = computed(() => { |
|||
return { |
|||
height: statusBarHeight.value |
|||
} |
|||
}) |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
$navbar__height: 75rpx; |
|||
$navbar__bg: white; |
|||
$navbar__title__size: 35px; |
|||
$navbar__title__color: deeppink; |
|||
$navbar__title__family: cursive; |
|||
|
|||
.x-navbar { |
|||
|
|||
.x-status-bar { |
|||
background-color: $navbar__bg; |
|||
} |
|||
|
|||
.x-navbar__fixed { |
|||
position: fixed; |
|||
top: 0; |
|||
left: 0; |
|||
right: 0; |
|||
border-bottom: 1px solid #eaeaea; |
|||
|
|||
} |
|||
|
|||
.x-navbar__content { |
|||
height: $navbar__height; |
|||
background-color: $navbar__bg; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
position: relative; |
|||
|
|||
.x-navbar__content__title { |
|||
font-size: $navbar__title__size; |
|||
color: $navbar__title__color; |
|||
font-family: $navbar__title__family; |
|||
} |
|||
|
|||
&__left { |
|||
position: absolute; |
|||
left: 0; |
|||
height: 100%; |
|||
align-items: center; |
|||
justify-content: center; |
|||
} |
|||
|
|||
&__right { |
|||
position: absolute; |
|||
right: 0; |
|||
height: 100%; |
|||
align-items: center; |
|||
justify-content: center; |
|||
} |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,35 @@ |
|||
<template> |
|||
<view class="x-page"> |
|||
<!-- #ifdef APP --> |
|||
<scroll-view class="x-page__page" :show-scrollbar="false"> |
|||
<!-- #endif --> |
|||
<slot></slot> |
|||
<!-- #ifdef APP --> |
|||
</scroll-view> |
|||
<!-- #endif --> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: "x-page", |
|||
data() { |
|||
return { |
|||
|
|||
}; |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style> |
|||
.x-page { |
|||
display: flex; |
|||
flex-direction: column; |
|||
height: 100%; |
|||
} |
|||
|
|||
|
|||
.x-page__page { |
|||
height: 100%; |
|||
} |
|||
</style> |
@ -0,0 +1,20 @@ |
|||
<template> |
|||
<view class="x-status-bar" :style="xStatusBarStyle"></view> |
|||
</template> |
|||
|
|||
<script setup> |
|||
const res = uni.getSystemInfoSync() |
|||
const statusBarHeight = ref(res.statusBarHeight) |
|||
|
|||
const xStatusBarStyle = computed(() => { |
|||
return { |
|||
height: statusBarHeight.value |
|||
} |
|||
}) |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
.x-status-bar { |
|||
height: var(--status-bar-height); |
|||
} |
|||
</style> |
@ -0,0 +1,116 @@ |
|||
const primaryKey = "id"; |
|||
const allData: IItem[] = []; |
|||
|
|||
interface IItem { |
|||
id?: number; |
|||
timestamp: string; |
|||
[key: string]: any; // 允许任意其他字段 |
|||
} |
|||
interface IPartialItem { |
|||
id?: number; |
|||
timestamp?: string; |
|||
[key: string]: any; // 允许任意其他字段 |
|||
} |
|||
|
|||
let key = 0; |
|||
|
|||
// 添加记录 |
|||
function addRecord(data: IItem): IItem { |
|||
const id = data.id ?? ++key; |
|||
const existingIndex = allData.findIndex((v) => v.id === id); |
|||
|
|||
if (existingIndex === -1) { |
|||
const newRecord = { |
|||
id, |
|||
...data, |
|||
timestamp: data.timestamp || String(Date.now()) |
|||
}; |
|||
allData.push(newRecord); |
|||
return newRecord; |
|||
} else { |
|||
throw new Error(`Record with id ${id} already exists`); |
|||
} |
|||
} |
|||
|
|||
// 查询所有记录*- |
|||
function getAllRecords(): IItem[] { |
|||
return [...allData]; // 返回副本以避免外部修改 |
|||
} |
|||
|
|||
// 根据ID查询单条记录 |
|||
function getRecordById(id: number): IItem | undefined { |
|||
return allData.find((v) => v.id === id); |
|||
} |
|||
|
|||
// 更新记录 |
|||
function updateRecord(id: number, updates: IPartialItem): IItem | undefined { |
|||
const index = allData.findIndex((v) => v.id === id); |
|||
if (index !== -1) { |
|||
const updatedRecord = { |
|||
...allData[index], |
|||
...updates, |
|||
id // 确保ID不会被更新 |
|||
}; |
|||
allData[index] = updatedRecord; |
|||
return updatedRecord; |
|||
} |
|||
return undefined; |
|||
} |
|||
|
|||
// 删除记录 |
|||
function deleteRecord(id: number): boolean { |
|||
const index = allData.findIndex((v) => v.id === id); |
|||
if (index !== -1) { |
|||
allData.splice(index, 1); |
|||
return true; |
|||
} |
|||
return false; |
|||
} |
|||
|
|||
// 查询记录 (简单条件) |
|||
function queryRecords(conditions: IPartialItem): IItem[] { |
|||
return allData.filter(item => { |
|||
return Object.entries(conditions).every(([key, value]: any) => { |
|||
return item[key] === value; |
|||
}); |
|||
}); |
|||
} |
|||
|
|||
// 事务支持 |
|||
function transaction(operations: (() => void)[]): boolean { |
|||
const originalData = [...allData]; |
|||
try { |
|||
operations.forEach(op => op()); |
|||
return true; |
|||
} catch (error) { |
|||
// 回滚 |
|||
allData.length = 0; |
|||
allData.push(...originalData); |
|||
console.error('Transaction failed:', error); |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
// 示例使用 |
|||
try { |
|||
// 添加记录 |
|||
addRecord({ timestamp: String(Date.now()), name: 'Item 1', price: 100 }); |
|||
addRecord({ timestamp: String(Date.now()), name: 'Item 2', price: 200 }); |
|||
|
|||
// 更新记录 |
|||
transaction([ |
|||
() => updateRecord(1, { price: 150 }), |
|||
() => addRecord({ timestamp: String(Date.now()), name: 'Item 3' }) |
|||
]); |
|||
|
|||
// 查询 |
|||
const expensiveItems = queryRecords({ price: 200 }); |
|||
console.log(expensiveItems); |
|||
|
|||
// 删除 |
|||
deleteRecord(2); |
|||
|
|||
console.log(getAllRecords()); |
|||
} catch (error) { |
|||
console.error('Database operation failed:', error); |
|||
} |
@ -0,0 +1,20 @@ |
|||
<!DOCTYPE html> |
|||
<html lang="en"> |
|||
<head> |
|||
<meta charset="UTF-8" /> |
|||
<script> |
|||
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') || |
|||
CSS.supports('top: constant(a)')) |
|||
document.write( |
|||
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' + |
|||
(coverSupport ? ', viewport-fit=cover' : '') + '" />') |
|||
</script> |
|||
<title></title> |
|||
<!--preload-links--> |
|||
<!--app-context--> |
|||
</head> |
|||
<body> |
|||
<div id="app"><!--app-html--></div> |
|||
<script type="module" src="/main"></script> |
|||
</body> |
|||
</html> |
@ -0,0 +1,10 @@ |
|||
import App from './App.uvue' |
|||
import "@/assets/style/common.scss" |
|||
|
|||
import { createSSRApp } from 'vue' |
|||
export function createApp() { |
|||
const app = createSSRApp(App) |
|||
return { |
|||
app |
|||
} |
|||
} |
@ -0,0 +1,48 @@ |
|||
{ |
|||
"name": "uni-x", |
|||
"appid": "__UNI__D9CF915", |
|||
"description": "", |
|||
"versionName": "1.0.0", |
|||
"versionCode": "100", |
|||
"uni-app-x": {}, |
|||
/* 快应用特有相关 */ |
|||
"quickapp": {}, |
|||
/* 小程序特有相关 */ |
|||
"mp-weixin": { |
|||
"appid": "", |
|||
"setting": { |
|||
"urlCheck": false |
|||
}, |
|||
"usingComponents": true |
|||
}, |
|||
"mp-alipay": { |
|||
"usingComponents": true |
|||
}, |
|||
"mp-baidu": { |
|||
"usingComponents": true |
|||
}, |
|||
"mp-toutiao": { |
|||
"usingComponents": true |
|||
}, |
|||
"uniStatistics": { |
|||
"enable": false |
|||
}, |
|||
"vueVersion": "3", |
|||
"app": { |
|||
"distribute": { |
|||
"icons": { |
|||
"android": { |
|||
"hdpi": "", |
|||
"xhdpi": "", |
|||
"xxhdpi": "", |
|||
"xxxhdpi": "" |
|||
} |
|||
} |
|||
} |
|||
}, |
|||
"web": { |
|||
"router": { |
|||
"mode": "" |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,17 @@ |
|||
{ |
|||
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages |
|||
{ |
|||
"path": "pages/index/index", |
|||
"style": { |
|||
"navigationStyle": "custom" |
|||
} |
|||
} |
|||
], |
|||
"globalStyle": { |
|||
"navigationBarTextStyle": "black", |
|||
"navigationBarTitleText": "uni-app x", |
|||
"navigationBarBackgroundColor": "#F8F8F8", |
|||
"backgroundColor": "#F8F8F8" |
|||
}, |
|||
"uniIdRouter": {} |
|||
} |
@ -0,0 +1,222 @@ |
|||
<template> |
|||
<x-page> |
|||
<x-navbar> |
|||
<text class="navbar-text">LuMi</text> |
|||
</x-navbar> |
|||
<view class="tabs"> |
|||
<view class="tab"> |
|||
<text class="tab-text">{{nowYear}}年{{nowMonth}}月</text> |
|||
</view> |
|||
</view> |
|||
<view class="rili"> |
|||
<view class="grid"> |
|||
<view class="grid-item" :style="getGridItemStyle(day)" v-for="day in all" :key="day"> |
|||
<view class="grid-item-box"> |
|||
<view class="grid-item-content"> |
|||
<text class="grid-item-text" :style="getGridItemTextStyle(day)">{{ day.label }}</text> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<!-- <text class="clear" @click="click2" v-if="recordDate.length">清除所有</text> --> |
|||
<view class="list"> |
|||
<view class="item" v-for="(item, index) in recordDate"> |
|||
<text class="label">{{item.label}}</text> |
|||
<text class="close" @click="delIem(item, index)">x</text> |
|||
</view> |
|||
</view> |
|||
<view class="float-btn" @click="click"> |
|||
<text class="float-btn-text">打卡</text> |
|||
</view> |
|||
</x-page> |
|||
</template> |
|||
|
|||
<script setup> |
|||
import { getCurMonthDayNum, getCurrentMonth, formatFull, getLastMonth, getLastMonthDay, format, getWeek, getNextMonthDay, generateDate } from "@/utils/date.uts" |
|||
|
|||
type TItem = { label : string; value : Date; } |
|||
|
|||
const nowDate = ref(new Date()) |
|||
const nowYear = computed(() => { |
|||
return nowDate.value.getFullYear() |
|||
}) |
|||
const nowMonth = computed(() => { |
|||
return nowDate.value.getMonth() + 1 |
|||
}) |
|||
const recordDate = ref<TItem[]>([]) |
|||
|
|||
const all = computed(() => { |
|||
return generateDate<TItem>(format(nowDate.value), (v : Date) => ({ |
|||
label: v.getDate() + "", |
|||
value: v |
|||
})) |
|||
}) |
|||
|
|||
const isRecord = (date : Date) => { |
|||
let count = 0 |
|||
for (var i = 0; i < recordDate.value.length; i++) { |
|||
var item = recordDate.value[i]; |
|||
if (format(item.value) == format(date)) { |
|||
count++ |
|||
} |
|||
} |
|||
return count |
|||
} |
|||
|
|||
const isToday = (date : Date) => { |
|||
return format(nowDate.value) == format(date) |
|||
} |
|||
|
|||
const getGridItemStyle = (day : TItem) => { |
|||
const count = isRecord(day.value) |
|||
return { |
|||
backgroundColor: count ? `rgba(0, 0, 0, ${count * 0.2})` : 'rgba(0, 0, 0, 0.05)' |
|||
} |
|||
} |
|||
|
|||
const getGridItemTextStyle = (day : TItem) => { |
|||
const count = isRecord(day.value) |
|||
return { |
|||
color: count ? '#ffffff' : isToday(day.value) ? 'black' : 'rgba(0, 0, 0, .08)' |
|||
} |
|||
} |
|||
|
|||
const data = uni.getStorageSync("save") |
|||
if (Array.isArray(data as [])) { |
|||
let result : TItem[] = [] |
|||
for (let i = 0; i < data.length; i++) { |
|||
let v : number = data[i] as number |
|||
const date = new Date(v) |
|||
result.push({ |
|||
label: formatFull(date), |
|||
value: date |
|||
}) |
|||
} |
|||
recordDate.value = result |
|||
} else { |
|||
recordDate.value = [] |
|||
} |
|||
|
|||
const click2 = () => { |
|||
uni.removeStorageSync("save") |
|||
recordDate.value = [] |
|||
} |
|||
|
|||
const click = () => { |
|||
const date = new Date() |
|||
recordDate.value.unshift({ |
|||
label: formatFull(date), |
|||
value: date |
|||
} as TItem) |
|||
uni.setStorageSync("save", unref(recordDate).map(v => v.value.getTime())) |
|||
} |
|||
|
|||
const delIem = (item : TItem, index : number) => { |
|||
recordDate.value.splice(index, 1) |
|||
uni.setStorageSync("save", unref(recordDate)) |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.navbar-text { |
|||
font-size: 45rpx; |
|||
font-family: ZhanKuKuaiLeTi; |
|||
} |
|||
|
|||
.tabs { |
|||
display: flex; |
|||
flex-direction: row; |
|||
align-items: center; |
|||
justify-content: center; |
|||
padding: 25rpx 0 15rpx; |
|||
margin-left: -20rpx; |
|||
|
|||
.tab { |
|||
margin-left: 20rpx; |
|||
|
|||
.tab-text { |
|||
font-size: 45rpx; |
|||
font-family: ZhanKuKuaiLeTi; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.clear { |
|||
padding: 20rpx 100rpx; |
|||
} |
|||
|
|||
.list { |
|||
.item { |
|||
padding: 20rpx 100rpx; |
|||
flex-direction: row; |
|||
align-items: center; |
|||
|
|||
.label { |
|||
flex: 1; |
|||
width: 0; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.rili { |
|||
margin-top: -30rpx; |
|||
|
|||
.grid { |
|||
flex-direction: row; |
|||
flex-wrap: wrap; |
|||
justify-content: center; |
|||
margin-left: -30rpx; |
|||
margin-top: -30rpx; |
|||
padding: 30rpx 80rpx 0; |
|||
|
|||
.grid-item { |
|||
width: 55rpx; |
|||
margin-left: 30rpx; |
|||
margin-top: 30rpx; |
|||
border-radius: 15rpx; |
|||
background-color: rgba(0, 0, 0, 0.05); |
|||
|
|||
.grid-item-box { |
|||
padding-bottom: 100%; |
|||
position: relative; |
|||
|
|||
.grid-item-content { |
|||
position: absolute; |
|||
left: 0; |
|||
right: 0; |
|||
top: 0; |
|||
bottom: 0; |
|||
align-items: center; |
|||
justify-content: center; |
|||
|
|||
.grid-item-text { |
|||
color: rgba(0, 0, 0, .08); |
|||
font-size: 25rpx; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
.float-btn { |
|||
position: fixed; |
|||
z-index: 99; |
|||
left: 50%; |
|||
transform: translate(-50%); |
|||
bottom: 100rpx; |
|||
width: 100rpx; |
|||
height: 100rpx; |
|||
align-items: center; |
|||
justify-content: center; |
|||
border-radius: 100rpx; |
|||
background-color: white; |
|||
box-shadow: |
|||
0 2px 10px rgba(0, 0, 0, 0.1); |
|||
|
|||
.float-btn-text { |
|||
font-size: 25rpx; |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1 @@ |
|||
[](https://ext.dcloud.net.cn/plugin?id=16902) |
After Width: | Height: | Size: 3.9 KiB |
@ -0,0 +1,76 @@ |
|||
/** |
|||
* 这里是uni-app内置的常用样式变量 |
|||
* |
|||
* uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量 |
|||
* 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App |
|||
* |
|||
*/ |
|||
|
|||
/** |
|||
* 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能 |
|||
* |
|||
* 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件 |
|||
*/ |
|||
|
|||
/* 颜色变量 */ |
|||
|
|||
/* 行为相关颜色 */ |
|||
$uni-color-primary: #007aff; |
|||
$uni-color-success: #4cd964; |
|||
$uni-color-warning: #f0ad4e; |
|||
$uni-color-error: #dd524d; |
|||
|
|||
/* 文字基本颜色 */ |
|||
$uni-text-color:#333;//基本色 |
|||
$uni-text-color-inverse:#fff;//反色 |
|||
$uni-text-color-grey:#999;//辅助灰色,如加载更多的提示信息 |
|||
$uni-text-color-placeholder: #808080; |
|||
$uni-text-color-disable:#c0c0c0; |
|||
|
|||
/* 背景颜色 */ |
|||
$uni-bg-color:#ffffff; |
|||
$uni-bg-color-grey:#f8f8f8; |
|||
$uni-bg-color-hover:#f1f1f1;//点击状态颜色 |
|||
$uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色 |
|||
|
|||
/* 边框颜色 */ |
|||
$uni-border-color:#c8c7cc; |
|||
|
|||
/* 尺寸变量 */ |
|||
|
|||
/* 文字尺寸 */ |
|||
$uni-font-size-sm:12px; |
|||
$uni-font-size-base:14px; |
|||
$uni-font-size-lg:16px; |
|||
|
|||
/* 图片尺寸 */ |
|||
$uni-img-size-sm:20px; |
|||
$uni-img-size-base:26px; |
|||
$uni-img-size-lg:40px; |
|||
|
|||
/* Border Radius */ |
|||
$uni-border-radius-sm: 2px; |
|||
$uni-border-radius-base: 3px; |
|||
$uni-border-radius-lg: 6px; |
|||
$uni-border-radius-circle: 50%; |
|||
|
|||
/* 水平间距 */ |
|||
$uni-spacing-row-sm: 5px; |
|||
$uni-spacing-row-base: 10px; |
|||
$uni-spacing-row-lg: 15px; |
|||
|
|||
/* 垂直间距 */ |
|||
$uni-spacing-col-sm: 4px; |
|||
$uni-spacing-col-base: 8px; |
|||
$uni-spacing-col-lg: 12px; |
|||
|
|||
/* 透明度 */ |
|||
$uni-opacity-disabled: 0.3; // 组件禁用态的透明度 |
|||
|
|||
/* 文章场景相关 */ |
|||
$uni-color-title: #2C405A; // 文章标题颜色 |
|||
$uni-font-size-title:20px; |
|||
$uni-color-subtitle: #555555; // 二级标题颜色 |
|||
$uni-font-size-subtitle:26px; |
|||
$uni-color-paragraph: #3F536E; // 文章段落颜色 |
|||
$uni-font-size-paragraph:15px; |
@ -0,0 +1,103 @@ |
|||
|
|||
export function getWeek(time : Date) { |
|||
let week = time.getDay() // 当前周几 |
|||
// week = (week - 1) < 0 ? 0 : (week - 1) |
|||
if(week == 0) week = 7 // 0 表示周日 |
|||
return week |
|||
} |
|||
|
|||
export function getCurrentMonth(time : Date) : number { |
|||
let month = time.getMonth() + 1 |
|||
return month |
|||
} |
|||
|
|||
export function getLastMonth(curDate : Date) { |
|||
let lastDate = new Date() |
|||
lastDate.setMonth(curDate.getMonth() - 1) |
|||
return lastDate |
|||
} |
|||
|
|||
export function getLastMonthDay(curDate : Date, offset : number) { |
|||
let lastDate = new Date(curDate.getTime()) |
|||
lastDate.setHours(-24 * offset); |
|||
return lastDate |
|||
} |
|||
|
|||
export function getNextMonthDay(curDate : Date, offset : number) { |
|||
let lastDate = new Date(curDate.getTime()) |
|||
lastDate.setHours(24 * offset); |
|||
return lastDate |
|||
} |
|||
|
|||
|
|||
export function format(time : Date) { |
|||
return `${time.getFullYear()}-${time.getMonth() + 1}-${time.getDate()}` |
|||
} |
|||
|
|||
export function formatFull(time : Date) { |
|||
const year = (time.getFullYear()) + "" |
|||
const month = (time.getMonth() + 1) + "" |
|||
const date = (time.getDate()) + "" |
|||
const hour = (time.getHours()) + "" |
|||
const minute = (time.getMinutes()) + "" |
|||
const second = (time.getSeconds()) + "" |
|||
return `${year}-${month.padStart(2, '0')}-${date.padStart(2, '0')} ${hour.padStart(2, '0')}:${minute.padStart(2, '0')}:${second.padStart(2, '0')}` |
|||
} |
|||
|
|||
// 获取当前月份应该有多少天 |
|||
export function getCurMonthDayNum(time : Date) : number { |
|||
let day = 31; |
|||
let month = time.getMonth() + 1 |
|||
let year = time.getFullYear() |
|||
if ([1, 3, 5, 7, 8, 10, 12].indexOf(month) != -1) { |
|||
day = 31; |
|||
} else if ([4, 6, 9, 11].indexOf(month) != -1) { |
|||
day = 30; |
|||
} else if (year % 4 == 0) { |
|||
day = 29 |
|||
} else { |
|||
day = 28 |
|||
} |
|||
return day |
|||
} |
|||
|
|||
export function generateDate<T = Date>(_nowDate : Date | string | number, format : (date : Date) => T = (v : Date) => (v as T)) { |
|||
if (typeof _nowDate === "string" || typeof _nowDate === "number") { |
|||
_nowDate = new Date(_nowDate as string) |
|||
} |
|||
|
|||
const allDate : T[] = [] |
|||
|
|||
let firstDate = new Date(_nowDate.getTime()) |
|||
firstDate.setDate(1) |
|||
const firstWeek = getWeek(firstDate) |
|||
console.log(firstDate.getTime()); |
|||
for (var i = 1; i < firstWeek; i++) { |
|||
const date = getLastMonthDay(firstDate, i) |
|||
allDate.unshift(format(new Date(date.getTime())) as T) |
|||
} |
|||
|
|||
let curDate = new Date(_nowDate.getTime()) |
|||
const allDay = getCurMonthDayNum(curDate) |
|||
for (var i = 1; i <= getCurMonthDayNum(curDate); i++) { |
|||
curDate.setDate(i) |
|||
allDate.push(format(new Date(curDate.getTime())) as T) |
|||
} |
|||
|
|||
let endDate = new Date(_nowDate.getTime()) |
|||
endDate.setDate(allDay) |
|||
const endWeek = 7 - getWeek(endDate) |
|||
for (var i = 1; i <= endWeek; i++) { |
|||
const date = getNextMonthDay(endDate, i) |
|||
allDate.push(format(new Date(date.getTime())) as T) |
|||
} |
|||
// 至少6行 |
|||
if (~~(allDate.length / 7) < 6) { |
|||
for (var i = endWeek + 1; i < endWeek + 1 + 7; i++) { |
|||
const date = getNextMonthDay(endDate, i) |
|||
allDate.push(format(new Date(date.getTime())) as T) |
|||
} |
|||
} |
|||
|
|||
return allDate |
|||
} |
Loading…
Reference in new issue