first commit

This commit is contained in:
chorblack 2025-04-22 20:58:44 +08:00
commit ac114a5f10
18 changed files with 716 additions and 0 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

26
app.ux Normal file
View File

@ -0,0 +1,26 @@
<script>
/**
* 应用级别的配置,供所有页面公用
*/
import device from '@blueos.hardware.deviceInfo'
export default {
onCreate() {
device.getInfo({
success: (res) => {
this.setScreenShape(res.model);
},
fail: function () {},
});
},
setScreenShape(shape) {
this.screenShape = shape;
console.log(shape)
},
onDestroy() {
console.info("Application onDestroy");
}
};
</script>

BIN
assets/.DS_Store vendored Normal file

Binary file not shown.

BIN
assets/images/.DS_Store vendored Normal file

Binary file not shown.

BIN
assets/images/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -0,0 +1,5 @@
@mixin flex-box-mixins($direction: row, $justify: center, $align-items: center) {
flex-direction: $direction;
justify-content: $justify;
align-items: $align-items;
}

2
assets/styles/style.scss Normal file
View File

@ -0,0 +1,2 @@
@import './variables.scss';
@import './mixins.scss';

View File

@ -0,0 +1,9 @@
$brand: #09ba07;
$white: #ffffff;
$black: #000000;
$grey: #9393aa;
$red: #fa0101;
$green: #ffff00;
$size-factor: 5px;

BIN
common/logo-256.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
common/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

1
common/utils/dayjs.js Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,16 @@
/**
* @param {any} year
* @param {any} month
* @param {any} day
*/
function getDateComponents (year, month, day) {
const date = new Date(year, month - 1, day); // 月份从 0 开始
return {
year: date.getFullYear(),
month: date.getMonth() + 1, // 月份从 0 开始
day: date.getDate(),
};
}
export default getDateComponents ;

View File

@ -0,0 +1,23 @@
{
"正月初一": "春节",
"正月十五": "元宵节",
"五月初五": "端午节",
"七月初七": "七夕节",
"七月十五": "中元节",
"八月十五": "中秋节",
"九月初九": "重阳节",
"腊月初八": "腊八节",
"腊月廿三": "小年",
"腊月三十": "除夕",
"1.1": "元旦",
"2.14": "情人节",
"3.8": "妇女节",
"3.12": "植树节",
"4.1": "愚人节",
"5.1": "劳动节",
"5.4": "青年节",
"6.1": "儿童节",
"9.10": "教师节",
"10.1": "国庆节",
"12.25": "圣诞节"
}

View File

