Skip to content

Commit 0545944

Browse files
committed
增加倒计时组件
1 parent bdf8c46 commit 0545944

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+1337
-855
lines changed

README.md

+13
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,19 @@ pnpm widget create
6868
- 组件路由:/widget/birthday_list
6969
- 配置路由:/widget/config/birthday_list
7070

71+
#### 代办事项
72+
![gif](screenshot/todo.png)
73+
74+
- 代码路径:/widgets/todo-list
75+
- 组件路由:/widget/todo-list
76+
- 配置路由:/widget/config/todo-list
77+
78+
#### 倒计时
79+
![gif](screenshot/countdown.png)
80+
81+
- 代码路径:/widgets/countdown
82+
- 组件路由:/widget/countdown
83+
- 配置路由:/widget/config/countdown
7184

7285
#### 灵动通知
7386

auto-imports.d.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Generated by 'unplugin-auto-import'
22
export {}
33
declare global {
4-
const ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
4+
55
}

package.json

+4-3
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@
3131
"@vueuse/integrations": "^9.6.0",
3232
"@vueuse/motion": "2.0.0-beta.12",
3333
"@vueuse/router": "^9.9.0",
34-
"@widget-js/core": "^0.1.19",
35-
"@widget-js/vue3": "^0.1.20",
34+
"@widget-js/core": "^0.1.20",
35+
"@widget-js/vue3": "^0.1.21",
3636
"animate.css": "^4.1.1",
3737
"axios": "^1.1.3",
3838
"color": "^4.2.3",
@@ -47,7 +47,8 @@
4747
"pinia": "^2.0.23",
4848
"vue": "^3.2.30",
4949
"vue-i18n": "^9.2.2",
50-
"vue-router": "^4.0.3"
50+
"vue-router": "^4.0.3",
51+
"vue-scroll-picker": "^1.1.3"
5152
},
5253
"devDependencies": {
5354
"@babel/core": "^7.20.2",

public/audio/ding.mp3

15.6 KB
Binary file not shown.

screenshot/countdown.png

37.9 KB
Loading

screenshot/todo.png

86 KB
Loading

script/scanWidgetPackage.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import fs from "fs";
22
import path from "path";
3-
import scanWidgets from "./scanWidgets";
3+
// import scanWidgets from "./scanWidgets";
44

55

66
const scanWidgetPackage = () => {
@@ -9,9 +9,9 @@ const scanWidgetPackage = () => {
99
if (!widgetPackage["widgets"]) {
1010
widgetPackage["widgets"] = [];
1111
}
12-
scanWidgets().forEach((it) => {
13-
widgetPackage["widgets"].push(it);
14-
})
12+
// scanWidgets().forEach((it) => {
13+
// widgetPackage["widgets"].push(it);
14+
// })
1515
return widgetPackage;
1616
}
1717

src/components/DatePickerDialog.vue

+94
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
<template>
2+
<div class="picker-group">
3+
<el-dialog v-model="visibleModel" :show-close="false" @opened="opened = true" @closed="opened= false">
4+
<template #header="{ close, titleId, titleClass }">
5+
<div class="header">
6+
<el-radio-group v-model="isLunarModel" label="label position">
7+
<el-radio-button :label="false">公历</el-radio-button>
8+
<el-radio-button :label="true">农历</el-radio-button>
9+
</el-radio-group>
10+
</div>
11+
</template>
12+
<template #footer>
13+
<span class="dialog-footer">
14+
<el-button @click="visibleModel = false">取消</el-button>
15+
<el-button type="primary" @click="visibleModel = false">
16+
确定
17+
</el-button>
18+
</span>
19+
</template>
20+
<template v-if="opened">
21+
<lunar-date-picker v-if="isLunarModel" v-model:date="dateModel"></lunar-date-picker>
22+
<solar-date-picker v-else v-model:date="dateModel"></solar-date-picker>
23+
</template>
24+
</el-dialog>
25+
</div>
26+
</template>
27+
28+
<script lang="ts" setup>
29+
import {computed, nextTick, onMounted, ref} from "vue";
30+
import 'vue-scroll-picker/lib/style.css'
31+
import SolarDatePicker from "@/components/SolarDatePicker.vue";
32+
import LunarDatePicker from "@/components/LunarDatePicker.vue";
33+
34+
const isLunar = ref(false);
35+
const opened = ref(false)
36+
const props = defineProps({
37+
visible: {
38+
type: Boolean,
39+
default: false
40+
},
41+
date: {
42+
type: Date,
43+
required: true
44+
},
45+
isLunar: {
46+
type: Boolean,
47+
default: false
48+
}
49+
});
50+
const emits = defineEmits(['update:visible', 'update:date', 'update:isLunar'])
51+
52+
onMounted(async () => {
53+
await nextTick();
54+
})
55+
const visibleModel = computed({
56+
get: () => {
57+
return props.visible
58+
},
59+
set: (value) => {
60+
emits('update:visible', value)
61+
}
62+
})
63+
64+
const dateModel = computed({
65+
get: () => {
66+
return props.date
67+
},
68+
set: (value) => {
69+
emits('update:date', value)
70+
}
71+
})
72+
73+
const isLunarModel = computed({
74+
get: () => {
75+
return props.isLunar
76+
},
77+
set: (value) => {
78+
emits('update:isLunar', value)
79+
}
80+
})
81+
</script>
82+
83+
<style scoped lang="scss">
84+
.header {
85+
display: flex;
86+
justify-items: center;
87+
justify-content: center;
88+
}
89+
90+
.el-dialog__header {
91+
padding: 0;
92+
}
93+
94+
</style>

src/components/LunarDatePicker.vue

+109
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
<template>
2+
<div class="picker-group">
3+
<VueScrollPicker :options="years" v-model="selectedYear"/>
4+
<VueScrollPicker :options="lunarMonths" v-model="selectedMonth"/>
5+
<VueScrollPicker :options="lunarDates" v-model="selectedDate"/>
6+
</div>
7+
</template>
8+
9+
<script lang="ts" setup>
10+
import {computed, ref, watch} from "vue";
11+
import {Lunar, LunarMonth, LunarUtil, LunarYear, Solar} from "lunar-typescript";
12+
import {VueScrollPicker} from 'vue-scroll-picker'
13+
import 'vue-scroll-picker/lib/style.css'
14+
15+
const props = defineProps({
16+
date: {
17+
type: Date,
18+
required: true
19+
},
20+
});
21+
22+
const lunar = Lunar.fromDate(props.date);
23+
console.log(lunar);
24+
const startYear = 1901;
25+
const selectedYear = ref(lunar.getYear());
26+
const selectedMonth = ref(lunar.getMonth())
27+
const selectedDate = ref(lunar.getDay())
28+
29+
const lunarMonths = computed(() => {
30+
const year = parseInt(selectedYear.value.toString());
31+
const lunarYear = new LunarYear(year);
32+
return lunarYear.getMonths().filter(it => it.getYear() == year).map((it) => {
33+
const lunarMonth = it.toString();
34+
console.log(lunarMonth.toString());
35+
return {
36+
name: lunarMonth.substring(lunarMonth.indexOf("") + 1, lunarMonth.indexOf("(")),
37+
value: it.getMonth()
38+
}
39+
});
40+
});
41+
42+
const lunarDates = computed(() => {
43+
if (!selectedMonth.value) return [{name: '初一', value: 1}];
44+
const lunarMonth = LunarMonth.fromYm(selectedYear.value, selectedMonth.value!);
45+
const dayCount = lunarMonth!.getDayCount();
46+
const arr: any[] = [];
47+
for (let i = 1; i <= dayCount; i++) {
48+
arr.push({
49+
name: getLunarDate(i),
50+
value: i,
51+
});
52+
}
53+
return arr;
54+
});
55+
56+
const getLunarDate = (i: number) => {
57+
const chineseNumber = ["", "", "", "", "", "", "", "", "", '']
58+
if (i < 11) {
59+
return "" + chineseNumber[i - 1];
60+
} else if (i < 20) {
61+
return "" + chineseNumber[i % 10 - 1];
62+
} else if (i == 20) {
63+
return "二十"
64+
} else if (i < 30) {
65+
return "廿" + chineseNumber[i % 10 - 1];
66+
} else {
67+
return "三十"
68+
}
69+
}
70+
71+
const years = [...Array(200).keys()].map((i) => {
72+
return i + startYear
73+
})
74+
75+
const emits = defineEmits(["update:date"])
76+
77+
function emitDateUpdate() {
78+
const selectedLunar = Lunar.fromYmd(selectedYear.value, selectedMonth.value, selectedDate.value);
79+
const solar = selectedLunar.getSolar();
80+
const date = new Date(solar.getYear(), solar.getMonth() - 1, solar.getDay());
81+
emits("update:date", date)
82+
}
83+
84+
watch(selectedYear, () => {
85+
emitDateUpdate()
86+
});
87+
88+
watch(selectedMonth, () => {
89+
emitDateUpdate()
90+
});
91+
92+
watch(selectedDate, () => {
93+
emitDateUpdate();
94+
});
95+
96+
97+
</script>
98+
99+
<style scoped lang="scss">
100+
.picker-group {
101+
width: 100%;
102+
display: flex;
103+
104+
.vue-scroll-picker {
105+
width: 33%;
106+
}
107+
}
108+
109+
</style>

src/components/SolarDatePicker.vue

+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
<template>
2+
<div class="picker-group">
3+
<VueScrollPicker :options="solarYears" v-model="selectedYear"/>
4+
<VueScrollPicker :options="solarMonths" v-model="selectedMonth"/>
5+
<VueScrollPicker :options="solarDates" v-model="selectedDate"/>
6+
</div>
7+
</template>
8+
9+
<script lang="ts" setup>
10+
import {computed, nextTick, onMounted, ref, watch} from "vue";
11+
import {VueScrollPicker} from 'vue-scroll-picker'
12+
import 'vue-scroll-picker/lib/style.css'
13+
import dayjs from "dayjs";
14+
15+
const props = defineProps({
16+
height: {
17+
type: Number,
18+
default: 150
19+
},
20+
date: {
21+
type: Date,
22+
required: true
23+
},
24+
});
25+
26+
const startYear = 1901;
27+
const selectedYear = ref(props.date.getFullYear());
28+
const selectedMonth = ref(props.date.getMonth());
29+
const selectedDate = ref(props.date.getDate());
30+
31+
const solarYears = computed(() => {
32+
return Array.from({length: 200}, (_, index) => index + startYear)
33+
});
34+
35+
const solarMonths = computed(() => {
36+
return Array.from({length: 12}, (_, index) => index + 1)
37+
})
38+
39+
const solarDates = computed(() => {
40+
const lastDay = new Date(selectedYear.value, selectedMonth.value, 0).getDate()
41+
return Array.from({length: lastDay}, (_, index) => index + 1)
42+
})
43+
44+
const emits = defineEmits(["update:date"])
45+
46+
function emitDateUpdate() {
47+
emits("update:date", dayjs({
48+
year: selectedYear.value,
49+
month: selectedMonth.value - 1,
50+
date: selectedDate.value
51+
}).toDate())
52+
}
53+
54+
watch(selectedYear, () => {
55+
emitDateUpdate();
56+
})
57+
58+
watch(selectedMonth, () => {
59+
emitDateUpdate();
60+
})
61+
62+
watch(selectedDate, () => {
63+
emitDateUpdate();
64+
})
65+
66+
watch(selectedYear, () => {
67+
console.log(selectedYear.value);
68+
})
69+
onMounted(async () => {
70+
await nextTick();
71+
});
72+
</script>
73+
74+
<style scoped lang="scss">
75+
.picker-group {
76+
width: 100%;
77+
display: flex;
78+
79+
.vue-scroll-picker {
80+
width: 33%;
81+
}
82+
}
83+
</style>

src/countdown/CountdownList.vue

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<template>
2+
<widget-base-dialog title="事项设置">
3+
<template #main>
4+
5+
</template>
6+
</widget-base-dialog>
7+
</template>
8+
9+
<script lang="ts" setup>
10+
import {WidgetApi} from "@widget-js/core";
11+
12+
const store = WidgetApi.getStore("cn.widgetjs.widgets.countdown-list");
13+
</script>
14+
15+
<style scoped lang="scss">
16+
.main {
17+
min-height: 500px;
18+
}
19+
</style>

src/countdown/Event.ts

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
export class Event {
2+
name: string
3+
date: string
4+
5+
dateType = DateType.SOLAR
6+
7+
constructor(name: string, date: string, dateType: DateType) {
8+
this.name = name;
9+
this.date = date;
10+
this.dateType = dateType;
11+
}
12+
}
13+
14+
15+
export enum DateType {
16+
LUNAR = "LUNAR",
17+
SOLAR = "SOLAR"
18+
}

0 commit comments

Comments
 (0)