diff --git a/.obsidian/app.json b/.obsidian/app.json index e609a07..9bd3f41 100644 --- a/.obsidian/app.json +++ b/.obsidian/app.json @@ -1,3 +1,4 @@ { - "promptDelete": false + "promptDelete": false, + "defaultViewMode": "source" } \ No newline at end of file diff --git a/.obsidian/community-plugins.json b/.obsidian/community-plugins.json index 72069e8..bf0f981 100644 --- a/.obsidian/community-plugins.json +++ b/.obsidian/community-plugins.json @@ -8,5 +8,6 @@ "obsidian-pandoc", "univer", "obsidian-image-auto-upload-plugin", - "obsidian-git" + "obsidian-git", + "remember-cursor-position" ] \ No newline at end of file diff --git a/.obsidian/core-plugins.json b/.obsidian/core-plugins.json index 74d54da..462ef0d 100644 --- a/.obsidian/core-plugins.json +++ b/.obsidian/core-plugins.json @@ -7,7 +7,7 @@ "canvas": true, "outgoing-link": true, "tag-pane": true, - "properties": false, + "properties": true, "page-preview": true, "daily-notes": true, "templates": true, diff --git a/.obsidian/plugins/remember-cursor-position/cursor-positions.json b/.obsidian/plugins/remember-cursor-position/cursor-positions.json new file mode 100644 index 0000000..ad07638 --- /dev/null +++ b/.obsidian/plugins/remember-cursor-position/cursor-positions.json @@ -0,0 +1 @@ +{"月度/8月/8月.md":{"scroll":371.8766,"cursor":{"from":{"ch":6,"line":481},"to":{"ch":6,"line":481}}}} \ No newline at end of file diff --git a/.obsidian/plugins/remember-cursor-position/main.js b/.obsidian/plugins/remember-cursor-position/main.js new file mode 100644 index 0000000..78dbc07 --- /dev/null +++ b/.obsidian/plugins/remember-cursor-position/main.js @@ -0,0 +1,302 @@ +/* +THIS IS A GENERATED/BUNDLED FILE BY ROLLUP +if you want to view the source visit the plugins github repository +*/ + +'use strict'; + +var obsidian = require('obsidian'); + +/****************************************************************************** +Copyright (c) Microsoft Corporation. + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. +***************************************************************************** */ + +function __awaiter(thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +} + +typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { + var e = new Error(message); + return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; +}; + +const SAFE_DB_FLUSH_INTERVAL = 5000; +const DEFAULT_SETTINGS = { + dbFileName: '.obsidian/plugins/remember-cursor-position/cursor-positions.json', + delayAfterFileOpening: 100, + saveTimer: SAFE_DB_FLUSH_INTERVAL, +}; +class RememberCursorPosition extends obsidian.Plugin { + constructor() { + super(...arguments); + this.loadedLeafIdList = []; + this.loadingFile = false; + } + onload() { + return __awaiter(this, void 0, void 0, function* () { + yield this.loadSettings(); + try { + this.db = yield this.readDb(); + this.lastSavedDb = yield this.readDb(); + } + catch (e) { + console.error("Remember Cursor Position plugin can\'t read database: " + e); + this.db = {}; + this.lastSavedDb = {}; + } + this.addSettingTab(new SettingTab(this.app, this)); + this.registerEvent(this.app.workspace.on('file-open', (file) => this.restoreEphemeralState())); + this.registerEvent(this.app.workspace.on('quit', () => { this.writeDb(this.db); })); + this.registerEvent(this.app.vault.on('rename', (file, oldPath) => this.renameFile(file, oldPath))); + this.registerEvent(this.app.vault.on('delete', (file) => this.deleteFile(file))); + //todo: replace by scroll and mouse cursor move events + this.registerInterval(window.setInterval(() => this.checkEphemeralStateChanged(), 100)); + this.registerInterval(window.setInterval(() => this.writeDb(this.db), this.settings.saveTimer)); + this.restoreEphemeralState(); + }); + } + renameFile(file, oldPath) { + let newName = file.path; + let oldName = oldPath; + this.db[newName] = this.db[oldName]; + delete this.db[oldName]; + } + deleteFile(file) { + let fileName = file.path; + delete this.db[fileName]; + } + checkEphemeralStateChanged() { + var _a; + let fileName = (_a = this.app.workspace.getActiveFile()) === null || _a === void 0 ? void 0 : _a.path; + //waiting for load new file + if (!fileName || !this.lastLoadedFileName || fileName != this.lastLoadedFileName || this.loadingFile) + return; + let st = this.getEphemeralState(); + if (!this.lastEphemeralState) + this.lastEphemeralState = st; + if (!isNaN(st.scroll) && !this.isEphemeralStatesEquals(st, this.lastEphemeralState)) { + this.saveEphemeralState(st); + this.lastEphemeralState = st; + } + } + isEphemeralStatesEquals(state1, state2) { + if (state1.cursor && !state2.cursor) + return false; + if (!state1.cursor && state2.cursor) + return false; + if (state1.cursor) { + if (state1.cursor.from.ch != state2.cursor.from.ch) + return false; + if (state1.cursor.from.line != state2.cursor.from.line) + return false; + if (state1.cursor.to.ch != state2.cursor.to.ch) + return false; + if (state1.cursor.to.line != state2.cursor.to.line) + return false; + } + if (state1.scroll && !state2.scroll) + return false; + if (!state1.scroll && state2.scroll) + return false; + if (state1.scroll && state1.scroll != state2.scroll) + return false; + return true; + } + saveEphemeralState(st) { + var _a; + return __awaiter(this, void 0, void 0, function* () { + let fileName = (_a = this.app.workspace.getActiveFile()) === null || _a === void 0 ? void 0 : _a.path; + if (fileName && fileName == this.lastLoadedFileName) { //do not save if file changed or was not loaded + this.db[fileName] = st; + } + }); + } + restoreEphemeralState() { + var _a, _b, _c; + return __awaiter(this, void 0, void 0, function* () { + let fileName = (_a = this.app.workspace.getActiveFile()) === null || _a === void 0 ? void 0 : _a.path; + if (fileName && this.loadingFile && this.lastLoadedFileName == fileName) //if already started loading + return; + let activeLeaf = this.app.workspace.getMostRecentLeaf(); + if (activeLeaf && this.loadedLeafIdList.includes(activeLeaf.id + ':' + activeLeaf.getViewState().state.file)) + return; + this.loadedLeafIdList = []; + this.app.workspace.iterateAllLeaves((leaf) => { + if (leaf.getViewState().type === "markdown") { + this.loadedLeafIdList.push(leaf.id + ':' + leaf.getViewState().state.file); + } + }); + this.loadingFile = true; + if (this.lastLoadedFileName != fileName) { + this.lastEphemeralState = {}; + this.lastLoadedFileName = fileName; + let st; + if (fileName) { + st = this.db[fileName]; + if (st) { + //waiting for load note + yield this.delay(this.settings.delayAfterFileOpening); + let scroll; + for (let i = 0; i < 20; i++) { + scroll = (_c = (_b = this.app.workspace.getActiveViewOfType(obsidian.MarkdownView)) === null || _b === void 0 ? void 0 : _b.currentMode) === null || _c === void 0 ? void 0 : _c.getScroll(); + if (scroll !== null) + break; + yield this.delay(10); + } + // TODO: if note opened by link like [link](note.md#header), do not scroll it + yield this.delay(10); + this.setEphemeralState(st); + } + } + this.lastEphemeralState = st; + } + this.loadingFile = false; + }); + } + readDb() { + return __awaiter(this, void 0, void 0, function* () { + let db = {}; + if (yield this.app.vault.adapter.exists(this.settings.dbFileName)) { + let data = yield this.app.vault.adapter.read(this.settings.dbFileName); + db = JSON.parse(data); + } + return db; + }); + } + writeDb(db) { + return __awaiter(this, void 0, void 0, function* () { + //create folder for db file if not exist + let newParentFolder = this.settings.dbFileName.substring(0, this.settings.dbFileName.lastIndexOf("/")); + if (!(yield this.app.vault.adapter.exists(newParentFolder))) + this.app.vault.adapter.mkdir(newParentFolder); + if (JSON.stringify(this.db) !== JSON.stringify(this.lastSavedDb)) { + this.app.vault.adapter.write(this.settings.dbFileName, JSON.stringify(db)); + this.lastSavedDb = JSON.parse(JSON.stringify(db)); + } + }); + } + getEphemeralState() { + // let state: EphemeralState = this.app.workspace.getActiveViewOfType(MarkdownView)?.getEphemeralState(); //doesn't work properly + var _a, _b, _c; + let state = {}; + state.scroll = Number((_c = (_b = (_a = this.app.workspace.getActiveViewOfType(obsidian.MarkdownView)) === null || _a === void 0 ? void 0 : _a.currentMode) === null || _b === void 0 ? void 0 : _b.getScroll()) === null || _c === void 0 ? void 0 : _c.toFixed(4)); + let editor = this.getEditor(); + if (editor) { + let from = editor.getCursor("anchor"); + let to = editor.getCursor("head"); + if (from && to) { + state.cursor = { + from: { + ch: from.ch, + line: from.line + }, + to: { + ch: to.ch, + line: to.line + } + }; + } + } + return state; + } + setEphemeralState(state) { + const view = this.app.workspace.getActiveViewOfType(obsidian.MarkdownView); + if (state.cursor) { + let editor = this.getEditor(); + if (editor) { + editor.setSelection(state.cursor.from, state.cursor.to); + } + } + if (view && state.scroll) { + view.setEphemeralState(state); + // view.previewMode.applyScroll(state.scroll); + // view.sourceMode.applyScroll(state.scroll); + } + } + getEditor() { + var _a; + return (_a = this.app.workspace.getActiveViewOfType(obsidian.MarkdownView)) === null || _a === void 0 ? void 0 : _a.editor; + } + loadSettings() { + return __awaiter(this, void 0, void 0, function* () { + let settings = Object.assign({}, DEFAULT_SETTINGS, yield this.loadData()); + if ((settings === null || settings === void 0 ? void 0 : settings.saveTimer) < SAFE_DB_FLUSH_INTERVAL) { + settings.saveTimer = SAFE_DB_FLUSH_INTERVAL; + } + this.settings = settings; + }); + } + saveSettings() { + return __awaiter(this, void 0, void 0, function* () { + yield this.saveData(this.settings); + }); + } + delay(ms) { + return __awaiter(this, void 0, void 0, function* () { + return new Promise(resolve => setTimeout(resolve, ms)); + }); + } +} +class SettingTab extends obsidian.PluginSettingTab { + constructor(app, plugin) { + super(app, plugin); + this.plugin = plugin; + } + display() { + let { containerEl } = this; + containerEl.empty(); + containerEl.createEl('h2', { text: 'Remember cursor position - Settings' }); + new obsidian.Setting(containerEl) + .setName('Data file name') + .setDesc('Save positions to this file') + .addText((text) => text + .setPlaceholder('Example: cursor-positions.json') + .setValue(this.plugin.settings.dbFileName) + .onChange((value) => __awaiter(this, void 0, void 0, function* () { + this.plugin.settings.dbFileName = value; + yield this.plugin.saveSettings(); + }))); + new obsidian.Setting(containerEl) + .setName('Delay after opening a new note') + .setDesc("This plugin shouldn't scroll if you used a link to the note header like [link](note.md#header). If it did, then increase the delay until everything works. If you are not using links to page sections, set the delay to zero (slider to the left). Slider values: 0-300 ms (default value: 100 ms).") + .addSlider((text) => text + .setLimits(0, 300, 10) + .setValue(this.plugin.settings.delayAfterFileOpening) + .onChange((value) => __awaiter(this, void 0, void 0, function* () { + this.plugin.settings.delayAfterFileOpening = value; + yield this.plugin.saveSettings(); + }))); + new obsidian.Setting(containerEl) + .setName('Delay between saving the cursor position to file') + .setDesc("Useful for multi-device users. If you don't want to wait until closing Obsidian to the cursor position been saved.") + .addSlider((text) => text + .setLimits(SAFE_DB_FLUSH_INTERVAL, SAFE_DB_FLUSH_INTERVAL * 10, 10) + .setValue(this.plugin.settings.saveTimer) + .onChange((value) => __awaiter(this, void 0, void 0, function* () { + this.plugin.settings.saveTimer = value; + yield this.plugin.saveSettings(); + }))); + } +} + +module.exports = RememberCursorPosition; + + +/* nosourcemap */ \ No newline at end of file diff --git a/.obsidian/plugins/remember-cursor-position/manifest.json b/.obsidian/plugins/remember-cursor-position/manifest.json new file mode 100644 index 0000000..4c938f9 --- /dev/null +++ b/.obsidian/plugins/remember-cursor-position/manifest.json @@ -0,0 +1,10 @@ +{ + "id": "remember-cursor-position", + "name": "Remember cursor position", + "version": "1.0.9", + "minAppVersion": "0.9.12", + "description": "Remember cursor and scroll position for each note", + "author": "Dmitry Savosh", + "authorUrl": "https://github.com/dy-sh/", + "isDesktopOnly": false +} diff --git a/.obsidian/types.json b/.obsidian/types.json new file mode 100644 index 0000000..0245770 --- /dev/null +++ b/.obsidian/types.json @@ -0,0 +1,8 @@ +{ + "types": { + "aliases": "aliases", + "cssclasses": "multitext", + "tags": "tags", + "图片": "multitext" + } +} \ No newline at end of file diff --git a/.obsidian/workspace.json b/.obsidian/workspace.json index 89dc348..35f0f24 100644 --- a/.obsidian/workspace.json +++ b/.obsidian/workspace.json @@ -4,34 +4,22 @@ "type": "split", "children": [ { - "id": "eb8d36499b2770da", + "id": "01b1a1c13ef56ab5", "type": "tabs", "children": [ { - "id": "09209a9a39e1187e", + "id": "f3b163eeb312320d", "type": "leaf", "state": { "type": "markdown", "state": { "file": "月度/8月/8月.md", "mode": "source", - "source": true + "source": false }, "icon": "lucide-file", "title": "8月" } - }, - { - "id": "753de844edc5016c", - "type": "leaf", - "state": { - "type": "docx-view", - "state": { - "file": "月度/8月/1.《新疆学生常见病监测信息管理系统》V5.3需求确认书(优化部分).docx" - }, - "icon": "lucide-file", - "title": "1.《新疆学生常见病监测信息管理系统》V5.3需求确认书(优化部分)" - } } ] } @@ -115,25 +103,6 @@ "title": "8月 的大纲" } }, - { - "id": "28e5320c71cac0db", - "type": "leaf", - "state": { - "type": "backlink", - "state": { - "file": "月度/8月/8月.md", - "collapseAll": false, - "extraContext": false, - "sortOrder": "alphabetical", - "showSearch": false, - "searchQuery": "", - "backlinkCollapsed": false, - "unlinkedCollapsed": true - }, - "icon": "links-coming-in", - "title": "8月 的反向链接列表" - } - }, { "id": "7c3be5a7fa146fb4", "type": "leaf", @@ -172,13 +141,58 @@ "icon": "git-pull-request", "title": "Source Control" } + }, + { + "id": "395ec3c7b07dfe34", + "type": "leaf", + "state": { + "type": "file-properties", + "state": { + "file": "月度/8月/8月.md" + }, + "icon": "lucide-info", + "title": "8月的笔记属性" + } + }, + { + "id": "87b7b54ecdb86451", + "type": "leaf", + "state": { + "type": "backlink", + "state": { + "file": "月度/8月/8月.md", + "collapseAll": false, + "extraContext": false, + "sortOrder": "alphabetical", + "showSearch": false, + "searchQuery": "", + "backlinkCollapsed": false, + "unlinkedCollapsed": true + }, + "icon": "links-coming-in", + "title": "8月 的反向链接列表" + } + }, + { + "id": "93f13e559958fc6b", + "type": "leaf", + "state": { + "type": "all-properties", + "state": { + "sortOrder": "frequency", + "showSearch": false, + "searchQuery": "" + }, + "icon": "lucide-archive", + "title": "添加笔记属性" + } } ], - "currentTab": 4 + "currentTab": 2 } ], "direction": "horizontal", - "width": 286.5 + "width": 327.5 }, "left-ribbon": { "hiddenItems": { @@ -196,39 +210,44 @@ "obsidian-git:Open Git source control": false } }, - "active": "09209a9a39e1187e", + "active": "f3b163eeb312320d", "lastOpenFiles": [ - "月度/8月/1.《新疆学生常见病监测信息管理系统》V5.3需求确认书(优化部分).docx", "月度/8月/8月.md", + "月度/3月/3月.md", + "月度/4月/4月.md", + "月度/5月/5月.md", + "月度/6月/6月.md", + "月度/7月/7月.md", + "月度/封面.base", + "图片/8月.png", + "图片/1756350239430_d.png", + "图片/1756348666259_d.png", + "图片", + "月度/8月/晨午检学校上报统计.xlsx", + "材料/转正材料/~$【20250314】技术部工作总结汇报.pptx", + "月度/8月/8.8技术部研讨会议纪要.md", + "Untitled 1.md", + "Untitled.md", + "月度/8月/1.《新疆学生常见病监测信息管理系统》V5.3需求确认书(优化部分).docx", "月度/7月/7月工作总结及8月工作计划.md", "材料/配置/Obsidian快捷键.md", "月度/8月/资源发展中心汇报/资源发展中心问题.md", "材料/转正材料/转正述职报告.md", - "月度/3月/3月.md", "月度/8月/CA身份认证app/CA身份认证app流程图.md", "材料/服务器.md", "月度/6月/6月份晨午检bug修复.md", "月度/7月/华为服务器测试报告.md", - "月度/8月/8.8技术部研讨会议纪要.md", - "月度/6月/6月.md", "月度/7月/7月份晨午检bug修复.md", "月度/7月/ca会议纪要.md", "月度/7月/设备管理中心研发记录.md", - "月度/4月/4月.md", - "月度/5月/5月.md", - "月度/7月/7月.md", "月度/8月/新疆青卫舜源2025年8月技术部KPI-研发工程师-颜准.xlsx", "月度/8月/未命名.md", "月度/8月/~$《新疆学生常见病监测信息管理系统》V5.3需求确认书(优化部分).docx", "月度/7月/Attachments/设备管理中心优化需求文档.png", - "月度/8月/晨午检学校上报统计.xlsx", "月度/晨午检学校上报统计.xlsx", "1755743563407_d.png", "月度/8月/CA身份认证app/移动认证中心需求.docx", "材料/code/dbcenter-master.zip", - "材料/code/spidercenter-main.zip", - "周报/技术部《第33周》颜准 周报(2025年8月15日)~C8F6E.tmp", - "周报/技术部《第33周》颜准 周报(2025年8月15日)~BEF36.tmp", "8.8技术部研讨会议纪要.md", "月度/8月/8.8技术部研讨会议纪要 - 副本.md", "Pasted image 20250808165433.png", @@ -238,12 +257,7 @@ "月度/8月/ca身份认证/未命名.canvas", "月度/8月/ca身份认证/Drawing 2025-08-08 12.42.17.excalidraw.md", "月度/7月/Attachments/设备管理中心优化需求文档 1.png", - "().md", - "1日报/8月.md", "月度/7月/Attachments/设备管理中心优化需求文档 2.png", - "3月度/7月/Attachments/设备管理中心优化需求文档.png", - "3月度/7月/Attachments/设备管理中心优化需求文档 2.png", - "3月度/7月/Attachments/设备管理中心优化需求文档 1.png", "未命名.canvas" ] } \ No newline at end of file diff --git a/图片/8月.png b/图片/8月.png new file mode 100644 index 0000000..4843859 Binary files /dev/null and b/图片/8月.png differ diff --git a/月度/8月/8月.md b/月度/8月/8月.md index adea5bc..9937b56 100644 --- a/月度/8月/8月.md +++ b/月度/8月/8月.md @@ -1,3 +1,5 @@ +![[8月.png]] + # 8.1 1.撰写技术部7月总结8月计划ppt [[7月工作总结及8月工作计划]] @@ -104,7 +106,7 @@ # 8.15 1. 常见病app登录请求加密 -常见病后端feat(security): 添加 AES 加密解密功能并集成到用户登录流程 + 常见病后端feat(security): 添加 AES 加密解密功能并集成到用户登录流程 - 新增 AesUtil 工具类,提供 AES 加密解密相关方法 - 在 DoctorController 中集成 AES 解密逻辑,用于处理客户端加密的用户名和密码 - 添加生成和存储随机偏移量(IV)的功能,以增强加密安全性 @@ -362,3 +364,119 @@ A071A01 A071A02 A071A03 A071A04 + +# 8.28 +1. 常见病apprefactor(physicalcheck): 重构体检数据漏项处理逻辑 +- 更新 MissItemEntity 和 MissItemModel 以适应新的数据结构 +- 优化学院体检新页面的数据保存和上传逻辑 +- 改进历史数据页面的学生详情弹窗,支持动态字段显示 +- 优化数据删除和重新上传功能 + 常见病后端feat(query): 优化体检结果漏项检查功能 +- 新增 MissingItemGroupVo 类用于封装遗漏项目的组信息 +- 重构 TestingResultController 中的 checkMissingTestingResultTtemByApp 方法 +- 更新 TestingResultServiceImpl 中的 checkTestingResultMissingItem 方法 +- 在 TestingResultVo 中添加 yaowei 字段用于记录腰围信息 +- 新增 ReflexObjectUtil 工具类用于反射操作对象属性 +2. 备份晨午检系统学生数据表(8.28),删除所有没有班级的学生信息 +3. 晨午检系统refactor(teacher): 修复教职工页面修改、删除打不开的bug +- 添加编辑和删除按钮的点击事件处理 +- 优化导入数据功能的代码结构 +- 移除冗余的空格和注释 +- 统一代码格式和风格 +1. 晨午检系统将部署在152上的两个节点切换至了10.10.35.23统信达梦服务器上 + + +脊柱侧弯检查部分 +**一(1)** 可多选,1-6;选1不能选别的 +**一(2)** 可多选,1-4;选1不能选别的 +**一(3)** 三个部位得ATR必填,0-30 +**一(4)** 只能选1或2,选1后面三个ATR值需填写,选2直接跳转至第二部分 +**二(4)** 选1不能选别的,2、3可多选,选1直接跳转第三部分,选2或3或2和3回答二(5) +**二(5)** 选1不能选别的;2、3可多选;选2筛查结果为4,选3筛查结果为5 +**疾病史**可多选,1-4 +**筛查结果** +选1不能选别的 +选2不能选别的 +3、4、5可同时多选 +如果选的有3要填脊柱侧弯级别 + + + + ```brainfuck + 请实现一个脊柱侧弯筛查结果自动判定函数,根据用户输入的表单数据自动计算初筛结果,具体要求如下: + +### 输入参数(对应字段名): + +- `generalExamination`: 一(1)一般检查结果(数组,可多选) + +- `adamsTest`: 一(2)前屈试验结果(数组,可多选) + +- `chestSegment`: 一(3)胸段检查结果(对象:{ option: string, atr: number }) + +- `waistChestSegment`: 一(3)腰胸段检查结果(同上) + +- `waistSegment`: 一(3)腰段检查结果(同上) + +- `spineMovementExperiment`: 一(4)是否进行脊柱运动试验(boolean,true为是) + +- `movementChestATR`: 一(4)运动试验后胸段ATR(number,可选) + +- `movementWaistChestATR`: 一(4)运动试验后腰胸段ATR(number,可选) + +- `movementWaistATR`: 一(4)运动试验后腰段ATR(number,可选) + +- `frontBackGeneral`: 二(4)前后弯曲一般检查(字符串,可选值:正常、前凸体征、后凸体征) + +- `proneTest`: 二(5)俯卧试验结果(字符串,可选值:前后凸体征消失、前凸体征、后凸体征) + + +### 逻辑要求: + +1. **脊柱侧弯部分判定**: + + - 若一(1)为“正常”、一(2)为“正常”且一(3)三个ATR均<5°,则初筛结果为“正常”。 + + - 否则,若一(4)为“是”且运动试验后三个ATR均<5°,则初筛结果为“姿态不良”。 + + - 否则,若任一运动试验后ATR≥5°,则初筛结果为“脊柱侧弯”,并需根据最大ATR值判定等级: + + - 5°≤ATR<7°:Ⅰ级 + + - 7°≤ATR<10°:Ⅱ级 + + - ATR≥10°:Ⅲ级 + +2. **脊柱前后弯曲部分判定**: + + - 若二(4)为“正常”,不影响初筛结果。 + + - 若二(4)为“前凸体征”或“后凸体征”,则必须进行二(5)俯卧试验: + + - 若二(5)为“前后凸体征消失”,则初筛结果为“姿态不良”(覆盖原有结果)。 + + - 若二(5)为“前凸体征”,则初筛结果为“脊柱前凸异常”。 + + - 若二(5)为“后凸体征”,则初筛结果为“脊柱后凸异常”。 + +3. **最终结果合并**: + + - 若脊柱侧弯部分已判定为“脊柱侧弯”或“姿态不良”,且前后弯曲部分也判定为异常,则最终结果为多选(如:["脊柱侧弯(Ⅱ级)", "脊柱前凸异常"])。 + + - 若脊柱侧弯部分为“正常”,则前后弯曲异常可覆盖结果为异常。 + + +### 输出: + +- 返回初筛结果数组,如:`["正常"]`、`["姿态不良"]`、`["脊柱侧弯(Ⅱ级)"]`、`["脊柱前凸异常", "脊柱后凸异常"]`等。 + + +### 代码建议: + +- 使用条件分支(if/else 或 switch)实现多级判断。 + +- 使用数组存储多选结果。 + +- 对ATR值进行范围校验(0–30)。 + +- 可使用常量或枚举定义选项值,提高可读性。 + ``` \ No newline at end of file diff --git a/月度/8月/晨午检学校上报统计.xlsx b/月度/8月/晨午检学校上报统计.xlsx index aec60f9..4b46191 100644 Binary files a/月度/8月/晨午检学校上报统计.xlsx and b/月度/8月/晨午检学校上报统计.xlsx differ diff --git a/月度/封面.base b/月度/封面.base new file mode 100644 index 0000000..a5a90f7 --- /dev/null +++ b/月度/封面.base @@ -0,0 +1,16 @@ +formulas: + 图片: file.embeds.filter(value.containsAny("png","jpg","webp","svg","jpeg"))[0] +properties: + formula.图片: + displayName: first_image +views: + - type: cards + name: 视图 + filters: + and: + - file.basename.endsWith("月") + - file.ext == "md" + image: formula.图片 + imageFit: "" + imageAspectRatio: 1.2 + cardSize: 160