@ -0,0 +1,183 @@
/*
1建立农历年份查询表
2计算输入公历日期与公历基准的相差天数
3从农历基准开始遍历农历查询表计算自农历基准之后每一年的天数并用相差天数依次相减确定农历年份
4利用剩余相差天数以及农历每个月的天数确定农历月份
5利用剩余相差天数确定农历哪一天 */
// 农历1949-2100年查询表
let lunarYearArr = [
0x0b557, //1949
0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5b0, 0x14573, 0x052b0, 0x0a9a8, 0x0e950, 0x06aa0, //1950-1959
0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, //1960-1969
0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b6a0, 0x195a6, //1970-1979
0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570, //1980-1989
0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x055c0, 0x0ab60, 0x096d5, 0x092e0, //1990-1999
0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5, //2000-2009
0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, //2010-2019
0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530, //2020-2029
0x05aa0, 0x076a3, 0x096d0, 0x04afb, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, //2030-2039
0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0, //2040-2049
0x14b63, 0x09370, 0x049f8, 0x04970, 0x064b0, 0x168a6, 0x0ea50, 0x06b20, 0x1a6c4, 0x0aae0, //2050-2059
0x0a2e0, 0x0d2e3, 0x0c960, 0x0d557, 0x0d4a0, 0x0da50, 0x05d55, 0x056a0, 0x0a6d0, 0x055d4, //2060-2069
0x052d0, 0x0a9b8, 0x0a950, 0x0b4a0, 0x0b6a6, 0x0ad50, 0x055a0, 0x0aba4, 0x0a5b0, 0x052b0, //2070-2079
0x0b273, 0x06930, 0x07337, 0x06aa0, 0x0ad50, 0x14b55, 0x04b60, 0x0a570, 0x054e4, 0x0d160, //2080-2089
0x0e968, 0x0d520, 0x0daa0, 0x16aa6, 0x056d0, 0x04ae0, 0x0a9d4, 0x0a2d0, 0x0d150, 0x0f252, //2090-2099
0x0d520 //2100
],
lunarMonth = ['正', '二', '三', '四', '五', '六', '七', '八', '九', '十', '冬', '腊'],
lunarDay = ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十', '初', '廿'],
tianGan = ['甲', '乙', '丙', '丁', '戊', '己', '庚', '辛', '壬', '癸'],
diZhi = ['子', '丑', '寅', '卯', '辰', '巳', '午', '未', '申', '酉', '戌', '亥'];
// 公历转农历函数
function sloarToLunar(sy, sm, sd) {
// 输入的月份减1处理
sm -= 1;
// 计算与公历基准的相差天数
// Date.UTC()返回的是距离公历1970年1月1日的毫秒数,传入的月份需要减1
let daySpan = (Date.UTC(sy, sm, sd) - Date.UTC(1949, 0, 29)) / (24 * 60 * 60 * 1000) + 1;
let ly, lm, ld;
// 确定输出的农历年份
for (let j = 0; j < lunarYearArr.length; j++) {
daySpan -= lunarYearDays(lunarYearArr[j]);
if (daySpan <= 0) {
ly = 1949 + j;
// 获取农历年份确定后的剩余天数
daySpan += lunarYearDays(lunarYearArr[j]);
break
}
}
// 确定输出的农历月份
for (let k = 0; k < lunarYearMonths(lunarYearArr[ly - 1949]).length; k++) {
daySpan -= lunarYearMonths(lunarYearArr[ly - 1949])[k];
if (daySpan <= 0) {
// 有闰月时月份的数组长度会变成13因此当闰月月份小于等于k时lm不需要加1
if (hasLeapMonth(lunarYearArr[ly - 1949]) && hasLeapMonth(lunarYearArr[ly - 1949]) <= k) {
if (hasLeapMonth(lunarYearArr[ly - 1949]) < k) {
lm = k;
} else if (hasLeapMonth(lunarYearArr[ly - 1949]) === k) {
lm = '闰' + k;
} else {
lm = k + 1;
}
} else {
lm = k + 1;
}
// 获取农历月份确定后的剩余天数
daySpan += lunarYearMonths(lunarYearArr[ly - 1949])[k];
break
}
}
// 确定输出农历哪一天
ld = daySpan;
// 将计算出来的农历月份转换成汉字月份,闰月需要在前面加上闰字
if (hasLeapMonth(lunarYearArr[ly - 1949]) && (typeof (lm) === 'string' && lm.indexOf('闰') > -1)) {
lm = `${lunarMonth[/\d/.exec(lm) - 1]}`
} else {
lm = lunarMonth[lm - 1];
}
// 将计算出来的农历年份转换为天干地支年
ly = getTianGan(ly) + getDiZhi(ly);
// 将计算出来的农历天数转换成汉字
if (ld < 11) {
ld = `${lunarDay[10]}${lunarDay[ld-1]}`
} else if (ld > 10 && ld < 20) {
ld = `${lunarDay[9]}${lunarDay[ld-11]}`
} else if (ld === 20) {
ld = `${lunarDay[1]}${lunarDay[9]}`
} else if (ld > 20 && ld < 30) {
ld = `${lunarDay[11]}${lunarDay[ld-21]}`
} else if (ld === 30) {
ld = `${lunarDay[2]}${lunarDay[9]}`
}
// console.log(ly, lm, ld);
return {
lunarYear: ly,
lunarMonth: lm,
lunarDay: ld,
}
}
// 计算农历年是否有闰月参数为存储农历年的16进制
// 农历年份信息用16进制存储其中16进制的最后1位可以用于判断是否有闰月
function hasLeapMonth(ly) {
// 获取16进制的最后1位需要用到&与运算符
if (ly & 0xf) {
return ly & 0xf
} else {
return false
}
}
// 如果有闰月计算农历闰月天数参数为存储农历年的16进制
// 农历年份信息用16进制存储其中16进制的第1位0x除外可以用于表示闰月是大月还是小月
function leapMonthDays(ly) {
if (hasLeapMonth(ly)) {
// 获取16进制的第1位0x除外
return (ly & 0xf0000) ? 30 : 29
} else {
return 0
}
}
// 计算农历一年的总天数参数为存储农历年的16进制
// 农历年份信息用16进制存储其中16进制的第2-4位0x除外可以用于表示正常月是大月还是小月
function lunarYearDays(ly) {
let totalDays = 0;
// 获取正常月的天数,并累加
// 获取16进制的第2-4位需要用到>>移位运算符
for (let i = 0x8000; i > 0x8; i >>= 1) {
let monthDays = (ly & i) ? 30 : 29;
totalDays += monthDays;
}
// 如果有闰月,需要把闰月的天数加上
if (hasLeapMonth(ly)) {
totalDays += leapMonthDays(ly);
}
return totalDays
}
// 获取农历每个月的天数
// 参数需传入16进制数值
function lunarYearMonths(ly) {
let monthArr = [];
// 获取正常月的天数并添加到monthArr数组中
// 获取16进制的第2-4位需要用到>>移位运算符
for (let i = 0x8000; i > 0x8; i >>= 1) {
monthArr.push((ly & i) ? 30 : 29);
}
// 如果有闰月,需要把闰月的天数加上
if (hasLeapMonth(ly)) {
monthArr.splice(hasLeapMonth(ly), 0, leapMonthDays(ly));
}
return monthArr
}
// 将农历年转换为天干,参数为农历年
function getTianGan(ly) {
let tianGanKey = (ly - 3) % 10;
if (tianGanKey === 0) tianGanKey = 10;
return tianGan[tianGanKey - 1]
}
// 将农历年转换为地支,参数为农历年
function getDiZhi(ly) {
let diZhiKey = (ly - 3) % 12;
if (diZhiKey === 0) diZhiKey = 12;
return diZhi[diZhiKey - 1]
}
export default sloarToLunar

