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

2275 lines
74 KiB
Vue
Raw Normal View History

2026-01-16 14:28:12 +08:00
<!-- 护嘱 -->
<template>
2026-02-03 15:13:24 +08:00
<view class="right-container" :style="isshow?{opacity: `1`}:{opacity: `0`}" @click="bottomisShaking=false;">
2026-01-21 17:02:35 +08:00
<severcard></severcard>
2026-01-16 14:28:12 +08:00
<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 timearr[0]?.children" :key="index">
<view class="boom-son" v-show="item.tagName">
<text class="boom-text">
{{item.tagName}}
</text>
</view>
</view>
</view>
</view>
</view>
2026-01-30 17:24:22 +08:00
<view class="super-card-container"
:style="isTuoing&&(postitem.levle||postitem.packageName)?{borderColor:`red`}:{}">
2026-01-26 13:19:11 +08:00
<scroll-view style="width: 100%;" scroll-with-animation :scroll-left="cardLeft"
2026-01-29 17:31:38 +08:00
:scroll-x="canmovechange" @scroll="handleTop" :show-scrollbar="false">
2026-01-16 14:28:12 +08:00
<view style="display: flex;width:4824rpx;">
2026-01-20 15:35:05 +08:00
<view v-for="(item0,index0) in timearr" :key="index0" class="super-card-right">
2026-01-16 14:28:12 +08:00
<view class="super-card-time">
{{(item0.positioning.length == 1 ? ('0' + item0.positioning) : item0.positioning) + ":00"}}
</view>
</view>
</view>
2026-01-20 15:35:05 +08:00
<view style="display: flex;height: 1225rpx;position: relative;">
2026-01-16 14:28:12 +08:00
<view class="xian-bian"></view>
2026-01-20 15:35:05 +08:00
<scroll-view style="height: 100%;width:6960rpx;background-color: #fff;"
2026-01-29 17:31:38 +08:00
:scroll-top="scrollTop" scroll-with-animation :scroll-y="canmovechange"
2026-01-20 15:35:05 +08:00
@scroll="handleScrolltime" :show-scrollbar="false">
2026-01-16 14:28:12 +08:00
<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;"
2026-01-28 16:40:50 +08:00
@touchstart="handleTouchStart1(item1,$event)"
2026-01-16 14:28:12 +08:00
@click="rulerTouchClick(item1,index0,index1)"
:data-index0="index0" :data-index1="index1">
<view class="title-time-blue"
2026-01-29 17:31:38 +08:00
v-show="saveEditIndex.index0 == index0 && saveEditIndex.index1 == index1 && !isTuoing">
<image class="blue-img" src="/static/index/newtarget.png" />
</view>
<view class="title-time-blue"
2026-01-30 17:24:22 +08:00
v-if="!(Number(postitem.positioning) == index0 && Number(postitem.positioningLong) == index1) && !(postitem.levle||postitem.packageName)"
v-show="targetrule[0] == index0 && targetrule[1] == index1 && isTuoing ">
2026-01-26 17:28:01 +08:00
<image class="blue-img"
2026-01-29 17:31:38 +08:00
:src="`/static/index/newtarget${timearr[index0]?.children[index1]?.id?`red`:``}.png`" />
2026-01-16 14:28:12 +08:00
</view>
2026-01-26 17:28:01 +08:00
<view class="card-bao" v-if="item1.izPackage==`Y`">
</view>
2026-01-16 14:28:12 +08:00
<view :class="getClass(item1,index0,index1)"
style="font-size: 30rpx;overflow: hidden;"
2026-02-03 15:13:24 +08:00
:style="{ animationDelay:`-${computeDelay(index0, index1).toFixed(2)}s`,border:saveEditIndex.index0 == index0 && saveEditIndex.index1 == index1 && !isTuoing && item1.startTime? `2rpx solid #46B2F6`:'' }">
2026-01-16 14:28:12 +08:00
<view class="title-time" v-if="item1.startTime"
style="flex-direction: column;">
2026-01-20 17:29:11 +08:00
<view v-if="item1.startTime"
class="title-time-font-rel">
{{ item1.directiveName?splitString(item1.directiveName)[0]:""}}
2026-01-16 14:28:12 +08:00
</view>
2026-01-20 17:29:11 +08:00
<view
v-if="item1.startTime&&splitString(item1.directiveName)[1]"
class="title-time-font-tags">
({{ item1.directiveName?splitString(item1.directiveName)[1]:""}})
2026-01-16 14:28:12 +08:00
</view>
2026-01-20 17:29:11 +08:00
<view v-if="item1.startTime" class="card-time">
<view class="weight-time">
{{ item1.startTime }}
<text style="margin: 0 3rpx;">
-
</text>
{{ item1.endTime }}
</view>
</view>
2026-01-16 14:28:12 +08:00
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</scroll-view>
</view>
</scroll-view>
</view>
2026-02-02 14:42:43 +08:00
<view class="right-order" @click="clickrighttoclean();">
<view class="right-tags" @click="clicktags()">
2026-01-20 16:23:05 +08:00
<view class="right-tags-title">
2026-01-20 17:29:11 +08:00
<view class="blue-shu" style="margin-left: 35rpx;"></view>
<view class="blue-font">
体型标签
</view>
<view class="blue-shu" style="margin-left: 92rpx;"></view>
<view class="blue-font">
情绪标签
</view>
2026-02-02 14:42:43 +08:00
<image class="blue-icon" @click.stop="tagsopen=!tagsopen"
src="/static/index/procurement/explain.png" mode="aspectFill"></image>
<view class="blue-text" v-show="tagsopen">
<view class="triangle">
<view class="triangle-small"></view>
</view>
<view class="">
情绪体型标签可复选两项
</view>
2026-01-20 17:29:11 +08:00
</view>
2026-01-16 14:28:12 +08:00
</view>
2026-01-21 10:33:13 +08:00
<view class="right-contont">
<view class="tags-leftmenu">
<view class="leftmenu-shu"></view>
2026-01-21 17:02:35 +08:00
<view class="tags-img-father">
2026-02-02 14:42:43 +08:00
<view v-for="(item,index) in bodyTagListLook" :key="index" class="tags-img-view"
@click.stop="clickbody(item,index)">
2026-01-29 17:31:38 +08:00
<image class="tags-img"
:src="item.pic ? (serverUrl + item.pic) : noimageshow" />
<view style="white-space: nowrap;">
2026-01-30 17:24:22 +08:00
{{ shortText(item.tagName,3) }}
2026-01-21 17:02:35 +08:00
</view>
</view>
</view>
2026-01-21 10:33:13 +08:00
2026-01-21 17:02:35 +08:00
<image class="haven-img" v-if="!bodyTagListLook.length"
2026-01-21 10:33:13 +08:00
src="/static/index/procurement/haven.png" mode="aspectFill"></image>
</view>
2026-01-21 17:02:35 +08:00
<view class="tags-rightmenu">
<view class="tags-img-father" style="margin-left: 10rpx;">
<view v-for="(item,index) in emotionTagListLook" :key="index"
2026-02-02 14:42:43 +08:00
class="tags-img-view" @click.stop="clickbody(item,index+2)">
2026-01-29 17:31:38 +08:00
<image class="tags-img"
:src="item.pic ? (serverUrl + item.pic) : noimageshow" />
2026-01-21 17:02:35 +08:00
<view class="">
2026-01-30 17:24:22 +08:00
{{ shortText(item.tagName,3) }}
2026-01-21 10:33:13 +08:00
</view>
</view>
</view>
2026-01-21 17:02:35 +08:00
<image class="haven-img" v-if="!emotionTagListLook.length"
src="/static/index/procurement/haven.png" mode="aspectFill"></image>
</view>
2026-02-02 14:42:43 +08:00
<view class="tags-detail" v-show="bodytagtarget?.tagName">
<view class="tags-instant" :style="{left:`${ docalc(detailtarget) }%`}">
<view class="tags-small-instant"></view>
</view>
<view class="tags-title">
{{ bodytagtarget.tagName }}
</view>
<view class="tags-contain">
{{ bodytagtarget.describ }}
</view>
2026-01-21 17:02:35 +08:00
</view>
2026-02-02 14:42:43 +08:00
</view>
<view class="setting-open" v-show="settingopen" @click.stop>
2026-01-21 17:02:35 +08:00
<view class="setting-menu">
<view class="menu-tags" :style="menutype===index?{fontWeight:`700`}:{}"
v-for="(item,index) in [`体型标签`,`情绪标签`]" :key="index" @click="clickmenu(index) ">
{{ item }}
</view>
<view class="menu-heng" :style="menutype?{left:`222rpx`}:{}"></view>
</view>
<view class="setting-list">
<scroll-view style="height: 100%;width:100%;" scroll-with-animation scroll-y>
<view class="list-items" v-for="(item,index) in listsave" :key="index"
@click="clickcard(index)">
<view :class="item.izSelected==`Y`?`check-box-target`: `check-box`">
</view>
2026-01-29 17:31:38 +08:00
<image class="check-img" :src="
item.izSelected === 'Y'
2026-01-30 17:24:22 +08:00
? (item.picFocus ? serverUrl + item.picFocus : noimageshowtarget)
2026-01-29 17:31:38 +08:00
: (item.pic ? serverUrl + item.pic : noimageshow)" />
<view class=" check-text-view">
2026-01-21 17:02:35 +08:00
<view class="check-weight"
:style="item.izSelected==`Y`?{color:`#0074E1`}: {}">
{{ item.tagName }}
</view>
<view class="check-text"
:style="item.izSelected==`Y`?{color:`#0074E1`}: {}">
2026-01-26 13:19:11 +08:00
{{ item.describ }}
2026-01-21 17:02:35 +08:00
</view>
</view>
</view>
</scroll-view>
</view>
<view class="setting-right" @click="saverightclick">
确定
</view>
</view>
2026-01-16 14:28:12 +08:00
</view>
2026-01-28 16:40:50 +08:00
<view class="forfixed" @click.stop>
<view class="right-instant" v-show="!openmore"
2026-01-30 17:24:22 +08:00
:style="isblue==`1`&&isTuoing?postitem?.packageName?{border:`4rpx dashed red`}:{border:`4rpx dashed #0089FE`}:{border:`4rpx dashed #fff`}">
2026-01-28 16:40:50 +08:00
<view class="right-instant-title">
<view class="blue-shu" style="margin-left: 30rpx;"></view>
<view class="blue-font">
即时标签
</view>
</view>
2026-02-02 14:42:43 +08:00
<image class="explain-icon" @click.stop="jishiopen=!jishiopen"
2026-01-30 17:24:22 +08:00
src="/static/index/procurement/explain.png" mode="aspectFill"></image>
<view class="explain-text" v-show="jishiopen">
<view class="triangle">
<view class="triangle-small"></view>
</view>
<view class="">
长按可进行删除操作
</view>
</view>
2026-01-28 16:40:50 +08:00
<view class="right-instant-items">
<image class="haven-img" v-if="!bottomItems.length"
src="/static/index/procurement/haven.png" mode="aspectFill"></image>
<view class="small-instant" v-show="!openmore">
<view class="forscroll" @touchstart="startdelete" @touchend="enddelete">
<view class="instant" :class="{ pop: popping && index === 0 }"
v-for="(item,index) in bottomItems.slice(0,3)">
2026-01-29 17:31:38 +08:00
<image class="instant-icon"
:src="item.immediateFile? (serverUrl + item.immediateFile ) : noimageshow "
2026-01-28 16:40:50 +08:00
:class="deleteshake?`wiggle`:``" mode="aspectFill"></image>
<view class="instant-text">
2026-01-30 17:24:22 +08:00
{{ shortText(item.directiveName,6) }}
2026-01-28 16:40:50 +08:00
</view>
<view class="instant-close" v-show="deleteshake"
2026-01-29 17:31:38 +08:00
@click.stop="killinstantopen(item)">
<image style="width: 80%;height: 80%;"
2026-01-28 16:40:50 +08:00
src="/static/index/deleticon.png" mode="aspectFill"></image>
</view>
</view>
</view>
</view>
<view class="instant-more" v-if="bottomItems.length > 3" @click="clickopenmore">
<image class="more-imge" src="/static/index/down.png" />
</view>
2026-01-26 13:19:11 +08:00
</view>
</view>
2026-01-28 16:40:50 +08:00
<view class="right-instant-more" v-if="openmore" @click="deleteshake = false"
2026-01-29 17:31:38 +08:00
:style="isblue==`1`&&isTuoing?{border:`4rpx dashed #0089FE`}:{border:`4rpx dashed #fff`}">
2026-01-28 16:40:50 +08:00
<view class="right-instant-title">
<view class="blue-shu" style="margin-left: 30rpx;"></view>
<view class="blue-font">
即时标签
</view>
</view>
2026-01-30 17:24:22 +08:00
2026-01-28 16:40:50 +08:00
<view class="right-instant-items" style="height: 430rpx;">
<view class="small-instant">
<scroll-view style="height: 100%;width:100%;" scroll-with-animation scroll-y
:scroll-top="gettop">
<view class="forscroll" @touchstart="startdelete" @touchend="enddelete">
<view class="instant" v-for="(item,index) in bottomItems"
2026-02-02 14:42:43 +08:00
@click.stop="clickinstant(index)">
2026-01-29 17:31:38 +08:00
<image class="instant-icon" :class="deleteshake?`wiggle`:``" :src="
index === moreindex
2026-01-30 17:24:22 +08:00
? (item.immediateFileFocus ? serverUrl + item.immediateFileFocus : noimageshowtarget)
2026-01-29 17:31:38 +08:00
: (item.immediateFile ? serverUrl + item.immediateFile : noimageshow)
" mode="aspectFill"></image>
2026-01-28 16:40:50 +08:00
<view class="instant-text"
:style="index === moreindex?{color:`#0084ff`}:{}">
2026-01-30 17:24:22 +08:00
{{ shortText(item.directiveName,6) }}
2026-01-28 16:40:50 +08:00
</view>
<view class="instant-close" v-show="deleteshake"
2026-01-29 17:31:38 +08:00
@click.stop="killinstantopen(item)">
<image style="width: 80%;height: 80%;"
2026-01-28 16:40:50 +08:00
src="/static/index/deleticon.png" mode="aspectFill"></image>
</view>
</view>
<view class="instant-detail"
:style="{top:`${(secondinstantshow[0]+1) *155 - 10}rpx`}"
v-show="secondinstantshow[0]!==-1">
<view class="triangle-instant"
:style="{left:`${(secondinstantshow[1]) * 32 + 15}%`}">
<view class="triangle-small-instant"></view>
</view>
<view class="detail-title">
{{ bottomItems[moreindex]?.directiveName }}
</view>
<view class="detail-contain">
{{ bottomItems[moreindex]?.serviceContent }}
</view>
</view>
</view>
</scroll-view>
<view class="instant-more" style="bottom: -71rpx;" @click="openmore=false">
<image class="more-imge" style="transform: rotate(180deg)"
src="/static/index/down.png" />
</view>
</view>
</view>
2026-01-26 13:19:11 +08:00
</view>
</view>
2026-02-02 14:42:43 +08:00
<view class="right-tree" @click="editopen=false;settingopen = false;">
2026-01-26 13:19:11 +08:00
<view class="right-servers">
<view :class="servertype===index?`servertarget`:`server`"
2026-01-28 16:40:50 +08:00
v-show="!ruleritem.directiveName" v-for="(item,index) in [`服务指令`,`服务指令包`]"
:key="index" @click="openserver(index)">
{{ item }}
</view>
<view class="servers-heng" v-show="!ruleritem.directiveName"
:style="servertype?{left:`294rpx`}:{}"></view>
<view class="servertarget" v-show="ruleritem.directiveName && ruleritem.izPackage==`N` "
v-for="(item,index) in [`服务指令`]" :key="index">
2026-01-26 13:19:11 +08:00
{{ item }}
</view>
2026-01-28 16:40:50 +08:00
<view class="servertarget" v-show="ruleritem.directiveName && ruleritem.izPackage==`Y` "
v-for="(item,index) in [`服务指令包`]" :key="index">
{{ item }}
</view>
2026-02-02 14:42:43 +08:00
<view class="servers-heng" :style="ruleritem.izPackage==`Y`?{left:`114rpx`}:{}"
v-show="ruleritem.directiveName"></view>
2026-01-28 16:40:50 +08:00
2026-02-02 14:42:43 +08:00
<image class="explain-icon" @click="explainopen=!explainopen" style="top: 0;"
2026-01-26 13:19:11 +08:00
src="/static/index/procurement/explain.png" mode="aspectFill"></image>
<view class="explain-text" v-show="explainopen">
<view class="triangle">
<view class="triangle-small"></view>
</view>
2026-01-30 17:24:22 +08:00
<view class="">
双击服务指令可添加矩阵, 长按服务指令可拖动到即时指令区进行添加
</view>
2026-01-26 13:19:11 +08:00
</view>
</view>
2026-01-28 16:40:50 +08:00
<view class="three-items" v-show="!ruleritem.directiveName && !servertype">
2026-01-26 13:19:11 +08:00
<view class="tree-item">
2026-01-29 17:31:38 +08:00
<scroll-view style="height: 100%;width:100%;" :scroll-y="canmovechange"
2026-01-26 13:19:11 +08:00
@scroll="handleScroll">
<view class="tree-card"
v-for="(item,index) in bigArray[upmenuIndex]?.children[downmenuIndex]?.children"
2026-01-28 16:40:50 +08:00
:key="index" @touchstart="handleTouchStart(item,$event)"
2026-01-26 13:19:11 +08:00
@click="clickaddnew(item,index)">
2026-01-29 17:31:38 +08:00
<image class="card-icon" :src="
index === thirdmenuIndex
2026-01-30 17:24:22 +08:00
? (item.immediateFileFocus ? serverUrl + item.immediateFileFocus : noimageshowtarget)
2026-01-29 17:31:38 +08:00
: (item.immediateFile ? serverUrl + item.immediateFile : noimageshow)
" mode="aspectFill"></image>
2026-01-26 13:19:11 +08:00
<view class="card-text" style="margin-top: 0;"
:style="index === thirdmenuIndex?{color:`#0084ff`}:{}">
2026-01-30 17:24:22 +08:00
{{ shortText(item.title,6) }}
2026-01-26 13:19:11 +08:00
</view>
</view>
</scroll-view>
</view>
<view class="tree-item">
<scroll-view style="height: 100%;width:100%;" scroll-with-animation
2026-01-29 17:31:38 +08:00
:scroll-y="canmovechange">
2026-01-26 13:19:11 +08:00
<view class="tree-card" v-for="(item,index) in bigArray[upmenuIndex]?.children"
:key="index" @click="secondContant(index)">
2026-02-02 14:42:43 +08:00
<donghua :width="`52rpx`" :height="`52rpx`" :links="item.url"
2026-01-26 13:19:11 +08:00
:playing="index === downmenuIndex" :interval="120" />
<view class="card-text"
:style="index === downmenuIndex?{color:`#0084ff`}:{}">
{{ item.title }}
</view>
</view>
</scroll-view>
</view>
<view class="tree-item" style="width: 28%;">
<scroll-view style="height: 100%;width:100%;" scroll-with-animation
2026-01-29 17:31:38 +08:00
:scroll-y="canmovechange">
2026-01-26 13:19:11 +08:00
<view class="tree-card" v-for="(item,index) in bigArray" :key="index"
@click="changLeft(index)">
2026-02-02 14:42:43 +08:00
<donghua :width="`52rpx`" :height="`52rpx`" :links="item.url"
2026-01-26 13:19:11 +08:00
:playing="index === upmenuIndex" :interval="120" />
<view class="card-text" :style="index === upmenuIndex?{color:`#0084ff`}:{}">
{{ item.title }}
</view>
</view>
</scroll-view>
</view>
</view>
2026-01-28 16:40:50 +08:00
<view class="three-items" v-show="!ruleritem.directiveName && servertype"
2026-01-30 17:24:22 +08:00
style="flex-direction: column;margin-left: 25rpx;width: 91.8%;">
2026-01-29 17:31:38 +08:00
<scroll-view class="pack-title" scroll-with-animation :scroll-x="canmovechange">
2026-01-28 16:40:50 +08:00
<view class="pack-father">
<view class="packs" :style="packnumber==index?{color:`#0089FE`}:{}"
v-for="(item,index) in savePackagelist" :key="index"
2026-01-30 17:24:22 +08:00
@touchstart="handleTouchStart(item,$event)" @click="packclick(item,index)">
2026-01-28 16:40:50 +08:00
<image class="pack-icon"
:src=" `/static/index/pack${packnumber==index?`target`:``}.png`"
mode="aspectFill">
</image>
2026-01-30 17:24:22 +08:00
<view class="pack-text"
:style="item.packageName.length>6?{fontSize:`24rpx`}:{}">
{{ item.packageName }}
</view>
<view class="blue-heng" v-show="packnumber==index"></view>
2026-01-28 16:40:50 +08:00
</view>
</view>
</scroll-view>
2026-02-03 15:13:24 +08:00
<view class="pack-heng"></view>
2026-01-29 17:31:38 +08:00
<scroll-view class="pack-detail" scroll-with-animation :scroll-y="canmovechange">
2026-01-28 16:40:50 +08:00
<view class="detail-father">
<view class="details"
v-for="(item,index) in savePackagelist[packnumber]?.directives"
:key="index">
2026-01-29 17:31:38 +08:00
<image class="detail-icon"
:src="item.immediateFile ? serverUrl + item.immediateFile : noimageshow"
2026-01-28 16:40:50 +08:00
mode="aspectFill">
</image>
<view class="">
{{ splitString(item.directiveName)[0] }}
</view>
2026-01-30 17:24:22 +08:00
<view style="font-size: 20rpx;">
2026-01-28 16:40:50 +08:00
{{ splitString(item.directiveName)[1] ? `(${splitString(item.directiveName)[1]})`:``}}
</view>
</view>
</view>
</scroll-view>
</view>
<view class="target-items-father"
v-if="ruleritem.directiveName && ruleritem.izPackage==`N`">
2026-01-26 17:28:01 +08:00
<view class="target-items">
<view class="target-gray">
{{ ruleritem.categoryName }}
</view>
<view class="target-shu">
|
</view>
<view class="target-gray">
{{ ruleritem.typeName }}
</view>
</view>
<view class="target-contain">
<view class="image-father">
2026-01-29 17:31:38 +08:00
<image class="target-img"
:src="ruleritem.immediateFile ? serverUrl + ruleritem.immediateFile : noimageshow" />
2026-01-26 17:28:01 +08:00
</view>
<view class="image-right">
<view class="right-title">
{{ ruleritem.directiveName }}
</view>
<view class="target-many">
<view class="target-strart">
{{ ruleritem.startTime }}
</view>
<view class="target-other">
<view class="target-shu">
|
</view>
<text class="target-blue">
{{ ruleritem.newtypename }}
</text>
<view class="target-shu">
|
</view>
<view class="">
{{ ruleritem.serviceDuration }}分钟
</view>
</view>
</view>
</view>
</view>
<view class="target-smalltext">
{{ ruleritem.serviceContent }}
</view>
2026-01-29 17:31:38 +08:00
<view class="target-edit" style="right: 150rpx;" @click.stop="editcardname"
v-show="editingmode">
修改
</view>
2026-01-28 16:40:50 +08:00
<view class="target-edit" @click.stop="edititems(ruleritem)" v-show="editingmode">
2026-01-26 17:28:01 +08:00
编辑
</view>
2026-01-28 16:40:50 +08:00
</view>
<view class="target-items-father"
v-if="ruleritem.directiveName && ruleritem.izPackage==`Y`">
<view class="packtargetmessage">
<image class="packtargetmessage-icon" :src=" `/static/index/packtarget.png`"
mode="aspectFill" />
<view class="packtarget-font">
{{ ruleritem.directiveName }}
</view>
<view class="packtarget-strart">
{{ ruleritem.startTime }}
</view>
<view class="packtarget-other">
<view class="packtarget-shu">
|
</view>
<text class="packtarget-blue">
{{ ruleritem.newtypename }}
</text>
<view class="packtarget-shu">
|
</view>
<view style="color: #919191;">
{{ ruleritem.serviceDuration }}分钟
</view>
</view>
</view>
<view class="packtarget-heng"></view>
2026-01-29 17:31:38 +08:00
<scroll-view class="packtarget-detail" scroll-with-animation :scroll-y="canmovechange">
2026-01-28 16:40:50 +08:00
<view class="detail-father">
<view class="details" :style="packtargetindex==index?{color:`#0089FE`}:{}"
v-for="(item,index) in ruleritem?.directivesList"
2026-01-30 17:24:22 +08:00
@click="packtargetindex=index;killbaddata = true" :key="index">
2026-01-29 17:31:38 +08:00
<image class="detail-icon" :src="
index === packtargetindex
2026-01-30 17:24:22 +08:00
? (item.immediateFileFocus ? serverUrl + item.immediateFileFocus : noimageshowtarget)
2026-01-29 17:31:38 +08:00
: (item.immediateFile ? serverUrl + item.immediateFile : noimageshow)
" mode="aspectFill">
2026-01-28 16:40:50 +08:00
</image>
<view class="">
{{ splitString(item.directiveName)[0] }}
</view>
<view style="height: 3rpx;font-size: 20rpx;">
{{ splitString(item.directiveName)[1] ? `(${splitString(item.directiveName)[1]})`:``}}
</view>
</view>
</view>
</scroll-view>
<view class="packtarget-heng"></view>
<view class="packtarget-end">
2026-01-29 17:31:38 +08:00
<image class="end-icon" :src="
ruleritem?.directivesList?.[packtargetindex]?.immediateFile
? serverUrl + ruleritem.directivesList[packtargetindex].immediateFile
: noimageshow
" mode="aspectFill">
2026-01-28 16:40:50 +08:00
</image>
<view class="">
<view class="packtarget-title">
<view class="target-gray">
{{ ruleritem?.directivesList[packtargetindex]?.categoryName }}
</view>
<view class="target-shu">
|
</view>
<view class="target-gray">
{{ ruleritem?.directivesList[packtargetindex]?.typeName }}
</view>
<view class="target-black">
{{ splitString(ruleritem?.directivesList[packtargetindex]?.directiveName)[0] }}
</view>
</view>
<view class="packtarget-serviceContent">
{{ ruleritem?.directivesList[packtargetindex]?.serviceContent }}
</view>
</view>
2026-01-29 17:31:38 +08:00
<view class="target-edit" style="right: 150rpx;" @click.stop="editcardname"
v-show="editingmode">
修改
</view>
2026-01-28 16:40:50 +08:00
<view class="target-edit" @click.stop="edititems(ruleritem)" v-show="editingmode">
编辑
</view>
</view>
2026-01-28 16:58:50 +08:00
2026-01-26 17:28:01 +08:00
</view>
<view class="edit-open" v-show="editopen" @click.stop>
<view class="edit-menu">
<view class="triangle">
<view class="triangle-small"></view>
</view>
2026-01-28 16:40:50 +08:00
<view class="edit-tags" :style="edittype===index?{fontWeight:`800`}:{}"
v-for="(item,index) in [`频率`,`星期`,`日期`]" :key="index"
2026-01-26 17:28:01 +08:00
@click="clickedit(index) ">
{{ item }}
</view>
<view class="edit-heng" :style="{left:`${40+edittype*100}rpx`}"></view>
</view>
2026-01-28 16:40:50 +08:00
<view class="edit-Frequency" v-show="!edittype">
<view class="Frequency-one" @click="clickeveryday">
<view class="Frequency-box"
:style="nosave.cycleTypeId==`1`?{borderColor:`#0089FE`}:{}">
<image class="box"
:src=" `/static/right${nosave.cycleTypeId==`1`?`target`:``}.png`" />
</view>
每天执行一次
</view>
<view class="Frequency-one" @click="clickmanyday">
<view class="Frequency-box"
:style="nosave.cycleTypeId==`5`&&nosave.cycleValue?{borderColor:`#0089FE`}:{}">
<image class="box"
:src=" `/static/right${nosave.cycleTypeId==`5`&&nosave.cycleValue?`target`:``}.png`" />
</view>
每隔
<view class="Frequency-add" @click="inputnum>0? inputnum--:``">
-
</view>
<view class="Frequency-input">
<input class="center-input" type="number" v-model="inputnum"
:maxlength="5" />
</view>
<view class="Frequency-add" @click="inputnum++">
+
</view>
天执行一次
</view>
<view class="Frequency-one" @click="clickonetime">
<view class="Frequency-box"
:style="nosave.cycleTypeId==`5`&&!nosave.cycleValue?{borderColor:`#0089FE`}:{}">
<image class="box"
:src=" `/static/right${nosave.cycleTypeId==`5`&&!nosave.cycleValue?`target`:``}.png`" />
</view>
临时一次
</view>
</view>
<view class="edit-week" v-show="edittype==1">
<view class="week-day"
:style="nosave.cycleTypeId==`3`&&nosave.cycleValue==index?{color:`#0089FE`}:{}"
v-for="(item,index) in weekDays" :key="index" @click="clickweektarget(index)">
2026-01-26 17:28:01 +08:00
{{ item }}
</view>
</view>
2026-01-28 16:40:50 +08:00
<view class="edit-month" v-show="edittype==2" style="margin-top: 5rpx;">
<view class="month-day"
:style="nosave.cycleTypeId==`4`&&nosave.cycleValue==Number(item)?{color:`#0089FE`}:{}"
v-for="(item,index) in monthDays" :key="index" @click="clickmonthtarget(item)">
2026-01-26 17:28:01 +08:00
{{ item }}
</view>
</view>
2026-01-28 16:40:50 +08:00
<view class="edit-right" @click="allisright">
2026-01-26 17:28:01 +08:00
确定
</view>
</view>
2026-01-26 13:19:11 +08:00
</view>
<view class="right-finally">
<image class="finally-older"
:src="`/static/index/newindex/leftmenu/${uni.getStorageSync('NUall').elderInfo?.name?`older`:`nopeople`}.png`" />
<view class="fin-button" @click="jumpToWatch">
<image class="button-imge" :src="`/static/index/newindex/leftmenu/watch.png`" />
<view class="button-text">
监控
</view>
</view>
<view class="fin-button" @click="shareToWeixin">
<image class="button-imge" :src="`/static/index/newindex/leftmenu/share.png`" />
<view class="button-text">
分享
</view>
</view>
<view class="blue-right" @click="cleanallopen();editingmode = !editingmode">
{{ editingmode?"确定":"+编辑" }}
</view>
2026-01-26 17:28:01 +08:00
2026-01-26 13:19:11 +08:00
</view>
2026-01-16 14:28:12 +08:00
</view>
</view>
</view>
</view>
<!-- 分享的弹出层 -->
<view v-show="shareShow" class="popup-share" @click="shareShow=false">
<view class="popup-share-content" :style="{ opacity: deletedownisopacity ? 1 : 0 }" @click.stop>
<view class="share-other">
<view class="share-title">
<image style="width: 50rpx;height: 50rpx;" src="/static/index/sharelogo.png" />
<view style="font-weight: 600;margin-left: 15rpx;">
护理单元
</view>
</view>
<view class="share-others">
<view style="font-weight: 600;font-size: 45rpx;">
护理流程
</view>
<view style="margin-top: 30rpx;">
{{uni.getStorageSync('nuName')}}
<text style="color: #1083F8;">
{{uni.getStorageSync('NUall').elderInfo?uni.getStorageSync('NUall').elderInfo.name:""}}
</text>
</view>
<view class="blue-button">
分享
</view>
</view>
</view>
</view>
</view>
<view :class="['neuro-wrapper', deletedonghua ? 'is-active' : '']" v-if="isDelete">
<!-- 遮罩层点击触发关闭 -->
<view class="neuro-mask" @click="isDelete=false"></view>
<!-- 拟态框阻止冒泡点击 -->
<view class="neuro-box" @click.stop>
<view class="delete-button-father">
<view class="button-white" @click="isDelete=false">取消</view>
2026-01-29 17:31:38 +08:00
<view class="button" @click="killruleclick">确定</view>
2026-01-16 14:28:12 +08:00
</view>
<view class="title">确定要删除指令吗</view>
2026-01-29 17:31:38 +08:00
<view class="card-box">
<view class="title-time-blue-card">
<image class="blue-img" src="/static/index/bluetarget.png" />
</view>
<view class="card-bao" v-if="postitem.izPackage==`Y`">
</view>
<view class="title-time-border-hisOk">
<view class="title-time">
<view class="title-time-font-rel">
{{ splitString(postitem.directiveName)[0]}}
</view>
<view v-if="splitString(postitem.directiveName)[1]" class="title-time-font-tags">
({{ splitString(postitem.directiveName)[1]}})
</view>
<view class="card-time">
<view class="weight-time">
{{ postitem.startTime }}
<text style="margin: 0 3rpx;">
-
</text>
{{ postitem.endTime }}
</view>
</view>
2026-01-16 14:28:12 +08:00
</view>
</view>
2026-01-29 17:31:38 +08:00
</view>
</view>
</view>
<view :class="['neuro-wrapper', deletedonghua ? 'is-active' : '']" v-if="killisopen">
<!-- 遮罩层点击触发关闭 -->
<view class="neuro-mask" @click="killisopen=false"></view>
<!-- 拟态框阻止冒泡点击 -->
<view class="neuro-box" @click.stop style="height: 450rpx;">
<view class="delete-button-father">
<view class="button-white" @click="killisopen=false">取消</view>
<view class="button" @click="killjishi">确定</view>
</view>
<view class="title">确定要删除指令吗</view>
<view class="title-time-border-yellow">
<image class="kill-icon"
:src="killthisid.immediateFile? (serverUrl + killthisid.immediateFile ) : noimageshow"
mode="aspectFill"></image>
<view class="kill-text">
{{ killthisid.directiveName }}
2026-01-16 14:28:12 +08:00
</view>
</view>
</view>
</view>
2026-01-26 13:19:11 +08:00
<errorshow :show="openerror" :font="errshow" @close="openerror=false" />
2026-01-16 14:28:12 +08:00
</view>
</template>
<script setup lang="ts">
2026-01-29 17:31:38 +08:00
import { ref, onMounted, onBeforeUnmount, computed, nextTick, watch, onUnmounted } from 'vue';
2026-01-16 14:28:12 +08:00
import { onShow, onHide } from '@dcloudio/uni-app';
2026-01-28 16:40:50 +08:00
import { getNclist, addBatch, addDirective, addInstant, deleteDirective, editDirective } from "./api.js";
2026-01-16 14:28:12 +08:00
import { myArray } from './yaoshandiao.js';
const props = defineProps({
isshow: {
type: Boolean,
required: true,
},
2026-01-26 13:19:11 +08:00
canmove: {
type: Boolean,
required: true,
},
isblue: {
2026-01-28 16:40:50 +08:00
type: Number,
2026-01-26 13:19:11 +08:00
required: true,
},
sendxy: {
type: Array,
required: true
2026-01-28 16:40:50 +08:00
},
targetrule: {
type: Array,
required: true
},
2026-01-30 17:24:22 +08:00
howtomove: {
type: Array,
required: true
}
2026-01-16 14:28:12 +08:00
});
2026-01-29 17:31:38 +08:00
2026-02-03 15:13:24 +08:00
const canmovechange = ref(true);
const nextpageing = ref(false)
let nextPageTimer = null
2026-01-29 17:31:38 +08:00
2026-02-03 15:13:24 +08:00
// 组件卸载时清理
onBeforeUnmount(() => {
if (nextPageTimer) {
clearTimeout(nextPageTimer)
nextPageTimer = null
}
})
2026-01-30 17:24:22 +08:00
watch(() => props.howtomove, (newVal : [number, number], oldVal : [number, number]) => {
if (oldVal[0] === 2) {
2026-02-03 15:13:24 +08:00
// 每次触发都立即设为 true
nextpageing.value = true
// 重置定时器(如果已有)
if (nextPageTimer) {
clearTimeout(nextPageTimer)
}
// 1 秒后如果未再次触发则设为 false
nextPageTimer = setTimeout(() => {
nextpageing.value = false
nextPageTimer = null
}, 1000)
2026-01-30 17:24:22 +08:00
const nextX = notrelxy.value[0] + newVal[0]
if (nextX >= 0 && nextX <= 23) {
notrelxy.value[0] = nextX
}
const nextY = notrelxy.value[1] + newVal[1]
if (nextY >= 0 && nextY <= 11) {
notrelxy.value[1] = nextY
}
notrelcenter(notrelxy.value[0], notrelxy.value[1])
}
},
{ deep: true });
2026-01-26 13:19:11 +08:00
watch(() => props.canmove, (newVal, oldVal) => {
if (oldVal === false && newVal === true) {
2026-02-02 14:42:43 +08:00
// console.log("结束")
2026-01-29 17:31:38 +08:00
isTuoing.value = false;
canmovechange.value = true;
if (props.isblue == 1) {
2026-01-28 16:40:50 +08:00
addinstantcommand()
2026-01-29 17:31:38 +08:00
} else if (props.isblue == 2) {
getNew()
}
else if (props.isblue == 3) {
// console.log("删除这个", postitem.value)
isDelete.value = true;
deletedonghua.value = false;
setTimeout(() => deletedonghua.value = true, 50)
2026-01-26 13:19:11 +08:00
}
}
});
2026-01-29 17:31:38 +08:00
const killruleclick = () => {
isDelete.value = false;
deleteDirective({ id: postitem.value.id }).then((res) => {
if (res.success) {
geteverything()
if (saveEditIndex.value.index0 != -1) {
setTimeout(() => {
rulerTouchClick(timearr.value[saveEditIndex.value.index0].children[saveEditIndex.value.index1], saveEditIndex.value.index0, saveEditIndex.value.index1)
}, 300)
}
}
})
}
const noimageshow = `/static/logo.png`;
2026-01-30 17:24:22 +08:00
const noimageshowtarget = `/static/logotarget.png`;
2026-01-28 16:40:50 +08:00
const clickrighttoclean = () => {
openmore.value = false;
deleteshake.value = false
2026-02-02 14:42:43 +08:00
bodytagtarget.value = {};
detailtarget.value = -1;
jishiopen.value = false;
tagsopen.value = false
2026-01-28 16:40:50 +08:00
}
const clickeveryday = () => {
nosave.value.cycleTypeId = "1";
nosave.value.cycleValue = ""
nosave.value.optCount = ""
}
const clickmanyday = () => {
nosave.value.cycleTypeId = "5";
// 去0
nosave.value.cycleValue = Number(inputnum.value).toString()
nosave.value.optCount = ""
}
const clickonetime = () => {
nosave.value.cycleTypeId = "5";
nosave.value.cycleValue = ""
nosave.value.optCount = "1"
}
const clickweektarget = (index : number) => {
nosave.value.cycleTypeId = "3";
nosave.value.cycleValue = index.toString()
nosave.value.optCount = ""
}
const clickmonthtarget = (index : string) => {
if (index) {
nosave.value.cycleTypeId = "4";
nosave.value.cycleValue = Number(index).toString()
nosave.value.optCount = ""
}
}
const allisright = () => {
// 特殊指令
if (nosave.value.cycleTypeId == `5` && nosave.value.cycleValue) {
nosave.value.cycleValue = Number(inputnum.value).toString()
}
let allobject = ruleritem.value
const now = new Date();
const ts = `${now.getFullYear()}-${(now.getMonth() + 1).toString().padStart(2, '0')}-${now.getDate().toString().padStart(2, '0')} ${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}:${now.getSeconds().toString().padStart(2, '0')}`;
let data = {
id: allobject.id,
nuId: uni.getStorageSync('nuId'),
directiveId: allobject.directiveId,
positioning: saveEditIndex.value.index0.toString(),
positioningLong: saveEditIndex.value.index1.toString(),
tagName: timearr.value[saveEditIndex.value.index0].children[saveEditIndex.value.index1].tagName,
startTime: allobject.startTime,
izPackage: ruleritem.value.izPackage,
cycleTypeId: nosave.value.cycleTypeId,
cycleValue: nosave.value.cycleValue,
optCount: nosave.value.optCount,
optTime: ts,
}
// return
editDirective(data).then((res) => {
console.log("kankan", data, res)
if (res.success) {
geteverything()
setTimeout(() => {
editopen.value = false
rulerTouchClick(timearr.value[saveEditIndex.value.index0].children[saveEditIndex.value.index1], saveEditIndex.value.index0, saveEditIndex.value.index1)
}, 300)
}
})
}
const inputnum = ref(1)
const secondinstantshow = ref([-1, -1])
const gettop = ref(0)
const clickinstant = (index : number) => {
if (moreindex.value !== index) {
moreindex.value = index
secondinstantshow.value = [Math.floor(index / 3), index % 3]
setTimeout(() => {
gettop.value = 77.5 * secondinstantshow.value[0]
}, 200)
} else {
moreindex.value = -1
secondinstantshow.value = [-1, -1]
}
}
const nosave = ref({
cycleTypeId: "",
cycleValue: "",
optCount: "",
})
const edititems = (item : any) => {
nosave.value.cycleTypeId = item.cycleTypeId;
nosave.value.cycleValue = item.cycleValue
nosave.value.optCount = item.optCount
editopen.value = true
if (item.cycleTypeId == "3") {
edittype.value = 1
} else if (item.cycleTypeId == "4") {
edittype.value = 2
} else {
edittype.value = 0
}
}
const deleteshake = ref(false);
let t
const startdelete = () => t = setTimeout(() => {
if (editingmode.value) {
deleteshake.value = true
}
}, 1000)
const enddelete = () => clearTimeout(t)
const addinstantcommand = () => {
2026-01-30 17:24:22 +08:00
if (!postitem.value.packageName) {
const exists = bottomItems.value.some((element : any) => {
return element.directiveId === postitem.value.id
})
2026-01-28 16:40:50 +08:00
2026-01-30 17:24:22 +08:00
if (exists) {
errshow.value = "请勿添加相同的服务指令"
openerror.value = true
return // ✅ 这次是真的 return 出函数了
2026-01-28 16:40:50 +08:00
}
2026-01-30 17:24:22 +08:00
let allobject = postitem.value
let postdata = {
nuId: uni.getStorageSync('nuId'),
directiveId: allobject.id,
izPackage: `N`,
cycleTypeId: 2,
}
addDirective(postdata).then((res) => {
console.log("kankan", postdata, res)
if (res.success) {
geteverything()
setTimeout(() => {
playFirstPop()
}, 200)
}
})
}
2026-01-28 16:40:50 +08:00
}
const moreindex = ref(-1)
2026-01-26 13:19:11 +08:00
const editingmode = ref(false);
const openerror = ref(false)
const errshow = ref("")
2026-02-03 15:13:24 +08:00
const emit = defineEmits(['handsend', `rulepush`, `cleanall`])
2026-01-26 13:19:11 +08:00
2026-01-21 10:33:13 +08:00
const serverUrl = ref(uni.getStorageSync('imagebase'))
2026-01-16 14:28:12 +08:00
const bodystatus = ref(false);
const bodystatustarget = ref(-1);
const facestatus = ref(false);
const facestatustarget = ref(-1);
2026-01-26 13:19:11 +08:00
const menutype = ref(0);
const servertype = ref(0);
2026-01-21 17:02:35 +08:00
const settingopen = ref(false);
2026-01-26 13:19:11 +08:00
const explainopen = ref(false);
2026-02-02 14:42:43 +08:00
const jishiopen = ref(false);
const tagsopen = ref(false);
2026-01-16 14:28:12 +08:00
/* ---- transform ----
注意虽然这是响应式但我们只在 rAF 里更新它受控更新避免频繁触发 Vue 渲染 */
const transformStyle = ref('translate3d(0, 0, 0)');
/* rAF / 计数器变量 */
let lastY = 0;
let ticking = false;
const open = ref(false);
const bottomItems = ref([])
2026-01-26 17:28:01 +08:00
const now = new Date();
const monthDays = ref(getMonthDaysArray(now.getFullYear(), now.getMonth(), true));
const weekDays = ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"];
2026-01-16 14:28:12 +08:00
const days = Array.from({ length: 31 }, (_, i) => (i + 1).toString().padStart(2, "0"));
2026-02-02 14:42:43 +08:00
2026-01-16 14:28:12 +08:00
// 是否周期
const iszhouqi = ref(false);
//高度回到最高
const scrollLeft = ref(0);
const cardLeft = ref(678);
//移动表格
const scrollTop = ref(0)
//左下的数组
const downList = ref<any>()
const isop = ref(false);
const bigArray = ref([]);
2026-01-26 13:19:11 +08:00
const smallArray = ref([]);
2026-01-16 14:28:12 +08:00
const isopen = ref(false)
const songisopen = ref(false)
const isopacity = ref(false)
const songisopacity = ref(false)
// 删除表格弹窗
const deleteisopen = ref(false);
const deletename = ref("")
2026-02-02 14:42:43 +08:00
2026-01-28 16:40:50 +08:00
const editopen = ref(false);
const openmore = ref(false)
2026-01-26 13:19:11 +08:00
// 清理所有弹窗
const cleanallopen = () => {
settingopen.value = false;
explainopen.value = false;
2026-01-28 16:40:50 +08:00
editopen.value = false;
openmore.value = false;
deleteshake.value = false;
packtargetindex.value = 0
2026-01-26 13:19:11 +08:00
}
2026-01-16 14:28:12 +08:00
// 这是二级菜单的动画的模板
const secondtemp = ref([])
// 上次点击时间
const lastTap = ref(0)
// 双击的最大间隔ms可根据体验调整
const DOUBLE_TAP_DELAY = 300
2026-01-28 16:40:50 +08:00
const clickopenmore = () => {
openmore.value = true;
deleteshake.value = false
moreindex.value = -1;
2026-01-30 17:24:22 +08:00
secondinstantshow.value = [-1, -1];
jishiopen.value = false
2026-01-28 16:40:50 +08:00
}
2026-01-16 14:28:12 +08:00
// 替换新的
const getNew = () => {
2026-01-29 17:31:38 +08:00
let item = timearr.value[Number(props.sendxy[0])]?.children[Number(Number(props.sendxy[1]))]
2026-02-02 14:42:43 +08:00
if (!item.id) {
2026-01-16 14:28:12 +08:00
doChangeNew()
2026-02-03 15:13:24 +08:00
}
2026-01-16 14:28:12 +08:00
}
const doChangeNew = () => {
2026-01-29 17:31:38 +08:00
let object = postitem.value;
indexsave.value = [Number(props.sendxy[0]), Number(props.sendxy[1])]
2026-01-16 14:28:12 +08:00
// 旧的tagName保存了
2026-01-29 17:31:38 +08:00
let tagName = postitem.value.tagName
timearr.value[Number(postitem.value.positioning)].children[Number(postitem.value.positioningLong)] = { directiveName: '', tagName: tagName }
2026-01-16 14:28:12 +08:00
//然后保存新的
let newtagName = timearr.value[indexsave.value[0]].children[indexsave.value[1]].tagName
timearr.value[indexsave.value[0]].children[indexsave.value[1]] = object
timearr.value[indexsave.value[0]].children[indexsave.value[1]].tagName = newtagName
let startTime = timearr.value[indexsave.value[0]].children[indexsave.value[1]].startTime;
let endTime = timearr.value[indexsave.value[0]].children[indexsave.value[1]].endTime;
let positioning = timearr.value[indexsave.value[0]].positioning;
// 解析原始时间(健壮地 trim
const parseTime = (t) => {
const parts = String(t || '').split(':').map(s => s.trim());
const h = Number(parts[0] ?? 0);
const m = Number(parts[1] ?? 0);
return {
hour: Number.isFinite(h) ? h : 0,
minute: Number.isFinite(m) ? m : 0
};
};
const sOrig = parseTime(startTime);
2026-01-26 17:28:01 +08:00
2026-01-16 14:28:12 +08:00
const eOrig = parseTime(endTime);
// 计算时长(分钟)。若发生负值,认为跨天(加 24*60
let duration = (eOrig.hour * 60 + eOrig.minute) - (sOrig.hour * 60 + sOrig.minute);
if (duration < 0) duration += 24 * 60; // 假设结束是在次日或跨日
// 解析新的起始分钟和小时positioning 可能是字符串)
const newStartMin = Number(String(newtagName).trim());
const newHour = Number(String(positioning).trim());
// 校验
if (!Number.isFinite(newStartMin) || newStartMin < 0 || newStartMin >= 60) {
throw new Error('newtagName 必须是 0-59 的数字字符串或数字');
}
if (!Number.isFinite(newHour) || newHour < 0) {
throw new Error('positioning 必须是有效小时(数字或数字字符串)');
}
// 计算新的起止总分钟
const newStartTotal = newHour * 60 + newStartMin;
const newEndTotal = newStartTotal + duration;
// 处理跨小时/跨天
const newEndHour = Math.floor(newEndTotal / 60) % 24; // 保持在 0-23
const newEndMin = newEndTotal % 60;
// 格式化字符串
const pad2 = (n) => String(n).padStart(2, '0');
2026-01-29 17:31:38 +08:00
let data = {
index0: indexsave.value[0],
index1: indexsave.value[1]
}
whereEvent(data);
2026-01-16 14:28:12 +08:00
timearr.value[indexsave.value[0]].children[indexsave.value[1]].startTime =
2026-01-30 17:24:22 +08:00
`${padZero(String(newHour))}:${pad2(newStartMin)}`;
2026-01-16 14:28:12 +08:00
timearr.value[indexsave.value[0]].children[indexsave.value[1]].endTime =
2026-01-30 17:24:22 +08:00
`${padZero(String(newEndHour))}:${pad2(newEndMin)}`;
2026-01-29 17:31:38 +08:00
let infoValue = object
infoValue.positioning = indexsave.value[0];
infoValue.positioningLong = indexsave.value[1];
infoValue.startTime = timearr.value[indexsave.value[0]].children[indexsave.value[1]].startTime;
infoValue.endTime = timearr.value[indexsave.value[0]].children[indexsave.value[1]].endTime;
2026-01-16 14:28:12 +08:00
editDirective(infoValue).then((res : any) => {
if (res.success) {
geteverything()
}
2026-01-29 17:31:38 +08:00
setTimeout(() => {
rulerTouchClick(timearr.value[indexsave.value[0]].children[indexsave.value[1]], indexsave.value[0], indexsave.value[1])
2026-01-30 17:24:22 +08:00
}, 300)
2026-01-16 14:28:12 +08:00
})
}
//变更左侧菜单
const changLeft = (index : number) => {
2026-01-26 13:19:11 +08:00
cleanallopen()
if (upmenuIndex.value === index) {
2026-01-16 14:28:12 +08:00
return
}
upmenuIndex.value = index
downList.value = bigArray.value[index]?.children
2026-02-02 14:42:43 +08:00
downmenuIndex.value = 0.001;
thirdmenuIndex.value = 0.001;
2026-01-26 13:19:11 +08:00
nextTick(() => {
downmenuIndex.value = 0;
thirdmenuIndex.value = 0;
})
2026-01-16 14:28:12 +08:00
}
const isDelete = ref(false);
2026-02-03 15:13:24 +08:00
2026-01-16 14:28:12 +08:00
// 给抖动用的
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);
2026-01-28 16:58:50 +08:00
2026-01-16 14:28:12 +08:00
function handleScrolltime(e) {
2026-02-03 15:13:24 +08:00
// 核心代码,双重拦截
if (killbaddata.value && !canmovechange.value && !nextpageing.value) {
emit('cleanall')
// console.log("上下移动")
}
2026-01-28 16:58:50 +08:00
killbaddata.value = true
2026-01-16 14:28:12 +08:00
// 为保险,先做容错判断
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)
2026-01-28 16:58:50 +08:00
const killbaddata = ref(true)
2026-01-16 14:28:12 +08:00
function handleTop(e) {
2026-02-03 15:13:24 +08:00
// 核心代码,双重拦截
if (killbaddata.value && !canmovechange.value && !nextpageing.value) {
emit('cleanall')
// console.log("左右移动")
}
2026-01-28 16:58:50 +08:00
killbaddata.value = true
2026-01-16 14:28:12 +08:00
leftIn.value = e.detail.scrollLeft
}
// 方法:根据条件返回不同的类名
const getClass = (item, index0, index1) => {
if (item.startTime) {
2026-02-02 14:42:43 +08:00
if (Number(postitem.value.positioning) == index0 && Number(postitem.value.positioningLong) == index1 && isTuoing.value && !(postitem.levle || postitem.packageName)) {
2026-01-30 17:24:22 +08:00
return `title-time-border-own`
}
2026-02-02 14:42:43 +08:00
else if (props.targetrule[0] == index0 && props.targetrule[1] == index1 && isTuoing.value && !(postitem.levle || postitem.packageName)) {
2026-01-29 17:31:38 +08:00
if (timearr.value[index0]?.children[index1]?.id) {
return `title-time-border-error`
}
}
2026-01-20 17:29:11 +08:00
return 'title-time-border-hisOk';
2026-01-16 14:28:12 +08:00
}
return 'title-time-border';
}
2026-01-20 17:29:11 +08:00
// 处理分钟和小时的函数
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 };
}
2026-01-16 14:28:12 +08:00
// 通用的生成函数
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 doctorsayList = ref([
{
url: genPaths(
'/static/index/newruler',
'daily_',
6, // 张数
'png',
1, // 起始索引
false // 不补零
), name: '日常'
},
{
url: genPaths(
'/static/index/newruler',
'clean_',
8, // 张数
'png',
1, // 起始索引
false // 不补零
), name: '清洁'
},
{
url: genPaths(
'/static/index/newruler',
'diet_',
7, // 张数
'png',
1, // 起始索引
false // 不补零
), name: '饮食'
},
{
url: genPaths(
'/static/index/newruler',
'sleep_',
5, // 张数
'png',
1, // 起始索引
false // 不补零
), name: '睡眠'
},
{
url: genPaths(
'/static/index/newruler',
'defecate_',
5, // 张数
'png',
1, // 起始索引
false // 不补零
), name: '排泄'
},
]);
// 当前选中的菜单索引
const upmenuIndex = ref<number>(1);
2026-01-26 13:19:11 +08:00
const downmenuIndex = ref<number>(1);
const downdonghua = ref(1);
const thirdmenuIndex = ref<number>(1);
2026-01-16 14:28:12 +08:00
const forthmenuIndex = ref<number>(0);
const saveEditIndex = ref({
index0: -1,
index1: -1
})
const secondContant = (index : number) => {
2026-01-26 13:19:11 +08:00
cleanallopen()
if (downmenuIndex.value === index) {
return
}
2026-01-16 14:28:12 +08:00
downmenuIndex.value = index;
thirdmenuIndex.value = 0;
}
const timer = ref(null);//计时器
const elementsInfo = ref({})//所有表格的信息
const moveX = ref(0)
const moveY = ref(0)
const deletedownisopacity = ref(false);
// 分享矩阵到微信
const shareShow = ref(false);
const shareToWeixin = () => {
shareShow.value = true;
deletedownisopacity.value = false;
setTimeout(() => {
deletedownisopacity.value = true
}, 100)
}
2026-01-26 13:19:11 +08:00
const jumpToWatch = () => {
uni.navigateTo({
url: "/pages/watch/full"
})
}
2026-01-16 14:28:12 +08:00
const clickshare = () => {
uni.share({
provider: "weixin",
scene: "WXSceneSession",
type: 0,
href: "http://192.168.2.31:3101/daytoday",
title: "护理日程分享",
summary: "九泰护理日程测试",
imageUrl: "https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/uni@2x.png",
2026-02-03 15:13:24 +08:00
2026-01-16 14:28:12 +08:00
});
}
2026-01-26 13:19:11 +08:00
// 表格信息
const ruleritem = ref({})
2026-01-28 16:40:50 +08:00
2026-01-29 17:31:38 +08:00
const editcardname = () => {
ruleritem.value = {
directiveName: ""
}
}
2026-01-28 16:40:50 +08:00
const packtargetindex = ref(0)
2026-01-16 14:28:12 +08:00
const rulerTouchClick = (item : any, index0 : number, index1 : number) => {
2026-01-30 17:24:22 +08:00
killbaddata.value = true
2026-01-16 14:28:12 +08:00
saveEditIndex.value.index0 = index0;
saveEditIndex.value.index1 = index1;
centerCell();
2026-01-26 13:19:11 +08:00
ruleritem.value = item;
2026-01-26 17:28:01 +08:00
switch (ruleritem.value.cycleTypeId) {
case `1`:
ruleritem.value.newtypename = "每天"
break
case `3`:
ruleritem.value.newtypename = weekDays[Number(ruleritem.value.cycleValue)]
break
case `4`:
ruleritem.value.newtypename = Number(ruleritem.value.cycleValue) + "日"
break
case `5`:
2026-01-28 16:40:50 +08:00
if (ruleritem.value.cycleValue) {
ruleritem.value.newtypename = Number(ruleritem.value.cycleValue) + "天执行一次"
} else {
ruleritem.value.newtypename = "临时一次"
}
2026-01-26 17:28:01 +08:00
break
}
2026-01-28 16:40:50 +08:00
cleanallopen()
2026-01-16 14:28:12 +08:00
}
2026-02-02 14:42:43 +08:00
2026-01-16 14:28:12 +08:00
const reldata = ref([]);
const deleteRuler = (index0 : number, index1 : number) => {
deleteDirective(timearr.value[index0]?.children[index1]).then((res : any) => {
if (res.success) {
geteverything()
}
})
}
const saveX = ref(0);
const saveY = ref(0);
const bottomTimer = ref(null);
const bottomisShaking = ref(false);
const bottomTouchStart = (e) => {
saveX.value = Math.floor(e.touches[0].pageX);
saveY.value = Math.floor(e.touches[0].pageY);
// 2秒后触发抖动效果
bottomTimer.value = setTimeout(() => {
bottomisShaking.value = true
}, 500)
}
const bottomTouchMove = (e) => {
const moveX = Math.floor(e.touches[0].pageX);
const moveY = Math.floor(e.touches[0].pageY);
// 计算移动距离
if (
Math.abs(moveX - saveX.value) > 0 ||
Math.abs(moveY - saveY.value) > 0
) {
if (bottomTimer.value) {
clearTimeout(bottomTimer.value)
bottomTimer.value = null
}
}
}
const bottomTouchEnd = () => {
if (bottomTimer.value) {
clearTimeout(bottomTimer.value)
bottomTimer.value = null
}
}
const indexsave = ref([-1, -1]);
2026-01-26 13:19:11 +08:00
2026-01-16 14:28:12 +08:00
const buttonBlue = ref(false)
let animTimer = null
const doaddDirective = (element : any) => {
addDirective(element).then((res) => {
if (res.success) {
geteverything()
}
})
}
2026-01-29 17:31:38 +08:00
const killisopen = ref(false)
const killthisid = ref("")
const killinstantopen = (item) => {
killthisid.value = item;
killisopen.value = true;
deletedonghua.value = true;
setTimeout(() => deletedonghua.value = true, 50)
}
const killjishi = () => {
killisopen.value = false;
deleteshake.value = false;
deleteDirective({ id: killthisid.value.id }).then((res) => {
2026-01-16 14:28:12 +08:00
if (res.success) {
geteverything()
}
})
}
const addnew = () => {
let haveValue = false;
if (timearr.value[saveEditIndex.value.index0]?.children[saveEditIndex.value.index1].directiveName) {
haveValue = true
}
let allobject = bigArray.value[upmenuIndex.value].children[downmenuIndex.value].children[thirdmenuIndex.value]
2026-02-02 14:42:43 +08:00
let cycleType = "日常";
2026-01-16 14:28:12 +08:00
let cycleValue = "";
const startHour = Number(saveEditIndex.value.index0)
const startMinute = Number(timearr.value[saveEditIndex.value.index0].children[saveEditIndex.value.index1].tagName)
const endMinute = startMinute + Number(allobject.serviceDuration)
const endHour = startHour + Math.floor(endMinute / 60)
const formattedStart = `${String(startHour)}:${String(startMinute).padStart(2, '0')}`
const formattedEnd = `${String(endHour)}:${String(endMinute % 60).padStart(2, '0')}`
let param = {
id: haveValue ? timearr.value[saveEditIndex.value.index0].children[saveEditIndex.value.index1].id : "",
nuId: uni.getStorageSync('nuId'),
nuName: uni.getStorageSync('nuName'),
elderId: uni.getStorageSync('elderId'),
elderName: uni.getStorageSync('NUall').elderInfo.name,
directiveId: allobject.id,
directiveName: allobject.title,
typeId: allobject.typeId,
typeName: allobject.typeName,
categoryId: allobject.categoryId,
categoryName: allobject.categoryName,
cycleTypeId: allobject.cycleTypeId,
cycleType: cycleType,
cycleValue: cycleValue,
startTime: formattedStart,
endTime: formattedEnd,
positioning: saveEditIndex.value.index0.toString(),
positioningLong: saveEditIndex.value.index1.toString(),
izPackage: 'N',
previewFile: allobject.previewFile,
previewFileSmall: allobject.previewFileSmall,
serviceDuration: allobject.serviceDuration,
immediateFile: allobject.immediateFile,
immediateFileFocus: allobject.immediateFileFocus,
2026-01-20 15:35:05 +08:00
netImmediateFileFocus: allobject.netImmediateFileFocus,
2026-01-16 14:28:12 +08:00
netImmediateFile: allobject.netImmediateFile,
tagName: timearr.value[saveEditIndex.value.index0].children[saveEditIndex.value.index1].tagName,
mp3File: allobject.mp3File,
netMp3File: allobject.netMp3File,
mp4File: allobject.mp4File,
netMp4File: allobject.netMp4File,
serviceContent: allobject.serviceContent,
2026-01-20 15:35:05 +08:00
netPreviewFile: allobject.netPreviewFile,
netPreviewFileSmall: allobject.netPreviewFileSmall,
2026-01-16 14:28:12 +08:00
}
//给表格赋值
timearr.value[saveEditIndex.value.index0].children[saveEditIndex.value.index1] = param;
let data = {
index0: saveEditIndex.value.index0,
index1: saveEditIndex.value.index1
}
whereEvent(data);
if (haveValue) {
editDirective(param).then((res : any) => {
if (res.success) {
geteverything()
}
})
} else {
doaddDirective(param);
}
}
const cleansettimeout = ref(null);
const cleansettimeoutrel = ref(null);
const saveAll = () => {
let info = []
bodyTagList.value.forEach((element : any) => {
if (element.izSelected == 'Y') {
info.push(element)
}
})
emotionTagList.value.forEach((element : any) => {
if (element.izSelected == 'Y') {
info.push(element)
}
})
let allvalue = {
nuId: uni.getStorageSync('nuId'),
nuName: uni.getStorageSync('nuName'),
elderId: uni.getStorageSync('elderId'),
elderName: uni.getStorageSync('NUall').elderInfo.name,
tagList: info
}
addBatch(allvalue).then(() => {
geteverything()
})
}
2026-02-02 14:42:43 +08:00
2026-01-16 14:28:12 +08:00
// 暂存器
const saveRulerTime = ref({
index0: -1,
index1: -1
})
const targetRuler = ref({
index0: -1,
index1: -1,
current: -1,
bordershow: true
})
2026-02-02 14:42:43 +08:00
// const solveWatch = ref(0)
2026-01-16 14:28:12 +08:00
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 emotionTagList = ref([]);
const bodyTagList = ref([]);
const geteverything = () => {
2026-02-03 15:13:24 +08:00
2026-01-16 14:28:12 +08:00
if (uni.getStorageSync('nuId') && uni.getStorageSync('elderId')) {
getNclist(uni.getStorageSync('nuId'), uni.getStorageSync('elderId')).then((res : any) => {
2026-02-03 15:13:24 +08:00
2026-01-16 14:28:12 +08:00
timearr.value = Array.from({ length: 24 }, (_, hour) => ({
positioning: hour.toString(),
children: minuteArr.map(time => ({
tagName: time, // 表示分钟,如 '00', '05' 等
directiveName: '' // 默认的 directiveName
}))
}))
res.result.serviceList.forEach((res : any) => {
timearr.value[res.positioning].children[res.positioningLong] = res;
})
bottomItems.value = res.result.instantList
2026-01-28 16:40:50 +08:00
if (!res.result.instantList.length) {
deleteshake.value = false
}
2026-01-16 14:28:12 +08:00
emotionTagList.value = res.result.emotionTagList;
emotionTagListLook.value = []
bodyTagListLook.value = []
res.result.emotionTagList.forEach((res : any) => {
if (res.izSelected == 'Y') {
2026-01-21 17:02:35 +08:00
emotionTagListLook.value.push(res)
2026-01-16 14:28:12 +08:00
}
})
bodyTagList.value = res.result.bodyTagList
res.result.bodyTagList.forEach((res : any) => {
if (res.izSelected == 'Y') {
2026-01-21 17:02:35 +08:00
bodyTagListLook.value.push(res)
2026-01-16 14:28:12 +08:00
}
})
})
}
}
const savePackagelist = ref([]);
2026-01-26 13:19:11 +08:00
2026-01-16 14:28:12 +08:00
onMounted(() => {
savePackagelist.value = uni.getStorageSync('Packagelist') || []
let res = uni.getStorageSync('saveTree0')
let goodArray = []
myArray.forEach((element : any) => {
2026-01-26 13:19:11 +08:00
element?.children.forEach((element1 : any) => {
2026-01-16 14:28:12 +08:00
goodArray.push({
name: element1.title,
url: element1.url,
})
})
})
secondtemp.value = goodArray
2026-01-26 13:19:11 +08:00
let data0 = res.result.fwzl
2026-02-02 14:42:43 +08:00
// console.log("0000", data0)
2026-01-26 13:19:11 +08:00
if (data0) {
data0.forEach((element : any) => {
if (element.netFlag == '0') {
doctorsayList.value.forEach((res : any) => {
if (res.name == element.title) {
element.url = res.url
}
})
if (!element.url) {
2026-01-30 17:24:22 +08:00
element.url = [`/static/logo.png`]
2026-01-26 13:19:11 +08:00
}
} else {
let array = []
element.animationPath.forEach((res : any) => {
array.push(serverUrl.value + res)
})
if (array.length) {
element.url = array
} else {
2026-01-30 17:24:22 +08:00
element.url = [`/static/logo.png`]
2026-01-26 13:19:11 +08:00
}
}
element?.children.forEach((res1 : any) => {
if (res1.netFlag == '0') {
secondtemp.value.forEach((res2 : any) => {
if (res2.name == res1.title) {
res1.url = res2.url
}
})
if (!res1.url) {
2026-01-30 17:24:22 +08:00
res1.url = [`/static/logo.png`]
2026-01-26 13:19:11 +08:00
}
// console.log("zzzz",res1)
} else {
let array = []
res1.animationPath.forEach((res : any) => {
array.push(serverUrl.value + res)
})
if (array.length) {
res1.url = array
} else {
2026-01-30 17:24:22 +08:00
res1.url = [`/static/logo.png`]
2026-01-26 13:19:11 +08:00
}
}
})
})
bigArray.value = data0;
}
let data1 = res.result.jszl
if (data1) {
data1.forEach((element : any) => {
2026-01-16 14:28:12 +08:00
if (element.netFlag == '0') {
doctorsayList.value.forEach((res : any) => {
if (res.name == element.title) {
element.url = res.url
}
})
} else {
element.url = element.animationPath
}
2026-01-26 13:19:11 +08:00
element?.children.forEach((res1 : any) => {
2026-01-16 14:28:12 +08:00
if (res1.netFlag == '0') {
secondtemp.value.forEach((res2 : any) => {
if (res2.name == res1.title) {
res1.url = res2.url
}
})
} else {
res1.url = res1.animationPath
}
})
})
2026-01-26 13:19:11 +08:00
smallArray.value = data1;
2026-01-16 14:28:12 +08:00
}
setTimeout(() => {
upmenuIndex.value = 0;
2026-01-26 13:19:11 +08:00
downmenuIndex.value = 0;
thirdmenuIndex.value = 0;
2026-01-16 14:28:12 +08:00
}, 50)
downdonghua.value = 0;
geteverything()
2026-01-20 15:35:05 +08:00
nextTick(() => {
timeNowMove()
})
2026-01-16 14:28:12 +08:00
})
2026-01-20 15:35:05 +08:00
const hournow = ref(new Date().getHours());
// 表格进来就给我居中
function timeNowMove() {
const cellCenterX = (hournow.value + 0.5) * 259;
let width = cellCenterX - visibleWidth / 2;
const totalWidth = totalColumns * 259;
cardLeft.value = Math.max(0, Math.min(width, totalWidth - visibleWidth)) / 2;
}
2026-01-16 14:28:12 +08:00
const bodyTagListLook = ref([]);
const emotionTagListLook = ref([]);
2026-01-21 17:02:35 +08:00
const bodyTagListLooksave = ref([]);
const emotionTagListLooksave = ref([]);
const listsave = ref([])
const clickopen = () => {
2026-01-26 13:19:11 +08:00
if (!settingopen.value) {
cleanallopen()
}
2026-01-21 17:02:35 +08:00
settingopen.value = !settingopen.value;
if (settingopen.value) {
bodyTagListLooksave.value = JSON.parse(JSON.stringify(bodyTagList.value));
emotionTagListLooksave.value = JSON.parse(JSON.stringify(emotionTagList.value));
listsave.value = bodyTagListLooksave.value
menutype.value = 0
}
}
const saverightclick = () => {
settingopen.value = false;
bodyTagList.value = bodyTagListLooksave.value;
emotionTagList.value = emotionTagListLooksave.value;
saveAll()
}
const clickmenu = (index : number) => {
menutype.value = index;
if (index) {
listsave.value = emotionTagListLooksave.value
} else {
listsave.value = bodyTagListLooksave.value
}
2026-01-26 17:28:01 +08:00
}
2026-02-02 14:42:43 +08:00
const clicktags = () => {
if (editingmode.value) {
clickopen()
}
}
2026-01-26 17:28:01 +08:00
const edittype = ref(0)
const clickedit = (index : number) => {
edittype.value = index;
2026-01-21 17:02:35 +08:00
}
2026-01-29 17:31:38 +08:00
let timerId : ReturnType<typeof setTimeout> | null = null
2026-02-02 14:42:43 +08:00
// const showtomuch = ref(false)
2026-01-21 17:02:35 +08:00
const clickcard = (index : number) => {
let data = menutype.value ? emotionTagListLooksave.value : bodyTagListLooksave.value
if (data[index].izSelected === 'Y') {
data[index].izSelected = 'N'
} else {
if (data.filter(item => item.izSelected === 'Y').length !== 2) {
data[index].izSelected = 'Y'
2026-02-03 15:13:24 +08:00
}
2026-01-21 17:02:35 +08:00
}
listsave.value = data
}
2026-01-29 17:31:38 +08:00
onUnmounted(() => {
if (timerId !== null) {
clearTimeout(timerId)
timerId = null
}
})
2026-01-26 13:19:11 +08:00
const openserver = (index : number) => {
servertype.value = index
}
2026-02-03 15:13:24 +08:00
2026-01-16 14:28:12 +08:00
onBeforeUnmount(() => {
if (animTimer) clearTimeout(animTimer)
ticking = false;
})
2026-02-02 14:42:43 +08:00
2026-01-16 14:28:12 +08:00
// 切割bigArray
function splitString(str) {
// 使用正则表达式找到所有括号的内容
let result = [];
let remainingStr = str;
// 正则匹配最外层括号(支持全角和半角)
let regex = /([^(]*)[(]([^)]+)[)]/;
while (regex.test(remainingStr)) {
let match = remainingStr.match(regex);
if (match) {
// 添加括号前的部分(去掉空白)
2026-01-28 16:40:50 +08:00
if (match[1]?.trim()) {
2026-01-16 14:28:12 +08:00
result.push(match[1].trim());
}
// 添加括号内的内容
2026-01-28 16:40:50 +08:00
if (match[2]?.trim()) {
2026-01-16 14:28:12 +08:00
result.push(match[2].trim());
}
// 更新剩余的字符串
2026-01-28 16:40:50 +08:00
remainingStr = remainingStr.replace(match[0], '')?.trim();
2026-01-16 14:28:12 +08:00
}
}
// 如果最后还有剩余部分,也加入结果
2026-01-28 16:40:50 +08:00
if (remainingStr?.trim()) {
result.push(remainingStr?.trim());
2026-01-16 14:28:12 +08:00
}
return result;
}
const totalColumns = 24; // 总列数
2026-01-28 16:40:50 +08:00
const totalRows = 12; // 总行数
2026-01-20 15:35:05 +08:00
const visibleWidth = 1295; // 可视区域宽度 (rpx),基于 scalcType * widthType ≈ 2220
const visibleHeight = 1225; // 可视区域高度 (rpx)假设显示约5行时 heightType = 102.5
2026-01-16 14:28:12 +08:00
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) * 259;
2026-01-20 15:35:05 +08:00
const cellCenterY = (saveEditIndex.value.index1 + 0.5) * 245;
2026-01-16 14:28:12 +08:00
// 计算 scrollLeft 和 scrollTop使格子中心位于可视区域中心
cardLeft.value = cellCenterX - visibleWidth / 2;
scrollTop.value = cellCenterY - visibleHeight / 2;
// 计算网格总宽高
const totalWidth = totalColumns * 259;
2026-01-20 15:35:05 +08:00
const totalHeight = totalRows * 245;
2026-01-16 14:28:12 +08:00
// 限制 scrollLeft 和 scrollTop 在有效范围内
cardLeft.value = Math.max(0, Math.min(cardLeft.value, totalWidth - visibleWidth)) / 2;
// scrollTop.value = 0
scrollTop.value = Math.max(0, Math.min(scrollTop.value, totalHeight - visibleHeight)) / 2;
}
}
2026-01-30 17:24:22 +08:00
function notrelcenter(index0, index1) {
// 计算点击格子的中心位置 (rpx)
const cellCenterX = (index0 + 0.5) * 259;
const cellCenterY = (index1 + 0.5) * 245;
// 计算 scrollLeft 和 scrollTop使格子中心位于可视区域中心
cardLeft.value = cellCenterX - visibleWidth / 2;
scrollTop.value = cellCenterY - visibleHeight / 2;
// 计算网格总宽高
const totalWidth = totalColumns * 259;
const totalHeight = totalRows * 245;
canmovechange.value = true;
// 限制 scrollLeft 和 scrollTop 在有效范围内
cardLeft.value = Math.max(0, Math.min(cardLeft.value, totalWidth - visibleWidth)) / 2;
// scrollTop.value = 0
scrollTop.value = Math.max(0, Math.min(scrollTop.value, totalHeight - visibleHeight)) / 2;
setTimeout(() => {
let reldata = []
const query = uni.createSelectorQuery()
query
.selectAll('.super-card-time-card')
.boundingClientRect((data : any) => {
data.forEach((res : any) => {
// 根据你的条件筛选元素
if (res.left > 88 && res.left < 723 && res.top < 622 && res.top > 32) {
reldata.push(res)
}
})
emit('rulepush', reldata)
})
.exec()
canmovechange.value = false;
2026-02-03 15:13:24 +08:00
// nextpageing.value = false
2026-01-30 17:24:22 +08:00
}, 300)
}
2026-01-26 13:19:11 +08:00
2026-02-02 14:42:43 +08:00
const deletedonghua = ref(false);
2026-01-28 16:40:50 +08:00
const popping = ref(false);
// 放大的动画
function playFirstPop() {
// 保证可重复触发:先清掉,再下一帧设置
popping.value = false;
requestAnimationFrame(() => {
popping.value = true;
// 0.2s 后取消(缩回)
setTimeout(() => {
popping.value = false;
}, 1000);
});
}
2026-02-02 14:42:43 +08:00
2026-01-26 13:19:11 +08:00
const longPressTimer = ref(null);
2026-01-28 16:40:50 +08:00
const isTuoing = ref(false);
// 传递过去的对象
const postitem = ref({});
2026-01-30 17:24:22 +08:00
const notrelxy = ref([0, 0])
2026-02-02 14:42:43 +08:00
// canmovechange
2026-01-28 16:40:50 +08:00
const handleTouchStart1 = (item : any, e : any) => {
if (!editingmode.value) return
saveX.value = Math.floor(e.touches[0].pageX);
saveY.value = Math.floor(e.touches[0].pageY);
2026-01-28 16:58:50 +08:00
killbaddata.value = false
2026-01-28 16:40:50 +08:00
longPressTimer.value = setTimeout(() => {
if (isScrolling.value) return
2026-01-29 17:31:38 +08:00
2026-01-28 16:40:50 +08:00
if (item.directiveName) {
2026-01-30 17:24:22 +08:00
if (killbaddata.value) return
2026-01-28 16:40:50 +08:00
let reldata = []
const query = uni.createSelectorQuery()
query
.selectAll('.super-card-time-card')
.boundingClientRect((data : any) => {
data.forEach((res : any) => {
// 根据你的条件筛选元素
if (res.left > 88 && res.left < 723 && res.top < 622 && res.top > 32) {
reldata.push(res)
}
})
2026-01-30 17:24:22 +08:00
notrelxy.value = [reldata[12].dataset.index0, reldata[12].dataset.index1]
2026-01-29 08:37:16 +08:00
if (killbaddata.value) return
2026-01-29 17:31:38 +08:00
canmovechange.value = false;
2026-01-28 16:40:50 +08:00
isTuoing.value = true;
emit('handsend', item)
emit('rulepush', reldata)
postitem.value = item
})
.exec()
}
2026-02-03 15:13:24 +08:00
}, 500)
2026-01-28 16:40:50 +08:00
}
const handleTouchStart = (item : any, e : any) => {
2026-01-26 13:19:11 +08:00
if (!editingmode.value) return
saveX.value = Math.floor(e.touches[0].pageX);
saveY.value = Math.floor(e.touches[0].pageY);
2026-01-29 17:31:38 +08:00
killbaddata.value = false
2026-01-28 16:58:50 +08:00
2026-01-26 13:19:11 +08:00
longPressTimer.value = setTimeout(() => {
if (isScrolling.value) return
2026-01-29 17:31:38 +08:00
if (killbaddata.value) return
canmovechange.value = false;
2026-01-26 13:19:11 +08:00
isTuoing.value = true;
emit('handsend', item)
2026-01-28 16:40:50 +08:00
postitem.value = item
2026-02-03 15:13:24 +08:00
}, 500)
2026-01-26 13:19:11 +08:00
}
const isScrolling = ref(false)
//长按计时器
let scrollTimeout = null
function handleScroll(e) {
2026-01-29 17:31:38 +08:00
killbaddata.value = true
2026-01-26 13:19:11 +08:00
isScrolling.value = true
// 清除之前的定时器
if (scrollTimeout) clearTimeout(scrollTimeout)
// 设置新的定时器
scrollTimeout = setTimeout(() => {
isScrolling.value = false;
}, 400)
}
const dblDelay = 300 // 双击判定阈值(ms)
const lastClick = ref(0)
let singleTimer = null
const clickaddnew = (item, index) => {
2026-01-30 17:24:22 +08:00
isTuoing.value = false
2026-01-29 17:31:38 +08:00
killbaddata.value = true
2026-01-26 13:19:11 +08:00
thirdmenuIndex.value = index
const now = Date.now()
if (now - lastClick.value < dblDelay) {
// 认定为双击
if (singleTimer) {
clearTimeout(singleTimer)
singleTimer = null
}
lastClick.value = 0
if (!editingmode.value) {
errshow.value = "添加服务指令,请切换成编辑模式"
openerror.value = true;
return
}
if (saveEditIndex.value.index0 === -1) {
errshow.value = "添加服务指令,请选择左侧的单元格"
openerror.value = true
return
}
newaddruler(item)
return
}
lastClick.value = now
}
const newaddruler = (item) => {
2026-01-29 17:31:38 +08:00
let cardvalue = JSON.parse(JSON.stringify(timearr.value[saveEditIndex.value.index0].children[saveEditIndex.value.index1]))
2026-01-26 13:19:11 +08:00
let allobject = item
let cycleType = "";
let cycleValue = "";
if (allobject.cycleTypeId == 1) {
cycleType = "日常"
2026-02-03 15:13:24 +08:00
}
2026-01-26 13:19:11 +08:00
const startHour = Number(saveEditIndex.value.index0)
const startMinute = Number(timearr.value[saveEditIndex.value.index0].children[saveEditIndex.value.index1].tagName)
const endMinute = startMinute + Number(allobject.serviceDuration)
const endHour = startHour + Math.floor(endMinute / 60)
2026-01-30 17:24:22 +08:00
const formattedStart = `${padZero(String(startHour))}:${String(startMinute).padStart(2, '0')}`
2026-01-26 13:19:11 +08:00
const formattedEnd = `${String(endHour)}:${String(endMinute % 60).padStart(2, '0')}`
// 数据先留着,万一以后要
let param = {
2026-01-26 17:28:01 +08:00
id: timearr.value[saveEditIndex.value.index0].children[saveEditIndex.value.index1].id,
2026-01-26 13:19:11 +08:00
nuId: uni.getStorageSync('nuId'),
nuName: uni.getStorageSync('nuName'),
elderId: uni.getStorageSync('elderId'),
elderName: uni.getStorageSync('NUall').elderInfo.name,
directiveId: allobject.id,
directiveName: allobject.title,
typeId: allobject.typeId,
typeName: allobject.typeName,
categoryId: allobject.categoryId,
categoryName: allobject.categoryName,
cycleTypeId: allobject.cycleTypeId,
cycleType: cycleType,
cycleValue: cycleValue,
startTime: formattedStart,
endTime: formattedEnd,
positioning: saveEditIndex.value.index0.toString(),
positioningLong: saveEditIndex.value.index1.toString(),
izPackage: 'N',
previewFile: allobject.previewFile,
previewFileSmall: allobject.previewFileSmall,
serviceDuration: allobject.serviceDuration,
immediateFile: allobject.immediateFile,
immediateFileFocus: allobject.immediateFileFocus,
netImmediateFileFocus: allobject.netImmediateFileFocus,
netImmediateFile: allobject.netImmediateFile,
tagName: timearr.value[saveEditIndex.value.index0].children[saveEditIndex.value.index1].tagName,
mp3File: allobject.mp3File,
netMp3File: allobject.netMp3File,
mp4File: allobject.mp4File,
netMp4File: allobject.netMp4File,
serviceContent: allobject.serviceContent,
netPreviewFile: allobject.netPreviewFile,
netPreviewFileSmall: allobject.netPreviewFileSmall,
}
//给表格赋值
timearr.value[saveEditIndex.value.index0].children[saveEditIndex.value.index1] = param;
// console.log("测试",param)
let data = {
index0: saveEditIndex.value.index0,
index1: saveEditIndex.value.index1
}
whereEvent(data);
const now = new Date();
2026-01-26 17:28:01 +08:00
const ts = `${now.getFullYear()}-${(now.getMonth() + 1).toString().padStart(2, '0')}-${now.getDate().toString().padStart(2, '0')} ${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}:${now.getSeconds().toString().padStart(2, '0')}`;
2026-01-26 13:19:11 +08:00
let postdata = {
2026-01-26 17:28:01 +08:00
nuId: uni.getStorageSync('nuId'),
2026-01-26 13:19:11 +08:00
directiveId: allobject.id,
2026-01-26 17:28:01 +08:00
positioning: saveEditIndex.value.index0.toString(),
2026-01-26 13:19:11 +08:00
positioningLong: saveEditIndex.value.index1.toString(),
2026-01-26 17:28:01 +08:00
tagName: timearr.value[saveEditIndex.value.index0].children[saveEditIndex.value.index1].tagName,
2026-01-26 13:19:11 +08:00
startTime: formattedStart,
2026-01-28 16:40:50 +08:00
izPackage: servertype.value ? `Y` : `N`,
cycleTypeId: 1,
2026-01-26 13:19:11 +08:00
}
2026-01-29 17:31:38 +08:00
if (cardvalue.directiveId) {
postdata.id = cardvalue.id,
editDirective(postdata).then((res) => {
if (res.success) {
geteverything()
setTimeout(() => {
rulerTouchClick(timearr.value[saveEditIndex.value.index0].children[saveEditIndex.value.index1], saveEditIndex.value.index0, saveEditIndex.value.index1)
2026-01-30 17:24:22 +08:00
}, 300)
2026-01-29 17:31:38 +08:00
}
})
} else {
addDirective(postdata).then((res) => {
if (res.success) {
geteverything()
setTimeout(() => {
rulerTouchClick(timearr.value[saveEditIndex.value.index0].children[saveEditIndex.value.index1], saveEditIndex.value.index0, saveEditIndex.value.index1)
2026-01-30 17:24:22 +08:00
}, 300)
2026-01-29 17:31:38 +08:00
}
})
}
2026-01-26 17:28:01 +08:00
2026-01-26 13:19:11 +08:00
}
onBeforeUnmount(() => {
if (singleTimer) clearTimeout(singleTimer)
})
2026-01-26 17:28:01 +08:00
function getMonthDaysArray(year, month, padEnd = false) {
const firstDay = new Date(year, month, 1);
// 周一为第一天Mon=0 ... Sun=6
const leadingEmptyCount = (firstDay.getDay() + 6) % 7;
const daysInMonth = new Date(year, month + 1, 0).getDate();
const arr = Array.from({ length: leadingEmptyCount }, () => '');
for (let d = 1; d <= daysInMonth; d++) {
arr.push(String(d).padStart(2, '0')); // ⭐ 关键:补 0
}
// 可选补齐到整周7 的倍数)
if (padEnd) {
while (arr.length % 7 !== 0) arr.push('');
}
return arr;
}
2026-01-28 16:40:50 +08:00
const packnumber = ref(0)
const packclick = (item, index) => {
2026-01-30 17:24:22 +08:00
isTuoing.value = false
killbaddata.value = true
2026-01-28 16:40:50 +08:00
packnumber.value = index;
const now = Date.now()
if (now - lastClick.value < dblDelay) {
// 认定为双击
if (singleTimer) {
clearTimeout(singleTimer)
singleTimer = null
}
lastClick.value = 0
if (!editingmode.value) {
errshow.value = "添加服务指令,请切换成编辑模式"
openerror.value = true;
return
}
if (saveEditIndex.value.index0 === -1) {
errshow.value = "添加服务指令,请选择左侧的单元格"
openerror.value = true
return
}
newaddruler(item)
return
}
lastClick.value = now
}
2026-01-30 17:24:22 +08:00
function shortText(str : string, number : number) {
return str.length > number ? str.slice(0, number) + '.' : str
}
function padZero(str : string) {
return str.length === 1 ? '0' + str : str
}
2026-02-02 14:42:43 +08:00
const bodytagtarget = ref<any>({})
const detailtarget = ref(-1)
const clickbody = (item : any, index : number) => {
if (!editingmode.value) {
if (detailtarget.value === index) {
bodytagtarget.value = {};
detailtarget.value = -1
} else {
bodytagtarget.value = item;
detailtarget.value = index
}
}
}
// 为啥这样写,是因为位置不规则
function docalc(index : number) {
switch (index) {
case 0:
return 9
case 1:
return 29
case 2:
return 57
case 3:
return 79
}
}
2026-01-16 14:28:12 +08:00
</script>
<style lang="less" scoped>
// 主页的css
@import './index';
</style>