hldy_app_mini/pages/NursingNew/component/nurse/bigindex.vue

632 lines
19 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!-- 护嘱 -->
<template>
<view class="right-container" :style="isshow?{opacity: `1`}:{opacity: `0`}">
<view class="doctorsay-container-view">
<view class="doctorsay-container-container">
<view class="super-card">
<view class="boom-father">
<view class="boom" :style="{ transform: transformStyle }">
<view>
<view v-for="(item,index) in timeArray" :key="index">
<view class="boom-son">
<text class="boom-text">
{{item}}
</text>
</view>
</view>
</view>
</view>
</view>
<view class="super-card-container">
<scroll-view style="width: 100%;" scroll-with-animation :scroll-left="cardLeft" scroll-x
@scroll="handleTop" :show-scrollbar="false">
<view style="display: flex;width:4824rpx;">
<view v-for="(item0,index0) in timearr" :key="index0" class="super-card-right">
<view class="super-card-time">
{{(item0.positioning.length == 1 ? ('0' + item0.positioning) : item0.positioning) + ":00"}}
</view>
</view>
</view>
<view style="display: flex;height: 1165rpx;position: relative;">
<view class="xian-bian"></view>
<scroll-view style="height: 100%;width:6960rpx;background-color: #fff;"
:scroll-top="scrollTop" scroll-with-animation :scroll-y="true"
@scroll="handleScrolltime" :show-scrollbar="false">
<view style="display: flex;height: 100%;">
<view v-for="(item0,index0) in timearr" :key="index0">
<view class="super-card-time-und">
<view v-for="(item1,index1) in item0.children" style="width: 100%;"
:key="index1">
<view
:class=" targetRuler.index0 === index0 && targetRuler.index1 === index1 ? targetRuler.index1 ?`title-time-border-big`:`title-time-border-big-top` : `super-card-time-card` "
:style="!targetRuler.bordershow && saveRulerTime.index0 === index0 && saveRulerTime.index1 === index1 ? {zIndex:999} : {borderBottom: '1rpx solid transparent'}"
:id="`a${index0}_${index1}`" style="position: relative;"
@click="rulerTouchClick(item1,index0,index1)"
:data-index0="index0" :data-index1="index1">
<view class="title-time-blue"
v-show="saveEditIndex.index0 == index0 && saveEditIndex.index1 == index1 && isRule">
<image class="blue-img"
src="/static/index/bluetarget.png" />
</view>
<view :class="getClass(item1,index0,index1)"
style="font-size: 30rpx;overflow: hidden;"
:style="{ animationDelay:`-${computeDelay(index0, index1).toFixed(2)}s`,border:saveEditIndex.index0 == index0 && saveEditIndex.index1 == index1? `2rpx solid #46B2F6`:'' }">
<view class="title-time" v-if="item1.startTime"
style="flex-direction: column;">
<view v-if="item1.startTime"
class="title-time-font-rel">
{{ item1.directiveName?splitString(item1.directiveName)[0]:""}}
</view>
<view
v-if="item1.startTime&&splitString(item1.directiveName)[1]"
class="title-time-font-tags">
({{ item1.directiveName?splitString(item1.directiveName)[1]:""}})
</view>
<view v-if="item1.startTime"
:class="getFontClass(item1,index0,index1)">
{{ `${parseHourMinutestring(item1.startTime).hour}:${parseHourMinutestring(item1.startTime).minute} - ${parseHourMinutestring(item1.endTime).hour}:${parseHourMinutestring(item1.endTime).minute}` }}
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</scroll-view>
</view>
</scroll-view>
</view>
<view class="right-order">
<view class="order-title">
<view class="order-month" @click="opendata=true">
{{ selectdata.month }}月
</view>
<scroll-view class="order-day" scroll-with-animation :scroll-x="true"
:scroll-left="movetime">
<view class="days-father">
<view :class="daytarget===index? `targetdays` :`days`"
v-for="(item,index) in daysarray" :key="index" @click="clickday(item,index)">
{{ item }}
</view>
</view>
</scroll-view>
</view>
<view class="calendar-father" v-show="opendata">
<calendarsimple @datachange="dateget" />
</view>
<view v-show="opendata" class="mengban"
@click="opendata=false">
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount, computed, nextTick, watch } from 'vue';
import { onShow, onHide } from '@dcloudio/uni-app';
import { getNclist, addBatch, addDirective, addInstant, deleteDirective, deleteInstant, editDirective, getDirectiveOrders } from "./api.js";
import { myArray } from './yaoshandiao.js';
import calendarsimple from '@/component/public/calendarsimple.vue'
const props = defineProps({
isshow: {
type: Boolean,
required: true,
},
});
// watch(
// () => props.isshow,
// (newVal, oldVal) => {
// // 只有当新旧值不相同时才执行
// if (newVal !== oldVal) {
// }
// }
// )
const opendata = ref(false);
const bodystatus = ref(false);
const bodystatustarget = ref(-1);
const facestatus = ref(false);
const facestatustarget = ref(-1);
/* ---- 用于 transform 的响应式字符串 ----
注意:虽然这是响应式,但我们只在 rAF 里更新它(受控更新),避免频繁触发 Vue 渲染 */
const transformStyle = ref('translate3d(0, 0, 0)');
/* rAF / 计数器变量 */
let lastY = 0;
let ticking = false;
const bodydonghua = ref(false)
const openbody = ref(false)
const openface = ref(false)
const hournow = ref(new Date().getHours());
// 获得现在的年月日
const dateref = ref(getTodayObj())
function getTodayObj() {
const d = new Date()
const month = String(d.getMonth() + 1).padStart(2, '0')
const day = String(d.getDate()).padStart(2, '0')
return {
year: d.getFullYear(),
month,
day
}
}
const selectdata = ref({
year: 0,
month: "",
day: ""
})
const daysarray = ref([]);
const movetime = ref(0)
function generateDayArray() {
const selY = Number(selectdata.value.year)
const selM = Number(selectdata.value.month)
// 校验:年/月 必须是有效数字且月在1-12之间
if (!Number.isFinite(selY) || !Number.isFinite(selM) || selM < 1 || selM > 12) {
return []
}
const todayY = Number(dateref.value.year)
const todayM = Number(dateref.value.month) // dateref.month 可能是字符串 "01"
const todayD = Number(dateref.value.day)
let endDay = 0
if (selY === todayY && selM === todayM) {
// 同年同月:到今天为止
endDay = todayD;
} else {
// 不同:计算该月总天数。注意 new Date(year, month, 0).getDate()
// 这里 month 要传 1-12这个构造会返回该月最后一天
endDay = new Date(selY, selM, 0).getDate()
}
daysarray.value = Array.from({ length: endDay }, (_, i) => String(i + 1).padStart(2, '0'))
// console.log("看看生成的咋样", daysarray.value)
if (selY === todayY && selM === todayM) {
movetime.value = 9998;
daytarget.value = daysarray.value.length - 1
} else {
movetime.value = 0.001;
daytarget.value = 0
setTimeout(() => {
movetime.value = 0;
}, 50)
}
// 生成字符串数组 ["01","02",...]
}
const daytarget = ref(0)
const clickday = (item : string, index : number) => {
daytarget.value = index
}
const facedonghua = ref(false)
const open = ref(false);
const bottomItems = ref([])
const nameArray = [
`标准`, `超重`, `强直`, `偏瘫`, `佝偻`, `稳定`, `焦虑`, `抑郁`, `暴力`, `恐惧`, `烦躁`, `易怒`, `臆想`,
]
const timeArray = [
`00`, `05`, `10`, `15`, `20`, `25`, `30`, `35`, `40`, `45`, `50`, `55`
];
const weekDays = ["周一", "周二", "周三", "周四", "周五", "周六", "周日"];
const days = Array.from({ length: 31 }, (_, i) => (i + 1).toString().padStart(2, "0"));
const isweek = ref(true);
// 是否周期
const iszhouqi = ref(false);
//高度回到最高
const firsttop = ref(0);
const secondtop = ref(0);
const scrollLeft = ref(0);
const cardLeft = ref(678);
//移动表格
const scrollTop = ref(0)
//左下的数组
const downList = ref<any>()
const isop = ref(false);
const bigArray = ref([]);
const isopen = ref(false)
const songisopen = ref(false)
const isopacity = ref(false)
const songisopacity = ref(false)
// 删除表格弹窗
const deleteisopen = ref(false);
const deletename = ref("")
const deleteisopacity = ref(false)
// 解释图标弹窗
const sayisopen = ref(false);
const sayname = ref("")
const sayisopacity = ref(false)
const saveleft = ref(6);
const saveright = ref(11);
const savetop = ref(0);
const savebottom = ref(3);
const isMove = ref(false);
const getjiao = computed(() => {
if (jiao.value[0] && jiao.value[1]) {
return "left-bottom"
} else if (!jiao.value[0] && jiao.value[1]) {
return "right-bottom"
} else if (jiao.value[0] && !jiao.value[1]) {
return "left-top"
} else {
return "right-top"
}
})
const getFontClass = (item : any, index0, index1) => {
switch (item.executeStatus) {
case 'hisFaild':
return 'card-time-red';
case 'current':
return 'card-time-blue';
default:
return 'card-time';
}
}
// 这是二级菜单的动画的模板
const secondtemp = ref([])
// 上次点击时间
const lastTap = ref(0)
// 双击的最大间隔ms可根据体验调整
const DOUBLE_TAP_DELAY = 300
//变更左侧菜单
const isempty = ref(false);
const isRule = ref(false);
const topindex = ref(-1)
const isDelete = ref(false);
// 给抖动用的
function pseudoRandom(index0, index1) {
const seed = index0 * 55.9898 + index1 * 78.233;
// 产生一个伪随机数,取小数部分
return Math.abs(Math.sin(seed) * 43758.5453) % 1;
}
function computeDelay(index0, index1) {
const range = 2; // 延迟范围 0 ~ 2 秒
return pseudoRandom(index0, index1) * range;
}
// 在作用域中声明一个定时器变量
let throttleTimer = null;
//监听拖拽
/* 兼容:如果不支持 requestAnimationFrame就用 setTimeout */
const requestAnimationFrame =
typeof window !== 'undefined' && window.requestAnimationFrame
? window.requestAnimationFrame
: (cb) => setTimeout(cb, 16);
function handleScrolltime(e) {
// uni-app 的 scroll 事件通常把位置放在 e.detail.scrollTop
// 为保险,先做容错判断
const scrollTop = (e && e.detail && (e.detail.scrollTop ?? e.detail.scrollY)) || 0;
lastY = scrollTop;
// 如果还在等待上一帧更新,就直接返回;否则安排下一帧更新
if (!ticking) {
ticking = true;
requestAnimationFrame(() => {
// 把 transform 更新为负的 scrollTop向上平移
// 使用 translate3d 触发 GPU 合成层
transformStyle.value = `translate3d(0, -${lastY}px, 0)`;
ticking = false;
});
}
}
const leftIn = ref(0)
function handleTop(e) {
leftIn.value = e.detail.scrollLeft
}
// 方法:根据条件返回不同的类名
const getClass = (item, index0, index1) => {
if (item.startTime) {
switch (item.executeStatus) {
case 'hisOk':
return 'title-time-border-hisOk';
case 'hisFaild':
return 'title-time-border-hisFaild';
case 'current':
return 'title-time-border-current';
case 'future':
return 'title-time-border-yellow';
}
}
return 'title-time-border';
}
// 通用的生成函数
function genPaths(base, prefix, count, ext = 'png', startIndex = 0, pad = false) {
return Array.from({ length: count }, (_, i) => {
const idx = pad
? String(i + startIndex).padStart(2, '0')
: i + startIndex
return `${base}/${prefix}${idx}.${ext}`
})
}
// 当前选中的菜单索引
const upmenuIndex = ref<number>(1);
const downmenuIndex = ref<number>(0);
const downdonghua = ref(-1);
const thirdmenuIndex = ref<number>(0);
const forthmenuIndex = ref<number>(0);
const saveEditIndex = ref({
index0: -1,
index1: -1
})
const timer = ref(null);//计时器
const elementsInfo = ref({})//所有表格的信息
const moveX = ref(0)
const moveY = ref(0)
const openX = ref(0)
const openY = ref(0)
const flyNumber = ref({
index0: 999,
index1: 999,
// tagName: ''
})
const deletedownisopacity = ref(false);
const touchindex1 = ref(-1);
const jiao = ref([false, false])
//表格点击开始
const showDetail = ref([-1, -1])
const rulerTouchClick = (item : any, index0 : number, index1 : number) => {
isDelete.value = false;
saveEditIndex.value.index0 = index0;
saveEditIndex.value.index1 = index1;
centerCell();
isRule.value = true;
}
const shakyTable = ref(false);
const saveX = ref(0);
const saveY = ref(0);
const indexsave = ref([-1, -1]);
const buttonBlue = ref(false)
let animTimer = null
// 暂存器
const saveRulerTime = ref({
index0: -1,
index1: -1
})
const targetRuler = ref({
index0: -1,
index1: -1,
current: -1,
bordershow: true
})
const whereEvent = (data : any) => {
saveEditIndex.value.index0 = data.index0;
saveEditIndex.value.index1 = data.index1;
centerCell();
targetRuler.value.index0 = data.index0;
targetRuler.value.index1 = data.index1;
saveRulerTime.value.index0 = targetRuler.value.index0;
saveRulerTime.value.index1 = targetRuler.value.index1;
targetRuler.value.bordershow = false;
setTimeout(() => {
targetRuler.value.index0 = -1;
targetRuler.value.index1 = -1;
targetRuler.value.current = -1
}, 400)
setTimeout(() => {
targetRuler.value.bordershow = true;
saveRulerTime.value.index0 = -1;
saveRulerTime.value.index1 = -1;
}, 1000)
}
// 定义每小时中的分钟数组,表示每 5 分钟一个时间段,总共 12 个
const minuteArr = ['00', '05', '10', '15', '20', '25', '30', '35', '40', '45', '50', '55']
const timearr = ref(
Array.from({ length: 24 }, (_, hour) => ({
positioning: hour.toString(),
children: minuteArr.map(time => ({
// tagName: time, // 表示分钟,如 '00', '05' 等
directiveName: '' // 默认的 directiveName
}))
}))
)
const geteverything = () => {
if (uni.getStorageSync('nuId') && uni.getStorageSync('elderId')) {
getTable()
}
}
// 处理分钟和小时的函数
function parseHourMinutestring(startTime) {
// 假设格式固定为 "YYYY-MM-DD HH:MM:SS"
const parts = startTime.split(' ');
if (parts.length < 2) return { hour: NaN, minute: NaN };
const [hh, mm] = parts[1].split(':');
return { hour: hh, minute: mm };
}
// 处理分钟和小时的函数(number)
function parseHourMinute(startTime) {
// 假设格式固定为 "YYYY-MM-DD HH:MM:SS"
const parts = startTime.split(' ');
if (parts.length < 2) return { hour: NaN, minute: NaN };
const [hh, mm] = parts[1].split(':');
return { hour: Number(hh), minute: Number(mm) };
}
const getTable = () => {
let time = `${selectdata.value.year}-${selectdata.value.month}-${selectdata.value.day}`
getDirectiveOrders(time).then((data) => {
// console.log("data",data.result.all)
timearr.value = Array.from({ length: 24 }, (_, hour) => ({
positioning: hour.toString(),
children: minuteArr.map(time => ({
// tagName: time, // 表示分钟,如 '00', '05' 等
directiveName: '' // 默认的 directiveName
}))
}))
data.result.all.forEach((element : any) => {
element.positioning = parseHourMinute(element.startTime).hour;
element.positioningLong = parseHourMinute(element.startTime).minute / 5;
timearr.value[element.positioning].children[element.positioningLong] = element;
})
})
}
const savePackagelist = ref([]);
onMounted(() => {
selectdata.value = dateref.value;
generateDayArray()
savePackagelist.value = uni.getStorageSync('Packagelist') || []
let res = uni.getStorageSync('saveTree0')
let goodArray = []
myArray.forEach((element : any) => {
element.children.forEach((element1 : any) => {
goodArray.push({
name: element1.title,
url: element1.url,
})
})
})
secondtemp.value = goodArray
if (res.result) {
bigArray.value = res.result;
}
downList.value = bigArray.value[0].children
upmenuIndex.value = -1;
downdonghua.value = -1;
setTimeout(() => {
upmenuIndex.value = 0;
downdonghua.value = 0;
}, 50)
uni.$on('where', findback);
downdonghua.value = 0;
geteverything()
scrollTop.value = 0.001
nextTick(() => {
scrollTop.value = 0
timeNowMove()
})
})
const bodyTagListLook = ref([]);
const emotionTagListLook = ref([]);
const cansumit = ref(false);
onBeforeUnmount(() => {
if (animTimer) clearTimeout(animTimer)
uni.$off('where', findback);
ticking = false;
})
function findback(data : any) {
// solveWatch.value = 3;
whereEvent(data)
}
// 切割bigArray
function splitString(str) {
// 使用正则表达式找到所有括号的内容
let result = [];
let remainingStr = str;
// 正则匹配最外层括号(支持全角和半角)
let regex = /([^(]*)[(]([^)]+)[)]/;
while (regex.test(remainingStr)) {
let match = remainingStr.match(regex);
if (match) {
// 添加括号前的部分(去掉空白)
if (match[1].trim()) {
result.push(match[1].trim());
}
// 添加括号内的内容
if (match[2].trim()) {
result.push(match[2].trim());
}
// 更新剩余的字符串
remainingStr = remainingStr.replace(match[0], '').trim();
}
}
// 如果最后还有剩余部分,也加入结果
if (remainingStr.trim()) {
result.push(remainingStr.trim());
}
return result;
}
const totalColumns = 24; // 总列数
const totalRows = 11; // 总行数
const visibleWidth = 1455; // 可视区域宽度 (rpx),基于 scalcType * widthType ≈ 2220
const visibleHeight = 1170; // 可视区域高度 (rpx)假设显示约5行时 heightType = 102.5
function centerCell() {
if (saveEditIndex.value.index0 >= 0 && saveEditIndex.value.index0 <= totalColumns && saveEditIndex.value.index1 >= 0 && saveEditIndex.value.index1 <= totalRows) {
// 计算点击格子的中心位置 (rpx)
const cellCenterX = (saveEditIndex.value.index0 + 0.5) * 290;
const cellCenterY = (saveEditIndex.value.index1 + 0.5) * 234;
// 计算 scrollLeft 和 scrollTop使格子中心位于可视区域中心
cardLeft.value = cellCenterX - visibleWidth / 2;
scrollTop.value = cellCenterY - visibleHeight / 2;
// 计算网格总宽高
const totalWidth = totalColumns * 290;
const totalHeight = totalRows * 234;
// 限制 scrollLeft 和 scrollTop 在有效范围内
cardLeft.value = Math.max(0, Math.min(cardLeft.value, totalWidth - visibleWidth)) / 2 + 0.7;
// scrollTop.value = 0
scrollTop.value = Math.max(0, Math.min(scrollTop.value, totalHeight - visibleHeight)) / 2;
}
}
// 表格进来就给我居中
function timeNowMove() {
const cellCenterX = (hournow.value + 0.5) * 290;
let width = cellCenterX - visibleWidth / 2;
const totalWidth = totalColumns * 290;
cardLeft.value = Math.max(0, Math.min(width, totalWidth - visibleWidth)) / 2 + 0.7;
}
const iszhiling = ref(false)
const zhilingbao = () => {
iszhiling.value = !iszhiling.value
forthmenuIndex.value = 0;
}
const deletedonghua = ref(false);
const dateget = (time) => {
opendata.value = false
console.log("time",time.date)
}
</script>
<style lang="less" scoped>
// 主页的css
@import './bigindex';
</style>