44
manifest.json Normal file
View File

@ -0,0 +1,44 @@
{
"package": "top.chorblack.calendar",
"name": "日历",
"versionName": "2.0.1",
"versionCode": 3,
"appCategory": [
"other"
],
"icon": "/assets/images/logo.png",
"features": [
{
"name": "blueos.app.appmanager.router"
},
{
"name": "blueos.hardware.deviceInfo"
}
],
"deviceTypeList": [
"watch",
"watch-square"
],
"config": {
"designWidth": 466
},
"router": {
"entry": "pages/index",
"pages": {
"pages/index": {
"component": "index"
},
"pages/detail": {
"component": "index"
}
}
},
"display": {
"backgroundColor": "#000000"
},
"permissions": [
{
"name": "watch.permission.DEVICE_INFO"
}
]
}

BIN
pages/.DS_Store vendored Normal file

Binary file not shown.

121
pages/detail/index.ux Normal file
View File

@ -0,0 +1,121 @@
<template>
<div class="detail-page" @swipe="goBack">
<text>{{ year }}年{{ formattedMonth }}月{{ day }}日</text>
<text if="{{!!week}}">周{{ week }}</text>
<text if="{{!!lunarYear}}">
{{ lunarYear }}年 {{ lunarMonth }}月 {{ lunarDay }}
</text>
<text>{{ festival }}</text>
</div>
</template>
<script>
import router from "@blueos.app.appmanager.router";
import sloarToLunar from "../../common/utils/sloarToLunar";
export default {
data: {
year: "",
month: "",
day: "",
week: null,
lunarYear: null,
lunarMonth: null,
lunarDay: null,
festival: "",
formattedMonth: '',
gregorianFestival: { //阳历
"1.1": "元旦",
"2.14": "情人节",
"3.8": "妇女节",
"3.12": "植树节",
"4.1": "愚人节",
"5.1": "劳动节",
"5.4": "青年节",
"6.1": "儿童节",
"9.10": "教师节",
"10.1": "国庆节",
"12.25": "圣诞节"
},
lunarFestival: { //阴历
"正月初一": "春节",
"正月十五": "元宵节",
"五月初五": "端午节",
"七月初七": "七夕节",
"七月十五": "中元节",
"八月十五": "中秋节",
"九月初九": "重阳节",
"腊月初八": "腊八节",
"腊月廿三": "小年",
"腊月三十": "除夕",
}
},
onInit() {
const { year, month, day } = this;
this.year = parseInt(year); // 转换为整数
this.month = parseInt(month); // 转换为整数
this.day = parseInt(day); // 转换为整数
const { lunarYear, lunarMonth, lunarDay } = sloarToLunar(this.year, this.month, this.day);
this.lunarYear = lunarYear;
this.lunarMonth = lunarMonth;
this.lunarDay = lunarDay;
this.getWeek();
this.formattedMonth = this.month < 10 ? `0${this.month}` : this.month;
const lunar = `${lunarMonth}月${lunarDay}`;
if (this.lunarFestival.hasOwnProperty(lunar)) {
this.festival = this.lunarFestival[lunar];
}
const solar = `${this.month}.${this.day}`;
if (this.gregorianFestival.hasOwnProperty(solar)) {
this.festival = this.gregorianFestival[solar];
}
},
getWeek() {
const { year, month, day } = this;
const weeks = ["日", "一", "二", "三", "四", "五", "六"];
const weekIndex = new Date(year, month - 1, day).getDay();
this.week = weeks[weekIndex];
},
backClick() {
router.back();
},
goBack(eve) {
if (eve.direction === "right") {
router.back();
}
},
};
</script>
<style>
.detail-page {
width: 100%;
height: 100%;
border-radius: 240px;
flex-direction: column;
align-items: center;
justify-content: center;
}
text {
font-size: 40px;
font-weight: 700;
color: #fff;
}
.container {
position: absolute;
left: 0;
right: 0;
bottom: 40px;
justify-content: center;
padding: 10px;
color: white;
border-radius: 20px;
margin: 0px 20px 0px 20px;
background-color: grey;
}
</style>

