+ 进样时间改进输入框,使提示文字始终可见

+ 操作规程新增 L389-101
+ 删除标水页面和设置页面
This commit is contained in:
2023-06-07 22:59:41 +08:00
parent a734ce2e54
commit 5c226f0ca7
8 changed files with 230 additions and 462 deletions

View File

@@ -9,17 +9,10 @@
<script src="./statics/modules/jquery.min.js"></script> <script src="./statics/modules/jquery.min.js"></script>
<script type="module"> <script type="module">
import { IO } from "./statics/modules/tools.js" import { IO } from "./statics/modules/tools.js"
let page = 10
let settings = new IO('settings')
let num = settings.read("index.history.num")
let page = num == null ? 10 : num
let url = `https://api.github.com/repos/hbk01/hbk01.github.io/commits?per_page=${page}` let url = `https://api.github.com/repos/hbk01/hbk01.github.io/commits?per_page=${page}`
let functions = [ let functions = [
{
"name": "标水",
"location": "./views/titer.html"
},
{ {
"name": "干燥失重", "name": "干燥失重",
"location": "./views/lod.html" "location": "./views/lod.html"
@@ -43,47 +36,13 @@
] ]
$(() => { $(() => {
// 检查是否已初始化设置
let init = settings.read("settings.initialized")
if (init != "true") {
// 移除所有项目
settings.listKeys().forEach(key => {
settings.remove(key)
})
// 云端获取默认设置并写入
$.getJSON("../statics/settings.json", (data) => {
for (const iterator of data) {
settings.write(iterator.id, iterator.default)
settings.write(`${iterator.id}.desc`, iterator.description)
}
// 写入完成后重新加载页面,以应用当前设置
window.location.reload()
})
}
let hidden = settings.read("index.functions.hidden")
hidden = hidden == "" ? [] : hidden.split(',')
// 加载功能列表 // 加载功能列表
functions.forEach(value => { functions.forEach(value => {
for (const iterator of hidden) { let onclick = `window.location.href='${value.location}'`
if (value.location.endsWith(iterator)) { let div = `<div class="item" onclick="${onclick}">${value.name}</div>`
return
}
}
let div = `<div class="item" onclick="window.location.href='${value.location}'">${value.name}</div>`
$(".list").append(div) $(".list").append(div)
}) })
let show = settings.read("index.history.enable")
if (show == "false") {
$("#changelog_title").hide()
return
}
// 加载最近的 commit 记录 // 加载最近的 commit 记录
$.getJSON(url, data => { $.getJSON(url, data => {
let color1 = '#f9f9f9' let color1 = '#f9f9f9'
@@ -124,7 +83,7 @@
</head> </head>
<body> <body>
<h4 onclick="window.location.href='./views/settings.html'">功能列表</h4> <h4>功能列表</h4>
<div class="list"></div> <div class="list"></div>
<h4>关于</h4> <h4>关于</h4>
<div class="about"> <div class="about">

View File

@@ -1,36 +0,0 @@
[
{
"id": "settings.initialized",
"group": "settings",
"title": "是否已经初始化",
"description": "指示初始化状态,请勿更改此项",
"type": "boolean",
"default": true
},
{
"id": "index.history.enable",
"group": "index.html",
"title": "显示变更日志",
"description": "若设置为 false ,则不显示变更日志",
"type": "boolean",
"default": true
},
{
"id": "index.history.num",
"group": "index.html",
"title": "日志显示数量",
"description": "要显示多少条变更日志",
"type": "number",
"default": 10
},
{
"id": "index.functions.hidden",
"group": "index.html",
"title": "隐藏入口",
"description": "在功能列表中隐藏匹配到文件名的条目",
"type": "array",
"default": [
"titer.html"
]
}
]

87
statics/sop/L389-101.md Normal file
View File

@@ -0,0 +1,87 @@
## L389-101 操作规程
检验依据QAS-ZJ389-101-03
### 1. 有关物质
#### 1.1. 色谱条件
色谱柱型号Waters Xbridge Shield RP18
色谱柱规格150mm x 4.6mm x 3.5um
流速1.0 mL/min
波长225 nm
运行时间24 min
后运行时间6 min
柱温40 °C
进样量5 uL
流动相A称取 1.36g 磷酸二氢钾于 1L 纯化水中,用磷酸调 pH=3.0&#177;0.02
流动相B乙腈
**注意流动相A需用于配制配样溶剂请确保配制的量足够。**
梯度程序:
| 时间(min) | A% | B% |
| :-------: | :---: | :---: |
| 0 | 70 | 30 |
| 3 | 50 | 50 |
| 7 | 15 | 85 |
| 17.5 | 15 | 85 |
| 17.6 | 70 | 30 |
| 24 | 70 | 30 |
#### 1.2. 样品配置
**溶剂**:乙腈:流动相A = 1:1
**灵敏度溶液**:移取 25uL 的样品溶液于 25mL 容量瓶中,定容。
**专属性储备液**:分别称取 1215mg 乙基三苯基溴化膦、三苯基磷、三苯基氧膦对照品于 50mL 容量瓶中,定容。
**专属性溶液**:称取 2327mg 的 L389-101 对照品于 100mL 容量瓶中,加入专属性储备液 1mL定容。
**样品溶液**:称取 2327mg 样品于 100mL 容量瓶中,定容。
#### 1.3. 容量瓶用量
| 规格(mL) | 数量 |
| :------: | :---: |
| 25 | 1 |
| 50 | 1 |
| 100 | 2 |
每多一批样品则多加 1 个 100 mL 容量瓶
#### 1.4. 进样顺序
**注意:样品溶液超过五针或测试时间超过五小时,需要回一针灵敏度溶液和专属性溶液。**
样品溶液不超过五针:
+ 空白
+ 灵敏度溶液
+ 专属性溶液-1
+ 专属性溶液-2
+ 样品溶液
样品溶液超过五针或测试时间超过五小时:
+ 空白
+ 灵敏度溶液-1
+ 专属性溶液-1
+ 专属性溶液-2
+ 样品溶液
+ 灵敏度溶液-2
+ 专属性溶液-3
#### 1.5. 系统适用性要求
+ 样品溶液图谱中主峰保留时间与对照品应一致
+ 专属性溶液中分离度不低于 1.5
+ 灵敏度溶液主峰的信噪比 &ge; 10
+ 专属性溶液平行测定的两次及回标的专属性溶液中,三苯基氧膦的峰面积百分比差值应不高于 10%
三苯基氧膦峰面积百分比差值 = ( 峰面积最高值 - 峰面积最低值 ) / 峰面积平均值 * 100%
#### 1.6. 标准要求
+ 总杂 &le; 5.0%

View File

@@ -44,7 +44,6 @@
color: red; color: red;
text-decoration: line-through; text-decoration: line-through;
} }
</style> </style>
<script src="../statics/modules/jquery.min.js"></script> <script src="../statics/modules/jquery.min.js"></script>
<script> <script>
@@ -60,8 +59,8 @@
} }
] ]
let info = {}
$(() => { $(() => {
let info = {}
let count = databases.length let count = databases.length
let interval = setInterval(() => { let interval = setInterval(() => {
if (count == 0) { if (count == 0) {
@@ -94,92 +93,92 @@
searchDevice(keyword) searchDevice(keyword)
searchStandard(keyword) searchStandard(keyword)
}) })
})
function searchDevice(keyword) { function searchDevice(keyword) {
let device = info.device.filter((value) => { let device = info.device.filter((value) => {
return value.id.toLowerCase().includes(keyword) return value.id.toLowerCase().includes(keyword)
}) })
if (device.length > 0) { if (device.length > 0) {
let table_device = createDeviceTable(device) let table_device = createDeviceTable(device)
$("#content").append(table_device) $("#content").append(table_device)
}
} }
}
function searchStandard(keyword) { function searchStandard(keyword) {
let standard = info.standard.filter((value) => { let standard = info.standard.filter((value) => {
return value.batch.toLowerCase().includes(keyword) return value.batch.toLowerCase().includes(keyword)
}) })
if (standard.length > 0) { if (standard.length > 0) {
let table_standard = createStandardTable(standard) let table_standard = createStandardTable(standard)
$("#content").append(table_standard) $("#content").append(table_standard)
}
} }
}
function createDeviceTable(data) { function createDeviceTable(data) {
return createTable(data, `设备信息(${data.length}条)`, ["名称", "编号", "有效期至"], hidden = ["where"]) return createTable(data, `设备信息(${data.length}条)`, ["名称", "编号", "有效期至"], ["where"])
}
function createStandardTable(data) {
return createTable(data, `对照品信息(${data.length}条)`, ["批号", "有效期至", "含量丨纯度"], ["kind"])
}
function createTable(data, captionText, header, hidden = []) {
let table = document.createElement("table")
table.setAttribute("class", "pure-table")
let caption = document.createElement("caption")
caption.innerText = captionText
table.appendChild(caption)
let tr = document.createElement("tr")
for (const headerText of header) {
let th = document.createElement("th")
th.innerText = headerText
tr.appendChild(th)
} }
table.appendChild(tr)
function createStandardTable(data) { data.forEach(element => {
return createTable(data, `对照品信息(${data.length}条)`, ["批号", "有效期至", "含量丨纯度"], hidden = ["kind"])
}
function createTable(data, captionText, header, hidden = []) {
let table = document.createElement("table")
table.setAttribute("class", "pure-table")
let caption = document.createElement("caption")
caption.innerText = captionText
table.appendChild(caption)
let tr = document.createElement("tr") let tr = document.createElement("tr")
for (const headerText of header) { for (const key in element) {
let th = document.createElement("th") if (Object.hasOwnProperty.call(element, key)) {
th.innerText = headerText if (hidden.includes(key)) {
tr.appendChild(th) continue
}
const value = element[key]
let td = document.createElement("td")
td.innerHTML = (key == "expir") ? checkExpir(value) : value
tr.appendChild(td)
}
} }
table.appendChild(tr) table.appendChild(tr)
})
data.forEach(element => { return table
let tr = document.createElement("tr") }
for (const key in element) {
if (Object.hasOwnProperty.call(element, key)) {
if (hidden.includes(key)) {
continue
}
const value = element[key]
let td = document.createElement("td")
td.innerHTML = (key == "expir") ? checkExpir(value) : value
tr.appendChild(td)
}
}
table.appendChild(tr)
})
return table function checkExpir(value) {
let date = new Date()
let array = value.split(".")
date.setFullYear(array[0], array[1] - 1, array[2])
let day = (date - Date.now()) / 86400000
if (day <= 0) {
return `<span class='expired'>${value}</span>`
} }
function checkExpir(value) { if (day <= 7) {
let date = new Date() return `<span class='expir7'>${value}</span>`
let array = value.split(".")
date.setFullYear(array[0], array[1] - 1, array[2])
let day = (date - Date.now()) / 86400000
if (day <= 0) {
return `<span class='expired'>${value}</span>`
}
if (day <= 7) {
return `<span class='expir7'>${value}</span>`
}
if (day <= 30) {
return `<span class='expir30'>${value}</span>`
}
return value
} }
})
if (day <= 30) {
return `<span class='expir30'>${value}</span>`
}
return value
}
</script> </script>
</head> </head>

View File

@@ -167,17 +167,77 @@
} }
</script> </script>
<style>
.inputbox {
display: flex;
display: -webkit-flex;
line-height: 32px;
border: 1px solid black;
border-radius: 5px;
justify-content: center;
align-items: baseline;
margin-bottom: 5px;
}
.inputbox label {
line-height: 32px;
font-size: small;
color: #777;
margin-left: 10px;
margin-right: 10px;
}
.inputbox div {
flex: 1;
}
.inputbox input {
/* 需设置宽度,否则 iOS 端的 Safari 无法正确显示 div.inputbox 的右边框 */
width: calc(100% - 20px);
/* 取消边框 */
border: none;
/* 取消选中时的边框高亮 */
outline: none;
margin: 0;
font-size: medium;
line-height: 32px;
}
</style>
</head> </head>
<body> <body>
<h3>进样时间</h3> <h3>进样时间</h3>
<div class="input"> <div class="input">
<div class="inputbox"> <div>
<input type="number" id="allId" placeholder="批处理中样品的总数" inputmode="decimal" autocomplete="off"> <div class="inputbox allId">
<input type="number" id="time" placeholder="每一针的运行时间" inputmode="decimal" autocomplete="off"> <label for="allId">样品总数</label>
<input type="number" id="nowId" placeholder="当前运行到第几针" inputmode="decimal" autocomplete="off"> <!-- 此处的 div 为解决 Safari 浏览器 align-items: baseline; 不对齐的问题 -->
<input type="number" id="nowTime" placeholder="现在这针运行多少分钟" inputmode="decimal" autocomplete="off"> <div>
<input type="number" id="offset" placeholder="时间偏移量" inputmode="decimal" autocomplete="off"> <input type="number" id="allId" inputmode="decimal" autocomplete="off">
</div>
</div>
<div class="inputbox time">
<label for="time">运行时间</label>
<div><input type="number" id="time" inputmode="decimal" autocomplete="off"></div>
</div>
<div class="inputbox nowId">
<label for="nowId">运行到第几针</label>
<div><input type="number" id="nowId" inputmode="decimal" autocomplete="off"></div>
</div>
<div class="inputbox nowTime">
<label for="nowTime">当前运行时间</label>
<div><input type="number" id="nowTime" inputmode="decimal" autocomplete="off"></div>
</div>
<div class="inputbox offset">
<label for="offset">时间偏移量</label>
<div><input type="number" id="offset" inputmode="decimal" autocomplete="off"></div>
</div>
</div> </div>
<br> <br>
<div class="buttons"> <div class="buttons">

View File

@@ -1,194 +0,0 @@
<!DOCTYPE html>
<html lang="zh-cmn-Hans">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Settings</title>
<script src="../statics/modules/jquery.min.js"></script>
<link rel="stylesheet" href="../statics/github.css">
<link rel="stylesheet" href="../statics/theme.css">
<style>
* {
padding: 0;
margin: 0;
}
textarea {
width: 85vw;
height: 70vh;
padding: 2vw;
margin: 3vw;
font-size: medium;
line-height: 1.2;
border: 1px solid #cbcbcb;
border-radius: 5px;
}
</style>
<script type="module">
import { IO } from "../statics/modules/tools.js"
const io = new IO("settings")
$(() => {
const textarea = $("#textarea")
// 写入默认设置
if (readSettings().length == 0) {
writeDefaultSettings(() => {
$("#refresh").click()
})
}
$("#reset").click(() => {
if (confirm("确定要恢复默认设置吗?\n该选项将会覆盖当前已保存的设置")) {
writeDefaultSettings(() => {
$("#refresh").click()
})
}
})
$("#go_index").click(() => {
window.location.href = "../index.html"
})
$("#refresh").click(() => {
let settings = readSettingsWithComments()
let string = ""
settings.forEach(item => {
string = string.concat(item).concat("\n")
})
textarea.val(string)
})
$("#refresh").click()
$("#save").click(() => {
let text = $("#textarea").val()
let settings = text.split("\n")
writeSettings(settings)
})
})
function readSettingsWithComments() {
let texts = []
texts.push("# 以井号开头的行是注释,注释将被忽略。")
texts.push("# 一行仅可填写一个设置,以键值对 (key=value) 的形式出现。")
texts.push("# 等号左边为设置的唯一标识,右边为该设置的值")
texts.push("# 若值有多个,使用英文逗号分隔 (e.g. key=value1,value2)")
texts.push("# 等号和用于分隔多个值的英文逗号左右两边不得有空格")
texts.push("")
for (const setting of readSettings()) {
let comment = io.read(`${setting.key}.desc`)
texts.push(`# ${comment}`)
texts.push(`${setting.key}=${setting.value}`)
texts.push("")
}
return texts
}
function readSettings() {
let settings = []
for (const iterator of io.listKeys().sort()) {
if (!iterator.endsWith(".desc")) {
settings.push({
key: iterator,
value: io.read(iterator)
})
}
}
return settings
}
function writeSettings(settings) {
if (settings.length == 0) {
return
}
io.listKeys().forEach(key => {
if (!key.endsWith(".desc")) {
io.remove(key)
}
})
settings.forEach(item => {
if (item.startsWith("#")) {
return
}
let key = item.split('=')[0]
let value = item.split('=')[1]
if (key != item && key != '') {
io.write(key, value)
}
})
}
function writeDefaultSettings(action) {
io.listKeys().forEach(key => {
io.remove(key)
})
$.getJSON("../statics/settings.json", (settings) => {
for (const iterator of settings) {
io.write(iterator.id, iterator.default)
io.write(`${iterator.id}.desc`, iterator.description)
}
action()
})
}
function createItem(data) {
let div = document.createElement("div")
div.setAttribute("class", "setting_item")
let span = document.createElement("span")
let span_title = document.createElement("span")
let span_description = document.createElement("span")
span_title.setAttribute("class", "title")
span_description.setAttribute("class", "description")
span_description.innerHTML = data.description
span.appendChild(span_title)
span.appendChild(document.createElement("br"))
span.appendChild(span_description)
div.appendChild(span)
switch (data.type) {
case 'boolean':
span_title.innerHTML = `${data.title} (${data.default ? "ON" : "OFF"})`
let button = document.createElement("button")
button.innerText = data.default ? "OFF" : "ON"
button.setAttribute("id", data.id)
div.appendChild(button)
break
case 'number':
span_title.innerHTML = `${data.title} (${data.default})`
let input = document.createElement("input")
input.setAttribute("type", "number")
input.setAttribute("value", data.default)
input.setAttribute("id", data.id)
div.appendChild(input)
break
default:
break
}
return div
}
</script>
</head>
<body>
<textarea id="textarea" wrap="off" autocomplete="off"></textarea>
<br>
<div id="buttons" style="text-align: center;">
<button id="reset">恢复默认设置</button>
<button id="go_index">回到首页</button>
<button id="refresh">刷新</button>
<button id="save">保存</button>
</div>
<div id="msg"></div>
</body>
</html>

View File

@@ -38,6 +38,7 @@
"L018-4W", "L018-4W",
"L018-5", "L018-5",
"L018-6", "L018-6",
"L389-101",
"L414-1", "L414-1",
"L414-5KR", "L414-5KR",
"L414-7", "L414-7",

View File

@@ -1,108 +0,0 @@
<!DOCTYPE html>
<html lang="zh-cmn-Hans">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>标水</title>
<link rel="stylesheet" href="../statics/github.css">
<link rel="stylesheet" href="../statics/theme.css">
<script src="../statics/modules/jquery.min.js"></script>
<script type="module">
import { Decimal } from "../statics/modules/decimal.mjs"
import { Formula } from "../statics/modules/tools.js"
let debug = false
let tip = `<br>
请输入三次 F 值<br>
公式:<br>
F' = AVERAGE(F1, F2, F3)<br>
RDx = [ Fx - F' ] / F' * 100`
let decimal = Decimal.set({
rounding: Decimal.ROUND_HALF_EVEN,
precision: 12
})
$(document).ready(() => {
message(tip)
$("#ok").click(() => {
let m0 = $("#m0").val()
let m1 = $("#m1").val()
let m2 = $("#m2").val()
let f = Formula.AVERAGE(m0, m1, m2).toFixed(4, Decimal.ROUND_HALF_EVEN)
let msg = `
<br>
F值平均值 = ${f}<br>
RD1 = ${format(titer(f, m0))}<br>
RD2 = ${format(titer(f, m1))}<br>
RD3 = ${format(titer(f, m2))}<br>
`
message(msg)
})
$("#clear").click(() => {
$("#m0").val("")
$("#m1").val("")
$("#m2").val("")
message(tip)
})
$("#new_page").click(() => {
window.open(window.location.href, "_blank")
})
if (debug) {
$("#m0").val(5.1183)
$("#m1").val(5.1823)
$("#m2").val(5.0926)
}
})
function message(msg) {
$(".msgbox").empty()
$(".msgbox").html(msg)
}
/**
* 计算标水
* @param f F值为三次mg/mL值的平均值
* @param m 该次mg/mL的值
*/
function titer(f, m) {
let temp = decimal.sub(m, f)
return temp.div(f).mul(100).toFixed(2, Decimal.ROUND_HALF_EVEN)
}
function format(value, min = -1, max = 1) {
if (value <= min || value >= max) {
return `<span style='font-family: none; color: red;'>${value}</span>`
}
return `<span style='font-family: none;'>${value}</span>`
}
</script>
</head>
<body>
<h3>标水</h3>
<div class="team">
<input type="number" id="m0" class="m0" placeholder="F1" inputmode="decimal"><br>
<input type="number" id="m1" class="m1" placeholder="F2" inputmode="decimal"><br>
<input type="number" id="m2" class="m2" placeholder="F3" inputmode="decimal"><br>
</div>
<br>
<div class="buttons">
<button id="new_page">新开标签页</button>
<button id="clear">清除内容</button>
<button id="ok">计算</button>
</div>
<div class="msgbox"></div>
</body>
</html>