commit 1eeb944be61cd8fff6422c899d4558c655f0e820
Author: npmrun <1549469775@qq.com>
Date: Mon Jun 9 00:41:52 2025 +0800
添加应用基础结构和样式,包含首页、导航栏、状态栏等组件,更新数据管理功能,增加日期处理工具,完善项目配置文件
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..efe7735
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+unpackage
\ No newline at end of file
diff --git a/App.uvue b/App.uvue
new file mode 100644
index 0000000..58ec612
--- /dev/null
+++ b/App.uvue
@@ -0,0 +1,46 @@
+
+
+
\ No newline at end of file
diff --git a/assets/fonts/ZhanKuKuaiLeTi2016XiuDingBan-1.ttf b/assets/fonts/ZhanKuKuaiLeTi2016XiuDingBan-1.ttf
new file mode 100644
index 0000000..ba2ad8a
Binary files /dev/null and b/assets/fonts/ZhanKuKuaiLeTi2016XiuDingBan-1.ttf differ
diff --git a/assets/style/common.scss b/assets/style/common.scss
new file mode 100644
index 0000000..17c6d3e
--- /dev/null
+++ b/assets/style/common.scss
@@ -0,0 +1,6 @@
+
+@font-face {
+ font-family: ZhanKuKuaiLeTi;
+ src: url('@/assets/fonts/ZhanKuKuaiLeTi2016XiuDingBan-1.ttf');
+}
+
\ No newline at end of file
diff --git a/components/x-navbar/x-navbar.uvue b/components/x-navbar/x-navbar.uvue
new file mode 100644
index 0000000..f4a83cc
--- /dev/null
+++ b/components/x-navbar/x-navbar.uvue
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/x-page/x-page.uvue b/components/x-page/x-page.uvue
new file mode 100644
index 0000000..d6cf89e
--- /dev/null
+++ b/components/x-page/x-page.uvue
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/x-status-bar/x-status-bar.uvue b/components/x-status-bar/x-status-bar.uvue
new file mode 100644
index 0000000..a1ad08b
--- /dev/null
+++ b/components/x-status-bar/x-status-bar.uvue
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/data/index.uts b/data/index.uts
new file mode 100644
index 0000000..db36be0
--- /dev/null
+++ b/data/index.uts
@@ -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);
+}
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..8ac465c
--- /dev/null
+++ b/index.html
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/main.uts b/main.uts
new file mode 100644
index 0000000..3b8febc
--- /dev/null
+++ b/main.uts
@@ -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
+ }
+}
\ No newline at end of file
diff --git a/manifest.json b/manifest.json
new file mode 100644
index 0000000..cd37515
--- /dev/null
+++ b/manifest.json
@@ -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": ""
+ }
+ }
+}
\ No newline at end of file
diff --git a/pages.json b/pages.json
new file mode 100644
index 0000000..55caef0
--- /dev/null
+++ b/pages.json
@@ -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": {}
+}
diff --git a/pages/index/index.uvue b/pages/index/index.uvue
new file mode 100644
index 0000000..1e82fae
--- /dev/null
+++ b/pages/index/index.uvue
@@ -0,0 +1,222 @@
+
+
+
+ LuMi
+
+
+
+ {{nowYear}}年{{nowMonth}}月
+
+
+
+
+
+
+
+ {{ day.label }}
+
+
+
+
+
+
+
+
+ {{item.label}}
+ x
+
+
+
+ 打卡
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/readme.md b/readme.md
new file mode 100644
index 0000000..7585ebf
--- /dev/null
+++ b/readme.md
@@ -0,0 +1 @@
+[](https://ext.dcloud.net.cn/plugin?id=16902)
\ No newline at end of file
diff --git a/static/logo.png b/static/logo.png
new file mode 100644
index 0000000..b5771e2
Binary files /dev/null and b/static/logo.png differ
diff --git a/uni.scss b/uni.scss
new file mode 100644
index 0000000..b9249e9
--- /dev/null
+++ b/uni.scss
@@ -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;
diff --git a/utils/date.uts b/utils/date.uts
new file mode 100644
index 0000000..2e482a6
--- /dev/null
+++ b/utils/date.uts
@@ -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(_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
+}
\ No newline at end of file