286
pages/index/index.ux Normal file
View File

@ -0,0 +1,286 @@
<template>
<div class="home-page" @swipe="handleSwipe">
<div class="header">
<div class="year-month">
<text class="title" style="color: white;">{{ year }}年</text>
<text class="title" style="color: white;">{{ formattedMonth }}月</text>
</div>
<div class="week-head">
<text class="week-text weekend">日</text>
<text class="week-text">一</text>
<text class="week-text">二</text>
<text class="week-text">三</text>
<text class="week-text">四</text>
<text class="week-text">五</text>
<text class="week-text weekend">六</text>
</div>
<div class="divider"></div>
</div>
<div class="list">
<div for="row in list" class="item" style="height: {{height}}">
<div class="cell" for="cell in row" tid="id">
<text @click="handleClick(cell)" class="{{cell.className}}">
{{ cell.value }}
</text>
</div>
</div>
</div>
</div>
</template>
<script>
import router from "@blueos.app.appmanager.router";
import app from '@blueos.app.context';
export default {
data: {
date: new Date(),
year: "",
month: "",
list: null,
height: "50px",
formattedMonth: '',// 用于存储格式化后的月份
index: 0,
},
onInit() {
this.initList();
this.getCalendar();
this.formattedMonth = this.month < 10 ? `0${this.month}` : this.month;
},
initList() {
let list = [];
for (let i = 0; i < 5; i++) {
let initArray = new Array(7).fill("x").map((_) => {
return {
value: "",
className: "",
};
});
list.push(initArray);
}
this.list = list;
},
backClick() {
app.terminate();
},
isToday(yy, mm, dd) {
const date = new Date();
const year = date.getFullYear();
const month = date.getMonth() + 1;
const day = date.getDate();
return yy === year && mm === month && dd === day;
},
getCalendar() {
const date = new Date();
const year = date.getFullYear();
const month = date.getMonth();
// 获取当月第一天为周几
const firstDay = new Date(year, month + this.index, 1).getDay();
// 获取当月的天数
const days = new Date(year, month + 1 + this.index, 0).getDate();
const monthOffset = month + this.index;
this.month = ((monthOffset % 12) + 12) % 12 + 1; // 确保月份在 1-12 之间
this.year = year + Math.floor(monthOffset / 12); // 更新年份
const rows = Math.ceil((days + firstDay) / 7);
this.updateListRows(rows);
this.height = 300 / rows + "px";
/**
* 更新日历:
* 1. 从当月第一天开始,根据总天数来进行更新
* 2. 前面的空白和后面的空白用“”来填充
* 3. 样式为“”或者“today”
*/
let count = 1;
for (let i = 0; i < rows; i++) {
for (let j = 0; j < 7; j++) {
if (j === 0 || j === 6) {
this.list[i][j].className = "cell-text-weekend";
} else {
this.list[i][j].className = "cell-text-workday";
}
if (i === 0 && j < firstDay) {
this.list[i][j].value = "";
continue;
}
if (count > days) {
this.list[i][j].value = "";
continue;
}
this.list[i][j].value = count;
this.list[i][j].id = "" + this.year + this.month + count;
if (this.isToday(this.year, this.month, count)) {
this.list[i][j].className = "cell-text-today";
}
count += 1;
}
}
},
updateListRows(rows) {
while (this.list.length < rows) {
let initArray = new Array(7).fill("x").map((_) => {
return {
value: "",
className: "",
};
});
this.list.push(initArray);
}
while (this.list.length > rows) {
this.list.pop();
}
},
prevMonth() {
this.date = new Date(this.year, this.month - 1 + this.index, 0);
this.getCalendar();
this.formattedMonth = this.month < 10 ? `0${this.month}` : this.month;
},
nextMonth() {
this.date = new Date(this.year, this.month + 1 + this.index, 0);
this.getCalendar();
this.formattedMonth = this.month < 10 ? `0${this.month}` : this.month;
},
handleClick(item) {
if (item.value === "") return;
router.push({
uri: "pages/detail",
params: {
year: this.year,
month: this.month,
day: item.value,
},
});
},
handleSwipe(eve) {
console.log(eve);
if (eve.direction == "up") {
this.index++;
this.nextMonth();
} else if (eve.direction == "down") {
this.index--;
this.prevMonth();
}
},
};
</script>
<style>
.home-page {
width: 100%;
height: 100%;
border-radius: 240px;
flex-direction: column;
align-items: center;
}
.header {
width: 100%;
height: 110px;
margin-top: 20px;
flex-direction: column;
justify-content: space-between;
align-items: center;
}
.year-month {
width: 240px;
height: 60px;
justify-content: center;
align-items: center;
}
.title {
font-weight: 700;
font-size: 40px;
}
.red {
color: #f00;
}
.week-head {
width: 100%;
justify-content: center;
align-items: center;
}
.week-text {
width: 64px;
font-size: 40px;
font-weight: 700;
color: rgb(255, 255, 255);
text-align: center;
}
.weekend {
color: rgba(255, 255, 255, 0.6);
}
.divider {
width: 100%;
height: 2px;
margin-top: 4px;
background-color: rgba(255, 255, 255, 0.3);
}
.list {
width: 100%;
height: 350px;
flex-direction: column;
}
.item {
width: 100%;
height: 80px; /* 增加每一行的高度 */
margin-bottom: 10px; /* 增加行与行之间的间距 */
}
.cell {
width: 64px;
height: 100%;
}
.cell-text-workday {
width: 100%;
height: 100%;
font-weight: 700;
font-size: 40px; /* 调整为你需要的大小 */
text-align: center;
color: rgb(255, 255, 255);
background-color: transparent;
}
.cell-text-weekend {
width: 100%;
height: 100%;
font-weight: 700;
font-size: 40px; /* 调整为你需要的大小 */
text-align: center;
color: rgba(255, 255, 255, 0.6);
background-color: transparent;
}
.cell-text-today {
width: 100%;
height: 100%;
font-weight: 700;
text-align: center;
color: rgba(255, 255, 255, 1);
background-color: #ff3a3a;
}
</style>