{"id":16654143,"url":"https://github.com/letmefly666/calendar","last_synced_at":"2025-07-07T03:07:48.344Z","repository":{"id":40652345,"uuid":"452709352","full_name":"LetMeFly666/Calendar","owner":"LetMeFly666","description":"微信小程序——默默无闻的日历罢了","archived":false,"fork":false,"pushed_at":"2024-02-15T13:45:16.000Z","size":422,"stargazers_count":9,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-09T18:11:34.682Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://docs.diary.letmefly.xyz/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/LetMeFly666.png","metadata":{"files":{"readme":"README.md","changelog":"changes.txt","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-01-27T14:13:23.000Z","updated_at":"2024-04-02T02:23:19.000Z","dependencies_parsed_at":"2025-04-09T18:21:27.089Z","dependency_job_id":null,"html_url":"https://github.com/LetMeFly666/Calendar","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/LetMeFly666/Calendar","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LetMeFly666%2FCalendar","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LetMeFly666%2FCalendar/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LetMeFly666%2FCalendar/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LetMeFly666%2FCalendar/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/LetMeFly666","download_url":"https://codeload.github.com/LetMeFly666/Calendar/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LetMeFly666%2FCalendar/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264005171,"owners_count":23542829,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-12T09:48:50.470Z","updated_at":"2025-07-07T03:07:48.327Z","avatar_url":"https://github.com/LetMeFly666.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003c!--\n * @Author: LetMeFly\n * @Date: 2022-01-27 22:13:45\n * @LastEditors: LetMeFly\n * @LastEditTime: 2022-05-09 15:54:00\n--\u003e\n{% raw %}\n\n# Calendar\n\n微信小程序——默默无闻的日历罢了\n\n\u003ccenter\u003e\u003cimg src=\"Docs/MiniProgramCode.jpg\" /\u003e\u003c/center\u003e\n\n**项目地址：** [https://github.com/LetMeFly666/Calendar](https://github.com/LetMeFly666/Calendar)\n\n**在线文档：** [https://docs.diary.letmefly.xyz/](https://docs.diary.letmefly.xyz/)\n\n进入主页，可以点击日历上的某一天添加日记/提醒。若设置了提醒时间(＞当前时间5分钟)并允许小程序发送通知，则在所设定的时间的前5分钟内，该微信号将会收到来自小程序的提醒。\n\n## 配置说明\n\n### 环境准备\n\n完全使用该项目之前，请具备以下条件\n\n1. 服务器\n   \u003e\n   \u003e 1. 拥有一台服务器\n   \u003e\n   \u003e 2. 拥有公网ip\n   \u003e\n   \u003e 3. 完成备案\n   \u003e\n   \u003e 4. 开启了https（微信小程序的限制）\n\n2. MySQL\n   \u003e\n   \u003e 1. 配置好了MySQL环境\n   \u003e\n   \u003e 2. 为该项目创建了一个database（空的即可）\n   \u003e\n   \u003e 3. 为该项目创建了一个用户，且该用户只具有操作此库的权限（减小可能的SQL注入造成的损失）\n\n3. python\n   \u003e \n   \u003e 1. 配置好了python环境\n   \u003e\n   \u003e 2. 安装了django（pip install django）、requests、django-crontab\n\n### 使用方法\n\n1. 将项目克隆到本地```git clone git@github.com:LetMeFly666/Calendar.git```\n\n2. 将```.\\Front\\```作为微信小程序的前端文件夹，将其上传至微信小程序开发平台，审核发布或设为体验\n\n3. 在微信小程序管理平台设置好图标、名称等信息，配置服务器中添加自己的服务器\n\n4. 在微信小程序管理平台选择“功能 -\u003e 订阅消息”，在“公共模板库”中找到“日程提醒”并选用，选择三个“关键词”(“日程时间”、“提醒内容”、“备注”)，“提交”并在“我的模板”中Copy“模板ID”\n\n5. 进入```.\\Back\\```，创建Secrets.py，在Secrets.py中，配置以下信息\n   \u003e SECRET_KEY = 'django-insecure-jafljalfsf*@46s' # 一串随机字符\n   \u003e\n   \u003e DATABASE_DBNAME = '数据库名称'\n   \u003e\n   \u003e DATABASE_USER = '数据库用户名'\n   \u003e\n   \u003e DATABASE_PASSWORD = '数据库密码'\n   \u003e\n   \u003e DATABASE_HOST = '数据库服务主机'\n   \u003e\n   \u003e DATABASE_PORT = '数据库端口'\n   \u003e\n   \u003e APP_ID = '微信小程序的AppID'\n   \u003e\n   \u003e APP_SECRET = '微信小程序的AppSecret'\n   \u003e\n   \u003e TEMPLATE_ID_DIARY_REMINDER = '微信消息订阅模板id'\n\n5. （启动mysql服务并)进行初始化```python manage.py makemigrations```、```python manage.py migrate```、```python manage.py crontab add```，之后运行即可(```python manage.py runserver```)\n\n\u003clarge\u003e\u003cb\u003e\u003cfont color=\"#f47920\"\u003e喜欢了别忘了给个star哦\u003c/font\u003e\u003c/b\u003e\u003c/large\u003e\n\n## Docs\n\n项目文档、笔记等\n\n## Front\n\n前端代码，即在微信小程序开发工具中的那一套\n\n前端全局配置笔记：[https://letmefly.xyz/Notes/WXminiProgram/](https://letmefly.xyz/Notes/WXminiProgram/)\n\n### 前端函数\n\n\u003csmall\u003e\u003cu\u003e“前端函数”中的介绍以 .\\Front\\ 作为根目录\u003c/u\u003e\u003c/small\u003e\n\n#### formatTime\n\n**位置：** utils/util.js\n\n**功能：** 将javascript的Date转化为“yyyy-MM-dd hh:mm:ss”格式的字符串\n\n**示例：**\n\n```javascript\nconst dateNow = new Date();\nconsole.log(formatTime(dateNow));\n\n// 2022-02-13 17:18:54\n```\n\n#### LetMeFly_request\n\n**位置：** utils/util.js\n\n**功能：** （微信小程序不支持cookie），此函数为二次封装的wx.request，使请求自动带上Storage中的session\n\n**示例：**\n\n```javascript\nLetMeFly_request({\n    url: 'https://diary.letmefly.xyz/GetAllDiaries/',\n    success: function(msg) {\n        const { diaries } = msg.data;\n        console.log(diaries);\n    }\n});\n\n// [\"第一个日记\", \"第二个日记\", \"66666\"]\n```\n\n**注释：** 服务器接收到微信小程序中的sessionid后，就可以取出session中保存的信息\n\n#### Subscribe1Reminder\n\n**位置：** utils/util.js\n\n**功能：** 让用户订阅一次消息提醒\n\n**示例：**\n\n```javascript\nSubscribe1Reminder();\n\n// （微信小程序将会询问是否订阅）\n```\n\n**注释：** 当前函数仅支持订阅一总类型的消息，即为“日程到期提醒”\n\n## Back\n\n后端代码，即后端逻辑，采用python的django实现。\n\n### 后端函数接口\n\n#### login\n\n**url：** /login/\n\n**函数：** Apps.Functions.User.login\n\n```\n登录函数，实现微信小程序的登陆功能\n函数根据登陆请求中的code向微信服务器索要用户openid和session_key\n    openid - 每个用户独一无二，唯一不变，用来唯一标识每个用户\n    session_key - 用来“数据签名校验”、“数据加密解密”等，会过期(但此次登陆结束之前不会过期)\n\nParameters:\n    request - http request\n        request.GET - {\"code\": (wx.login -\u003e msg) msg.code}\n    \nReturns:\n    JsonResponse - {\"code\": 0}\n```\n\n#### add1diary\n\n**url：** /AddADiary/\n\n**函数：** Apps.Functions.User.add1diary\n\n```\n添加一个日记\n\nParameters:\n    request - http request\n        request.session - 包含登录时保存到小程序Storage中的sessionid，由此来获取用户的userid\n        json.loads(request.body) - {\"content\": 要添加的日记的内容}\n\nReturns:\n    JsonResponse - {\"code\": 状态码}\n        0 - 发送成功\n        1 - 内容为空\n```\n\n#### getAllDiaries\n\n**url：** /GetAllDiaries/\n\n**函数：** Apps.Functions.User.getAllDiaries\n\n```\n获取所有日记\n\nParameters:\n    request - http request\n        request.session - 包含登录时保存到小程序Storage中的sessionid，由此来获取用户的userid\n\nReturns:\n    JsonResponse - {\"code\": 0, \"diaries\": diaries}\n        diaries - [日记1, 日记2, 日记3, ...]\n            日记1 - {\"content\": 日记内容, \"id\": 日记id, \"publishTime\": 发布时间, \"remindTime\": 提醒时间}\n```\n\n#### get1diary\n\n**url：** /Get1Diary/\n\n**函数：** Apps.Functions.User.get1diary\n\n```\n获取一个日记\n\nParameters:\n    request - http request\n        session - session\n        diaryId - 要操作的日记的id\n\nReturns:\n    JsonResponse - http response\n        成功 - {\"code\": 0, \"diary\": 日记}\n            日记 - {\"content\": 日记内容, \"id\": 日记id, \"publishTime\": 发布时间, \"remindTime\": 提醒时间}\n        失败 - {\"code\": 非0}\n            code - 1 没有权限\n```\n\n#### del1diary\n\n**url：** /Del1Diary/\n\n**函数：** Apps.Functions.User.del1diary\n\n```\n删除一条日记\n\nParameters:\n    request - http request\n        session - session\n        diaryId - 要操作的日记的id\n\nReturns:\n    code - 状态码\n        0 - 删除成功\n        1 - 没有权限或日记不存在\n```\n\n#### getAccessToken\n\n**url：** 无\n\n**函数：** Apps.Functions.Server.getAccessToken\n\n```\n获取小程序全局唯一后台接口调用凭据（access_token）\n\nReturns:\n    json - 调用结果\n        正常调用 - {\"access_token\": \"ACCESS_TOKEN\", \"expires_in\": 7200} (过期时间当前为2h，后期可能会有所调整)\n        系统繁忙 - {\"errcode\": 40001, \"errmsg\": ...}\n```\n\n#### send1Message\n\n**url：** 无\n\n**函数：** Apps.Functions.Server.send1Message\n\n```\n推送一次消息给用户\n\nParameters:\n    toWho - 用户的openid\n    templateId - 模板的template_id\n    data - 要替换的模板中的内容\n        {\"date4\": {\"value\": \"2022-02-14 16:58\"}, \"thing1\": {\"value\": \"...\"}, ...}\n\nReturns:\n    code - 状态码\n        0 - 发送成功\n        1 - 用户拒收（用户撤销了订阅 或 用户未订阅）\n        2 - 不合法的用户openid\n        -1 - 其他错误\n```\n\n\n#### send1Message_DiaryReminder\n\n**url：** 无\n\n**函数：** Apps.Functions.Server.send1Message_DiaryReminder\n\n```\n推送一次用户设置的提醒给用户\n\nParameters:\n    toWho - 用户的openid\n    date - 提醒时间\n    content - 消息内容 （微信要求20字以内，若超过将会被截取为{{前17个字}...}）\n    jumpto - 用户点击消息卡片所跳转到的页面，默认我“我的日记页面”\n\nReturns:\n    code - 状态码\n        0 - 发送成功\n        1 - 用户拒收（用户撤销了订阅 或 用户未订阅）\n        2 - 不合法的用户openid\n        -1 - 其他错误\n```\n\n### 后端数据库\n\n#### 用户\n\n```python\nclass user(models.Model):\n    userid = models.CharField(verbose_name=\"openid\", max_length=40, unique=True)\n    session_key = models.CharField(verbose_name=\"session_key\", max_length=40)\n    remark = models.CharField(verbose_name=\"备注\", max_length=50, null=True)\n```\n\n#### 日记\n\n```python\nclass diaries(models.Model):\n    userid = models.CharField(verbose_name=\"openid\", max_length=40)\n    content = models.CharField(verbose_name=\"日记内容\", max_length=1024)\n    publish_time = models.DateTimeField(verbose_name=\"发布时间\", auto_now_add=True)\n    remind_time = models.DateTimeField(verbose_name=\"提醒时间\", null=True)\n```\n\n## TODO\n\n- [ ] \u003ccode\u003euser/usser\u003c/code\u003e误拼\n\n- [ ] 发行版\u003ccode\u003epages/user/usser\u003c/code\u003e页面不能获取用户头像和昵称。自21年起就不能直接获取用户头像和信息了，必须使用wx.getUserProfile来获取。但是wx.getUserProfile每次调用都需要弹窗获得用户的同意，除非获取一次后就把头像、昵称保存到服务器。这就需要增加不少的后端代码。我猜，这就是为什么很多小程序头像都是失效图片的原因吧。\n\n- [ ] 从“我的日记”页面进入一个日记并日记后会跳转到新的“我的日记”页面，新的“我的日记”页面不会展示刚刚删除的日记。但是如果用户点击两次“返回”，就会先返回到刚刚删除日记的那个页面，然后再次返回就会回到删除日记之前的“我的日记”页面。这个页面中的日记仍会显示，若用户再次点击此条日记就会访问一条已经删除的日记儿出现错误。\n\n- [x] \u003ccode\u003eicon\u003c/code\u003e 和 \u003ccode\u003esource/Img\u003c/code\u003e重复性冗余，待整合\n\n- [x] “我的日记”页面的内容应该以时间为依据倒序显示，即最新发布的最前。\n\n- [x] 采用自定义url的图片，不修改源码可实现背景图片的更换\n\n{% endraw %}","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fletmefly666%2Fcalendar","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fletmefly666%2Fcalendar","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fletmefly666%2Fcalendar/lists"}