|
@@ -1,303 +1,291 @@
|
|
|
-import {type InjectionKey, ref} from "vue";
|
|
|
-import {EditType, Outline} from "@/utils/emr/edit";
|
|
|
-import {xcMessage} from "@/utils/xiaochan-element-plus";
|
|
|
-import {stringNotBlank} from "@/utils/blank-utils";
|
|
|
+import { ref } from "vue";
|
|
|
+import { EditType, Outline } from "@/utils/emr/edit";
|
|
|
+import { xcMessage } from "@/utils/xiaochan-element-plus";
|
|
|
+import { stringNotBlank } from "@/utils/blank-utils";
|
|
|
import usePromise from "@/utils/cy-use/usePromise";
|
|
|
import XEUtils from "xe-utils";
|
|
|
-import {CyMessageBox} from "@/components/cy/message-box";
|
|
|
+import { CyMessageBox } from "@/components/cy/message-box";
|
|
|
import * as utilsPlugins from "../emr-editor/plugins";
|
|
|
-import {ReturnPlugins} from "../emr-editor/plugins";
|
|
|
-import {UseEmrInitReturn} from "@/utils/emr/emr-init-v2";
|
|
|
-import {EmrRightTabs} from "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/emr-init";
|
|
|
+import { ReturnPlugins } from "../emr-editor/plugins";
|
|
|
+import { UseEmrInitReturn } from "@/utils/emr/emr-init-v2";
|
|
|
+import { EmrRightTabs } from "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/emr-init";
|
|
|
import sleep from "@/utils/sleep";
|
|
|
import emrFunUtils from "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-func/emr-fun-utils";
|
|
|
-import {EmrPatientData} from "@/api/zhu-yuan-yi-sheng/emr-patient";
|
|
|
-import * as socket
|
|
|
- from "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/socket/useEmrSocket";
|
|
|
+import { EmrPatientData } from "@/api/zhu-yuan-yi-sheng/emr-patient";
|
|
|
+import * as socket from "@/views/hospitalization/zhu-yuan-yi-sheng/electronic-medical-record/emr-editor/socket/useEmrSocket";
|
|
|
|
|
|
type Pl<D> = {
|
|
|
- [K in keyof D]: D[K] extends (...args: any[]) => infer R ? R : any;
|
|
|
+ [K in keyof D]: D[K] extends (...args: any[]) => infer R ? R : any;
|
|
|
};
|
|
|
|
|
|
export const rightCompIndex = {
|
|
|
- opinion: 0,
|
|
|
- ca: 1,
|
|
|
+ opinion: 0,
|
|
|
+ ca: 1,
|
|
|
};
|
|
|
|
|
|
function getPlugins() {
|
|
|
- const tmp = {};
|
|
|
- for (let key in utilsPlugins) {
|
|
|
- tmp[key] = utilsPlugins[key]();
|
|
|
- }
|
|
|
- return tmp as Pl<typeof utilsPlugins>;
|
|
|
+ const tmp = {};
|
|
|
+ for (let key in utilsPlugins) {
|
|
|
+ tmp[key] = utilsPlugins[key]();
|
|
|
+ }
|
|
|
+ return tmp as Pl<typeof utilsPlugins>;
|
|
|
}
|
|
|
|
|
|
export type RightComp = {
|
|
|
- name: string;
|
|
|
- comp: any;
|
|
|
- refValue?: any;
|
|
|
- paneProps?: any;
|
|
|
+ name: string;
|
|
|
+ comp: any;
|
|
|
+ refValue?: any;
|
|
|
+ paneProps?: any;
|
|
|
};
|
|
|
|
|
|
export const useEmrStore = (patId: string) => {
|
|
|
- const patInfo = ref({});
|
|
|
- const emrPatientData = ref({});
|
|
|
- const outline = ref<Outline[]>([]);
|
|
|
- let editor: EditType | null = null;
|
|
|
+ const patInfo = ref({});
|
|
|
+ const emrPatientData = ref({});
|
|
|
+ const outline = ref<Outline[]>([]);
|
|
|
+ let editor: EditType | null = null;
|
|
|
|
|
|
- const emrTemplate = ref({
|
|
|
- emrTree: [],
|
|
|
- deptTree: [],
|
|
|
- patientTree: [],
|
|
|
- });
|
|
|
+ const emrTemplate = ref({
|
|
|
+ emrTree: [],
|
|
|
+ deptTree: [],
|
|
|
+ patientTree: [],
|
|
|
+ });
|
|
|
|
|
|
- const store = reactive({
|
|
|
- currentPlugins: [] as ReturnPlugins[],
|
|
|
- plugins: [] as ReturnPlugins[],
|
|
|
- right: EmrRightTabs.fragment,
|
|
|
- rightWidth: 220,
|
|
|
- courseJumpId: null,
|
|
|
- editor: null as EditType,
|
|
|
- rightComp: [] as RightComp[],
|
|
|
- // 病历的名称
|
|
|
- templateName: "",
|
|
|
- // 病历的编码
|
|
|
- categoryCode: "",
|
|
|
- // 如果不是模板就有这个
|
|
|
- emrPatientData: {} as EmrPatientData,
|
|
|
- parent: "",
|
|
|
- isEditorChange: false,
|
|
|
+ const store = reactive({
|
|
|
+ currentPlugins: [] as ReturnPlugins[],
|
|
|
+ plugins: [] as ReturnPlugins[],
|
|
|
+ right: EmrRightTabs.fragment,
|
|
|
+ rightWidth: 220,
|
|
|
+ courseJumpId: null,
|
|
|
+ editor: null as EditType,
|
|
|
+ rightComp: [] as RightComp[],
|
|
|
+ // 病历的名称
|
|
|
+ templateName: "",
|
|
|
+ // 病历的编码
|
|
|
+ categoryCode: "",
|
|
|
+ // 如果不是模板就有这个
|
|
|
+ emrPatientData: {} as EmrPatientData,
|
|
|
+ parent: "",
|
|
|
+ isEditorChange: false,
|
|
|
|
|
|
- currentDocumentData: [] as { id: string; name: string }[],
|
|
|
+ currentDocumentData: [] as { id: string; name: string }[],
|
|
|
|
|
|
- socketToken: "",
|
|
|
- });
|
|
|
+ socketToken: "",
|
|
|
+ });
|
|
|
|
|
|
- const kicked = reactive({
|
|
|
- // 踢人方
|
|
|
- a: {
|
|
|
- dialog: false,
|
|
|
- id: "",
|
|
|
- waitForSeconds: 0,
|
|
|
- resolve: () => {
|
|
|
- },
|
|
|
- reject: () => {
|
|
|
- },
|
|
|
+ const kicked = reactive({
|
|
|
+ // 踢人方
|
|
|
+ a: {
|
|
|
+ dialog: false,
|
|
|
+ id: "",
|
|
|
+ waitForSeconds: 0,
|
|
|
+ resolve: () => {},
|
|
|
+ reject: () => {},
|
|
|
|
|
|
- open(value: string) {
|
|
|
- kicked.a.waitForSeconds = 0;
|
|
|
- kicked.a.id = value;
|
|
|
- kicked.a.dialog = true;
|
|
|
- return new Promise((resolve, reject) => {
|
|
|
- //@ts-ignore
|
|
|
- kicked.a.resolve = resolve;
|
|
|
- kicked.a.reject = reject;
|
|
|
- });
|
|
|
- },
|
|
|
- },
|
|
|
- // 被踢方
|
|
|
- b: {
|
|
|
- dialog: false,
|
|
|
- title: "",
|
|
|
- message: [],
|
|
|
- userInfo: {},
|
|
|
- wsSend: (value: { code: string; data?: any }) => {
|
|
|
- },
|
|
|
- onMsg: {
|
|
|
- kickItOut: value => {
|
|
|
- kicked.b.userInfo = value;
|
|
|
- kicked.b.dialog = true;
|
|
|
- kicked.b.title = `【${value.name}】想要编辑,当前病历`;
|
|
|
- },
|
|
|
- },
|
|
|
- agree: () => 0 as any,
|
|
|
+ open(value: string) {
|
|
|
+ kicked.a.waitForSeconds = 0;
|
|
|
+ kicked.a.id = value;
|
|
|
+ kicked.a.dialog = true;
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
+ //@ts-ignore
|
|
|
+ kicked.a.resolve = resolve;
|
|
|
+ kicked.a.reject = reject;
|
|
|
+ });
|
|
|
+ },
|
|
|
+ },
|
|
|
+ // 被踢方
|
|
|
+ b: {
|
|
|
+ dialog: false,
|
|
|
+ title: "",
|
|
|
+ message: [],
|
|
|
+ userInfo: {},
|
|
|
+ wsSend: (value: { code: string; data?: any }) => {},
|
|
|
+ onMsg: {
|
|
|
+ kickItOut: value => {
|
|
|
+ kicked.b.userInfo = value;
|
|
|
+ kicked.b.dialog = true;
|
|
|
+ kicked.b.title = `【${value.name}】想要编辑,当前病历`;
|
|
|
},
|
|
|
- });
|
|
|
+ },
|
|
|
+ agree: () => 0 as any,
|
|
|
+ },
|
|
|
+ });
|
|
|
|
|
|
- const plugins = getPlugins();
|
|
|
- const editFun = emrFunUtils();
|
|
|
-
|
|
|
- const mutation = {
|
|
|
- setEmrPatientData(data: any) {
|
|
|
- emrPatientData.value = data;
|
|
|
- },
|
|
|
- setEditor(value: EditType) {
|
|
|
- editor = value;
|
|
|
- store.editor = editor;
|
|
|
- editFun.setEditor(value);
|
|
|
- },
|
|
|
- async setOutline() {
|
|
|
- await sleep(500);
|
|
|
- outline.value = editor.getOutline();
|
|
|
- },
|
|
|
- installPlugins(value: UseEmrInitReturn, tmpStore: any) {
|
|
|
- for (let key in plugins) {
|
|
|
- const item = plugins[key];
|
|
|
- item?.install?.({e: value.editor, r: value.runtime, s: tmpStore});
|
|
|
- store.plugins.push(item);
|
|
|
- }
|
|
|
- },
|
|
|
- setCurrentPlugin(code: string) {
|
|
|
- if (!code) {
|
|
|
- store.currentPlugins = [];
|
|
|
- }
|
|
|
- const tmp = [];
|
|
|
- for (let i = 0; i < store.plugins.length; i++) {
|
|
|
- const item = store.plugins[i];
|
|
|
- if (typeof item.categoryCode === "undefined") {
|
|
|
- tmp.push(item);
|
|
|
- }
|
|
|
- if (item.categoryCode && item.categoryCode.includes(code)) {
|
|
|
- tmp.push(item);
|
|
|
- }
|
|
|
- }
|
|
|
- store.currentPlugins = tmp;
|
|
|
- },
|
|
|
- };
|
|
|
+ const plugins = getPlugins();
|
|
|
+ const editFun = emrFunUtils();
|
|
|
|
|
|
- const cache = {
|
|
|
- open() {
|
|
|
- if (window.indexedDB) {
|
|
|
- editor?.openCache();
|
|
|
- xcMessage.success("您的电脑支持本地缓存");
|
|
|
- return;
|
|
|
- }
|
|
|
- xcMessage.error("您的电脑不支持缓存,请升级浏览器");
|
|
|
- },
|
|
|
- saveCache() {
|
|
|
- if (editor == null) {
|
|
|
- xcMessage.error("无法缓存,请等待页面加载完成");
|
|
|
- return;
|
|
|
- }
|
|
|
- if (!editor!._cacheDBIsOpen) {
|
|
|
- xcMessage.error("您的电脑不支持缓存,请升级浏览器");
|
|
|
- return;
|
|
|
- }
|
|
|
- let key = "";
|
|
|
- if (stringNotBlank(editor?.documentData._id)) {
|
|
|
- key = "id-" + editor?.documentData._id;
|
|
|
- } else if (stringNotBlank(editor?.documentData.categoryId)) {
|
|
|
- key = "code-" + patId + "-" + editor?.documentData.categoryId;
|
|
|
- } else {
|
|
|
- xcMessage.error("无法缓存,请先打开一个病历");
|
|
|
- return;
|
|
|
- }
|
|
|
- editor.setCacheData(key);
|
|
|
- xcMessage.success("缓存成功,刷新后可恢复");
|
|
|
- },
|
|
|
- getAll(table = "docdata") {
|
|
|
- const promise = usePromise<{ _key: string }[]>();
|
|
|
+ const mutation = {
|
|
|
+ setEmrPatientData(data: any) {
|
|
|
+ emrPatientData.value = data;
|
|
|
+ },
|
|
|
+ setEditor(value: EditType) {
|
|
|
+ editor = value;
|
|
|
+ store.editor = editor;
|
|
|
+ editFun.setEditor(value);
|
|
|
+ },
|
|
|
+ async setOutline() {
|
|
|
+ await sleep(500);
|
|
|
+ outline.value = editor.getOutline();
|
|
|
+ },
|
|
|
+ installPlugins(value: UseEmrInitReturn, tmpStore: any) {
|
|
|
+ for (let key in plugins) {
|
|
|
+ const item = plugins[key];
|
|
|
+ item?.install?.({ e: value.editor, r: value.runtime, s: tmpStore });
|
|
|
+ store.plugins.push(item);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ setCurrentPlugin(code: string) {
|
|
|
+ if (!code) {
|
|
|
+ store.currentPlugins = [];
|
|
|
+ }
|
|
|
+ const tmp = [];
|
|
|
+ for (let i = 0; i < store.plugins.length; i++) {
|
|
|
+ const item = store.plugins[i];
|
|
|
+ if (typeof item.categoryCode === "undefined") {
|
|
|
+ tmp.push(item);
|
|
|
+ }
|
|
|
+ if (item.categoryCode && item.categoryCode.includes(code)) {
|
|
|
+ tmp.push(item);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ store.currentPlugins = tmp;
|
|
|
+ },
|
|
|
+ };
|
|
|
|
|
|
- const transaction = editor!._cacheDB.db.transaction(table, "readwrite");
|
|
|
- transaction.oncomplete = event => {
|
|
|
- promise.resolve(event);
|
|
|
- };
|
|
|
- transaction.onerror = event => {
|
|
|
- promise.reject(event);
|
|
|
- };
|
|
|
- let objectStore = transaction.objectStore(table);
|
|
|
- objectStore.getAll().onsuccess = event => {
|
|
|
- // @ts-ignore
|
|
|
- const data = event.target.result;
|
|
|
- if (XEUtils.isArray(data)) {
|
|
|
- promise.resolve(data);
|
|
|
- } else {
|
|
|
- promise.reject(event);
|
|
|
- }
|
|
|
- };
|
|
|
- return promise.promise;
|
|
|
- },
|
|
|
- reduction({
|
|
|
- id,
|
|
|
- categoryId,
|
|
|
- }: {
|
|
|
- id: string | null | undefined;
|
|
|
- categoryId: string;
|
|
|
- }) {
|
|
|
- return new Promise(async (resolve, reject) => {
|
|
|
- const cacheData = await this.getAll().catch(() => []);
|
|
|
- let key = "";
|
|
|
- if (stringNotBlank(id)) {
|
|
|
- key = "id-" + id;
|
|
|
- } else if (stringNotBlank(categoryId)) {
|
|
|
- key = "code-" + patId + "-" + categoryId;
|
|
|
- }
|
|
|
+ const cache = {
|
|
|
+ open() {
|
|
|
+ if (window.indexedDB) {
|
|
|
+ editor?.openCache();
|
|
|
+ xcMessage.success("您的电脑支持本地缓存");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ xcMessage.error("您的电脑不支持缓存,请升级浏览器");
|
|
|
+ },
|
|
|
+ saveCache() {
|
|
|
+ if (editor == null) {
|
|
|
+ xcMessage.error("无法缓存,请等待页面加载完成");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (!editor!._cacheDBIsOpen) {
|
|
|
+ xcMessage.error("您的电脑不支持缓存,请升级浏览器");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ let key = "";
|
|
|
+ if (stringNotBlank(editor?.documentData._id)) {
|
|
|
+ key = "id-" + editor?.documentData._id;
|
|
|
+ } else if (stringNotBlank(editor?.documentData.categoryId)) {
|
|
|
+ key = "code-" + patId + "-" + editor?.documentData.categoryId;
|
|
|
+ } else {
|
|
|
+ xcMessage.error("无法缓存,请先打开一个病历");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ editor.setCacheData(key);
|
|
|
+ xcMessage.success("缓存成功,刷新后可恢复");
|
|
|
+ },
|
|
|
+ getAll(table = "docdata") {
|
|
|
+ const promise = usePromise<{ _key: string }[]>();
|
|
|
|
|
|
- function dialog(dataKey: string) {
|
|
|
- CyMessageBox.confirm({
|
|
|
- message: "监测到本地缓存是否使用缓存的数据",
|
|
|
- confirmButtonText: "使用",
|
|
|
- cancelButtonText: "不使用",
|
|
|
- })
|
|
|
- .then(() => {
|
|
|
- editor!.loadCacheData(dataKey);
|
|
|
- editor!.delCacheData(dataKey);
|
|
|
- resolve(true);
|
|
|
- })
|
|
|
- .catch(() => {
|
|
|
- reject(false);
|
|
|
- });
|
|
|
- }
|
|
|
+ const transaction = editor!._cacheDB.db.transaction(table, "readwrite");
|
|
|
+ transaction.oncomplete = event => {
|
|
|
+ promise.resolve(event);
|
|
|
+ };
|
|
|
+ transaction.onerror = event => {
|
|
|
+ promise.reject(event);
|
|
|
+ };
|
|
|
+ let objectStore = transaction.objectStore(table);
|
|
|
+ objectStore.getAll().onsuccess = event => {
|
|
|
+ // @ts-ignore
|
|
|
+ const data = event.target.result;
|
|
|
+ if (XEUtils.isArray(data)) {
|
|
|
+ promise.resolve(data);
|
|
|
+ } else {
|
|
|
+ promise.reject(event);
|
|
|
+ }
|
|
|
+ };
|
|
|
+ return promise.promise;
|
|
|
+ },
|
|
|
+ reduction({
|
|
|
+ id,
|
|
|
+ categoryId,
|
|
|
+ }: {
|
|
|
+ id: string | null | undefined;
|
|
|
+ categoryId: string;
|
|
|
+ }) {
|
|
|
+ return new Promise(async (resolve, reject) => {
|
|
|
+ const cacheData = await this.getAll().catch(() => []);
|
|
|
+ let key = "";
|
|
|
+ if (stringNotBlank(id)) {
|
|
|
+ key = "id-" + id;
|
|
|
+ } else if (stringNotBlank(categoryId)) {
|
|
|
+ key = "code-" + patId + "-" + categoryId;
|
|
|
+ }
|
|
|
|
|
|
- for (let i = 0; i < cacheData.length; i++) {
|
|
|
- const item = cacheData[i];
|
|
|
- if (item._key === key) {
|
|
|
- dialog(item._key);
|
|
|
- return;
|
|
|
- }
|
|
|
- }
|
|
|
- reject(false);
|
|
|
+ function dialog(dataKey: string) {
|
|
|
+ CyMessageBox.confirm({
|
|
|
+ message: "监测到本地缓存是否使用缓存的数据",
|
|
|
+ confirmButtonText: "使用",
|
|
|
+ cancelButtonText: "不使用",
|
|
|
+ })
|
|
|
+ .then(() => {
|
|
|
+ editor!.loadCacheData(dataKey);
|
|
|
+ editor!.delCacheData(dataKey);
|
|
|
+ resolve(true);
|
|
|
+ })
|
|
|
+ .catch(() => {
|
|
|
+ reject(false);
|
|
|
});
|
|
|
- },
|
|
|
- };
|
|
|
-
|
|
|
- const emrSocket = socket.useEmrSocket(patId, store, () => editor);
|
|
|
- const documentSocket = socket.documentSocket(kicked, () => editor);
|
|
|
-
|
|
|
- return {
|
|
|
- patInfo,
|
|
|
- getEditor() {
|
|
|
- return editor;
|
|
|
- },
|
|
|
- documentSocket,
|
|
|
- emrSocket,
|
|
|
- emrPatientData,
|
|
|
- mutation,
|
|
|
- outline,
|
|
|
- cache,
|
|
|
- plugins,
|
|
|
- store,
|
|
|
- emrTemplate,
|
|
|
- editFun,
|
|
|
- kicked,
|
|
|
- getRightComp(index) {
|
|
|
- return store.rightComp[index];
|
|
|
- },
|
|
|
- };
|
|
|
-};
|
|
|
+ }
|
|
|
|
|
|
-type EmrStore = ReturnType<typeof useEmrStore>;
|
|
|
-export const emrRootContextKey = "emrRootContext"
|
|
|
+ for (let i = 0; i < cacheData.length; i++) {
|
|
|
+ const item = cacheData[i];
|
|
|
+ if (item._key === key) {
|
|
|
+ dialog(item._key);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ reject(false);
|
|
|
+ });
|
|
|
+ },
|
|
|
+ };
|
|
|
|
|
|
-type EmrRootContext = {
|
|
|
- store: EmrStore;
|
|
|
-}
|
|
|
+ const emrSocket = socket.useEmrSocket(patId, store, () => editor);
|
|
|
+ const documentSocket = socket.documentSocket(kicked, () => editor);
|
|
|
|
|
|
-export type {EmrStore, EmrRootContext};
|
|
|
+ return {
|
|
|
+ patInfo,
|
|
|
+ getEditor() {
|
|
|
+ return editor;
|
|
|
+ },
|
|
|
+ documentSocket,
|
|
|
+ emrSocket,
|
|
|
+ emrPatientData,
|
|
|
+ mutation,
|
|
|
+ outline,
|
|
|
+ cache,
|
|
|
+ plugins,
|
|
|
+ store,
|
|
|
+ emrTemplate,
|
|
|
+ editFun,
|
|
|
+ kicked,
|
|
|
+ getRightComp(index) {
|
|
|
+ return store.rightComp[index];
|
|
|
+ },
|
|
|
+ };
|
|
|
+};
|
|
|
|
|
|
+export type EmrStore = ReturnType<typeof useEmrStore>;
|
|
|
+export const emrRootContextKey = "emrRootContext";
|
|
|
|
|
|
export const elementHas = (
|
|
|
- view,
|
|
|
- name,
|
|
|
- code: "internal" | "business" = "internal"
|
|
|
+ view,
|
|
|
+ name,
|
|
|
+ code: "internal" | "business" = "internal"
|
|
|
) => {
|
|
|
- const element = view.getAttribute("element");
|
|
|
- if (element) {
|
|
|
- const data = XEUtils.get(element, `code.${code}`);
|
|
|
- if (data === name) {
|
|
|
- return element;
|
|
|
- }
|
|
|
+ const element = view.getAttribute("element");
|
|
|
+ if (element) {
|
|
|
+ const data = XEUtils.get(element, `code.${code}`);
|
|
|
+ if (data === name) {
|
|
|
+ return element;
|
|
|
}
|
|
|
- throw new Error("no elementHas");
|
|
|
+ }
|
|
|
+ throw new Error("no elementHas");
|
|
|
};
|
|
|
-
|