2022-06-02 06:36:30 +00:00
|
|
|
|
<!doctype html>
|
2022-05-04 11:04:58 +00:00
|
|
|
|
<html>
|
|
|
|
|
<head>
|
2022-06-02 06:36:30 +00:00
|
|
|
|
<meta charset='UTF-8'><meta name='viewport' content='width=device-width initial-scale=1'>
|
|
|
|
|
|
|
|
|
|
<link href='https://fonts.loli.net/css?family=Open+Sans:400italic,700italic,700,400&subset=latin,latin-ext' rel='stylesheet' type='text/css' /><style type='text/css'>html {overflow-x: initial !important;}:root { --bg-color:#ffffff; --text-color:#333333; --select-text-bg-color:#B5D6FC; --select-text-font-color:auto; --monospace:"Lucida Console",Consolas,"Courier",monospace; --title-bar-height:20px; }
|
|
|
|
|
.mac-os-11 { --title-bar-height:28px; }
|
|
|
|
|
html { font-size: 14px; background-color: var(--bg-color); color: var(--text-color); font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; }
|
|
|
|
|
body { margin: 0px; padding: 0px; height: auto; inset: 0px; font-size: 1rem; line-height: 1.42857; overflow-x: hidden; background: inherit; tab-size: 4; }
|
|
|
|
|
iframe { margin: auto; }
|
|
|
|
|
a.url { word-break: break-all; }
|
|
|
|
|
a:active, a:hover { outline: 0px; }
|
|
|
|
|
.in-text-selection, ::selection { text-shadow: none; background: var(--select-text-bg-color); color: var(--select-text-font-color); }
|
|
|
|
|
#write { margin: 0px auto; height: auto; width: inherit; word-break: normal; overflow-wrap: break-word; position: relative; white-space: normal; overflow-x: visible; padding-top: 36px; }
|
|
|
|
|
#write.first-line-indent p { text-indent: 2em; }
|
|
|
|
|
#write.first-line-indent li p, #write.first-line-indent p * { text-indent: 0px; }
|
|
|
|
|
#write.first-line-indent li { margin-left: 2em; }
|
|
|
|
|
.for-image #write { padding-left: 8px; padding-right: 8px; }
|
|
|
|
|
body.typora-export { padding-left: 30px; padding-right: 30px; }
|
|
|
|
|
.typora-export .footnote-line, .typora-export li, .typora-export p { white-space: pre-wrap; }
|
|
|
|
|
.typora-export .task-list-item input { pointer-events: none; }
|
|
|
|
|
@media screen and (max-width: 500px) {
|
|
|
|
|
body.typora-export { padding-left: 0px; padding-right: 0px; }
|
|
|
|
|
#write { padding-left: 20px; padding-right: 20px; }
|
|
|
|
|
}
|
|
|
|
|
#write li > figure:last-child { margin-bottom: 0.5rem; }
|
|
|
|
|
#write ol, #write ul { position: relative; }
|
|
|
|
|
img { max-width: 100%; vertical-align: middle; image-orientation: from-image; }
|
|
|
|
|
button, input, select, textarea { color: inherit; font: inherit; }
|
|
|
|
|
input[type="checkbox"], input[type="radio"] { line-height: normal; padding: 0px; }
|
|
|
|
|
*, ::after, ::before { box-sizing: border-box; }
|
|
|
|
|
#write h1, #write h2, #write h3, #write h4, #write h5, #write h6, #write p, #write pre { width: inherit; }
|
|
|
|
|
#write h1, #write h2, #write h3, #write h4, #write h5, #write h6, #write p { position: relative; }
|
|
|
|
|
p { line-height: inherit; }
|
|
|
|
|
h1, h2, h3, h4, h5, h6 { break-after: avoid-page; break-inside: avoid; orphans: 4; }
|
|
|
|
|
p { orphans: 4; }
|
|
|
|
|
h1 { font-size: 2rem; }
|
|
|
|
|
h2 { font-size: 1.8rem; }
|
|
|
|
|
h3 { font-size: 1.6rem; }
|
|
|
|
|
h4 { font-size: 1.4rem; }
|
|
|
|
|
h5 { font-size: 1.2rem; }
|
|
|
|
|
h6 { font-size: 1rem; }
|
|
|
|
|
.md-math-block, .md-rawblock, h1, h2, h3, h4, h5, h6, p { margin-top: 1rem; margin-bottom: 1rem; }
|
|
|
|
|
.hidden { display: none; }
|
|
|
|
|
.md-blockmeta { color: rgb(204, 204, 204); font-weight: 700; font-style: italic; }
|
|
|
|
|
a { cursor: pointer; }
|
|
|
|
|
sup.md-footnote { padding: 2px 4px; background-color: rgba(238, 238, 238, 0.7); color: rgb(85, 85, 85); border-radius: 4px; cursor: pointer; }
|
|
|
|
|
sup.md-footnote a, sup.md-footnote a:hover { color: inherit; text-transform: inherit; text-decoration: inherit; }
|
|
|
|
|
#write input[type="checkbox"] { cursor: pointer; width: inherit; height: inherit; }
|
|
|
|
|
figure { overflow-x: auto; margin: 1.2em 0px; max-width: calc(100% + 16px); padding: 0px; }
|
|
|
|
|
figure > table { margin: 0px; }
|
2022-07-02 02:20:17 +00:00
|
|
|
|
thead, tr { break-inside: avoid; break-after: auto; }
|
2022-06-02 06:36:30 +00:00
|
|
|
|
thead { display: table-header-group; }
|
|
|
|
|
table { border-collapse: collapse; border-spacing: 0px; width: 100%; overflow: auto; break-inside: auto; text-align: left; }
|
|
|
|
|
table.md-table td { min-width: 32px; }
|
|
|
|
|
.CodeMirror-gutters { border-right: 0px; background-color: inherit; }
|
|
|
|
|
.CodeMirror-linenumber { user-select: none; }
|
|
|
|
|
.CodeMirror { text-align: left; }
|
|
|
|
|
.CodeMirror-placeholder { opacity: 0.3; }
|
|
|
|
|
.CodeMirror pre { padding: 0px 4px; }
|
|
|
|
|
.CodeMirror-lines { padding: 0px; }
|
|
|
|
|
div.hr:focus { cursor: none; }
|
|
|
|
|
#write pre { white-space: pre-wrap; }
|
|
|
|
|
#write.fences-no-line-wrapping pre { white-space: pre; }
|
|
|
|
|
#write pre.ty-contain-cm { white-space: normal; }
|
|
|
|
|
.CodeMirror-gutters { margin-right: 4px; }
|
|
|
|
|
.md-fences { font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; overflow: visible; white-space: pre; background: inherit; position: relative !important; }
|
|
|
|
|
.md-fences-adv-panel { width: 100%; margin-top: 10px; text-align: center; padding-top: 0px; padding-bottom: 8px; overflow-x: auto; }
|
|
|
|
|
#write .md-fences.mock-cm { white-space: pre-wrap; }
|
|
|
|
|
.md-fences.md-fences-with-lineno { padding-left: 0px; }
|
|
|
|
|
#write.fences-no-line-wrapping .md-fences.mock-cm { white-space: pre; overflow-x: auto; }
|
|
|
|
|
.md-fences.mock-cm.md-fences-with-lineno { padding-left: 8px; }
|
|
|
|
|
.CodeMirror-line, twitterwidget { break-inside: avoid; }
|
2022-07-02 02:20:17 +00:00
|
|
|
|
svg { break-inside: avoid; }
|
2022-06-02 06:36:30 +00:00
|
|
|
|
.footnotes { opacity: 0.8; font-size: 0.9rem; margin-top: 1em; margin-bottom: 1em; }
|
|
|
|
|
.footnotes + .footnotes { margin-top: 0px; }
|
|
|
|
|
.md-reset { margin: 0px; padding: 0px; border: 0px; outline: 0px; vertical-align: top; background: 0px 0px; text-decoration: none; text-shadow: none; float: none; position: static; width: auto; height: auto; white-space: nowrap; cursor: inherit; -webkit-tap-highlight-color: transparent; line-height: normal; font-weight: 400; text-align: left; box-sizing: content-box; direction: ltr; }
|
|
|
|
|
li div { padding-top: 0px; }
|
|
|
|
|
blockquote { margin: 1rem 0px; }
|
|
|
|
|
li .mathjax-block, li p { margin: 0.5rem 0px; }
|
|
|
|
|
li blockquote { margin: 1rem 0px; }
|
|
|
|
|
li { margin: 0px; position: relative; }
|
|
|
|
|
blockquote > :last-child { margin-bottom: 0px; }
|
|
|
|
|
blockquote > :first-child, li > :first-child { margin-top: 0px; }
|
|
|
|
|
.footnotes-area { color: rgb(136, 136, 136); margin-top: 0.714rem; padding-bottom: 0.143rem; white-space: normal; }
|
|
|
|
|
#write .footnote-line { white-space: pre-wrap; }
|
|
|
|
|
@media print {
|
|
|
|
|
body, html { border: 1px solid transparent; height: 99%; break-after: avoid; break-before: avoid; font-variant-ligatures: no-common-ligatures; }
|
2022-07-02 02:20:17 +00:00
|
|
|
|
#write { margin-top: 0px; padding-top: 0px; border-color: transparent !important; padding-bottom: 0px !important; }
|
2022-06-02 06:36:30 +00:00
|
|
|
|
.typora-export * { -webkit-print-color-adjust: exact; }
|
|
|
|
|
.typora-export #write { break-after: avoid; }
|
|
|
|
|
.typora-export #write::after { height: 0px; }
|
|
|
|
|
.is-mac table { break-inside: avoid; }
|
|
|
|
|
.typora-export-show-outline .typora-export-sidebar { display: none; }
|
|
|
|
|
}
|
|
|
|
|
.footnote-line { margin-top: 0.714em; font-size: 0.7em; }
|
|
|
|
|
a img, img a { cursor: pointer; }
|
|
|
|
|
pre.md-meta-block { font-size: 0.8rem; min-height: 0.8rem; white-space: pre-wrap; background: rgb(204, 204, 204); display: block; overflow-x: hidden; }
|
|
|
|
|
p > .md-image:only-child:not(.md-img-error) img, p > img:only-child { display: block; margin: auto; }
|
|
|
|
|
#write.first-line-indent p > .md-image:only-child:not(.md-img-error) img { left: -2em; position: relative; }
|
|
|
|
|
p > .md-image:only-child { display: inline-block; width: 100%; }
|
|
|
|
|
#write .MathJax_Display { margin: 0.8em 0px 0px; }
|
|
|
|
|
.md-math-block { width: 100%; }
|
|
|
|
|
.md-math-block:not(:empty)::after { display: none; }
|
|
|
|
|
.MathJax_ref { fill: currentcolor; }
|
|
|
|
|
[contenteditable="true"]:active, [contenteditable="true"]:focus, [contenteditable="false"]:active, [contenteditable="false"]:focus { outline: 0px; box-shadow: none; }
|
|
|
|
|
.md-task-list-item { position: relative; list-style-type: none; }
|
|
|
|
|
.task-list-item.md-task-list-item { padding-left: 0px; }
|
|
|
|
|
.md-task-list-item > input { position: absolute; top: 0px; left: 0px; margin-left: -1.2em; margin-top: calc(1em - 10px); border: none; }
|
|
|
|
|
.math { font-size: 1rem; }
|
|
|
|
|
.md-toc { min-height: 3.58rem; position: relative; font-size: 0.9rem; border-radius: 10px; }
|
|
|
|
|
.md-toc-content { position: relative; margin-left: 0px; }
|
|
|
|
|
.md-toc-content::after, .md-toc::after { display: none; }
|
|
|
|
|
.md-toc-item { display: block; color: rgb(65, 131, 196); }
|
|
|
|
|
.md-toc-item a { text-decoration: none; }
|
|
|
|
|
.md-toc-inner:hover { text-decoration: underline; }
|
|
|
|
|
.md-toc-inner { display: inline-block; cursor: pointer; }
|
|
|
|
|
.md-toc-h1 .md-toc-inner { margin-left: 0px; font-weight: 700; }
|
|
|
|
|
.md-toc-h2 .md-toc-inner { margin-left: 2em; }
|
|
|
|
|
.md-toc-h3 .md-toc-inner { margin-left: 4em; }
|
|
|
|
|
.md-toc-h4 .md-toc-inner { margin-left: 6em; }
|
|
|
|
|
.md-toc-h5 .md-toc-inner { margin-left: 8em; }
|
|
|
|
|
.md-toc-h6 .md-toc-inner { margin-left: 10em; }
|
|
|
|
|
@media screen and (max-width: 48em) {
|
|
|
|
|
.md-toc-h3 .md-toc-inner { margin-left: 3.5em; }
|
|
|
|
|
.md-toc-h4 .md-toc-inner { margin-left: 5em; }
|
|
|
|
|
.md-toc-h5 .md-toc-inner { margin-left: 6.5em; }
|
|
|
|
|
.md-toc-h6 .md-toc-inner { margin-left: 8em; }
|
|
|
|
|
}
|
|
|
|
|
a.md-toc-inner { font-size: inherit; font-style: inherit; font-weight: inherit; line-height: inherit; }
|
|
|
|
|
.footnote-line a:not(.reversefootnote) { color: inherit; }
|
2022-07-02 02:20:17 +00:00
|
|
|
|
.reversefootnote { font-family: ui-monospace, sans-serif; }
|
2022-06-02 06:36:30 +00:00
|
|
|
|
.md-attr { display: none; }
|
|
|
|
|
.md-fn-count::after { content: "."; }
|
|
|
|
|
code, pre, samp, tt { font-family: var(--monospace); }
|
|
|
|
|
kbd { margin: 0px 0.1em; padding: 0.1em 0.6em; font-size: 0.8em; color: rgb(36, 39, 41); background: rgb(255, 255, 255); border: 1px solid rgb(173, 179, 185); border-radius: 3px; box-shadow: rgba(12, 13, 14, 0.2) 0px 1px 0px, rgb(255, 255, 255) 0px 0px 0px 2px inset; white-space: nowrap; vertical-align: middle; }
|
|
|
|
|
.md-comment { color: rgb(162, 127, 3); opacity: 0.6; font-family: var(--monospace); }
|
|
|
|
|
code { text-align: left; vertical-align: initial; }
|
|
|
|
|
a.md-print-anchor { white-space: pre !important; border-width: initial !important; border-style: none !important; border-color: initial !important; display: inline-block !important; position: absolute !important; width: 1px !important; right: 0px !important; outline: 0px !important; background: 0px 0px !important; text-decoration: initial !important; text-shadow: initial !important; }
|
|
|
|
|
.os-windows.monocolor-emoji .md-emoji { font-family: "Segoe UI Symbol", sans-serif; }
|
|
|
|
|
.md-diagram-panel > svg { max-width: 100%; }
|
|
|
|
|
[lang="flow"] svg, [lang="mermaid"] svg { max-width: 100%; height: auto; }
|
|
|
|
|
[lang="mermaid"] .node text { font-size: 1rem; }
|
|
|
|
|
table tr th { border-bottom: 0px; }
|
|
|
|
|
video { max-width: 100%; display: block; margin: 0px auto; }
|
|
|
|
|
iframe { max-width: 100%; width: 100%; border: none; }
|
|
|
|
|
.highlight td, .highlight tr { border: 0px; }
|
|
|
|
|
mark { background: rgb(255, 255, 0); color: rgb(0, 0, 0); }
|
|
|
|
|
.md-html-inline .md-plain, .md-html-inline strong, mark .md-inline-math, mark strong { color: inherit; }
|
|
|
|
|
.md-expand mark .md-meta { opacity: 0.3 !important; }
|
|
|
|
|
mark .md-meta { color: rgb(0, 0, 0); }
|
|
|
|
|
@media print {
|
|
|
|
|
.typora-export h1, .typora-export h2, .typora-export h3, .typora-export h4, .typora-export h5, .typora-export h6 { break-inside: avoid; }
|
|
|
|
|
}
|
|
|
|
|
.md-diagram-panel .messageText { stroke: none !important; }
|
|
|
|
|
.md-diagram-panel .start-state { fill: var(--node-fill); }
|
|
|
|
|
.md-diagram-panel .edgeLabel rect { opacity: 1 !important; }
|
|
|
|
|
.md-fences.md-fences-math { font-size: 1em; }
|
|
|
|
|
.md-fences-advanced:not(.md-focus) { padding: 0px; white-space: nowrap; border: 0px; }
|
|
|
|
|
.md-fences-advanced:not(.md-focus) { background: inherit; }
|
|
|
|
|
.typora-export-show-outline .typora-export-content { max-width: 1440px; margin: auto; display: flex; flex-direction: row; }
|
|
|
|
|
.typora-export-sidebar { width: 300px; font-size: 0.8rem; margin-top: 80px; margin-right: 18px; }
|
|
|
|
|
.typora-export-show-outline #write { --webkit-flex:2; flex: 2 1 0%; }
|
|
|
|
|
.typora-export-sidebar .outline-content { position: fixed; top: 0px; max-height: 100%; overflow: hidden auto; padding-bottom: 30px; padding-top: 60px; width: 300px; }
|
|
|
|
|
@media screen and (max-width: 1024px) {
|
|
|
|
|
.typora-export-sidebar, .typora-export-sidebar .outline-content { width: 240px; }
|
|
|
|
|
}
|
|
|
|
|
@media screen and (max-width: 800px) {
|
|
|
|
|
.typora-export-sidebar { display: none; }
|
|
|
|
|
}
|
|
|
|
|
.outline-content li, .outline-content ul { margin-left: 0px; margin-right: 0px; padding-left: 0px; padding-right: 0px; list-style: none; }
|
|
|
|
|
.outline-content ul { margin-top: 0px; margin-bottom: 0px; }
|
|
|
|
|
.outline-content strong { font-weight: 400; }
|
|
|
|
|
.outline-expander { width: 1rem; height: 1.42857rem; position: relative; display: table-cell; vertical-align: middle; cursor: pointer; padding-left: 4px; }
|
|
|
|
|
.outline-expander::before { content: ""; position: relative; font-family: Ionicons; display: inline-block; font-size: 8px; vertical-align: middle; }
|
|
|
|
|
.outline-item { padding-top: 3px; padding-bottom: 3px; cursor: pointer; }
|
|
|
|
|
.outline-expander:hover::before { content: ""; }
|
|
|
|
|
.outline-h1 > .outline-item { padding-left: 0px; }
|
|
|
|
|
.outline-h2 > .outline-item { padding-left: 1em; }
|
|
|
|
|
.outline-h3 > .outline-item { padding-left: 2em; }
|
|
|
|
|
.outline-h4 > .outline-item { padding-left: 3em; }
|
|
|
|
|
.outline-h5 > .outline-item { padding-left: 4em; }
|
|
|
|
|
.outline-h6 > .outline-item { padding-left: 5em; }
|
|
|
|
|
.outline-label { cursor: pointer; display: table-cell; vertical-align: middle; text-decoration: none; color: inherit; }
|
|
|
|
|
.outline-label:hover { text-decoration: underline; }
|
|
|
|
|
.outline-item:hover { border-color: rgb(245, 245, 245); background-color: var(--item-hover-bg-color); }
|
|
|
|
|
.outline-item:hover { margin-left: -28px; margin-right: -28px; border-left: 28px solid transparent; border-right: 28px solid transparent; }
|
|
|
|
|
.outline-item-single .outline-expander::before, .outline-item-single .outline-expander:hover::before { display: none; }
|
|
|
|
|
.outline-item-open > .outline-item > .outline-expander::before { content: ""; }
|
|
|
|
|
.outline-children { display: none; }
|
|
|
|
|
.info-panel-tab-wrapper { display: none; }
|
|
|
|
|
.outline-item-open > .outline-children { display: block; }
|
|
|
|
|
.typora-export .outline-item { padding-top: 1px; padding-bottom: 1px; }
|
|
|
|
|
.typora-export .outline-item:hover { margin-right: -8px; border-right: 8px solid transparent; }
|
|
|
|
|
.typora-export .outline-expander::before { content: "+"; font-family: inherit; top: -1px; }
|
|
|
|
|
.typora-export .outline-expander:hover::before, .typora-export .outline-item-open > .outline-item > .outline-expander::before { content: "−"; }
|
|
|
|
|
.typora-export-collapse-outline .outline-children { display: none; }
|
|
|
|
|
.typora-export-collapse-outline .outline-item-open > .outline-children, .typora-export-no-collapse-outline .outline-children { display: block; }
|
|
|
|
|
.typora-export-no-collapse-outline .outline-expander::before { content: "" !important; }
|
|
|
|
|
.typora-export-show-outline .outline-item-active > .outline-item .outline-label { font-weight: 700; }
|
|
|
|
|
.md-inline-math-container mjx-container { zoom: 0.95; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.CodeMirror { height: auto; }
|
|
|
|
|
.CodeMirror.cm-s-inner { background: inherit; }
|
|
|
|
|
.CodeMirror-scroll { overflow: auto hidden; z-index: 3; }
|
|
|
|
|
.CodeMirror-gutter-filler, .CodeMirror-scrollbar-filler { background-color: rgb(255, 255, 255); }
|
|
|
|
|
.CodeMirror-gutters { border-right: 1px solid rgb(221, 221, 221); background: inherit; white-space: nowrap; }
|
|
|
|
|
.CodeMirror-linenumber { padding: 0px 3px 0px 5px; text-align: right; color: rgb(153, 153, 153); }
|
|
|
|
|
.cm-s-inner .cm-keyword { color: rgb(119, 0, 136); }
|
|
|
|
|
.cm-s-inner .cm-atom, .cm-s-inner.cm-atom { color: rgb(34, 17, 153); }
|
|
|
|
|
.cm-s-inner .cm-number { color: rgb(17, 102, 68); }
|
|
|
|
|
.cm-s-inner .cm-def { color: rgb(0, 0, 255); }
|
|
|
|
|
.cm-s-inner .cm-variable { color: rgb(0, 0, 0); }
|
|
|
|
|
.cm-s-inner .cm-variable-2 { color: rgb(0, 85, 170); }
|
|
|
|
|
.cm-s-inner .cm-variable-3 { color: rgb(0, 136, 85); }
|
|
|
|
|
.cm-s-inner .cm-string { color: rgb(170, 17, 17); }
|
|
|
|
|
.cm-s-inner .cm-property { color: rgb(0, 0, 0); }
|
|
|
|
|
.cm-s-inner .cm-operator { color: rgb(152, 26, 26); }
|
|
|
|
|
.cm-s-inner .cm-comment, .cm-s-inner.cm-comment { color: rgb(170, 85, 0); }
|
|
|
|
|
.cm-s-inner .cm-string-2 { color: rgb(255, 85, 0); }
|
|
|
|
|
.cm-s-inner .cm-meta { color: rgb(85, 85, 85); }
|
|
|
|
|
.cm-s-inner .cm-qualifier { color: rgb(85, 85, 85); }
|
|
|
|
|
.cm-s-inner .cm-builtin { color: rgb(51, 0, 170); }
|
|
|
|
|
.cm-s-inner .cm-bracket { color: rgb(153, 153, 119); }
|
|
|
|
|
.cm-s-inner .cm-tag { color: rgb(17, 119, 0); }
|
|
|
|
|
.cm-s-inner .cm-attribute { color: rgb(0, 0, 204); }
|
|
|
|
|
.cm-s-inner .cm-header, .cm-s-inner.cm-header { color: rgb(0, 0, 255); }
|
|
|
|
|
.cm-s-inner .cm-quote, .cm-s-inner.cm-quote { color: rgb(0, 153, 0); }
|
|
|
|
|
.cm-s-inner .cm-hr, .cm-s-inner.cm-hr { color: rgb(153, 153, 153); }
|
|
|
|
|
.cm-s-inner .cm-link, .cm-s-inner.cm-link { color: rgb(0, 0, 204); }
|
|
|
|
|
.cm-negative { color: rgb(221, 68, 68); }
|
|
|
|
|
.cm-positive { color: rgb(34, 153, 34); }
|
|
|
|
|
.cm-header, .cm-strong { font-weight: 700; }
|
|
|
|
|
.cm-del { text-decoration: line-through; }
|
|
|
|
|
.cm-em { font-style: italic; }
|
|
|
|
|
.cm-link { text-decoration: underline; }
|
|
|
|
|
.cm-error { color: red; }
|
|
|
|
|
.cm-invalidchar { color: red; }
|
|
|
|
|
.cm-constant { color: rgb(38, 139, 210); }
|
|
|
|
|
.cm-defined { color: rgb(181, 137, 0); }
|
|
|
|
|
div.CodeMirror span.CodeMirror-matchingbracket { color: rgb(0, 255, 0); }
|
|
|
|
|
div.CodeMirror span.CodeMirror-nonmatchingbracket { color: rgb(255, 34, 34); }
|
|
|
|
|
.cm-s-inner .CodeMirror-activeline-background { background: inherit; }
|
|
|
|
|
.CodeMirror { position: relative; overflow: hidden; }
|
|
|
|
|
.CodeMirror-scroll { height: 100%; outline: 0px; position: relative; box-sizing: content-box; background: inherit; }
|
|
|
|
|
.CodeMirror-sizer { position: relative; }
|
|
|
|
|
.CodeMirror-gutter-filler, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-vscrollbar { position: absolute; z-index: 6; display: none; outline: 0px; }
|
|
|
|
|
.CodeMirror-vscrollbar { right: 0px; top: 0px; overflow: hidden; }
|
|
|
|
|
.CodeMirror-hscrollbar { bottom: 0px; left: 0px; overflow: auto hidden; }
|
|
|
|
|
.CodeMirror-scrollbar-filler { right: 0px; bottom: 0px; }
|
|
|
|
|
.CodeMirror-gutter-filler { left: 0px; bottom: 0px; }
|
|
|
|
|
.CodeMirror-gutters { position: absolute; left: 0px; top: 0px; padding-bottom: 10px; z-index: 3; overflow-y: hidden; }
|
|
|
|
|
.CodeMirror-gutter { white-space: normal; height: 100%; box-sizing: content-box; padding-bottom: 30px; margin-bottom: -32px; display: inline-block; }
|
|
|
|
|
.CodeMirror-gutter-wrapper { position: absolute; z-index: 4; background: 0px 0px !important; border: none !important; }
|
|
|
|
|
.CodeMirror-gutter-background { position: absolute; top: 0px; bottom: 0px; z-index: 4; }
|
|
|
|
|
.CodeMirror-gutter-elt { position: absolute; cursor: default; z-index: 4; }
|
|
|
|
|
.CodeMirror-lines { cursor: text; }
|
|
|
|
|
.CodeMirror pre { border-radius: 0px; border-width: 0px; background: 0px 0px; font-family: inherit; font-size: inherit; margin: 0px; white-space: pre; overflow-wrap: normal; color: inherit; z-index: 2; position: relative; overflow: visible; }
|
|
|
|
|
.CodeMirror-wrap pre { overflow-wrap: break-word; white-space: pre-wrap; word-break: normal; }
|
|
|
|
|
.CodeMirror-code pre { border-right: 30px solid transparent; width: fit-content; }
|
|
|
|
|
.CodeMirror-wrap .CodeMirror-code pre { border-right: none; width: auto; }
|
|
|
|
|
.CodeMirror-linebackground { position: absolute; inset: 0px; z-index: 0; }
|
|
|
|
|
.CodeMirror-linewidget { position: relative; z-index: 2; overflow: auto; }
|
|
|
|
|
.CodeMirror-wrap .CodeMirror-scroll { overflow-x: hidden; }
|
|
|
|
|
.CodeMirror-measure { position: absolute; width: 100%; height: 0px; overflow: hidden; visibility: hidden; }
|
|
|
|
|
.CodeMirror-measure pre { position: static; }
|
|
|
|
|
.CodeMirror div.CodeMirror-cursor { position: absolute; visibility: hidden; border-right: none; width: 0px; }
|
|
|
|
|
.CodeMirror div.CodeMirror-cursor { visibility: hidden; }
|
|
|
|
|
.CodeMirror-focused div.CodeMirror-cursor { visibility: inherit; }
|
|
|
|
|
.cm-searching { background: rgba(255, 255, 0, 0.4); }
|
|
|
|
|
span.cm-underlined { text-decoration: underline; }
|
|
|
|
|
span.cm-strikethrough { text-decoration: line-through; }
|
|
|
|
|
.cm-tw-syntaxerror { color: rgb(255, 255, 255); background-color: rgb(153, 0, 0); }
|
|
|
|
|
.cm-tw-deleted { text-decoration: line-through; }
|
|
|
|
|
.cm-tw-header5 { font-weight: 700; }
|
|
|
|
|
.cm-tw-listitem:first-child { padding-left: 10px; }
|
|
|
|
|
.cm-tw-box { border-style: solid; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-color: inherit; border-top-width: 0px !important; }
|
|
|
|
|
.cm-tw-underline { text-decoration: underline; }
|
|
|
|
|
@media print {
|
|
|
|
|
.CodeMirror div.CodeMirror-cursor { visibility: hidden; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
:root {
|
|
|
|
|
--side-bar-bg-color: #fafafa;
|
|
|
|
|
--control-text-color: #777;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@include-when-export url(https://fonts.loli.net/css?family=Open+Sans:400italic,700italic,700,400&subset=latin,latin-ext);
|
|
|
|
|
|
|
|
|
|
/* open-sans-regular - latin-ext_latin */
|
|
|
|
|
/* open-sans-italic - latin-ext_latin */
|
|
|
|
|
/* open-sans-700 - latin-ext_latin */
|
|
|
|
|
/* open-sans-700italic - latin-ext_latin */
|
|
|
|
|
html {
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
-webkit-font-smoothing: antialiased;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
body {
|
|
|
|
|
font-family: "Open Sans","Clear Sans", "Helvetica Neue", Helvetica, Arial, 'Segoe UI Emoji', sans-serif;
|
|
|
|
|
color: rgb(51, 51, 51);
|
|
|
|
|
line-height: 1.6;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#write {
|
|
|
|
|
max-width: 860px;
|
|
|
|
|
margin: 0 auto;
|
|
|
|
|
padding: 30px;
|
|
|
|
|
padding-bottom: 100px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@media only screen and (min-width: 1400px) {
|
|
|
|
|
#write {
|
|
|
|
|
max-width: 1024px;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@media only screen and (min-width: 1800px) {
|
|
|
|
|
#write {
|
|
|
|
|
max-width: 1200px;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#write > ul:first-child,
|
|
|
|
|
#write > ol:first-child{
|
|
|
|
|
margin-top: 30px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
a {
|
|
|
|
|
color: #4183C4;
|
|
|
|
|
}
|
|
|
|
|
h1,
|
|
|
|
|
h2,
|
|
|
|
|
h3,
|
|
|
|
|
h4,
|
|
|
|
|
h5,
|
|
|
|
|
h6 {
|
|
|
|
|
position: relative;
|
|
|
|
|
margin-top: 1rem;
|
|
|
|
|
margin-bottom: 1rem;
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
line-height: 1.4;
|
|
|
|
|
cursor: text;
|
|
|
|
|
}
|
|
|
|
|
h1:hover a.anchor,
|
|
|
|
|
h2:hover a.anchor,
|
|
|
|
|
h3:hover a.anchor,
|
|
|
|
|
h4:hover a.anchor,
|
|
|
|
|
h5:hover a.anchor,
|
|
|
|
|
h6:hover a.anchor {
|
|
|
|
|
text-decoration: none;
|
|
|
|
|
}
|
|
|
|
|
h1 tt,
|
|
|
|
|
h1 code {
|
|
|
|
|
font-size: inherit;
|
|
|
|
|
}
|
|
|
|
|
h2 tt,
|
|
|
|
|
h2 code {
|
|
|
|
|
font-size: inherit;
|
|
|
|
|
}
|
|
|
|
|
h3 tt,
|
|
|
|
|
h3 code {
|
|
|
|
|
font-size: inherit;
|
|
|
|
|
}
|
|
|
|
|
h4 tt,
|
|
|
|
|
h4 code {
|
|
|
|
|
font-size: inherit;
|
|
|
|
|
}
|
|
|
|
|
h5 tt,
|
|
|
|
|
h5 code {
|
|
|
|
|
font-size: inherit;
|
|
|
|
|
}
|
|
|
|
|
h6 tt,
|
|
|
|
|
h6 code {
|
|
|
|
|
font-size: inherit;
|
|
|
|
|
}
|
|
|
|
|
h1 {
|
|
|
|
|
font-size: 2.25em;
|
|
|
|
|
line-height: 1.2;
|
|
|
|
|
border-bottom: 1px solid #eee;
|
|
|
|
|
}
|
|
|
|
|
h2 {
|
|
|
|
|
font-size: 1.75em;
|
|
|
|
|
line-height: 1.225;
|
|
|
|
|
border-bottom: 1px solid #eee;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*@media print {
|
|
|
|
|
.typora-export h1,
|
|
|
|
|
.typora-export h2 {
|
|
|
|
|
border-bottom: none;
|
|
|
|
|
padding-bottom: initial;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.typora-export h1::after,
|
|
|
|
|
.typora-export h2::after {
|
|
|
|
|
content: "";
|
|
|
|
|
display: block;
|
|
|
|
|
height: 100px;
|
|
|
|
|
margin-top: -96px;
|
|
|
|
|
border-top: 1px solid #eee;
|
|
|
|
|
}
|
|
|
|
|
}*/
|
|
|
|
|
|
|
|
|
|
h3 {
|
|
|
|
|
font-size: 1.5em;
|
|
|
|
|
line-height: 1.43;
|
|
|
|
|
}
|
|
|
|
|
h4 {
|
|
|
|
|
font-size: 1.25em;
|
|
|
|
|
}
|
|
|
|
|
h5 {
|
|
|
|
|
font-size: 1em;
|
|
|
|
|
}
|
|
|
|
|
h6 {
|
|
|
|
|
font-size: 1em;
|
|
|
|
|
color: #777;
|
|
|
|
|
}
|
|
|
|
|
p,
|
|
|
|
|
blockquote,
|
|
|
|
|
ul,
|
|
|
|
|
ol,
|
|
|
|
|
dl,
|
|
|
|
|
table{
|
|
|
|
|
margin: 0.8em 0;
|
|
|
|
|
}
|
|
|
|
|
li>ol,
|
|
|
|
|
li>ul {
|
|
|
|
|
margin: 0 0;
|
|
|
|
|
}
|
|
|
|
|
hr {
|
|
|
|
|
height: 2px;
|
|
|
|
|
padding: 0;
|
|
|
|
|
margin: 16px 0;
|
|
|
|
|
background-color: #e7e7e7;
|
|
|
|
|
border: 0 none;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
box-sizing: content-box;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
li p.first {
|
|
|
|
|
display: inline-block;
|
|
|
|
|
}
|
|
|
|
|
ul,
|
|
|
|
|
ol {
|
|
|
|
|
padding-left: 30px;
|
|
|
|
|
}
|
|
|
|
|
ul:first-child,
|
|
|
|
|
ol:first-child {
|
|
|
|
|
margin-top: 0;
|
|
|
|
|
}
|
|
|
|
|
ul:last-child,
|
|
|
|
|
ol:last-child {
|
|
|
|
|
margin-bottom: 0;
|
|
|
|
|
}
|
|
|
|
|
blockquote {
|
|
|
|
|
border-left: 4px solid #dfe2e5;
|
|
|
|
|
padding: 0 15px;
|
|
|
|
|
color: #777777;
|
|
|
|
|
}
|
|
|
|
|
blockquote blockquote {
|
|
|
|
|
padding-right: 0;
|
|
|
|
|
}
|
|
|
|
|
table {
|
|
|
|
|
padding: 0;
|
|
|
|
|
word-break: initial;
|
|
|
|
|
}
|
|
|
|
|
table tr {
|
|
|
|
|
border: 1px solid #dfe2e5;
|
|
|
|
|
margin: 0;
|
|
|
|
|
padding: 0;
|
|
|
|
|
}
|
|
|
|
|
table tr:nth-child(2n),
|
|
|
|
|
thead {
|
|
|
|
|
background-color: #f8f8f8;
|
|
|
|
|
}
|
|
|
|
|
table th {
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
border: 1px solid #dfe2e5;
|
|
|
|
|
border-bottom: 0;
|
|
|
|
|
margin: 0;
|
|
|
|
|
padding: 6px 13px;
|
|
|
|
|
}
|
|
|
|
|
table td {
|
|
|
|
|
border: 1px solid #dfe2e5;
|
|
|
|
|
margin: 0;
|
|
|
|
|
padding: 6px 13px;
|
|
|
|
|
}
|
|
|
|
|
table th:first-child,
|
|
|
|
|
table td:first-child {
|
|
|
|
|
margin-top: 0;
|
|
|
|
|
}
|
|
|
|
|
table th:last-child,
|
|
|
|
|
table td:last-child {
|
|
|
|
|
margin-bottom: 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.CodeMirror-lines {
|
|
|
|
|
padding-left: 4px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.code-tooltip {
|
|
|
|
|
box-shadow: 0 1px 1px 0 rgba(0,28,36,.3);
|
|
|
|
|
border-top: 1px solid #eef2f2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.md-fences,
|
|
|
|
|
code,
|
|
|
|
|
tt {
|
|
|
|
|
border: 1px solid #e7eaed;
|
|
|
|
|
background-color: #f8f8f8;
|
|
|
|
|
border-radius: 3px;
|
|
|
|
|
padding: 0;
|
|
|
|
|
padding: 2px 4px 0px 4px;
|
|
|
|
|
font-size: 0.9em;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
code {
|
|
|
|
|
background-color: #f3f4f4;
|
|
|
|
|
padding: 0 2px 0 2px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.md-fences {
|
|
|
|
|
margin-bottom: 15px;
|
|
|
|
|
margin-top: 15px;
|
|
|
|
|
padding-top: 8px;
|
|
|
|
|
padding-bottom: 6px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.md-task-list-item > input {
|
|
|
|
|
margin-left: -1.3em;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@media print {
|
|
|
|
|
html {
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
}
|
|
|
|
|
pre {
|
|
|
|
|
page-break-inside: avoid;
|
|
|
|
|
word-wrap: break-word;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.md-fences {
|
|
|
|
|
background-color: #f8f8f8;
|
|
|
|
|
}
|
|
|
|
|
#write pre.md-meta-block {
|
|
|
|
|
padding: 1rem;
|
|
|
|
|
font-size: 85%;
|
|
|
|
|
line-height: 1.45;
|
|
|
|
|
background-color: #f7f7f7;
|
|
|
|
|
border: 0;
|
|
|
|
|
border-radius: 3px;
|
|
|
|
|
color: #777777;
|
|
|
|
|
margin-top: 0 !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.mathjax-block>.code-tooltip {
|
|
|
|
|
bottom: .375rem;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.md-mathjax-midline {
|
|
|
|
|
background: #fafafa;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#write>h3.md-focus:before{
|
|
|
|
|
left: -1.5625rem;
|
|
|
|
|
top: .375rem;
|
|
|
|
|
}
|
|
|
|
|
#write>h4.md-focus:before{
|
|
|
|
|
left: -1.5625rem;
|
|
|
|
|
top: .285714286rem;
|
|
|
|
|
}
|
|
|
|
|
#write>h5.md-focus:before{
|
|
|
|
|
left: -1.5625rem;
|
|
|
|
|
top: .285714286rem;
|
|
|
|
|
}
|
|
|
|
|
#write>h6.md-focus:before{
|
|
|
|
|
left: -1.5625rem;
|
|
|
|
|
top: .285714286rem;
|
|
|
|
|
}
|
|
|
|
|
.md-image>.md-meta {
|
|
|
|
|
/*border: 1px solid #ddd;*/
|
|
|
|
|
border-radius: 3px;
|
|
|
|
|
padding: 2px 0px 0px 4px;
|
|
|
|
|
font-size: 0.9em;
|
|
|
|
|
color: inherit;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.md-tag {
|
|
|
|
|
color: #a7a7a7;
|
|
|
|
|
opacity: 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.md-toc {
|
|
|
|
|
margin-top:20px;
|
|
|
|
|
padding-bottom:20px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.sidebar-tabs {
|
|
|
|
|
border-bottom: none;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#typora-quick-open {
|
|
|
|
|
border: 1px solid #ddd;
|
|
|
|
|
background-color: #f8f8f8;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#typora-quick-open-item {
|
|
|
|
|
background-color: #FAFAFA;
|
|
|
|
|
border-color: #FEFEFE #e5e5e5 #e5e5e5 #eee;
|
|
|
|
|
border-style: solid;
|
|
|
|
|
border-width: 1px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** focus mode */
|
|
|
|
|
.on-focus-mode blockquote {
|
|
|
|
|
border-left-color: rgba(85, 85, 85, 0.12);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
header, .context-menu, .megamenu-content, footer{
|
|
|
|
|
font-family: "Segoe UI", "Arial", sans-serif;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.file-node-content:hover .file-node-icon,
|
|
|
|
|
.file-node-content:hover .file-node-open-state{
|
|
|
|
|
visibility: visible;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.mac-seamless-mode #typora-sidebar {
|
|
|
|
|
background-color: #fafafa;
|
|
|
|
|
background-color: var(--side-bar-bg-color);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.md-lang {
|
|
|
|
|
color: #b4654d;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*.html-for-mac {
|
|
|
|
|
--item-hover-bg-color: #E6F0FE;
|
|
|
|
|
}*/
|
|
|
|
|
|
|
|
|
|
#md-notification .btn {
|
|
|
|
|
border: 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.dropdown-menu .divider {
|
|
|
|
|
border-color: #e5e5e5;
|
|
|
|
|
opacity: 0.4;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.ty-preferences .window-content {
|
|
|
|
|
background-color: #fafafa;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.ty-preferences .nav-group-item.active {
|
|
|
|
|
color: white;
|
|
|
|
|
background: #999;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.menu-item-container a.menu-style-btn {
|
|
|
|
|
background-color: #f5f8fa;
|
|
|
|
|
background-image: linear-gradient( 180deg , hsla(0, 0%, 100%, 0.8), hsla(0, 0%, 100%, 0));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2022-06-08 07:52:50 +00:00
|
|
|
|
</style><title>物联网平台开发及使用手册</title>
|
2022-05-04 11:04:58 +00:00
|
|
|
|
</head>
|
2022-06-02 06:36:30 +00:00
|
|
|
|
<body class='typora-export os-windows typora-export-show-outline typora-export-collapse-outline'><div class='typora-export-content'>
|
2022-07-02 02:20:17 +00:00
|
|
|
|
<div class="typora-export-sidebar"><div class="outline-content"><li class="outline-item-wrapper outline-h2"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#0-前言说明">0 前言说明</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#01-编译说明">0.1 编译说明</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#02-功能特点">0.2 功能特点</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#021-软件模块">0.2.1 软件模块</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#022-基础功能">0.2.2 基础功能</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#023-特色功能">0.2.3 特色功能</a></div><ul class="outline-children"></ul></li></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#03-相关站点">0.3 相关站点</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#04-特别说明">0.4 特别说明</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#05-简易操作">0.5 简易操作</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#06-版本说明">0.6 版本说明</a></div><ul class="outline-children"></ul></li></ul></li><li class="outline-item-wrapper outline-h2"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#1-用户登录退出">1 用户登录退出</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#11-用户登录">1.1 用户登录</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h3 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#12-用户退出">1.2 用户退出</a></div><ul class="outline-children"></ul></li></ul></li><li class="outline-item-wrapper outline-h2"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#2-系统设置">2 系统设置</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h3"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#21-基本设置">2.1 基本设置</a></div><ul class="outline-children"><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#211-常规设置">2.1.1 常规设置</a></div><ul class="outline-children"></ul></li><li class="outline-item-wrapper outline-h4 outline-item-single"><div class="outline-item"><span class="outline-expander"></span><a class="outline-label" href="#212-本地数据库设置">2.1.2 本地数据库设置</a></div><ul class="outline-children"></ul></li><
|
|
|
|
|
<span> </span><img src="snap/1-1-2.jpg" referrerpolicy="no-referrer"></p><p><span>系统启动后,首先会弹出用户登录界面,从用户姓名的下拉框选择用户名,然后输入密码(默认用户名密码都是admin),单击登录按钮,密码正确则会进入到系统主界面,错误会弹出提示,错误超过三次自动关闭,需要重新打开软件。</span></p><p><span>在登录界面可以勾选是否记住密码,是否自动登录,如果勾选了记住密码,则下次启用软件会自动填入最后用户的密码,勾选了自动登录(以最后的用户信息作为当前登录用户)则启动后直接进入主界面。如果开启了自动登录,不会弹出登录界面,可以在系统设置中关闭自动登录和记住密码。</span></p><h3 id='12-用户退出'><span>1.2 用户退出</span></h3><p><span> </span><img src="snap/1-2-1.jpg" referrerpolicy="no-referrer"></p><p><span>在主界面单击右上角的关闭按钮,会弹出用户退出界面,需要输入密码验证防止误关闭,会自动填入登录的用户名,密码输入正确才会退出软件。用户登录和退出都内置了超级密码a防止管理员忘记密码。</span></p><h2 id='2-系统设置'><span>2 系统设置</span></h2><h3 id='21-基本设置'><span>2.1 基本设置</span></h3><p><span> </span><img src="snap/2-1-0.jpg" referrerpolicy="no-referrer"></p><h4 id='211-常规设置'><span>2.1.1 常规设置</span></h4><p><span> </span><img src="snap/2-1-1.jpg" referrerpolicy="no-referrer"></p><p><span>基本设置中有部分参数的切换会自动重启应用。</span></p><p><strong><span>参数说明</span></strong></p><ol start='' ><li><span>开机运行:开启以后自动随着系统启动运行,默认开启。</span></li><li><span>自动登录:开启以后会自动以最后登录的用户信息登录到系统,默认关闭。</span></li><li><span>记住密码:开启以后会自动填入最后登录的用户信息到登录窗体,默认关闭。</span></li><li><span>中文标题:软件左上角标题栏的中文标题,改动立即应用。</span></li><li><span>英文标题:软件左上角标题栏的英文标题,改动立即应用。</span></li><li><span>版权所有:当前软件版权所有的公司,显示在软件的底部信息栏中。</span></li><li><span>调试日志:开启后会将打印日志输出到日志文件,默认关闭,日志文件存放在可执行文件夹下的log目录下。</span></li><li><span>运行时间:开启后会实时记录系统的运行时间,记录当前软件启动后运行了多久,运行时间文件存放在可执行文件夹下的log目录下。</span></li><li><span>工作模式:默认设备采集,可选数据库采集、数据库读取、设备采集2等,一般都是特殊定制需求的在这里切换工作模式。</span></li><li><span>导航样式:用于选择顶部导航栏和左侧导航栏的样式,上侧+左侧表示顶部导航栏上侧样式(图标在上面,文字在下面),左侧导航栏左侧样式(图标在左侧,文字在右侧)。</span></li><li><span>界面样式:系统自带17套皮肤,可以在这里自动换肤,默认视频黑。</span></li><li><span>软件图标:自动从logo文件夹读取,可以自行选择对应的logo文件。</span></li><li><span>报警声音:开启后当探测器报警后,会播放报警声音,默认开启。</span></li><li><span>播放次数:播放报警声音的次数,默认1次。</span></li><li><span>警情行数:主界面运行监测左侧显示报警信息的最大行数。新警情自动追加在最前面。0表示自动根据尺寸填充,100表示禁用。</span></li><li><span>自动确认:开启后自动确认警情存入报警记录,默认开启。</span></li><li><span>设备列数:设备监控主界面设备面板的列数。</span></li><li><span>记录行数:在数据查询的表格中,显示的记录的行数。</span></li></ol><p><strong><span>工作模式</span></strong></p><ol start='' ><li
|
2022-06-02 06:36:30 +00:00
|
|
|
|
</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -34.9916px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">13</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-comment">//自动切换默认数据库端口</span></span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -34.9916px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">14</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable-3">void</span> <span class="cm-def">DbHelper::getDbDefaultInfo</span>(<span class="cm-keyword">const</span> <span class="cm-variable">QString</span> <span class="cm-operator">&</span><span class="cm-variable">dbType</span>, <span class="cm-variable">QString</span> <span class="cm-operator">&</span><span class="cm-variable">hostPort</span>,</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -34.9916px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">15</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> <span class="cm-variable">QString</span> <span class="cm-operator">&</span><span class="cm-variable">userName</span>, <span class="cm-variable">QString</span> <span class="cm-operator">&</span><span class="cm-variable">userPwd</span>)</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -34.9916px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">16</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">{</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -34.9916px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">17</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> <span class="cm-keyword">if</span> (<span class="cm-variable">dbType</span> <span class="cm-operator">==</span> <span class="cm-string">"MYSQL"</span>) {</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -34.9916px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">18</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> <span class="cm-variable">hostPort</span> <span class="cm-operator">=</span> <span class="cm-string">"3306"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -34.9916px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt" style="left: 0px; width: 27px;">19</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> <span class="cm-variable">userName</span> <span class="cm-operator">=</span> <span class="cm-string">"root"</span>;</span></pre></div><div style="position: relative;"><div class="CodeMirror-gutter-wrapper" style="left: -34.9916px;"><div class="CodeMirror-linenumber CodeMirror-gutter-elt CodeMirror-linenumber-show" style="left: 0px; width: 27px;">20</div></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> <span class="cm-variable">userPwd</span> <span class="cm-operator">=</span> <span class="cm-string">"root"</span>;</span></pre></div><div style="position: relative;"><d
|
|
|
|
|
<span> </span><img src="snap/3-1-8-2.jpg" referrerpolicy="no-referrer"></p><p><span>假设设置了用户没有系统设置和删除记录的权限,则关闭系统的时候会弹出错误信息提示当前用户没有权限。</span></p><h3 id='32-地图管理'><span>3.2 地图管理</span></h3><p><span> </span><img src="snap/3-2-1.jpg" referrerpolicy="no-referrer"></p><p><span>在地图管理中,可以导入和删除地图。</span></p><h3 id='33-位置调整'><span>3.3 位置调整</span></h3><p><span> </span><img src="snap/3-3-1.jpg" referrerpolicy="no-referrer"></p><p><span>位置调整中,可以拖动探测器到正确的位置,右侧单击地图切换可以看到对应的该地图对应的探测器,全部位置调整好之后,单击右下角保存按钮即可,会立即应用。</span></p><h3 id='34-组态设计'><span>3.4 组态设计</span></h3><p><span> </span><img src="snap/3-4-1.jpg" referrerpolicy="no-referrer"></p><p><span>组态设计模块中提供的是简单的示例,演示如何加载自定义控件动态库、将控件拖曳到背景地图上,配置好对应控件的属性,可定义用户属性,可导出控件的配置信息到xml文件,并支持导入xml文件自动加载上次保存的控件配置信息。目前是一个简单的组态雏形,等后期架构好如何应用再重写整个模块。</span></p><p><strong><span>本系统默认不包括里面控件的源码,提供动态库的形式使用,如果还想学习自定义控件大全的源码(目前共202个控件卖700元),需要额外单独购买。</span></strong></p><h3 id='35-设备调试'><span>3.5 设备调试</span></h3><p><span> </span><img src="snap/3-5-1.jpg" referrerpolicy="no-referrer"></p><p><span>可以自行选择通讯端口+设备名称进行数据的过滤,可查看所有的通信数据。不同收发数据不同颜色,还可以指定关键字过滤数据,每个收发数据都有对应的中文解释。能够很方便的对运行中的系统查看设备数据,规避是下位机还是上位机问题扯皮的事情。</span></p><h2 id='4-设备监控'><span>4 设备监控</span></h2><p><span> </span><img src="snap/4-0-1.jpg" referrerpolicy="no-referrer"></p><p><span>设备监控界面主要包括4个模块,分别是数据监控、设备面板、地图监控、曲线监控,设备的实时数据可以同时反应到四个模块上面,相当于以4种不同的表现形式展现采集到的数据。</span></p><p><strong><span>模式说明</span></strong></p><ul><li><span>数据监控:表格形式一行行展示数据。</span></li><li><span>设备面板:每个探测器都是个独立的一个面板展示数据和信息。</span></li><li><span>地图监控:设备按钮放在对应地图上,长条状显示数据和符号单位。</span></li><li><span>曲线监控:对每个设备过滤曲线显示采集到的数据。</span></li><li><span>设备报警后,如果设置了报警弹窗,则右下角都会弹出对应的报警信息。</span></li><li><span>设备报警后,对应表格行、设备面板、地图按钮等都会突出颜色显示。</span></li></ul><h3 id='41-数据监控'><span>4.1 数据监控</span></h3><p><span> </span><img src="snap/4-1-1.jpg" referrerpolicy="no-referrer"></p><p><span>本页面会是使用频率最高的页面,默认就是停留在本页面实时查看所有探测器的数据。左侧为警情信息栏,分别显示时间、位号、报警值。如果有探测器报警,则消息自动追加到最前面。</span>
|
2022-07-02 02:20:17 +00:00
|
|
|
|
<span>表格依次显示序号、位号、控制器名称、控制器型号、探测器名称、探测器型号、气体种类、浓度值、气体符号。</span></p><h3 id='42-设备面板'><span>4.2 设备面板</span></h3><p><strong><span>面板说明</span></strong></p><ol start='' ><li><span>探测器作为一个个独立的设备面板控件。</span></li><li><span>有多少个探测器就会生成多少个面板,放在面板容器中。</span></li><li><span>可以在系统设置中选择设备列数,按照该设备列数来排列,超过会自动产生滚动条拖动查看。</span></li><li><span>报警后整个设备面板会突出颜色显示比如高报是红色、低报是黄色等。</span></li><li><span>双击探测器面板,会跳转到该探测器的详细信息界面,在该界面上后期可以按照实际用户需求定制回控操作。</span></li><li><span>面板有多种样式可供选择,比如普通样式、仪表样式。可直接在右侧切换立即运用。</span></li></ol><h4 id='421-普通样式'><span>4.2.1 普通样式</span></h4><p><span> </span><img src="snap/4-2-1.jpg" referrerpolicy="no-referrer"></p><h4 id='422-仪表样式'><span>4.2.2 仪表样式</span></h4><p><img src="snap/4-2-2.jpg" referrerpolicy="no-referrer"></p><h4 id='423-仪表样式2'><span>4.2.3 仪表样式2</span></h4><p><img src="snap/4-2-3.jpg" referrerpolicy="no-referrer"></p><h3 id='43-地图监控'><span>4.3 地图监控</span></h3><p><span> </span><img src="snap/4-3-1.jpg" referrerpolicy="no-referrer"></p><p><span>本页面以地图的形式显示所有探测器,右侧单击对应地图可以手动切换地图,当探测器报警后会自动切换到当前地图,探测器图标红色闪烁,探测器图标实时显示当前的浓度值。双击探测器按钮图标,会跳转到该探测器的详细信息界面,在该界面上后期可以按照实际用户需求定制回控操作。</span></p><h3 id='44-曲线监控'><span>4.4 曲线监控</span></h3><p><span>在本页面可以查看某个探测器的实时曲线,第一步先选择通信端口,第二步选择控制器,第三步选择探测器,然后就可以在左侧看到实时曲线,颜色可以在系统设置中设置。单击打印按钮会将当前曲线以截图的形式打印出来。勾选暂停显示记录数据复选框会暂停显示当前的数据。</span></p><h4 id='441-实时曲线'><span>4.4.1 实时曲线</span></h4><p><span> </span><img src="snap/4-4-1.jpg" referrerpolicy="no-referrer"></p><h4 id='442-历史曲线'><span>4.4.2 历史曲线</span></h4><p><span> </span><img src="snap/4-4-2.jpg" referrerpolicy="no-referrer"></p><h2 id='5-数据查询'><span>5 数据查询</span></h2><h3 id='51-报警记录'><span>5.1 报警记录</span></h3><p><span>在本页面,可以指定日期范围查询报警记录,还可以查询单个的控制器或者探测器的报警记录。也可以手动输入探测器的位号进行查询,下拉选择探测器后会自动填入位号。还可以选择报警类型(浓度上限报警、浓度下限报警)查询对应的类型,也可以输入报警值进行精准查询。</span></p><p><span>如果数据超过一页,会自动分页处理,单击右侧的上一页、下一页、第一页、末一页进行翻页查看,所有查询的数据可以导出到excel表格,也可以直接打印。单击删除按钮会弹出时间范围选择框,选择该时间段后确定,会删除该时间段的所有记录。</span></p><p><span>双击对应的报警记录可以打开警情确认对话框,重新填写确认意见,鼠标右键弹出删除记录菜单,可以删除当前选中的记录,支持多选,例如按住Ctrl键选择多个记录。</span></p><h4 id='511-记录查询'><span>5.1.1 记录查询</span></h4><p><span> </span><img src="snap/5-1-1.jpg" referrerpolicy="no-referrer"></p><h4 id='512-记录打印'><span>5.1.2 记录打印</span></h4><p><span> </span><img src="snap/5-1-2.jpg" referrerpolicy="no-referrer"></p><h4 id='513-记录导出'><span>5.1.3 记录导出</
|
2022-06-02 06:36:30 +00:00
|
|
|
|
<span> </span><img src="snap/5-1-4.jpg" referrerpolicy="no-referrer"></p><h3 id='52-运行记录'><span>5.2 运行记录</span></h3><p><span>在本页面,可以指定日期范围查询运行记录,还可以查询单个的控制器或者探测器的运行记录。也可以手动输入探测器的位号进行查询,下拉选择探测器后会自动填入位号。</span></p><p><span>如果数据超过一页,会自动分页处理,单击右侧的上一页、下一页、第一页、末一页进行翻页查看,所有查询的数据可以导出到excel表格,也可以直接打印。单击删除按钮会弹出时间范围选择框,选择该时间段后确定,会删除该时间段的所有记录。</span></p><h4 id='521-记录查询'><span>5.2.1 记录查询</span></h4><p><span> </span><img src="snap/5-2-1.jpg" referrerpolicy="no-referrer"></p><h4 id='522-记录打印'><span>5.2.2 记录打印</span></h4><p><span> </span><img src="snap/5-2-2.jpg" referrerpolicy="no-referrer"></p><h4 id='523-记录导出'><span>5.2.3 记录导出</span></h4><p><span> </span><img src="snap/5-2-3.jpg" referrerpolicy="no-referrer">
|
|
|
|
|
<span> </span><img src="snap/5-2-4.jpg" referrerpolicy="no-referrer"></p><h3 id='53-操作记录'><span>5.3 操作记录</span></h3><p><span>所有的用户操作都会记录到系统数据库,包括清空报警记录、删除记录、清空报警信息等操作。可以在本界面选择时间段范围查询,也可以选择日志类型(用户操作、设备上报)进行查询。 </span></p><p><span>如果数据超过一页,会自动分页处理,单击右侧的上一页、下一页、第一页、末一页进行翻页查看,所有查询的数据可以导出到excel表格,也可以直接打印。单击删除按钮会弹出时间范围选择框,选择该时间段后确定,会删除该时间段的所有记录。</span></p><h4 id='531-记录查询'><span>5.3.1 记录查询</span></h4><p><span> </span><img src="snap/5-3-1.jpg" referrerpolicy="no-referrer"></p><h4 id='532-记录打印'><span>5.3.2 记录打印</span></h4><p><span> </span><img src="snap/5-3-2.jpg" referrerpolicy="no-referrer"></p><h4 id='533-记录导出'><span>5.3.3 记录导出</span></h4><p><span> </span><img src="snap/5-3-3.jpg" referrerpolicy="no-referrer">
|
|
|
|
|
<span> </span><img src="snap/5-3-4.jpg" referrerpolicy="no-referrer"></p><h2 id='6-通信协议'><span>6 通信协议</span></h2><h3 id='61-通信流程'><span>6.1 通信流程</span></h3><ol start='' ><li><span>整体的结构是:控制器挂在通信端口,一个控制器下有多个探测器节点,相当于主设备、子设备。</span></li><li><span>因为是需要遍历轮询,所以一个通信端口上的控制器地址不能重复。</span></li><li><span>不同通信端口,控制器地址可以重复,所以如果控制器数量较多可以分在不同的通信端口。</span></li><li><span>一个控制器可以挂多个探测器,控制器平时也在不断轮询探测器的数据并记录,等待上位机程序的轮询命令后,将探测器数据一起打包发回。</span></li><li><span>本软件只和控制器通信,不和探测器通信,控制器负责和探测器通信。为何这样设计?因为这种架构最通用,可接的设备数量也是最大的。</span></li><li><span>本系统默认按照标准modbus协议进行通信,modbus是标准的通信框架协议,支持串口和网络等通信方式,至于具体是通过串口还是网络通信根据设备厂家选择。</span></li><li><span>modbus是通信协议框架,至于具体数据位的每个字节对应的数据含义,每个厂家不一样,都是厂家自定义,一般2个字节表示一个数据。</span></li><li><span>端口可以是串口和网络,在添加端口时候可选择不同通信解析协议。</span></li></ol><h4 id='611-fc1003-1'><span>6.1.1 FC1003-1</span></h4><p><span> </span><img src="snap/6-1-1.jpg" referrerpolicy="no-referrer"></p><h4 id='612-fc1003-8'><span>6.1.2 FC1003-8</span></h4><p><span> </span><img src="snap/6-1-2.jpg" referrerpolicy="no-referrer"></p><h4 id='613-fc1003-16'><span>6.1.3 FC1003-16</span></h4><p><span> </span><img src="snap/6-1-3.jpg" referrerpolicy="no-referrer"></p><h4 id='614-fc1103显示板'><span>6.1.4 FC1103显示板</span></h4><p><span> </span><img src="snap/6-1-4.jpg" referrerpolicy="no-referrer"></p><h4 id='615-sams-4128'><span>6.1.5 SAMS-4128</span></h4><p><span> </span><img src="snap/6-1-5.jpg" referrerpolicy="no-referrer"></p><h4 id='616-ft21047p'><span>6.1.6 FT21047P</span></h4><p><span> </span><img src="snap/6-1-6.jpg" referrerpolicy="no-referrer"></p><h3 id='62-协议解释'><span>6.2 协议解释</span></h3><ol start='' ><li><span>主机发送是软件发送数据给设备,主动发送。</span></li><li><span>从机应答是设备根据收到的数据后作出应答数据,被动回复。</span></li><li><span>一条发送命令会对应一条应答命令。</span></li><li><span>寄存器地址2字节,高位在前低位在后。</span></li><li><span>读取长度2字节,高位在前低位在后。</span></li><li><span>数据位2字节,高位在前低位在后。</span></li><li><span>CRC校验2字节,低位在前高位在后。</span></li><li><span>功能码有 03(读只读寄存器)、04(读可读可写寄存器)、06(写读写寄存器)。</span></li><li><span>主机发送的功能码和从机应答的功能码相同。</span></li></ol><h4 id='621-主机发送'><span>6.2.1 主机发送</span></h4><figure><table><thead><tr><th style='text-align:left;' ><span>地址</span></th><th style='text-align:left;' ><span>功能码</span></th><th style='text-align:left;' ><span>寄存器地址</span></th><th style='text-align:left;' ><span>寄存器个数</span></th><th style='text-align:left;' ><span>CRC校验</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>01</span></td><td style='text-align:left;' ><span>03</span></td><td style='text-align:left;' ><span>00 00</span></td><td style='text-align:left;' ><span>00 04</span></td><td style='text-align:left;' ><span>44 09</span></td></tr></tbody></table></figure><h4 id='622-从机应答'><span>6.2.2 从机应答</span></h4><figure><table><thead><tr><th style='text-align:left;' ><span>地址</span></th><th style='text-align:left;' ><span>功能码</span></th><th style='text-ali
|
|
|
|
|
<span> </span><img src="snap/7-0-3.jpg" referrerpolicy="no-referrer">
|
|
|
|
|
<span> </span><img src="snap/7-0-5.jpg" referrerpolicy="no-referrer">
|
|
|
|
|
<span> </span><img src="snap/7-0-11.jpg" referrerpolicy="no-referrer">
|
|
|
|
|
<span> </span><img src="snap/7-0-15.jpg" referrerpolicy="no-referrer">
|
|
|
|
|
<span> </span><img src="snap/7-0-17.jpg" referrerpolicy="no-referrer"></p><h3 id='71-windows-mingw'><span>7.1 windows-mingw</span></h3><p><span> </span><img src="snap/7-1-1.jpg" referrerpolicy="no-referrer"></p><h3 id='72-windows-msvc'><span>7.2 windows-msvc</span></h3><p><span> </span><img src="snap/7-2-1.jpg" referrerpolicy="no-referrer"></p><h3 id='73-linux-ubuntu'><span>7.3 linux-ubuntu</span></h3><p><span> </span><img src="snap/7-3-1.jpg" referrerpolicy="no-referrer"></p><h3 id='74-linux-uos'><span>7.4 linux-uos</span></h3><p><span> </span><img src="snap/7-4-1.jpg" referrerpolicy="no-referrer"></p><h3 id='75-linux-kylin'><span>7.5 linux-kylin</span></h3><p><span> </span><img src="snap/7-5-1.jpg" referrerpolicy="no-referrer"></p><h3 id='76-linux-neokylin'><span>7.6 linux-neokylin</span></h3><p><span> </span><img src="snap/7-6-1.jpg" referrerpolicy="no-referrer"></p><h3 id='77-linux-centos'><span>7.7 linux-centos</span></h3><p><span> </span><img src="snap/7-7-1.jpg" referrerpolicy="no-referrer"></p><h3 id='78-linux-fedora'><span>7.8 linux-fedora</span></h3><p><span> </span><img src="snap/7-8-1.jpg" referrerpolicy="no-referrer"></p><h3 id='79-unix-mac'><span>7.9 unix-mac</span></h3><p><span> </span><img src="snap/7-9-1.jpg" referrerpolicy="no-referrer"></p><h2 id='8-程序框架说明'><span>8 程序框架说明</span></h2><ul><li><span>下面的截图和说明未必是最新的,但是大部分是一致的。</span></li><li><span>整体的框架不会改变,可能会有新增加子模块和代码,具体以最新的代码为准。</span></li><li><span>程序会一直更新完善,不断迭代中。</span></li></ul><h3 id='81-整体代码结构'><span>8.1 整体代码结构</span></h3><p><span> </span><img src="snap/8-1-1.jpg" referrerpolicy="no-referrer"></p><p><span>本系统采用模块化的设备,有用到第三方开源类库比如串口通信qextserialport,全部放在3rd下面,有用到很多自己封装完善的通用类库比如数据导入导出组件,全部放在core下面,设备通信和辅助处理全部放在class下面,所有界面全部放在ui下面,相当于一个个小的组件合起来,最终形成了整个监控系统的完整代码。</span></p><h3 id='82-主模块说明'><span>8.2 主模块说明</span></h3><figure><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>3rd</span></td><td style='text-align:left;' ><span>一些第三方开源的类库,比如串口通信qextserialport。</span></td></tr><tr><td style='text-align:left;' ><span>class</span></td><td style='text-align:left;' ><span>存放系统初始化、样式控制、自定义控件、设备通信等。</span></td></tr><tr><td style='text-align:left;' ><span>core</span></td><td style='text-align:left;' ><span>本人一直持续更新完善的通用的类库,比如数据导入导出组件。</span></td></tr><tr><td style='text-align:left;' ><span>ui</span></td><td style='text-align:left;' ><span>所有的界面都分门别类放在这里。</span></td></tr></tbody></table></figure><h3 id='83-子模块说明'><span>8.3 子模块说明</span></h3><h4 id='831-第三方类库'><span>8.3.1 第三方类库</span></h4><p><span> </span><img src="snap/8-3-1.jpg" referrerpolicy="no-referrer"></p><p><span>这里放的全部是第三方开源的轮子,感谢开源、感谢github、gitee等开源社区。具体代码不做过多说明,网上会有很多介绍和使用说明。</span></p><figure><table><thead><tr><th style='text-align:left;' ><span>名称</span></th><th style='text-align:left;' ><span>说明</span></th></tr></thead><tbody><tr><td style='text-align:left;' ><span>3rd_qcustomplot</span></td><td style='text-align:left;' ><span>第三方精美图表控件qcustomplot,Qt自带的qchart功能有限而且不支持大量数据。</span></td></tr><tr><td style='text-align:left;' ><span>3rd_qextserialport</span></td><td style='text-align:left;' ><span>第三方串口通信qextserial
|
|
|
|
|
<span> </span><img src="snap/10-1-2.jpg" referrerpolicy="no-referrer">
|
|
|
|
|
<span> </span><img src="snap/10-1-3.jpg" referrerpolicy="no-referrer"></p><p><span>本系统专门配备了设备模拟工具,用来在没有外接真实设备的时候,模拟modbus协议数据,支持多个设备,支持串口和网络方式,可切换正常数据和报警数据,反应到主程序上。对应主程序中两种端口,一种是串口端口(这个可以用虚拟串口工具 Virtual Serial Port 虚拟一对串口用于测试),一种是网络端口(注意选择的监听主机地址和端口)。数据库模拟对应程序中的数据库采集运行模式,可以勾选自动模拟复选框。随机生成状态字段数据。</span></p><h3 id='102-modbus仿真'><span>10.2 modbus仿真</span></h3><p><span> </span><img src="snap/10-2-1.jpg" referrerpolicy="no-referrer"></p><p><span>作为国际知名的modbus模拟仿真工具Modbus Slave,本系统也提供了对应的数据配置文件iotsystem.mbs,在db目录下,对应添加FC-1003-8控制器。两边的通信方式必须一致,比如软件上设置的串口则两边都是串口。具体Modbus Slave工具详细使用可以自行搜索,比如这篇文章 </span><a href='https://blog.csdn.net/xuw_xy/article/details/81166305'><span>https://blog.csdn.net/xuw_xy/article/details/81166305</span></a><span> 。</span></p><h3 id='103-邮件转发设置'><span>10.3 邮件转发设置</span></h3><p><span> </span><img src="snap/10-3-1.jpg" referrerpolicy="no-referrer">
|
2022-07-02 02:20:17 +00:00
|
|
|
|
<span> </span><img src="snap/10-3-2.jpg" referrerpolicy="no-referrer">
|
|
|
|
|
<span> </span><img src="snap/10-3-3.jpg" referrerpolicy="no-referrer"></p><p><span>本系统支持邮件转发,前提是对应的邮箱账号需要开通 POP3/SMTP 等服务,按照图示开启即可,一般开启后会设置独立的管理密码,记得在系统设置那边的邮件转发,填写密码的时候要填的是独立管理密码,而不是邮箱号的密码,这个机制和任何第三方邮箱管理软件都一样。</span></p><h3 id='104-短信转发设置'><span>10.4 短信转发设置</span></h3><p><span> </span><img src="snap/10-4-1.jpg" referrerpolicy="no-referrer"></p><p><span>本系统支持串口短信发送,需要发短信的硬件支持(俗称DXM),采用通用的标准的AT指令短信发送协议,支持任意厂家的串口短信设备。当设备报警后会自动组建报警短信发送给设定的收件人。支持中文短信发送和长短信发送,可以自行网上GM对应的硬件。</span></p><h3 id='105-代码行数统计'><span>10.5 代码行数统计</span></h3><p><span> </span><img src="snap/10-5-1.jpg" referrerpolicy="no-referrer"></p><p><span>本系统除去第三方库(串口通信3rd_qextserialport、曲线图表3rd_qcustomplot、属性控件3rd_qtpropertybrowser、邮件发送3rd_smtpclient)的代码,总代码行数约4W行,纯代码行数约3W行。</span></p><h3 id='106-多种数据库支持'><span>10.6 多种数据库支持</span></h3><p><span>本系统支持多种数据库,包括sqlite、mysql、sqlserver、postgresql、oracle、kingbase等,直接在系统设置中的数据库配置中切换即可,切换完数据库以后记得初始化数据库,否则数据库不存在。</span></p><h4 id='1061-sqlite'><span>10.6.1 sqlite</span></h4><p><span> </span><img src="snap/10-6-1.jpg" referrerpolicy="no-referrer"></p><h4 id='1062-mysql'><span>10.6.2 mysql</span></h4><p><span> </span><img src="snap/10-6-2.jpg" referrerpolicy="no-referrer"></p><h4 id='1063-sqlserver'><span>10.6.3 sqlserver</span></h4><p><span> </span><img src="snap/10-6-3.jpg" referrerpolicy="no-referrer"></p><h4 id='1064-postgresql'><span>10.6.4 postgresql</span></h4><p><span> </span><img src="snap/10-6-4.jpg" referrerpolicy="no-referrer"></p><h4 id='1065-oracle'><span>10.6.5 oracle</span></h4><p><span> </span><img src="snap/10-6-5.jpg" referrerpolicy="no-referrer"></p><h4 id='1066-kingbase'><span>10.6.6 kingbase</span></h4><p><span> </span><img src="snap/10-6-6.jpg" referrerpolicy="no-referrer"></p><h3 id='107-采集数据转发'><span>10.7 采集数据转发</span></h3><p><span> </span><img src="snap/10-7-1.jpg" referrerpolicy="no-referrer">
|
2022-06-02 06:36:30 +00:00
|
|
|
|
<span> </span><img src="snap/10-7-2.jpg" referrerpolicy="no-referrer"></p><p><span>在系统设置中设置好网络转发参数后,可以在接收的地方开启网络数据接收,这样只需要接收数据解析反应到界面就行,相当于数据源不是硬件设备而是网络转发过来的数据,不需要直接接硬件设备。</span></p><p><span>网络转发端,单击同步数据会把本地的端口信息、控制器信息、探测器信息发到远端。网络转发模块也可以作为无限级联使用,比如接收端还可以开启转发,继续转发给需要的地方,一个客户端上设置的转发也支持多个,用英文分号 ; 隔开,一对多关系,采用的无连接udp协议,几乎不占用系统资源。</span></p><h3 id='108-云端数据库同步'><span>10.8 云端数据库同步</span></h3><p><span> </span><img src="snap/10-8-1.jpg" referrerpolicy="no-referrer">
|
|
|
|
|
<span> </span><img src="snap/10-8-2.jpg" referrerpolicy="no-referrer">
|
|
|
|
|
<span> </span><img src="snap/10-8-3.jpg" referrerpolicy="no-referrer"></p><p><span>云端数据库同步,相当于把本地采集到的数据实时存储到云端,至于这些记录到了云端后什么用途,一般会用来做web请求访问,或者app请求获取数据,具体应用看用户需求。</span></p><p><span>云端数据库也会存储到NodeData表中,意味着任意地方的客户端,都可以选择数据库采集模式,直接连接云端的数据库作为数据源。相当于可以无限级联。</span></p></div></div>
|
|
|
|
|
|
|
|
|
|
<script>(function(){var e=document.body.parentElement,t=[],n=null,i=document.body.classList.contains("typora-export-collapse-outline"),r=function(e,t,n){document.addEventListener(e,function(e){if(!e.defaultPrevented)for(var i=e.target;i&&i!=this;i=i.parentNode)if(i.matches(t)){!1===n.call(i,e)&&(e.preventDefault(),e.stopPropagation());break}},!1)};function o(){return e.scrollTop}r("click",".outline-expander",function(e){var t=this.closest(".outline-item-wrapper").classList;return t.contains("outline-item-open")?t.remove("outline-item-open"):t.add("outline-item-open"),d(),!1}),r("click",".outline-item",function(e){var t=this.querySelector(".outline-label");if(location.hash="#"+t.getAttribute("href"),i){var n=this.closest(".outline-item-wrapper").classList;n.contains("outline-item-open")||n.add("outline-item-open"),c(),n.add("outline-item-active")}});var a,s,l=function(){var e=o();n=null;for(var i=0;i<t.length&&t[i][1]-e<60;i++)n=t[i]},c=function(){document.querySelectorAll(".outline-item-active").forEach(e=>e.classList.remove("outline-item-active")),document.querySelectorAll(".outline-item-single.outline-item-open").forEach(e=>e.classList.remove("outline-item-open"))},d=function(){if(n){c();var e=document.querySelector('.outline-label[href="#'+(CSS.escape?CSS.escape(n[0]):n[0])+'"]');if(e)if(i){var t=e.closest(".outline-item-open>ul>.outline-item-wrapper");if(t)t.classList.add("outline-item-active");else{for(var r=(e=e.closest(".outline-item-wrapper")).parentElement.closest(".outline-item-wrapper");r;)r=(e=r).parentElement.closest(".outline-item-wrapper");e.classList.add("outline-item-active")}}else e.closest(".outline-item-wrapper").classList.add("outline-item-active")}};window.addEventListener("scroll",function(e){a&&clearTimeout(a),a=setTimeout(function(){l(),d()},300)});var u=function(){s=setTimeout(function(){!function(){t=[];var e=o();document.querySelector("#write").querySelectorAll("h1, h2, h3, h4, h5, h6").forEach(n=>{var i=n.getAttribute("id");t.push([i,e+n.getBoundingClientRect().y])})}(),l(),d()},300)};window.addEventListener("resize",function(e){s&&clearTimeout(s),u()}),u()})();</script></body>
|
2022-05-04 11:04:58 +00:00
|
|
|
|
</html>
|