This commit is contained in:
Teng 2026-01-19 17:35:31 +08:00
parent 5834d65356
commit 33e48294eb
10 changed files with 274 additions and 118 deletions

20
App.vue
View File

@ -41,19 +41,19 @@
}, },
onShow() { onShow() {
console.log('App Show'); // console.log('App Show');
if (uni.getStorageSync('userInfo')) { // if (uni.getStorageSync('userInfo')) {
// // //
connectWs() // connectWs()
} // }
}, },
onHide() { onHide() {
console.log('App Hide'); // console.log('App Hide');
if (uni.getStorageSync('userInfo')) { // if (uni.getStorageSync('userInfo')) {
// socket // // socket
closeWs() // closeWs()
} // }
} }
} }
</script> </script>

View File

@ -2,15 +2,18 @@
// 带中文日志与消息体打印选项的 WsRequest替换你当前文件即可 // 带中文日志与消息体打印选项的 WsRequest替换你当前文件即可
class WsRequest { class WsRequest {
// 静态:防止重复全局绑定
static _globalBound = false;
constructor(url = '', options = {}) { constructor(url = '', options = {}) {
this.url = url || ''; this.url = url || '';
this.options = Object.assign({ this.options = Object.assign({
header: {}, header: {},
protocols: [], protocols: [],
debug: true, debug: true,
lang: 'zh', // 'zh' 或 'en',控制日志语言(默认中文) lang: 'zh', // 'zh' 或 'en'
showMessageBody: true, // 是否在日志中显示收到消息的完整 JSON默认 true showMessageBody: true,
filterPing: true, // 是否过滤掉 ping/pong 日志(默认 true filterPing: true,
heartbeatInterval: 30000, heartbeatInterval: 30000,
heartbeatTimeout: 15000, heartbeatTimeout: 15000,
pingMessage: { type: 'ping' }, pingMessage: { type: 'ping' },
@ -30,7 +33,18 @@ class WsRequest {
this._hbTimeoutTimer = null; this._hbTimeoutTimer = null;
this._subscriptions = new Map(); this._subscriptions = new Map();
if (this.options.bindGlobal) this._bindGlobalSocketEvents(); // 是否允许自动重连(主动 close 时设为 false
this._shouldReconnect = true;
this._manualClose = false;
// 如果要求全局绑定且还没绑定过,则绑定一次(静态控制)
if (this.options.bindGlobal && !WsRequest._globalBound) {
this._bindGlobalSocketEvents();
WsRequest._globalBound = true;
} else if (this.options.bindGlobal && WsRequest._globalBound) {
// 已由其他实例绑定,跳过
}
if (this.options.autoConnect) setTimeout(() => this.open(), 0); if (this.options.autoConnect) setTimeout(() => this.open(), 0);
} }
@ -69,10 +83,9 @@ class WsRequest {
return this.options.lang === 'zh' ? zh[key] || key : en[key] || key; return this.options.lang === 'zh' ? zh[key] || key : en[key] || key;
} }
// 简单统一日志 // 简单统一日志(恢复 console 输出,便于调试)
log(...args) { log(...args) {
if (!this.options.debug) return; if (!this.options.debug) return;
// 如果是对象,格式化输出以便控制台可读
const out = args.map(a => { const out = args.map(a => {
if (typeof a === 'object') { if (typeof a === 'object') {
try { return JSON.stringify(a, null, 2); } catch (e) { return String(a); } try { return JSON.stringify(a, null, 2); } catch (e) { return String(a); }
@ -86,32 +99,63 @@ class WsRequest {
open() { open() {
if (!this.url) { this.log(this._label('open'), this._label('noUrl') || 'no url'); return; } if (!this.url) { this.log(this._label('open'), this._label('noUrl') || 'no url'); return; }
if (this.connected) { this.log(this._label('alreadyConnected')); return; } if (this.connected) { this.log(this._label('alreadyConnected')); return; }
this.log(this._label('open'), this.url); this.log(this._label('open'), this.url);
// 主动 open允许后续自动重连如果被之前的手动关闭禁止过open 表示想要恢复)
this._shouldReconnect = true;
this._manualClose = false;
try { try {
const task = uni.connectSocket({ url: this.url, header: this.options.header, protocols: this.options.protocols }); const task = uni.connectSocket({ url: this.url, header: this.options.header, protocols: this.options.protocols });
if (task && typeof task.onOpen === 'function') { if (task && typeof task.onOpen === 'function') {
this._bindSocketTask(task); this._bindSocketTask(task);
} else { } else {
this.log(this._label('connectNoTask')); this.log(this._label('connectNoTask'));
// 依赖全局回调,_bindGlobalSocketEvents 已经绑定则会处理 onOpen/onMessage // 依赖全局回调,已在构造时绑定
} }
} catch (e) { } catch (e) {
console.error(e); console.error(e);
} }
} }
close(code = 1000, reason = 'client close') { /**
* close(code, reason, manual)
* manual: 是否为手动/意图性关闭默认 true
* - manual === true 时将禁止自动重连用于用户主动关闭
* - manual === false 时视为异常或内部触发的关闭允许重连
*/
close(code = 1000, reason = 'client close', manual = true) {
// 标记手动关闭以禁止后续自动重连
if (manual) {
this._shouldReconnect = false;
this._manualClose = true;
} else {
// 非手动关闭(例如心跳超时)则保持 _shouldReconnect 原有值(通常为 true
this._manualClose = false;
}
this._stopHeartbeat(); this._stopHeartbeat();
try { try {
if (this.socketTask && typeof this.socketTask.close === 'function') { if (this.socketTask && typeof this.socketTask.close === 'function') {
this.socketTask.close({ code, reason }); try {
this.socketTask.close({ code, reason });
} catch (e) {
// 某些平台 socketTask.close 可能会抛错
this.log(this._label('closeError'), e);
// 尝试全局 close
if (typeof uni.closeSocket === 'function') uni.closeSocket();
}
} else if (typeof uni.closeSocket === 'function') { } else if (typeof uni.closeSocket === 'function') {
uni.closeSocket(); uni.closeSocket();
} }
} catch (e) { } catch (e) {
this.log(this._label('closeError'), e); this.log(this._label('closeError'), e);
} }
this.connected = false; this.connected = false;
// 清理 socketTask 引用,释放资源,防止重复使用导致 FD 泄漏
this.socketTask = null;
} }
send(payload) { send(payload) {
@ -150,6 +194,10 @@ class WsRequest {
this._startHeartbeat(); this._startHeartbeat();
this._flushQueue(); this._flushQueue();
this.options.onOpen && this.options.onOpen(res); this.options.onOpen && this.options.onOpen(res);
// 打开时允许后续重连(如果连接成功)
this._shouldReconnect = true;
this._manualClose = false;
}); });
task.onMessage(msg => { task.onMessage(msg => {
@ -161,6 +209,7 @@ class WsRequest {
this.connected = false; this.connected = false;
this._stopHeartbeat(); this._stopHeartbeat();
this.options.onClose && this.options.onClose(res); this.options.onClose && this.options.onClose(res);
// 仅当允许重连时才触发重连逻辑
this._tryReconnect(); this._tryReconnect();
}); });
@ -182,15 +231,13 @@ class WsRequest {
} }
const type = (data && data.type) || '__default__'; const type = (data && data.type) || '__default__';
// 过滤 ping/pong (若你想看 ping/pong把 filterPing 设为 false // 过滤 ping/pong
const isPing = data && (data.type === 'ping' || data.type === 'pong' || (typeof data === 'string' && (data === 'ping' || data === 'pong'))); const isPing = data && (data.type === 'ping' || data.type === 'pong' || (typeof data === 'string' && (data === 'ping' || data === 'pong')));
if (isPing && this.options.filterPing) { if (isPing && this.options.filterPing) {
// 仍更新 lastPong但不打印消息体除非 showMessageBody 强制 true
if (this.options.debug && this.options.showMessageBody === false) { if (this.options.debug && this.options.showMessageBody === false) {
this.log(this._label('onMessage'), type); this.log(this._label('onMessage'), type);
} }
} else { } else {
// 打印消息类型与(可选)格式化消息体
if (this.options.debug) { if (this.options.debug) {
if (this.options.showMessageBody) { if (this.options.showMessageBody) {
let bodyStr; let bodyStr;
@ -202,13 +249,12 @@ class WsRequest {
} }
} }
// 外部回调与订阅异步派发
if (this.options.onMessage) setTimeout(() => this.options.onMessage(data, msg), 0); if (this.options.onMessage) setTimeout(() => this.options.onMessage(data, msg), 0);
setTimeout(() => this._dispatch(type, data, msg), 0); setTimeout(() => this._dispatch(type, data, msg), 0);
} }
_bindGlobalSocketEvents() { _bindGlobalSocketEvents() {
// 解绑默认全局再绑定,避免重复 // 解绑默认全局再绑定,避免重复(但是本函数只会被调用一次,受静态保护)
try { uni.offSocketOpen && uni.offSocketOpen(); } catch (e) {} try { uni.offSocketOpen && uni.offSocketOpen(); } catch (e) {}
try { uni.offSocketMessage && uni.offSocketMessage(); } catch (e) {} try { uni.offSocketMessage && uni.offSocketMessage(); } catch (e) {}
try { uni.offSocketClose && uni.offSocketClose(); } catch (e) {} try { uni.offSocketClose && uni.offSocketClose(); } catch (e) {}
@ -223,12 +269,15 @@ class WsRequest {
this._startHeartbeat(); this._startHeartbeat();
this._flushQueue(); this._flushQueue();
this.options.onOpen && this.options.onOpen(res); this.options.onOpen && this.options.onOpen(res);
// 同上,打开时允许重连
this._shouldReconnect = true;
this._manualClose = false;
}); });
} catch (e) {} } catch (e) {}
try { try {
uni.onSocketMessage(msg => { uni.onSocketMessage(msg => {
// 全局收到消息也走统一处理
if (this.options.debug) this.log(this._label('globalOnMessage')); if (this.options.debug) this.log(this._label('globalOnMessage'));
this._handleIncoming(msg); this._handleIncoming(msg);
}); });
@ -267,7 +316,8 @@ class WsRequest {
const since = Date.now() - this._lastPongAt; const since = Date.now() - this._lastPongAt;
if (since > this.options.heartbeatTimeout) { if (since > this.options.heartbeatTimeout) {
this.log(this._label('hbTimeout'), since); this.log(this._label('hbTimeout'), since);
try { this.close(); } catch (e) { this.log('hb close fail', e); } // 由心跳触发的关闭视为“异常/内部”关闭 — 传 manual = false 以允许重连
try { this.close(1000, 'hb timeout', false); } catch (e) { this.log('hb close fail', e); }
} }
}, this.options.heartbeatTimeout); }, this.options.heartbeatTimeout);
}, this.options.heartbeatInterval); }, this.options.heartbeatInterval);
@ -279,14 +329,26 @@ class WsRequest {
} }
_tryReconnect() { _tryReconnect() {
// 先检查是否允许自动重连(主动关闭时应被禁用)
if (!this._shouldReconnect) {
this.log(this._label('reconnectScheduled'), 'reconnect disabled (manual close)');
return;
}
if (this.reconnectAttempts >= this.options.maxReconnectAttempts) { this.log(this._label('reconnectScheduled'), 'exhausted'); return; } if (this.reconnectAttempts >= this.options.maxReconnectAttempts) { this.log(this._label('reconnectScheduled'), 'exhausted'); return; }
this.reconnectAttempts++; this.reconnectAttempts++;
const delay = Math.min(this.options.reconnectDelayBase * Math.pow(1.5, this.reconnectAttempts - 1), 30000);
this.log(this._label('reconnectScheduled'), delay + 'ms', 'attempt', this.reconnectAttempts); // 指数退避 + jitter避免同时大量重连
const base = this.options.reconnectDelayBase || 1000;
const delay = Math.min(base * Math.pow(1.5, this.reconnectAttempts - 1), 30000);
const jitter = Math.floor(Math.random() * 401) - 200; // -200 .. +200 ms
const finalDelay = Math.max(0, Math.floor(delay) + jitter);
this.log(this._label('reconnectScheduled'), finalDelay + 'ms', 'attempt', this.reconnectAttempts);
setTimeout(() => { setTimeout(() => {
this.socketTask = null; this.socketTask = null;
this.connectIfForeground(); this.connectIfForeground();
}, delay); }, finalDelay);
} }
connectIfForeground() { connectIfForeground() {

View File

@ -3,25 +3,49 @@ import WsRequest from '@/common/websocket.js';
let globalWs = null; let globalWs = null;
const initWs = (url, options) => { const initWs = (url, options = {}) => {
// 如果已经有 WebSocket 实例,直接返回 // 如果已经有 WebSocket 实例且 URL 相同,直接返回
if (globalWs) return globalWs; if (globalWs) {
if (globalWs.url === url) {
return globalWs;
}
// 否则先将旧实例以“手动关闭”方式关闭并清理,避免旧实例干扰
try {
globalWs._shouldReconnect = false;
globalWs.close(1000, 'reinit', true);
} catch (e) {
// 忽略关闭错误
}
globalWs = null;
}
globalWs = new WsRequest(url, options); // 强烈建议:全局只 bind 一次WsRequest 内部已用静态保护)
const opt = Object.assign({ bindGlobal: true }, options);
globalWs = new WsRequest(url, opt);
return globalWs; return globalWs;
}; };
const connectWs = () => { const connectWs = () => {
if (globalWs) { if (!globalWs) return;
globalWs.reconnectAttempts = 0; // 重置重连计数 // 如果已经连接,直接返回,避免重复 open
globalWs.open(); // 打开 WebSocket 连接 if (globalWs.connected) return;
} // 明确表示这是一次主动连接请求,允许自动重连
globalWs.reconnectAttempts = 0;
globalWs._shouldReconnect = true;
globalWs._manualClose = false;
globalWs.open();
}; };
const closeWs = () => { const closeWs = (manual = true) => {
if (globalWs) { if (!globalWs) return;
globalWs.close(); // 关闭 WebSocket 连接 // 主动关闭时先禁止自动重连
if (manual) {
globalWs._shouldReconnect = false;
} }
// 传 manual 参数到 close以便内部区分是否允许重连
globalWs.close(1000, 'manager close', !!manual);
// 如果你想下次重新 init 时创建新实例,可以把 globalWs 置空
// globalWs = null;
}; };
export { initWs, connectWs, closeWs }; export { initWs, connectWs, closeWs };

View File

@ -43,7 +43,7 @@
// String/Date/Number // String/Date/Number
const props = defineProps({ const props = defineProps({
modelValue: { modelValue: {
type: [String, Date, Number, Object],
default: null default: null
} }
}); });

View File

@ -1186,7 +1186,7 @@
},200) },200)
}) })
onHide(() => { onHide(() => {
playall.value = false; photoplay.value = false;
}) })
const filteredMenu = (index : number) => { const filteredMenu = (index : number) => {
return leftMenuArray.value.filter(item => Number(item.areaFlag) - 1 == index); return leftMenuArray.value.filter(item => Number(item.areaFlag) - 1 == index);

View File

@ -1728,12 +1728,12 @@
} }
const savePackagelist = ref([]); const savePackagelist = ref([]);
onMounted(() => { onMounted(() => {
// if(uni.getStorageSync('elderId')===null){ if(uni.getStorageSync('elderId')===null){
// uni.setStorageSync('elderId', ""); uni.setStorageSync('elderId', "");
// } }
savePackagelist.value = uni.getStorageSync('Packagelist') || [] savePackagelist.value = uni.getStorageSync('Packagelist') || []
let res = uni.getStorageSync('saveTree2') let res = uni.getStorageSync('saveTree2')
console.log("啥啊啊啊啊",savePackagelist.value,res) // console.log("",myArray)
let goodArray = [] let goodArray = []
myArray.forEach((element : any) => { myArray.forEach((element : any) => {

View File

@ -465,39 +465,60 @@
width: 100%; width: 100%;
height: 100rpx; height: 100rpx;
display: flex; display: flex;
align-items: center; /* align-items: center; */
/* background-color: red; */ /* background-color: red; */
.order-month { .order-month {
margin-left: 30rpx; margin-left: 30rpx;
font-size: 37rpx; font-size: 37rpx;
font-weight: 800; font-weight: 800;
width: 100rpx; width: 105rpx;
/* background-color: green; */
height: 100rpx;
display: flex;
align-items: center;
position: relative;
.order-month-right{
position: absolute;
right: 0;
top: 50%;
transform: translateY(-50%);
height: 60%;
width: 10rpx;
background: linear-gradient(to right, #ececec, white);
}
} }
.order-day { .order-day {
width: 440rpx; width: 440rpx;
height: 100rpx; height: 100rpx;
/* background-color: red; */ /* background-color: red; */
.days-father { .days-father {
display: flex; display: flex;
align-items: center; align-items: center;
font-size: 31rpx; font-size: 31rpx;
margin-top: 20rpx;
.days { .days {
height: 75rpx; height: 59rpx;
min-width: 75rpx; min-width: 59rpx;
margin: 0 8rpx;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
/* background-color: red; */
border-radius: 50%;
/* color: #BBBABA; */ /* color: #BBBABA; */
} }
.targetdays { .targetdays {
height: 75rpx; height: 59rpx;
min-width: 75rpx; min-width: 59rpx;
margin: 0 8rpx;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
@ -517,46 +538,51 @@
position: relative; position: relative;
.history-spe { .history-spe {
min-width: 86%; min-width: 88%;
height: 100%; height: 100%;
margin-left: 14%; margin-left: 11%;
background-color: #F7F8F9; background-color: #F7F8F9;
border-radius: 25rpx; border-radius: 25rpx;
padding-top: 10rpx; padding-top: 10rpx;
padding-left: 20rpx; padding-left: 20rpx;
/* position: relative; */ /* position: relative; */
.history-left-jiao { .history-left-jiao {
position: absolute; position: absolute;
right: 0; right: 30rpx;
top: 0; top: 15rpx;
width: 85rpx; width: 100rpx;
height: 45rpx; height: 45rpx;
background-color: #D9E5FF; background-color: #4690FF;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
border-top-right-radius: 25rpx; border: 2rpx solid #4690FF;
border-bottom-left-radius: 25rpx; margin-top: 20rpx;
color: #3C9CFD; margin-right: 30rpx;
font-size: 19rpx; border-radius: 10rpx;
color: #fff;
font-size: 27rpx;
font-weight: 600; font-weight: 600;
} }
.history-left-jiao-error { .history-left-jiao-error {
position: absolute; position: absolute;
right: 0; right: 30rpx;
top: 0; top: 15rpx;
width: 85rpx; width: 100rpx;
height: 45rpx; height: 45rpx;
background-color: #FFEBEB; background-color: #FFEBEB;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
border-top-right-radius: 25rpx; border: 2rpx solid #F76E6E;
border-bottom-left-radius: 25rpx; margin-top: 20rpx;
margin-right: 30rpx;
border-radius: 10rpx;
color: #F76E6E; color: #F76E6E;
font-size: 19rpx; font-size: 27rpx;
font-weight: 600; font-weight: 600;
} }
} }
@ -564,27 +590,37 @@
/* background-color: red; */ /* background-color: red; */
.history-title { .history-title {
width: 100%; width: 100%;
height: 70rpx; height: 80rpx;
display: flex; display: flex;
align-items: center; align-items: center;
padding: 0 30rpx; padding: 0 30rpx;
justify-content: space-between; justify-content: space-between;
.history-left { .history-left {
font-size: 30rpx; .history-blue{
width: 8rpx;
height: 25rpx;
margin-top: 8rpx;
border-radius: 10rpx;
background-color: #0089FE;
margin-right: 15rpx;
}
font-size: 33rpx;
margin-top: 10rpx; margin-top: 10rpx;
display:flex;
position: relative;
} }
.history-right { .history-right {
margin-top: 0.5vw; margin-top: 0.5vw;
width: 7vw; width: 7vw;
height: 2.5vw; height: 2.8vw;
background: linear-gradient(to bottom, #009DEF, #0076FF); background: linear-gradient(to bottom, #009DEF, #0076FF);
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
border-radius: 40rpx; border-radius: 10rpx;
color: #fff; color: #fff;
font-size: 28rpx; font-size: 28rpx;
position: relative; position: relative;
@ -594,13 +630,14 @@
.history-items { .history-items {
width: 100%; width: 100%;
margin-top: 15rpx; margin-top: 15rpx;
height: 440rpx; height: 570rpx;
/* background-color: red; */
.history-item { .history-item {
/* margin-left: 1%; */ /* margin-left: 1%; */
width: 95%; width: 95%;
height: 120rpx; height: 176rpx;
margin-bottom: 13rpx; margin-bottom: 20rpx;
position: relative; position: relative;
display: flex; display: flex;
align-items: center; align-items: center;
@ -609,6 +646,7 @@
.history-left { .history-left {
/* margin-left: 58rpx; */ /* margin-left: 58rpx; */
width: 120rpx; width: 120rpx;
} }
.history-right { .history-right {
@ -655,10 +693,10 @@
.history-shu-up { .history-shu-up {
position: absolute; position: absolute;
left: 32rpx; left: 33rpx;
bottom: calc(50% + 13rpx); bottom: calc(50% + 13rpx);
width: 3rpx; width: 3rpx;
height: 110rpx; height: 173rpx;
background-color: #E5E5E5; background-color: #E5E5E5;
transition: height 0.3s ease; transition: height 0.3s ease;
@ -669,8 +707,8 @@
left: 20rpx; left: 20rpx;
top: 50%; top: 50%;
transform: translateY(-50%); transform: translateY(-50%);
width: 26.5rpx; width: 30rpx;
height: 26.5rpx; height: 30rpx;
border-radius: 50%; border-radius: 50%;
border: 4.5rpx solid #D0D1D1; border: 4.5rpx solid #D0D1D1;
z-index: 1; z-index: 1;
@ -681,30 +719,31 @@
.order-future { .order-future {
width: 100%; width: 100%;
height: 640rpx; height: 480rpx;
margin-top: -12rpx; /* margin-top: -12rpx; */
position: relative; position: relative;
/* background-color: red; */
.future-items { .future-items {
width: 100%; width: 100%;
height: 100%; height: 100%;
.future-fonts { .future-fonts {
font-size: 27rpx; font-size: 30rpx;
display: flex; display: flex;
} }
.future-item-target { .future-item-target {
width: 90%; width: 90%;
margin-left: 5%; margin-left: 5%;
height: 152rpx; height: 140rpx;
margin-bottom: 10rpx; margin-bottom: 20rpx;
background-color: #F7F8F9; background-color: #F7F8F9;
border-radius: 30rpx; border-radius: 30rpx;
/* padding: 25rpx; */ /* padding: 25rpx; */
padding-top: 25rpx; padding-top: 20rpx;
padding-left: 25rpx; padding-left: 25rpx;
font-size: 25rpx; font-size: 30rpx;
color: #555555; color: #555555;
position: relative; position: relative;
border: 2rpx solid #4690FF; border: 2rpx solid #4690FF;
@ -715,14 +754,14 @@
.future-item { .future-item {
width: 90%; width: 90%;
margin-left: 5%; margin-left: 5%;
height: 152rpx; height: 140rpx;
margin-bottom: 10rpx; margin-bottom: 20rpx;
background-color: #F7F8F9; background-color: #F7F8F9;
border-radius: 30rpx; border-radius: 30rpx;
/* padding: 25rpx; */ /* padding: 25rpx; */
padding-top: 25rpx; padding-top: 20rpx;
padding-left: 25rpx; padding-left: 25rpx;
font-size: 25rpx; font-size: 30rpx;
color: #555555; color: #555555;
position: relative; position: relative;
border: 2rpx solid #F7F8F9; border: 2rpx solid #F7F8F9;
@ -732,13 +771,13 @@
.future-time { .future-time {
width: 100%; width: 100%;
margin-top: 20rpx; margin-top: 12rpx;
height: 50rpx; height: 50rpx;
display: flex; display: flex;
align-items: center; align-items: center;
.time { .time {
font-size: 48rpx; font-size: 52rpx;
font-weight: 800; font-weight: 800;
color: black; color: black;
} }
@ -747,7 +786,7 @@
} }
} }
.future-tag { /* .future-tag {
position: absolute; position: absolute;
right: 23rpx; right: 23rpx;
top: 23rpx; top: 23rpx;
@ -761,7 +800,7 @@
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
} } */
.future-info { .future-info {
position: absolute; position: absolute;
@ -876,14 +915,14 @@
.time-right-bad { .time-right-bad {
color: #666666; color: #666666;
font-size: 24rpx; font-size: 27rpx;
margin-left: 10rpx; margin-left: 10rpx;
margin-top: 10rpx; margin-top: 10rpx;
} }
.time-right-blue { .time-right-blue {
color: #4690FF; color: #4690FF;
font-size: 24rpx; font-size: 27rpx;
margin-left: 10rpx; margin-left: 10rpx;
margin-top: 10rpx; margin-top: 10rpx;
display: flex; display: flex;
@ -951,6 +990,7 @@
.serviceContent { .serviceContent {
color: #999999; color: #999999;
margin-top: 20rpx; margin-top: 20rpx;
font-size: 25rpx;
} }
.weight-time { .weight-time {
@ -958,3 +998,7 @@
font-size: 32rpx; font-size: 32rpx;
margin-top: -5rpx; margin-top: -5rpx;
} }
.spec-shu{
margin: 0 7rpx;
color: #BABABA;
}

View File

@ -108,6 +108,9 @@
<view class="order-title"> <view class="order-title">
<view class="order-month" @click="dateshow()"> <view class="order-month" @click="dateshow()">
{{ selectdata.month }} {{ selectdata.month }}
<view class="order-month-right">
</view>
</view> </view>
<scroll-view class="order-day" scroll-with-animation scroll-x :scroll-left="movetime"> <scroll-view class="order-day" scroll-with-animation scroll-x :scroll-left="movetime">
<view class="days-father"> <view class="days-father">
@ -128,7 +131,17 @@
<view class="card-over"> <view class="card-over">
{{ item.directiveName }} {{ item.directiveName }}
</view> </view>
{{ ` | ` +item.serviceDuration + `分钟` }} <view class="spec-shu">
|
</view>
<text style="color: #4690FF;">
每天
</text>
<view class="spec-shu">
|
</view>
{{ item.serviceDuration + `分钟` }}
</view> </view>
<view class="future-time"> <view class="future-time">
<text class="time"> <text class="time">
@ -145,9 +158,9 @@
</view> </view>
</view> </view>
</view> </view>
<view class="future-tag"> <!-- <view class="future-tag">
{{ item.cycleType }} {{ item.cycleType }}
</view> </view> -->
<view class="open-img-father" v-if="!item.tagtype" <view class="open-img-father" v-if="!item.tagtype"
@click.stop="clickfirstarray(item,index);" @click.stop="clickfirstarray(item,index);"
:style="firstListTarget===index?{transform: `rotate(180deg)`}:{}"> :style="firstListTarget===index?{transform: `rotate(180deg)`}:{}">
@ -157,15 +170,24 @@
<view <view
style="position: absolute;top: 0;left: 0;transition: height 0.3s, top 0.3s;z-index: 9999; ;" style="position: absolute;top: 0;left: 0;transition: height 0.3s, top 0.3s;z-index: 9999; ;"
:class="moveById===item.id? `future-item-target`: `future-item`" :style="{ :class="moveById===item.id? `future-item-target`: `future-item`" :style="{
height: firstListTarget === index ? '320rpx' : '152rpx', height: firstListTarget === index ? '300rpx' : '140rpx',
left: firstListTargetShow === index ? '0' : '999rpx', left: firstListTargetShow === index ? '0' : '999rpx',
top: index === upmenuarray.length - 1 && firstListTarget === index? `-168rpx`:`0rpx` top: index === upmenuarray.length - 1 && firstListTarget === index? `-164rpx`:`0rpx`
}"> }">
<view class="future-fonts"> <view class="future-fonts">
<view class="card-over"> <view class="card-over">
{{ item.directiveName }} {{ item.directiveName }}
</view> </view>
{{ ` | ` +item.serviceDuration + `分钟` }} <view class="spec-shu">
|
</view>
<text style="color: #4690FF;">
每天
</text>
<view class="spec-shu">
|
</view>
{{ item.serviceDuration + `分钟` }}
</view> </view>
<view class="future-time"> <view class="future-time">
<text class="time"> <text class="time">
@ -182,9 +204,7 @@
</view> </view>
</view> </view>
</view> </view>
<view class="future-tag">
{{ item.cycleType }}
</view>
<view class="future-info" v-if="firstListTarget===index"> <view class="future-info" v-if="firstListTarget===index">
<view class="info" v-if="item.optType == 2"> <view class="info" v-if="item.optType == 2">
<image class="info-img" src="/static/index/leftpeople.png" lazy-load /> <image class="info-img" src="/static/index/leftpeople.png" lazy-load />
@ -222,7 +242,9 @@
</view> </view>
<view class="order-history"> <view class="order-history">
<view class="history-title"> <view class="history-title">
<view class="history-left"> <view class="history-left">
<view class="history-blue"></view>
服务指令 服务指令
</view> </view>
<view class="history-right"> <view class="history-right">
@ -241,7 +263,7 @@
<view class="history-left"> <view class="history-left">
<view <view
:class="item.executeStatus!==`hisOk`?`history-left-jiao-error`: `history-left-jiao`" :class="item.executeStatus!==`hisOk`?`history-left-jiao-error`: `history-left-jiao`"
style="top: 1.5rpx;right: 1.5rpx;"
v-show="secondListTargetShow !== index"> v-show="secondListTargetShow !== index">
{{ item.rightshow }} {{ item.rightshow }}
</view> </view>
@ -262,7 +284,7 @@
<view class="history-spe" <view class="history-spe"
style="position: absolute;top: 0;left: 0;transition: height 0.3s, top 0.3s;z-index: 9999; " style="position: absolute;top: 0;left: 0;transition: height 0.3s, top 0.3s;z-index: 9999; "
:style="{ :style="{
height: secondListTarget === index ? '260rpx' : '120rpx', height: secondListTarget === index ? '372rpx' : '176rpx',
left: secondListTargetShow === index ? '0' : '999rpx', left: secondListTargetShow === index ? '0' : '999rpx',
top: index === downmenuarray.length - 1 && secondListTarget === index ? '-140rpx' : '0rpx', top: index === downmenuarray.length - 1 && secondListTarget === index ? '-140rpx' : '0rpx',
border: moveById === item.id ? '2rpx solid #46B2F6' : '2rpx solid transparent' border: moveById === item.id ? '2rpx solid #46B2F6' : '2rpx solid transparent'
@ -270,7 +292,9 @@
<view class="history-left"> <view class="history-left">
<view <view
:class="item.executeStatus!==`hisOk`?`history-left-jiao-error`: `history-left-jiao`" :class="item.executeStatus!==`hisOk`?`history-left-jiao-error`: `history-left-jiao`"
v-show="secondListTargetShow === index"> v-show="secondListTargetShow === index"
>
{{ item.rightshow }} {{ item.rightshow }}
</view> </view>
<view class="history-time"> <view class="history-time">
@ -509,12 +533,13 @@
} }
daysarray.value = Array.from({ length: endDay }, (_, i) => String(i + 1).padStart(2, '0')) daysarray.value = Array.from({ length: endDay }, (_, i) => String(i + 1).padStart(2, '0'))
// console.log("", daysarray.value) // console.log("", daysarray.value)
movetime.value = (Number(selectdata.value.day) - 3) * 25 movetime.value = (Number(selectdata.value.day) - 3) * 37.5
} }
const daytarget = ref(0) const daytarget = ref(0)
const clickday = (item : string, index : number) => { const clickday = (item : string, index : number) => {
selectdata.value.day = item; selectdata.value.day = item;
movetime.value = (index - 2) * 25 selectdata.value = JSON.parse(JSON.stringify(selectdata.value))
movetime.value = (index - 2) * 37.5
getTable() getTable()
} }
const facedonghua = ref(false) const facedonghua = ref(false)
@ -822,8 +847,8 @@
getDirectiveOrders(time).then((data) => { getDirectiveOrders(time).then((data) => {
firstListTarget.value = -1; firstListTarget.value = -1;
secondListTarget.value = -1; secondListTarget.value = -1;
// console.log("", data.result.all) // console.log("", time,uni.getStorageSync('serverUrl'),uni.getStorageSync('nuId'),uni.getStorageSync('elderId'))
// console.log("", data.result.future) // console.log("", uni.getStorageSync('token'))
data.result.current.forEach((element : any) => { data.result.current.forEach((element : any) => {
element.tagtype = 0 element.tagtype = 0
}) })
@ -845,6 +870,7 @@
} }
}) })
downmenuarray.value = [...data.result.history] downmenuarray.value = [...data.result.history]
console.log("aaaaa", downmenuarray.value)
timearr.value = Array.from({ length: 24 }, (_, hour) => ({ timearr.value = Array.from({ length: 24 }, (_, hour) => ({
positioning: hour.toString(), positioning: hour.toString(),
children: minuteArr.map(() => ({ children: minuteArr.map(() => ({

View File

@ -884,7 +884,7 @@
nuId:nuId nuId:nuId
} }
queryCountByType(data).then(res=>{ queryCountByType(data).then(res=>{
console.log(res) // console.log(res)
hldyobj.value = res.result hldyobj.value = res.result
}) })
} }
@ -1077,7 +1077,7 @@
const getmenu = () => { const getmenu = () => {
queryPadPageList().then((res => { queryPadPageList().then((res => {
leftMenuArray.value = res.result.records; leftMenuArray.value = res.result.records;
console.log(leftMenuArray.value ) console.log(leftMenuArray.value)
filteredMenu(2).forEach((element : any, index : number) => { filteredMenu(2).forEach((element : any, index : number) => {
if (element.nuId === uni.getStorageSync('NUall').nuId) { if (element.nuId === uni.getStorageSync('NUall').nuId) {
menutarget.value = index; menutarget.value = index;

View File

@ -141,7 +141,7 @@
if (len === 10) return '1.3vw' // 10 if (len === 10) return '1.3vw' // 10
if (len < 10) return '1.5vw' // 10 if (len < 10) return '1.5vw' // 10
if (len <= 15) return '1.1vw' // 11~15 if (len <= 15) return '1.1vw' // 11~15
return '0.9vw' // 15 return '0.9vw' // 151
}) })
onHide(() => { onHide(() => {
playall.value = false; playall.value = false;