addVisitatPage.vue 34 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160
  1. <!-- 快捷添加巡视单页面专用 -->
  2. <template>
  3. <view>
  4. <nav-bar :navbarData="navbarData"></nav-bar>
  5. <view :style="'margin-top: ' + (height * 2 - 10) + 'rpx; height: calc(100vh - ' + (height * 2 - 2) + 'rpx)'">
  6. <view class="content" :style="editFlag !== 'E' ? 'height:95%' : ''">
  7. <view v-if="pdaScanStatus === 'N'" class="topinfo">
  8. <view class="item">
  9. <view class="bedcode">{{ patInfo.admInfo.admBedCode }}</view>
  10. <view class="border"></view>
  11. <view class="info">{{ patInfo.basicInfo.patName }}</view>
  12. <view v-if="patInfo.admInfo.nurseLv === '特级'" class="nurse-lv-css-red">{{ patInfo.admInfo.nurseLv }}</view>
  13. <view v-if="patInfo.admInfo.nurseLv === '一级'" class="nurse-lv-css-pink">{{ patInfo.admInfo.nurseLv }}</view>
  14. <view v-if="patInfo.admInfo.nurseLv === '二级'" class="nurse-lv-css-blue">{{ patInfo.admInfo.nurseLv }}</view>
  15. <view v-if="patInfo.admInfo.nurseLv === '三级'" class="nurse-lv-css-greenyellow">{{ patInfo.admInfo.nurseLv }}</view>
  16. <view class="bedcode">{{ patInfo.basicInfo.patSexDesc }}</view>
  17. <view class="border"></view>
  18. <view class="info">{{ patInfo.basicInfo.patAge }}</view>
  19. <view class="border"></view>
  20. <view class="info">{{ patInfo.basicInfo.patNo }}</view>
  21. <view class="border"></view>
  22. <view class="info">入院:{{ patInfo.admInfo.admDatetime }}</view>
  23. </view>
  24. </view>
  25. <view v-if="pdaScanStatus === 'Y'" class="topinfo">
  26. <view class="scan-container">
  27. <!-- 扫描提示图片 -->
  28. <image
  29. class="scan-img"
  30. src="/static/pdaphone.jpeg"
  31. mode="widthFix"
  32. ></image>
  33. <!-- 闪烁提示文字 -->
  34. <view class="scan-text">请点击PDA侧边按钮扫描患者标识</view>
  35. </view>
  36. </view>
  37. <view v-if="pdaScanStatus === 'N'" class="elementitem" v-for="(item, index) in elementData" :key="index">
  38. <van-row class="item">
  39. <van-col
  40. v-if="item.hideTitle !== 'Y'"
  41. :span="item.elementTypeCode === 'Label' ? '24' : '9'"
  42. :class="item.elementTypeCode === 'Label' ? 'title' : 'itemtitle'"
  43. >
  44. <view :class="item.elementTypeCode === 'Label' ? 'title' : ''">
  45. <view v-if="item.elementTypeCode === 'Label'" class="border"></view>
  46. <view>{{ item.IEMRTempElementDesc }}{{ item.elementTypeCode === 'Label' ? '' : ':' }}</view>
  47. </view>
  48. </van-col>
  49. <van-col :span="item.hideTitle !== 'Y' ? '15' : 24" class="itemdata">
  50. <view v-if="item.elementTypeCode === 'Input'" class="inputclass">
  51. <input
  52. :data-dataindex="index"
  53. v-model="item.IEMRTempElementData"
  54. type="text"
  55. @input="(e) => inputOnChange(e.detail.value, { dataindex: index })"
  56. @blur="(e) => inputOnBlur(e.detail.value, { dataindex: index })"
  57. :placeholder="item.addItemFlag === 'Y' ? '总和' : '请输入'"
  58. :disabled="item.disable === 'Y'"
  59. style="margin-top: 6px;width: 100%;padding: 2px 0;border: none;outline: none;font-size: 14px;"
  60. />
  61. </view>
  62. <view v-if="item.elementTypeCode === 'ScanCode'" class="scanCodeclass">
  63. <view
  64. :class="item.IEMRTempElementData === '腕带核对正确' ? 'scanViewColor_green' : 'scanViewColor_red'"
  65. >
  66. {{ item.IEMRTempElementData }}
  67. </view>
  68. <image
  69. v-if="item.IEMRTempElementData !== '腕带核对正确'"
  70. :src="imgDomain + '/images/icon/ydhl_scanBlue.png'"
  71. :data-dataindex="index"
  72. class="custom-icon"
  73. @tap="(e) => inputScanOnChange(e, { dataindex: index })"
  74. />
  75. </view>
  76. <view v-if="item.elementTypeCode === 'Labelarea'" class="areaclass">
  77. <input
  78. :data-dataindex="index"
  79. v-model="item.IEMRTempElementData"
  80. type="textarea"
  81. @input="(e) => inputOnChange(e.detail.value, { dataindex: index })"
  82. placeholder="请输入"
  83. :disabled="item.disable === 'Y'"
  84. style="margin-top: 6px;width: 100%;padding: 2px 0;border: none;outline: none;font-size: 14px;"/>
  85. </view>
  86. <view v-if="item.elementTypeCode === 'ComboBox'" class="comboboxclass">
  87. <van-row>
  88. <checkbox-group @change="checkChange" :data-dataindex="index">
  89. <view class="radio-container">
  90. <view
  91. v-for="(checkitem, checkid) in item.elmentData"
  92. :span="checkitem.descripts.length > 4 ? 24 : 12"
  93. :key="checkid"
  94. style="border-bottom:1px solid #e4e5e4"
  95. :class="checkitem.descripts.length > 4 ? 'rowitem2' : 'rowitem'"
  96. >
  97. <checkbox
  98. :value="checkitem.descripts"
  99. shape="square"
  100. :disabled="item.disable === 'Y'"
  101. :checked="getCheckFlag(item.IEMRTempElementData, checkitem.descripts)"
  102. >
  103. {{checkitem.descripts}}
  104. </checkbox>
  105. </view>
  106. </view>
  107. </checkbox-group>
  108. </van-row>
  109. </view>
  110. <view v-if="item.elementTypeCode === 'RadioBox'" class="radioboxclass">
  111. <van-row>
  112. <radio-group @change="checkChange" :data-dataindex="index">
  113. <view class="radio-container">
  114. <view
  115. v-for="(checkitem, checkid) in item.elmentData"
  116. :key="checkid"
  117. :class="checkitem.descripts.length > 4 ? 'rowitem2' : 'rowitem'"
  118. >
  119. <radio
  120. :value="checkitem.descripts"
  121. :checked="item.IEMRTempElementData.value === checkitem.descripts || item.IEMRTempElementData === checkitem.descripts"
  122. >
  123. {{checkitem.descripts}}
  124. </radio>
  125. </view>
  126. </view>
  127. </radio-group>
  128. </van-row>
  129. </view>
  130. <view v-if="item.elementTypeCode === 'Select'" class="selectclass">
  131. <van-cell
  132. :is-link="item.IEMRTempElementData === ''"
  133. arrow-direction="down"
  134. :value="item.IEMRTempElementData"
  135. :border="false"
  136. :data-dataindex="index"
  137. @tap="(e) => selectItem(e, { dataindex: index })"
  138. >
  139. <span>{{item.IEMRTempElementData}}</span>
  140. <van-icon
  141. v-if="item.IEMRTempElementData !== '' && item.disable !== 'Y'"
  142. name="cross"
  143. slot="right-icon"
  144. custom-class="delicon"
  145. :data-dataindex="index"
  146. @tap.stop.prevent="(e) => deleteData(e, { dataindex: index })"
  147. ></van-icon>
  148. </van-cell>
  149. </view>
  150. <view v-if="item.elementTypeCode === 'MultipleSelect'" class="selectclass">
  151. <van-cell
  152. is-link
  153. arrow-direction="down"
  154. :value="getData(item.IEMRTempElementData)"
  155. :border="false"
  156. :data-dataindex="index"
  157. @tap="(e) => multipleSelectItem(e, { dataindex: index })"
  158. />
  159. </view>
  160. <view v-if="item.elementTypeCode === 'Date'" class="dateclass">
  161. <uni-datetime-picker
  162. type="date"
  163. :hide-second="true"
  164. :model-value="item.IEMRTempElementData"
  165. @show="openUniDateTimePicker(index, item)"
  166. @change="(e) => handleUniDateTimeConfirm(e,index)"
  167. title="选择日期"
  168. :border="false"
  169. />
  170. </view>
  171. <view v-if="item.elementTypeCode === 'Time'" class="dateclass">
  172. <picker
  173. mode="multiSelector"
  174. :range="timeRange"
  175. :value="timeIndex"
  176. @change="(e)=>onTimeChange(e,index)"
  177. @columnchange="onColumnChange">
  178. <view class="picker-view">{{item.IEMRTempElementData || '点击选择时间'}}</view>
  179. </picker>
  180. </view>
  181. <view v-if="item.elementTypeCode === 'DateTime'">
  182. <uni-datetime-picker
  183. type="datetime"
  184. :hide-second="true"
  185. :model-value="item.IEMRTempElementData"
  186. @show="openUniDateTimePicker(index, item)"
  187. @change="(e) => handleUniDateTimeConfirm(e,index)"
  188. title="选择日期时间"
  189. :border="false"
  190. />
  191. </view>
  192. </van-col>
  193. </van-row>
  194. </view>
  195. </view>
  196. <view class="multiBtn-content">
  197. <button class="multiBtn-left" @tap="goBackPage">首页</button>
  198. <button v-if="pdaScanStatus === 'N'" class="multiBtn-right" @tap="addRecord">保存</button>
  199. </view>
  200. </view>
  201. <van-action-sheet
  202. :show="actionShow"
  203. :actions="selectData"
  204. @close="onClose"
  205. @cancel="onClose"
  206. @select="onSelect"
  207. cancel-text="取消"
  208. />
  209. <van-action-sheet
  210. :show="mutilCheckshow"
  211. title="请选择"
  212. @close="onClose"
  213. @cancel="onClose"
  214. >
  215. <view class="mutilCheck">
  216. <view class="checkData">
  217. <view
  218. span="8"
  219. class="checkitem"
  220. :style="'background:' + multicheckitem.color + '; border-color:' + multicheckitem.color + ';color:' + (multicheckitem.checked ? '#fff' : '#333')"
  221. :data-index="multicheckid"
  222. @tap="multiItemCheck"
  223. v-for="(multicheckitem, multicheckid) in selectData"
  224. :key="multicheckid"
  225. >
  226. {{ multicheckitem.descripts }}
  227. </view>
  228. </view>
  229. <view>
  230. <view class="multiBtn-content">
  231. <button class="multiBtn-left" @tap="onClose">取消</button>
  232. <button class="multiBtn-right" @tap="onConfirmMultiCheck">保存</button>
  233. </view>
  234. </view>
  235. </view>
  236. </van-action-sheet>
  237. </view>
  238. </template>
  239. <script setup>
  240. import { ref, onMounted,onUnmounted, computed, defineExpose } from 'vue';
  241. import { $http } from '../../config/https';
  242. import { onLoad ,onShow } from '@dcloudio/uni-app';
  243. import Util from '../../utils/util.js';
  244. import navBar from '@/pages/components/navbar/index';
  245. // 状态定义
  246. const height = ref('');
  247. const templateID = ref('');
  248. const newFlag = ref('0');
  249. const elementData = ref([]);
  250. const selectData = ref([]);
  251. const actionShow = ref(false);
  252. const mutilCheckshow = ref(false);
  253. const clickIndex = ref('-1');
  254. const currentDate = ref(getCurrentDateTime());
  255. const admID_SM = ref('');
  256. const patID_SM = ref('');
  257. const editFlag = ref('');
  258. const checkitem = ref({ descripts: [] });
  259. const checkid = ref(false);
  260. const multicheckitem = ref({ checked: false, color: '', descripts: '' });
  261. const multicheckid = ref('');
  262. const imgDomain = ref(uni.getStorageSync('appUrlAddress'));
  263. const navbarData = ref({
  264. background: '',
  265. title: '记录',
  266. height: '100',
  267. bottom: true,
  268. isGoBack: true,
  269. isGoHome: true,
  270. cleanPat: 'Y'
  271. });
  272. const patInfo = ref({});
  273. const pdaScanStatus = ref('Y'); // Y:需要扫码 N:已有患者信息
  274. // 计算属性
  275. const getData = (dataArray) => {
  276. if (dataArray !== "") {
  277. return dataArray.join("、");
  278. } else {
  279. return "";
  280. }
  281. };
  282. const getCheckFlag = (a, b) => {
  283. if (a.value) {
  284. return a.value.indexOf(b) === -1 ? false : true;
  285. } else {
  286. return a.indexOf(b) === -1 ? false : true;
  287. }
  288. };
  289. // 时间范围数据
  290. const timeRange = ref([])
  291. // 选中的时间索引
  292. const timeIndex = ref([0, 0])
  293. // 初始化时间范围
  294. const initTimeRange = () => {
  295. // 生成小时数据 (0-23)
  296. const hours = Array.from({ length: 24 }, (_, i) => i.toString().padStart(2, '0'))
  297. // 生成分钟数据 (0-59)
  298. const minutes = Array.from({ length: 60 }, (_, i) => i.toString().padStart(2, '0'))
  299. timeRange.value = [hours, minutes]
  300. // 设置默认时间为当前时间
  301. const now = new Date()
  302. timeIndex.value = [
  303. now.getHours(),
  304. now.getMinutes()
  305. ]
  306. }
  307. // 当选择器的值改变时触发
  308. const onTimeChange = (e,index) => {
  309. timeIndex.value = e.detail.value
  310. const [hour, minute] = timeIndex.value
  311. const timeValue = `${timeRange.value[0][hour]}:${timeRange.value[1][minute]}`
  312. const item = elementData.value[index];
  313. if (item.elementTypeCode === 'Time') {
  314. item.IEMRTempElementData = timeValue;
  315. item.IEMRTempElementPrintData = timeValue;
  316. elementData.value = [...elementData.value];
  317. }
  318. }
  319. // uni-datetime-picker-默认当前日期时间
  320. const formatDateTime = (elementTypeCode) => {
  321. const date = new Date();
  322. if (elementTypeCode === 'DateTime') {
  323. return `${date.getFullYear()}-${(date.getMonth()+1).toString().padStart(2, '0')}-${date.getDate().toString().padStart(2, '0')} ${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`;
  324. } else if (elementTypeCode === 'Date') {
  325. return `${date.getFullYear()}-${(date.getMonth()+1).toString().padStart(2, '0')}-${date.getDate().toString().padStart(2, '0')}`;
  326. }
  327. };
  328. // uni-datetime-picker-打开日期时间选择器方法
  329. const openUniDateTimePicker = (index, item) => {
  330. if (!item.IEMRTempElementData) {
  331. item.IEMRTempElementData = formatDateTime(item.elementTypeCode)
  332. }
  333. };
  334. // uni-datetime-picker确认选择
  335. const handleUniDateTimeConfirm = (e,index) => {
  336. if (index === -1) return;
  337. const item = elementData.value[index];
  338. item.IEMRTempElementData = e;
  339. item.IEMRTempElementPrintData = e;
  340. elementData.value = [...elementData.value];
  341. };
  342. onLoad((options) => {
  343. const app = getApp();
  344. newFlag.value = options.newFlag;
  345. editFlag.value = options.editFlag;
  346. templateID.value = options.templateID;
  347. admID_SM.value = options.admID;
  348. patID_SM.value = options.patID;
  349. navbarData.value.title = options.title;
  350. imgDomain.value = uni.getStorageSync('appUrlAddress');
  351. });
  352. onShow(() => {
  353. try {
  354. const pages = getCurrentPages()
  355. if (pages.length > 0) {
  356. const currentPage = pages[pages.length - 1]
  357. const currentRoute = currentPage.route // 当前页面路由
  358. // 更新全局变量
  359. if (uni.$appGlobal) {
  360. uni.$appGlobal.globalData.value.currentRoute = currentRoute
  361. }
  362. }
  363. } catch (err) {
  364. console.error('更新当前路由失败:', err)
  365. }
  366. })
  367. // 生命周期
  368. onMounted(() => {
  369. initTimeRange();
  370. // 注册全局事件
  371. uni.$on('callGetPDAScanInfo', (code) => {
  372. getPDAScanInfo(code);
  373. });
  374. });
  375. onUnmounted(() => {
  376. // 销毁全局事件,避免内存泄漏
  377. uni.$off('callGetPDAScanInfo');
  378. });
  379. // 方法定义
  380. function getCurrentDateTime() {
  381. const now = new Date();
  382. const year = now.getFullYear();
  383. const month = String(now.getMonth() + 1).padStart(2, '0');
  384. const day = String(now.getDate()).padStart(2, '0');
  385. const hours = String(now.getHours()).padStart(2, '0');
  386. const minutes = String(now.getMinutes()).padStart(2, '0');
  387. return `${year}-${month}-${day} ${hours}:${minutes}`;
  388. }
  389. //获取单据数据
  390. function getTemplateData(templateID, recordID, linktemplateID, disable) {
  391. const patInfo = uni.getStorageSync('patInfo');
  392. $http.post('urlDeault',this, {
  393. code: '10020016',
  394. data: {
  395. params: [{
  396. IEMRRecordID: recordID,
  397. IEMRTemplateID: templateID,
  398. status: 'Y',
  399. linktemplateID,
  400. disable,
  401. admID: patInfo.admInfo.admID
  402. }]
  403. },
  404. success: function(res) {
  405. if (+res.errorCode === 0) {
  406. elementData.value = res.result;
  407. addValue();
  408. }
  409. }
  410. });
  411. }
  412. //获取单据目录
  413. function getTemplateElement(templateID,scanPatNo) {
  414. const patInfo = uni.getStorageSync('patInfo');
  415. $http.post('urlDeault',this, {
  416. code: '10020015',
  417. data: {
  418. params: [{
  419. IEMRTemplateID: templateID,
  420. admID: patInfo.admInfo.admID
  421. }]
  422. },
  423. success: function(res) {
  424. if (+res.errorCode === 0) {
  425. elementData.value = res.result;
  426. //新巡视单,直接核对腕带数据
  427. if(templateID === '306'){
  428. const item = elementData.value[0];
  429. const result = scanPatNo === patInfo.basicInfo.patNo
  430. ? '腕带核对正确' : '腕带核对不正确';
  431. item.IEMRTempElementData = result;
  432. item.IEMRTempElementPrintData = result;
  433. elementData.value = [...elementData.value];
  434. }
  435. addValue();
  436. }
  437. }
  438. });
  439. }
  440. function selectItem(e, _dataset) {
  441. handleDataset(e, _dataset);
  442. const { dataindex } = e.currentTarget.dataset;
  443. const item = elementData.value[dataindex];
  444. if (item.disable === 'Y') {
  445. showToast({
  446. icon: 'none',
  447. title: '该元素已被禁用,不可编辑'
  448. });
  449. return;
  450. }
  451. const newSelectData = item.elmentData.map(data => {
  452. const isSelected = item.IEMRTempElementData === data.descripts || item.IEMRTempElementData === data.value;
  453. return {
  454. name: data.descripts,
  455. color: isSelected ? '#1890FF' : '#000'
  456. };
  457. });
  458. selectData.value = newSelectData;
  459. actionShow.value = true;
  460. clickIndex.value = dataindex;
  461. }
  462. function multipleSelectItem(e, _dataset) {
  463. handleDataset(e, _dataset);
  464. const { dataindex } = _dataset;
  465. const item = elementData.value[dataindex];
  466. const value = item.IEMRTempElementData || [];
  467. const newSelectData = item.elmentData.map(data => {
  468. const isChecked = value.some(v => v === data.descripts);
  469. return {
  470. ...data,
  471. color: isChecked ? '#1890FF' : '#e4e5e4',
  472. checked: isChecked
  473. };
  474. });
  475. selectData.value = newSelectData;
  476. mutilCheckshow.value = true;
  477. clickIndex.value = dataindex;
  478. }
  479. function multiItemCheck(e) {
  480. const { index } = e.currentTarget.dataset;
  481. const item = selectData.value[index];
  482. item.checked = !item.checked;
  483. item.color = item.checked ? '#1890FF' : '#e4e5e4';
  484. selectData.value = [...selectData.value];
  485. }
  486. function onConfirmMultiCheck() {
  487. const dataindex = clickIndex.value;
  488. const item = elementData.value[dataindex];
  489. let printData = '';
  490. const data = [];
  491. selectData.value.forEach(selectItem => {
  492. if (selectItem.checked) {
  493. data.push(selectItem.descripts);
  494. printData = printData
  495. ? `${printData};${item.printValue === 'Y' ? selectItem.value : selectItem.descripts}`
  496. : `${item.printValue === 'Y' ? selectItem.value : selectItem.descripts}`;
  497. }
  498. });
  499. item.IEMRTempElementData = data;
  500. item.IEMRTempElementPrintData = printData;
  501. elementData.value = [...elementData.value];
  502. mutilCheckshow.value = false;
  503. addValue();
  504. }
  505. function onSelect(e) {
  506. const dataindex = clickIndex.value;
  507. const item = elementData.value[dataindex];
  508. const data = e.name;
  509. let printData = data;
  510. if (item.printValue === 'Y') {
  511. const found = item.elmentData.find(d => d.descripts === data);
  512. if (found) printData = found.value;
  513. }
  514. item.IEMRTempElementData = data;
  515. item.IEMRTempElementPrintData = printData;
  516. elementData.value = [...elementData.value];
  517. onClose();
  518. addValue();
  519. }
  520. function onClose() {
  521. mutilCheckshow.value = false;
  522. actionShow.value = false;
  523. selectData.value = [];
  524. clickIndex.value = '-1';
  525. }
  526. //暴露给外部函数,获取PDA扫码反馈
  527. function getPDAScanInfo(code) {
  528. Util.getPatInfoNew(code, (res) => {
  529. const newPatInfo = res;
  530. if (Object.keys(patInfo.value).length === 0) {
  531. patInfo.value = { ...newPatInfo }; // 初始化响应式对象
  532. } else {
  533. Object.assign(patInfo.value, newPatInfo);
  534. }
  535. pdaScanStatus.value = 'N';
  536. getTemplateElement(templateID.value,code);
  537. });
  538. }
  539. function inputScanOnChange(e, _dataset) {
  540. const patInfo = uni.getStorageSync('patInfo');
  541. const { dataindex } = e.currentTarget.dataset;
  542. uni.scanCode({
  543. success(res) {
  544. const item = elementData.value[dataindex];
  545. const result = res.result === patInfo.basicInfo.patNo
  546. ? '腕带核对正确'
  547. : '腕带核对不正确';
  548. item.IEMRTempElementData = result;
  549. item.IEMRTempElementPrintData = result;
  550. elementData.value = [...elementData.value];
  551. addValue();
  552. }
  553. });
  554. }
  555. // v-model绑定了变量 item.IEMRTempElementData,绑定的变量已自动更新输入框内容
  556. function inputOnChange(e, { dataindex }) {
  557. const item = elementData.value[dataindex];
  558. item.IEMRTempElementPrintData = item.IEMRTempElementData;
  559. elementData.value = [...elementData.value];
  560. addValue();
  561. }
  562. function inputOnBlur(e, { dataindex }) {
  563. const item = elementData.value[dataindex];
  564. let value = item.IEMRTempElementData.replace(item.unit, '');
  565. if (item.unit && !isNaN(value) && value !== '') {
  566. value += item.unit;
  567. }
  568. item.IEMRTempElementData = value;
  569. item.IEMRTempElementPrintData = value;
  570. elementData.value = [...elementData.value];
  571. addValue();
  572. }
  573. function deleteData(e, { dataindex }) {
  574. handleDataset(e, { dataindex });
  575. const item = elementData.value[dataindex];
  576. item.IEMRTempElementData = '';
  577. item.IEMRTempElementPrintData = '';
  578. elementData.value = [...elementData.value];
  579. addValue();
  580. }
  581. function checkChange(e, _dataset) {
  582. handleDataset(e, _dataset);
  583. const { dataindex } = e.currentTarget.dataset;
  584. const item = elementData.value[dataindex];
  585. const data = e.detail.value;
  586. const printData = [];
  587. if (item.printValue === 'Y') {
  588. item.elmentData.forEach(el => {
  589. data.forEach(d => {
  590. if (el.descripts === d) {
  591. printData.push(el.value);
  592. }
  593. });
  594. });
  595. } else {
  596. item.elmentData.forEach(el => {
  597. if (Array.isArray(data)) {
  598. data.forEach(d => {
  599. if (el.descripts === d) {
  600. printData.push(el.descripts);
  601. }
  602. });
  603. }
  604. });
  605. }
  606. if (Array.isArray(data) && data.length > 1) {
  607. item.IEMRTempElementData = printData;
  608. item.IEMRTempElementPrintData = printData;
  609. } else {
  610. item.IEMRTempElementData = e.detail.value;
  611. item.IEMRTempElementPrintData = e.detail.value;
  612. }
  613. elementData.value = [...elementData.value];
  614. addValue();
  615. }
  616. // 回到首页
  617. function goBackPage(){
  618. uni.reLaunch({ url: '../index/index' });
  619. }
  620. // 保存事件
  621. function addRecord() {
  622. addValue();
  623. const patInfo = uni.getStorageSync('patInfo');
  624. const userData = uni.getStorageSync('userData');
  625. const recordID = newFlag.value !== '0' ? newFlag.value : '';
  626. $http.post('urlDeault',this, {
  627. code: '10020003',
  628. data: {
  629. params: [{
  630. IEMRTemplateID: templateID.value,
  631. admID: admID_SM.value || patInfo.admInfo?.admID,
  632. patID: patID_SM.value || patInfo.basicInfo?.patID,
  633. updateUserID: userData.userID,
  634. IEMRRecordID: recordID,
  635. detailData: elementData.value
  636. }]
  637. },
  638. success: function(res) {
  639. if (+res.errorCode === 0) {
  640. uni.showToast({
  641. icon: 'none',
  642. title: '保存成功!',
  643. success: () => {
  644. patInfo.value = {};
  645. pdaScanStatus.value = 'Y'; // Y:需要扫码 N:已有患者信息
  646. }
  647. });
  648. } else {
  649. uni.showToast({
  650. icon: 'none',
  651. title: res.errorMessage
  652. });
  653. }
  654. }
  655. });
  656. }
  657. function addValue() {
  658. var addElement = [];
  659. let elementDataN = elementData.value;
  660. elementData.value.map((item, index) => {
  661. if (item.addItemFlag == 'Y') {
  662. item.index = index;
  663. addElement[item.IEMRTempElementID] = item;
  664. elementData.value[index].IEMRTempElementData = elementData.value[index].defaultValue || 0;
  665. elementData.value[index].IEMRTempElementPrintData = elementData.value[index].defaultValue || 0;
  666. }
  667. });
  668. elementData.value.map((item) => {
  669. if (item.addItemID != null && item.addItemID != '') {
  670. var value = '';
  671. var valueDesc = item.IEMRTempElementData;
  672. if (Array.isArray(valueDesc)) {
  673. item.elmentData.map((detail) => {
  674. valueDesc.map((valueitem) => {
  675. if ((detail.descripts == valueitem || detail.code ==
  676. valueitem || detail.value == valueitem) &&
  677. valueitem != '') {
  678. if (isNaN(valueitem) && value == '0') {
  679. value = '';
  680. }
  681. if (value != '') {
  682. value = value + ';';
  683. }
  684. if (addElement[item.addItemID].printValue == 'Y') {
  685. value = value + detail.value;
  686. } else {
  687. value = value + detail.descripts;
  688. }
  689. }
  690. });
  691. });
  692. } else if (item.elmentData.length > 0) {
  693. item.elmentData.map((detail) => {
  694. if (detail.descripts == valueDesc) {
  695. value = detail.value;
  696. }
  697. });
  698. } else {
  699. value = valueDesc;
  700. }
  701. if (value != '' && value != 0) {
  702. var tempvalue = [];
  703. if ((value + '').indexOf(';') < 0) {
  704. tempvalue.push(value);
  705. } else {
  706. tempvalue = value.split(';');
  707. }
  708. for (var i = 0; i < tempvalue.length; i++) {
  709. value = tempvalue[i];
  710. if (addElement && addElement.length > 0 && item.addItemID && addElement[item
  711. .addItemID] && addElement[item.addItemID].index) {
  712. if (
  713. addElement[item.addItemID] &&
  714. addElement[item.addItemID].IEMRTempElementData != '' &&
  715. addElement[item.addItemID].IEMRTempElementData != undefined
  716. ) {
  717. if (!isNaN(value)) {
  718. elementData.value[addElement[item.addItemID].index].IEMRTempElementData =
  719. Number(elementData.value[addElement[item.addItemID].index]
  720. .IEMRTempElementData) + Number(value);
  721. elementData.value[addElement[item.addItemID].index]
  722. .IEMRTempElementPrintData = elementData.value[addElement[item
  723. .addItemID].index].IEMRTempElementData;
  724. } else {
  725. elementData.value[addElement[item.addItemID].index].IEMRTempElementData =
  726. elementData.value[addElement[item.addItemID].index]
  727. .IEMRTempElementData + ';' + value;
  728. elementData.value[addElement[item.addItemID].index]
  729. .IEMRTempElementPrintData = elementData.value[addElement[item
  730. .addItemID].index].IEMRTempElementData;
  731. }
  732. } else {
  733. if (!isNaN(value)) {
  734. elementData.value[addElement[item.addItemID].index].IEMRTempElementData =
  735. Number(value);
  736. elementData.value[addElement[item.addItemID].index]
  737. .IEMRTempElementPrintData = Number(value);
  738. } else {
  739. elementData.value[addElement[item.addItemID].index].IEMRTempElementData =
  740. value;
  741. elementData.value[addElement[item.addItemID].index]
  742. .IEMRTempElementPrintData = value;
  743. }
  744. }
  745. }
  746. }
  747. }
  748. }
  749. });
  750. //遍历总和项
  751. addElement.map((item, itemIndex) => {
  752. var index = item.index;
  753. if (item.elementTypeCode == 'Select') {
  754. var data = elementData.value[index].IEMRTempElementData;
  755. var printData = elementData.value[index].IEMRTempElementPrintData;
  756. elementData.value[index].elmentData.map((dataitem, dataIndex) => {
  757. if (dataitem.value.indexOf('-') < 0) {
  758. if (dataitem.value == data) {
  759. elementData.value[index].IEMRTempElementData = dataitem.descripts;
  760. if (elementData.value[index].printValue == 'Y') {
  761. //打印值
  762. elementData.value[index].IEMRTempElementPrintData = dataitem.value;
  763. } else {
  764. //打印描述
  765. elementData.value[index].IEMRTempElementPrintData = dataitem
  766. .descripts;
  767. }
  768. }
  769. } else {
  770. var valuerange = dataitem.value.split('-');
  771. if (data >= valuerange[0] && data <= valuerange[1]) {
  772. elementData.value[index].IEMRTempElementData = dataitem.descripts;
  773. if (elementData.value[index].printValue == 'Y') {
  774. //打印值
  775. elementData.value[index].IEMRTempElementPrintData = dataitem.value;
  776. } else {
  777. //打印描述
  778. elementData.value[index].IEMRTempElementPrintData = dataitem
  779. .descripts;
  780. }
  781. }
  782. }
  783. });
  784. }
  785. });
  786. setGradeFun();
  787. }
  788. function setGradeFun() {
  789. let totleValue;
  790. elementData.value.forEach(item => {
  791. if (item.addItemFlag === 'Y') {
  792. totleValue = item.IEMRTempElementData;
  793. }
  794. if (item.IEMRTempElementDesc === '自理能力等级') {
  795. item.elmentData.forEach(child => {
  796. const myValue = child.value.split('-');
  797. if (!myValue[1]) {
  798. if (Number(totleValue) === Number(myValue[0])) {
  799. item.IEMRTempElementData = child.descripts;
  800. item.IEMRTempElementPrintData = child.descripts;
  801. }
  802. } else {
  803. if (Number(totleValue) >= Number(myValue[0]) && Number(totleValue) <= Number(myValue[1])) {
  804. item.IEMRTempElementData = child.descripts;
  805. item.IEMRTempElementPrintData = child.descripts;
  806. }
  807. }
  808. });
  809. }
  810. });
  811. elementData.value = [...elementData.value];
  812. }
  813. function handleDataset(e, _dataset) {
  814. // 处理数据集合并到事件对象中
  815. if (_dataset) {
  816. Object.keys(_dataset).forEach(key => {
  817. if (!e.currentTarget.dataset[key]) {
  818. e.currentTarget.dataset[key] = _dataset[key];
  819. }
  820. });
  821. }
  822. }
  823. </script>
  824. <style>
  825. /* 保持原有样式不变 */
  826. .content {
  827. height: calc(100% - 200rpx);
  828. padding: 4rpx 15rpx;
  829. overflow: auto;
  830. }
  831. .elementitem {
  832. border-bottom: 1px solid #e5e5e4;
  833. }
  834. .item .title {
  835. height: 85rpx;
  836. line-height: 85rpx;
  837. background: #f6f6f6;
  838. font-size: 28rpx;
  839. font-weight: 400;
  840. color: #333333;
  841. display: flex;
  842. flex-direction: row;
  843. }
  844. .title .border {
  845. border: 8rpx solid #007aff;
  846. border-radius: 4rpx;
  847. height: 28rpx;
  848. margin: 20rpx 10rpx 20rpx 0;
  849. }
  850. .itemtitle {
  851. line-height: 85rpx;
  852. }
  853. .itemdata {
  854. line-height: 85rpx;
  855. }
  856. .itemdata .van-cell {
  857. padding: 0 !important;
  858. }
  859. .inputclass {
  860. border: 1px solid #999999;
  861. margin: 18rpx 8rpx;
  862. line-height: 80rpx;
  863. }
  864. .inputclass .van-cell {
  865. padding: 0 !important;
  866. }
  867. .scanCodeclass {
  868. line-height: 80rpx;
  869. display: flex;
  870. text-align: center;
  871. }
  872. .scanViewColor_green {
  873. color: #66bb6a;
  874. }
  875. .scanViewColor_red {
  876. color: #f44336;
  877. }
  878. .custom-icon {
  879. width: 30px;
  880. height: 30px;
  881. margin-top: 10rpx;
  882. margin-left: 15rpx;
  883. }
  884. .comboboxclass {
  885. margin: 8rpx;
  886. }
  887. .radioboxclass {
  888. margin: 8rpx;
  889. line-height: 80rpx;
  890. }
  891. .areaclass {
  892. min-height: 185rpx;
  893. border: 1px solid #999999;
  894. margin: 8rpx;
  895. }
  896. .selectclass {
  897. min-height: 60rpx;
  898. border: 1px solid #999999;
  899. margin: 8rpx;
  900. vertical-align: middle;
  901. }
  902. .delicon {
  903. margin-right: 10rpx;
  904. }
  905. .selectclass .van-cell__right-icon-wrap {
  906. /* padding-top: 14rpx;
  907. padding-right: 10rpx; */
  908. }
  909. .content .van-cell__value:empty {
  910. display: block !important;
  911. }
  912. .label {
  913. width: 100%;
  914. height: 78rpx;
  915. background: #f6f6f6;
  916. display: flex;
  917. flex-direction: row;
  918. }
  919. .radio-container {
  920. display: flex;
  921. flex-wrap: wrap;
  922. }
  923. .rowitem {
  924. line-height: 50rpx;
  925. width: 50%;
  926. box-sizing: border-box;
  927. padding: 5px;
  928. }
  929. .rowitem2 {
  930. line-height: 50rpx;
  931. width: 100%;
  932. box-sizing: border-box;
  933. padding: 5px;
  934. }
  935. .mutilCheck {
  936. height: 500rpx;
  937. width: calc(100% - 48rpx);
  938. padding: 24rpx;
  939. }
  940. .mutilCheck .checkData {
  941. display: flex;
  942. flex-direction: row;
  943. flex-wrap: wrap;
  944. overflow: auto;
  945. height: 434rpx;
  946. font-size: 30rpx;
  947. font-weight: bold;
  948. align-content: start;
  949. }
  950. .checkitem {
  951. width: calc(33% - 26rpx);
  952. word-break: break-all;
  953. margin: 10rpx 12rpx;
  954. min-height: 60rpx;
  955. border: 1px solid #e4e5e4;
  956. border-radius: 5px;
  957. background: #e4e5e4;
  958. height: 90rpx;
  959. }
  960. /* 外层容器:淡蓝色边框 + 圆角 */
  961. .topinfo {
  962. /* 淡蓝色边框,宽度1px,线条类型为实线 */
  963. border: 1px solid #7cb5ff;
  964. /* 边角圆润,数值可根据需求调整 */
  965. border-radius: 8px;
  966. /* 内部留白,避免内容贴边 */
  967. padding: 10px;
  968. /* 可选:添加轻微阴影增强层次感 */
  969. box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
  970. margin: 10px; /* 与其他元素保持间距,可按需删除 */
  971. }
  972. /* 内部内容容器:弹性布局确保排列整齐 */
  973. .topinfo .item {
  974. /* 弹性布局,让子元素横向排列 */
  975. display: flex;
  976. /* 子元素垂直居中对齐 */
  977. align-items: center;
  978. /* 子元素之间均匀分布,两端无多余空间 */
  979. justify-content: flex-start;
  980. /* 自动换行,避免屏幕过小时内容溢出 */
  981. flex-wrap: wrap;
  982. /* 子元素之间的间距 */
  983. gap: 12px;
  984. }
  985. /* 基础文本样式:统一字体、放大字号、清晰显示 */
  986. .topinfo .bedcode,
  987. .topinfo .info {
  988. /* 统一字体,适配不同设备 */
  989. font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  990. /* 字体放大,比默认字号稍大 */
  991. font-size: 16px;
  992. /* 字体加粗,提升清晰度 */
  993. font-weight: 500;
  994. /* 字体颜色:深灰色,避免过黑刺眼 */
  995. color: #333333;
  996. }
  997. /* 分割线样式:灰色细线条,区分内容 */
  998. .topinfo .border {
  999. /* 分割线为竖线 */
  1000. width: 1px;
  1001. height: 18px;
  1002. /* 灰色线条,颜色比边框稍深 */
  1003. background-color: #dcdcdc;
  1004. }
  1005. /* 护理级别样式:不同级别对应不同颜色,突出显示 */
  1006. .topinfo .nurse-lv-css-red {
  1007. font-size: 16px;
  1008. font-weight: 600;
  1009. color: #ff4d4f; /* 特级 - 红色 */
  1010. padding: 2px 8px;
  1011. border-radius: 4px;
  1012. background-color: #fff1f0; /* 浅色背景衬托 */
  1013. }
  1014. .topinfo .nurse-lv-css-pink {
  1015. font-size: 16px;
  1016. font-weight: 600;
  1017. color: #ff7a75; /* 一级 - 粉色 */
  1018. padding: 2px 8px;
  1019. border-radius: 4px;
  1020. background-color: #fff2f0;
  1021. }
  1022. .topinfo .nurse-lv-css-blue {
  1023. font-size: 16px;
  1024. font-weight: 600;
  1025. color: #1890ff; /* 二级 - 蓝色 */
  1026. padding: 2px 8px;
  1027. border-radius: 4px;
  1028. background-color: #e6f7ff;
  1029. }
  1030. .topinfo .nurse-lv-css-greenyellow {
  1031. font-size: 16px;
  1032. font-weight: 600;
  1033. color: #52c41a; /* 三级 - 黄绿色 */
  1034. padding: 2px 8px;
  1035. border-radius: 4px;
  1036. background-color: #f6ffed;
  1037. }
  1038. /* 内部容器布局 */
  1039. .scan-container {
  1040. display: flex;
  1041. flex-direction: column;
  1042. align-items: center;
  1043. justify-content: center;
  1044. gap: 15px; /* 图片与文字间距 */
  1045. }
  1046. /* 图片样式 */
  1047. .scan-img {
  1048. width: 100%; /* 图片宽度,可按需调整 */
  1049. height: auto;
  1050. opacity: 0.9;
  1051. }
  1052. /* 文字样式 - 高亮、放大、闪烁 */
  1053. .scan-text {
  1054. font-size: 20px; /* 大字体 */
  1055. font-weight: bold;
  1056. color: #1890ff; /* 高亮蓝色 */
  1057. text-align: center;
  1058. padding: 10px 15px;
  1059. border-radius: 6px;
  1060. background-color: rgba(255, 255, 255, 0.8); /* 白色背景增强对比度 */
  1061. /* 闪烁动画 */
  1062. animation: blink 1.5s infinite;
  1063. }
  1064. /* 闪烁动画定义 */
  1065. @keyframes blink {
  1066. 0%, 100% {
  1067. opacity: 1;
  1068. transform: scale(1);
  1069. }
  1070. 50% {
  1071. opacity: 0.6;
  1072. transform: scale(1.05); /* 轻微放大增强闪烁感 */
  1073. }
  1074. }
  1075. </style>