This commit is contained in:
parent
5834d65356
commit
33e48294eb
20
App.vue
20
App.vue
|
|
@ -41,19 +41,19 @@
|
|||
},
|
||||
|
||||
onShow() {
|
||||
console.log('App Show');
|
||||
if (uni.getStorageSync('userInfo')) {
|
||||
// 重置重连计数,确保立即重连
|
||||
connectWs()
|
||||
}
|
||||
// console.log('App Show');
|
||||
// if (uni.getStorageSync('userInfo')) {
|
||||
// // 重置重连计数,确保立即重连
|
||||
// connectWs()
|
||||
// }
|
||||
},
|
||||
|
||||
onHide() {
|
||||
console.log('App Hide');
|
||||
if (uni.getStorageSync('userInfo')) {
|
||||
// 可选择关闭 socket,或只是停止心跳
|
||||
closeWs()
|
||||
}
|
||||
// console.log('App Hide');
|
||||
// if (uni.getStorageSync('userInfo')) {
|
||||
// // 可选择关闭 socket,或只是停止心跳
|
||||
// closeWs()
|
||||
// }
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -2,15 +2,18 @@
|
|||
// 带中文日志与消息体打印选项的 WsRequest(替换你当前文件即可)
|
||||
|
||||
class WsRequest {
|
||||
// 静态:防止重复全局绑定
|
||||
static _globalBound = false;
|
||||
|
||||
constructor(url = '', options = {}) {
|
||||
this.url = url || '';
|
||||
this.options = Object.assign({
|
||||
header: {},
|
||||
protocols: [],
|
||||
debug: true,
|
||||
lang: 'zh', // 'zh' 或 'en',控制日志语言(默认中文)
|
||||
showMessageBody: true, // 是否在日志中显示收到消息的完整 JSON(默认 true)
|
||||
filterPing: true, // 是否过滤掉 ping/pong 日志(默认 true)
|
||||
lang: 'zh', // 'zh' 或 'en'
|
||||
showMessageBody: true,
|
||||
filterPing: true,
|
||||
heartbeatInterval: 30000,
|
||||
heartbeatTimeout: 15000,
|
||||
pingMessage: { type: 'ping' },
|
||||
|
|
@ -30,7 +33,18 @@ class WsRequest {
|
|||
this._hbTimeoutTimer = null;
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
@ -69,10 +83,9 @@ class WsRequest {
|
|||
return this.options.lang === 'zh' ? zh[key] || key : en[key] || key;
|
||||
}
|
||||
|
||||
// 简单统一日志
|
||||
// 简单统一日志(恢复 console 输出,便于调试)
|
||||
log(...args) {
|
||||
if (!this.options.debug) return;
|
||||
// 如果是对象,格式化输出以便控制台可读
|
||||
const out = args.map(a => {
|
||||
if (typeof a === 'object') {
|
||||
try { return JSON.stringify(a, null, 2); } catch (e) { return String(a); }
|
||||
|
|
@ -86,32 +99,63 @@ class WsRequest {
|
|||
open() {
|
||||
if (!this.url) { this.log(this._label('open'), this._label('noUrl') || 'no url'); return; }
|
||||
if (this.connected) { this.log(this._label('alreadyConnected')); return; }
|
||||
|
||||
this.log(this._label('open'), this.url);
|
||||
|
||||
// 主动 open:允许后续自动重连(如果被之前的手动关闭禁止过,open 表示想要恢复)
|
||||
this._shouldReconnect = true;
|
||||
this._manualClose = false;
|
||||
|
||||
try {
|
||||
const task = uni.connectSocket({ url: this.url, header: this.options.header, protocols: this.options.protocols });
|
||||
if (task && typeof task.onOpen === 'function') {
|
||||
this._bindSocketTask(task);
|
||||
} else {
|
||||
this.log(this._label('connectNoTask'));
|
||||
// 依赖全局回调,_bindGlobalSocketEvents 已经绑定则会处理 onOpen/onMessage
|
||||
// 依赖全局回调,已在构造时绑定
|
||||
}
|
||||
} catch (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();
|
||||
try {
|
||||
if (this.socketTask && typeof this.socketTask.close === 'function') {
|
||||
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') {
|
||||
uni.closeSocket();
|
||||
}
|
||||
} catch (e) {
|
||||
this.log(this._label('closeError'), e);
|
||||
}
|
||||
|
||||
this.connected = false;
|
||||
// 清理 socketTask 引用,释放资源,防止重复使用导致 FD 泄漏
|
||||
this.socketTask = null;
|
||||
}
|
||||
|
||||
send(payload) {
|
||||
|
|
@ -150,6 +194,10 @@ class WsRequest {
|
|||
this._startHeartbeat();
|
||||
this._flushQueue();
|
||||
this.options.onOpen && this.options.onOpen(res);
|
||||
|
||||
// 打开时允许后续重连(如果连接成功)
|
||||
this._shouldReconnect = true;
|
||||
this._manualClose = false;
|
||||
});
|
||||
|
||||
task.onMessage(msg => {
|
||||
|
|
@ -161,6 +209,7 @@ class WsRequest {
|
|||
this.connected = false;
|
||||
this._stopHeartbeat();
|
||||
this.options.onClose && this.options.onClose(res);
|
||||
// 仅当允许重连时才触发重连逻辑
|
||||
this._tryReconnect();
|
||||
});
|
||||
|
||||
|
|
@ -182,15 +231,13 @@ class WsRequest {
|
|||
}
|
||||
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')));
|
||||
if (isPing && this.options.filterPing) {
|
||||
// 仍更新 lastPong,但不打印消息体,除非 showMessageBody 强制 true
|
||||
if (this.options.debug && this.options.showMessageBody === false) {
|
||||
this.log(this._label('onMessage'), type);
|
||||
}
|
||||
} else {
|
||||
// 打印消息类型与(可选)格式化消息体
|
||||
if (this.options.debug) {
|
||||
if (this.options.showMessageBody) {
|
||||
let bodyStr;
|
||||
|
|
@ -202,13 +249,12 @@ class WsRequest {
|
|||
}
|
||||
}
|
||||
|
||||
// 外部回调与订阅异步派发
|
||||
if (this.options.onMessage) setTimeout(() => this.options.onMessage(data, msg), 0);
|
||||
setTimeout(() => this._dispatch(type, data, msg), 0);
|
||||
}
|
||||
|
||||
_bindGlobalSocketEvents() {
|
||||
// 解绑默认全局再绑定,避免重复
|
||||
// 解绑默认全局再绑定,避免重复(但是本函数只会被调用一次,受静态保护)
|
||||
try { uni.offSocketOpen && uni.offSocketOpen(); } catch (e) {}
|
||||
try { uni.offSocketMessage && uni.offSocketMessage(); } catch (e) {}
|
||||
try { uni.offSocketClose && uni.offSocketClose(); } catch (e) {}
|
||||
|
|
@ -223,12 +269,15 @@ class WsRequest {
|
|||
this._startHeartbeat();
|
||||
this._flushQueue();
|
||||
this.options.onOpen && this.options.onOpen(res);
|
||||
|
||||
// 同上,打开时允许重连
|
||||
this._shouldReconnect = true;
|
||||
this._manualClose = false;
|
||||
});
|
||||
} catch (e) {}
|
||||
|
||||
try {
|
||||
uni.onSocketMessage(msg => {
|
||||
// 全局收到消息也走统一处理
|
||||
if (this.options.debug) this.log(this._label('globalOnMessage'));
|
||||
this._handleIncoming(msg);
|
||||
});
|
||||
|
|
@ -267,7 +316,8 @@ class WsRequest {
|
|||
const since = Date.now() - this._lastPongAt;
|
||||
if (since > this.options.heartbeatTimeout) {
|
||||
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.heartbeatInterval);
|
||||
|
|
@ -279,14 +329,26 @@ class WsRequest {
|
|||
}
|
||||
|
||||
_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; }
|
||||
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(() => {
|
||||
this.socketTask = null;
|
||||
this.connectIfForeground();
|
||||
}, delay);
|
||||
}, finalDelay);
|
||||
}
|
||||
|
||||
connectIfForeground() {
|
||||
|
|
|
|||
|
|
@ -3,25 +3,49 @@ import WsRequest from '@/common/websocket.js';
|
|||
|
||||
let globalWs = null;
|
||||
|
||||
const initWs = (url, options) => {
|
||||
// 如果已经有 WebSocket 实例,直接返回
|
||||
if (globalWs) return globalWs;
|
||||
const initWs = (url, options = {}) => {
|
||||
// 如果已经有 WebSocket 实例且 URL 相同,直接返回
|
||||
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;
|
||||
};
|
||||
|
||||
const connectWs = () => {
|
||||
if (globalWs) {
|
||||
globalWs.reconnectAttempts = 0; // 重置重连计数
|
||||
globalWs.open(); // 打开 WebSocket 连接
|
||||
}
|
||||
if (!globalWs) return;
|
||||
// 如果已经连接,直接返回,避免重复 open
|
||||
if (globalWs.connected) return;
|
||||
// 明确表示这是一次主动连接请求,允许自动重连
|
||||
globalWs.reconnectAttempts = 0;
|
||||
globalWs._shouldReconnect = true;
|
||||
globalWs._manualClose = false;
|
||||
globalWs.open();
|
||||
};
|
||||
|
||||
const closeWs = () => {
|
||||
if (globalWs) {
|
||||
globalWs.close(); // 关闭 WebSocket 连接
|
||||
const closeWs = (manual = true) => {
|
||||
if (!globalWs) return;
|
||||
// 主动关闭时先禁止自动重连
|
||||
if (manual) {
|
||||
globalWs._shouldReconnect = false;
|
||||
}
|
||||
// 传 manual 参数到 close,以便内部区分是否允许重连
|
||||
globalWs.close(1000, 'manager close', !!manual);
|
||||
// 如果你想下次重新 init 时创建新实例,可以把 globalWs 置空
|
||||
// globalWs = null;
|
||||
};
|
||||
|
||||
export { initWs, connectWs, closeWs };
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@
|
|||
// 支持对象和旧类型(String/Date/Number)
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
type: [String, Date, Number, Object],
|
||||
|
||||
default: null
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1186,7 +1186,7 @@
|
|||
},200)
|
||||
})
|
||||
onHide(() => {
|
||||
playall.value = false;
|
||||
photoplay.value = false;
|
||||
})
|
||||
const filteredMenu = (index : number) => {
|
||||
return leftMenuArray.value.filter(item => Number(item.areaFlag) - 1 == index);
|
||||
|
|
|
|||
|
|
@ -1728,12 +1728,12 @@
|
|||
}
|
||||
const savePackagelist = ref([]);
|
||||
onMounted(() => {
|
||||
// if(uni.getStorageSync('elderId')===null){
|
||||
// uni.setStorageSync('elderId', "");
|
||||
// }
|
||||
if(uni.getStorageSync('elderId')===null){
|
||||
uni.setStorageSync('elderId', "");
|
||||
}
|
||||
savePackagelist.value = uni.getStorageSync('Packagelist') || []
|
||||
let res = uni.getStorageSync('saveTree2')
|
||||
console.log("啥啊啊啊啊",savePackagelist.value,res)
|
||||
// console.log("啥啊啊啊啊",myArray)
|
||||
|
||||
let goodArray = []
|
||||
myArray.forEach((element : any) => {
|
||||
|
|
|
|||
|
|
@ -465,39 +465,60 @@
|
|||
width: 100%;
|
||||
height: 100rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
/* align-items: center; */
|
||||
/* background-color: red; */
|
||||
|
||||
.order-month {
|
||||
margin-left: 30rpx;
|
||||
font-size: 37rpx;
|
||||
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 {
|
||||
width: 440rpx;
|
||||
height: 100rpx;
|
||||
|
||||
/* background-color: red; */
|
||||
|
||||
.days-father {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 31rpx;
|
||||
margin-top: 20rpx;
|
||||
|
||||
.days {
|
||||
height: 75rpx;
|
||||
min-width: 75rpx;
|
||||
height: 59rpx;
|
||||
min-width: 59rpx;
|
||||
|
||||
margin: 0 8rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
/* background-color: red; */
|
||||
border-radius: 50%;
|
||||
/* color: #BBBABA; */
|
||||
}
|
||||
|
||||
.targetdays {
|
||||
height: 75rpx;
|
||||
min-width: 75rpx;
|
||||
height: 59rpx;
|
||||
min-width: 59rpx;
|
||||
|
||||
margin: 0 8rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
|
@ -517,46 +538,51 @@
|
|||
position: relative;
|
||||
|
||||
.history-spe {
|
||||
min-width: 86%;
|
||||
min-width: 88%;
|
||||
height: 100%;
|
||||
margin-left: 14%;
|
||||
margin-left: 11%;
|
||||
background-color: #F7F8F9;
|
||||
border-radius: 25rpx;
|
||||
padding-top: 10rpx;
|
||||
padding-left: 20rpx;
|
||||
/* position: relative; */
|
||||
|
||||
|
||||
.history-left-jiao {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 85rpx;
|
||||
right: 30rpx;
|
||||
top: 15rpx;
|
||||
width: 100rpx;
|
||||
height: 45rpx;
|
||||
background-color: #D9E5FF;
|
||||
background-color: #4690FF;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-top-right-radius: 25rpx;
|
||||
border-bottom-left-radius: 25rpx;
|
||||
color: #3C9CFD;
|
||||
font-size: 19rpx;
|
||||
border: 2rpx solid #4690FF;
|
||||
margin-top: 20rpx;
|
||||
margin-right: 30rpx;
|
||||
border-radius: 10rpx;
|
||||
color: #fff;
|
||||
font-size: 27rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.history-left-jiao-error {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 85rpx;
|
||||
right: 30rpx;
|
||||
top: 15rpx;
|
||||
width: 100rpx;
|
||||
height: 45rpx;
|
||||
background-color: #FFEBEB;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-top-right-radius: 25rpx;
|
||||
border-bottom-left-radius: 25rpx;
|
||||
border: 2rpx solid #F76E6E;
|
||||
margin-top: 20rpx;
|
||||
margin-right: 30rpx;
|
||||
border-radius: 10rpx;
|
||||
color: #F76E6E;
|
||||
font-size: 19rpx;
|
||||
font-size: 27rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
|
@ -564,27 +590,37 @@
|
|||
/* background-color: red; */
|
||||
.history-title {
|
||||
width: 100%;
|
||||
height: 70rpx;
|
||||
height: 80rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 30rpx;
|
||||
justify-content: space-between;
|
||||
|
||||
|
||||
.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;
|
||||
display:flex;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.history-right {
|
||||
margin-top: 0.5vw;
|
||||
width: 7vw;
|
||||
height: 2.5vw;
|
||||
height: 2.8vw;
|
||||
background: linear-gradient(to bottom, #009DEF, #0076FF);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 40rpx;
|
||||
border-radius: 10rpx;
|
||||
color: #fff;
|
||||
font-size: 28rpx;
|
||||
position: relative;
|
||||
|
|
@ -594,13 +630,14 @@
|
|||
.history-items {
|
||||
width: 100%;
|
||||
margin-top: 15rpx;
|
||||
height: 440rpx;
|
||||
height: 570rpx;
|
||||
/* background-color: red; */
|
||||
|
||||
.history-item {
|
||||
/* margin-left: 1%; */
|
||||
width: 95%;
|
||||
height: 120rpx;
|
||||
margin-bottom: 13rpx;
|
||||
height: 176rpx;
|
||||
margin-bottom: 20rpx;
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
|
@ -609,6 +646,7 @@
|
|||
.history-left {
|
||||
/* margin-left: 58rpx; */
|
||||
width: 120rpx;
|
||||
|
||||
}
|
||||
|
||||
.history-right {
|
||||
|
|
@ -655,10 +693,10 @@
|
|||
|
||||
.history-shu-up {
|
||||
position: absolute;
|
||||
left: 32rpx;
|
||||
left: 33rpx;
|
||||
bottom: calc(50% + 13rpx);
|
||||
width: 3rpx;
|
||||
height: 110rpx;
|
||||
height: 173rpx;
|
||||
background-color: #E5E5E5;
|
||||
transition: height 0.3s ease;
|
||||
|
||||
|
|
@ -669,8 +707,8 @@
|
|||
left: 20rpx;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 26.5rpx;
|
||||
height: 26.5rpx;
|
||||
width: 30rpx;
|
||||
height: 30rpx;
|
||||
border-radius: 50%;
|
||||
border: 4.5rpx solid #D0D1D1;
|
||||
z-index: 1;
|
||||
|
|
@ -681,30 +719,31 @@
|
|||
|
||||
.order-future {
|
||||
width: 100%;
|
||||
height: 640rpx;
|
||||
margin-top: -12rpx;
|
||||
height: 480rpx;
|
||||
/* margin-top: -12rpx; */
|
||||
position: relative;
|
||||
/* background-color: red; */
|
||||
|
||||
.future-items {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.future-fonts {
|
||||
font-size: 27rpx;
|
||||
font-size: 30rpx;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.future-item-target {
|
||||
width: 90%;
|
||||
margin-left: 5%;
|
||||
height: 152rpx;
|
||||
margin-bottom: 10rpx;
|
||||
height: 140rpx;
|
||||
margin-bottom: 20rpx;
|
||||
background-color: #F7F8F9;
|
||||
border-radius: 30rpx;
|
||||
/* padding: 25rpx; */
|
||||
padding-top: 25rpx;
|
||||
padding-top: 20rpx;
|
||||
padding-left: 25rpx;
|
||||
font-size: 25rpx;
|
||||
font-size: 30rpx;
|
||||
color: #555555;
|
||||
position: relative;
|
||||
border: 2rpx solid #4690FF;
|
||||
|
|
@ -715,14 +754,14 @@
|
|||
.future-item {
|
||||
width: 90%;
|
||||
margin-left: 5%;
|
||||
height: 152rpx;
|
||||
margin-bottom: 10rpx;
|
||||
height: 140rpx;
|
||||
margin-bottom: 20rpx;
|
||||
background-color: #F7F8F9;
|
||||
border-radius: 30rpx;
|
||||
/* padding: 25rpx; */
|
||||
padding-top: 25rpx;
|
||||
padding-top: 20rpx;
|
||||
padding-left: 25rpx;
|
||||
font-size: 25rpx;
|
||||
font-size: 30rpx;
|
||||
color: #555555;
|
||||
position: relative;
|
||||
border: 2rpx solid #F7F8F9;
|
||||
|
|
@ -732,13 +771,13 @@
|
|||
|
||||
.future-time {
|
||||
width: 100%;
|
||||
margin-top: 20rpx;
|
||||
margin-top: 12rpx;
|
||||
height: 50rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.time {
|
||||
font-size: 48rpx;
|
||||
font-size: 52rpx;
|
||||
font-weight: 800;
|
||||
color: black;
|
||||
}
|
||||
|
|
@ -747,7 +786,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
.future-tag {
|
||||
/* .future-tag {
|
||||
position: absolute;
|
||||
right: 23rpx;
|
||||
top: 23rpx;
|
||||
|
|
@ -761,7 +800,7 @@
|
|||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
} */
|
||||
|
||||
.future-info {
|
||||
position: absolute;
|
||||
|
|
@ -876,14 +915,14 @@
|
|||
|
||||
.time-right-bad {
|
||||
color: #666666;
|
||||
font-size: 24rpx;
|
||||
font-size: 27rpx;
|
||||
margin-left: 10rpx;
|
||||
margin-top: 10rpx;
|
||||
}
|
||||
|
||||
.time-right-blue {
|
||||
color: #4690FF;
|
||||
font-size: 24rpx;
|
||||
font-size: 27rpx;
|
||||
margin-left: 10rpx;
|
||||
margin-top: 10rpx;
|
||||
display: flex;
|
||||
|
|
@ -951,6 +990,7 @@
|
|||
.serviceContent {
|
||||
color: #999999;
|
||||
margin-top: 20rpx;
|
||||
font-size: 25rpx;
|
||||
}
|
||||
|
||||
.weight-time {
|
||||
|
|
@ -958,3 +998,7 @@
|
|||
font-size: 32rpx;
|
||||
margin-top: -5rpx;
|
||||
}
|
||||
.spec-shu{
|
||||
margin: 0 7rpx;
|
||||
color: #BABABA;
|
||||
}
|
||||
|
|
@ -108,6 +108,9 @@
|
|||
<view class="order-title">
|
||||
<view class="order-month" @click="dateshow()">
|
||||
{{ selectdata.month }}月
|
||||
<view class="order-month-right">
|
||||
|
||||
</view>
|
||||
</view>
|
||||
<scroll-view class="order-day" scroll-with-animation scroll-x :scroll-left="movetime">
|
||||
<view class="days-father">
|
||||
|
|
@ -128,7 +131,17 @@
|
|||
<view class="card-over">
|
||||
{{ item.directiveName }}
|
||||
</view>
|
||||
{{ ` | ` +item.serviceDuration + `分钟` }}
|
||||
<view class="spec-shu">
|
||||
|
|
||||
</view>
|
||||
|
||||
<text style="color: #4690FF;">
|
||||
每天
|
||||
</text>
|
||||
<view class="spec-shu">
|
||||
|
|
||||
</view>
|
||||
{{ item.serviceDuration + `分钟` }}
|
||||
</view>
|
||||
<view class="future-time">
|
||||
<text class="time">
|
||||
|
|
@ -145,9 +158,9 @@
|
|||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="future-tag">
|
||||
<!-- <view class="future-tag">
|
||||
{{ item.cycleType }}
|
||||
</view>
|
||||
</view> -->
|
||||
<view class="open-img-father" v-if="!item.tagtype"
|
||||
@click.stop="clickfirstarray(item,index);"
|
||||
:style="firstListTarget===index?{transform: `rotate(180deg)`}:{}">
|
||||
|
|
@ -157,15 +170,24 @@
|
|||
<view
|
||||
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="{
|
||||
height: firstListTarget === index ? '320rpx' : '152rpx',
|
||||
height: firstListTarget === index ? '300rpx' : '140rpx',
|
||||
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="card-over">
|
||||
{{ item.directiveName }}
|
||||
</view>
|
||||
{{ ` | ` +item.serviceDuration + `分钟` }}
|
||||
<view class="spec-shu">
|
||||
|
|
||||
</view>
|
||||
<text style="color: #4690FF;">
|
||||
每天
|
||||
</text>
|
||||
<view class="spec-shu">
|
||||
|
|
||||
</view>
|
||||
{{ item.serviceDuration + `分钟` }}
|
||||
</view>
|
||||
<view class="future-time">
|
||||
<text class="time">
|
||||
|
|
@ -182,9 +204,7 @@
|
|||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="future-tag">
|
||||
{{ item.cycleType }}
|
||||
</view>
|
||||
|
||||
<view class="future-info" v-if="firstListTarget===index">
|
||||
<view class="info" v-if="item.optType == 2">
|
||||
<image class="info-img" src="/static/index/leftpeople.png" lazy-load />
|
||||
|
|
@ -222,7 +242,9 @@
|
|||
</view>
|
||||
<view class="order-history">
|
||||
<view class="history-title">
|
||||
|
||||
<view class="history-left">
|
||||
<view class="history-blue"></view>
|
||||
服务指令
|
||||
</view>
|
||||
<view class="history-right">
|
||||
|
|
@ -241,7 +263,7 @@
|
|||
<view class="history-left">
|
||||
<view
|
||||
:class="item.executeStatus!==`hisOk`?`history-left-jiao-error`: `history-left-jiao`"
|
||||
style="top: 1.5rpx;right: 1.5rpx;"
|
||||
|
||||
v-show="secondListTargetShow !== index">
|
||||
{{ item.rightshow }}
|
||||
</view>
|
||||
|
|
@ -262,7 +284,7 @@
|
|||
<view class="history-spe"
|
||||
style="position: absolute;top: 0;left: 0;transition: height 0.3s, top 0.3s;z-index: 9999; "
|
||||
:style="{
|
||||
height: secondListTarget === index ? '260rpx' : '120rpx',
|
||||
height: secondListTarget === index ? '372rpx' : '176rpx',
|
||||
left: secondListTargetShow === index ? '0' : '999rpx',
|
||||
top: index === downmenuarray.length - 1 && secondListTarget === index ? '-140rpx' : '0rpx',
|
||||
border: moveById === item.id ? '2rpx solid #46B2F6' : '2rpx solid transparent'
|
||||
|
|
@ -270,7 +292,9 @@
|
|||
<view class="history-left">
|
||||
<view
|
||||
:class="item.executeStatus!==`hisOk`?`history-left-jiao-error`: `history-left-jiao`"
|
||||
v-show="secondListTargetShow === index">
|
||||
v-show="secondListTargetShow === index"
|
||||
|
||||
>
|
||||
{{ item.rightshow }}
|
||||
</view>
|
||||
<view class="history-time">
|
||||
|
|
@ -509,12 +533,13 @@
|
|||
}
|
||||
daysarray.value = Array.from({ length: endDay }, (_, i) => String(i + 1).padStart(2, '0'))
|
||||
// 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 clickday = (item : string, index : number) => {
|
||||
selectdata.value.day = item;
|
||||
movetime.value = (index - 2) * 25
|
||||
selectdata.value = JSON.parse(JSON.stringify(selectdata.value))
|
||||
movetime.value = (index - 2) * 37.5
|
||||
getTable()
|
||||
}
|
||||
const facedonghua = ref(false)
|
||||
|
|
@ -822,8 +847,8 @@
|
|||
getDirectiveOrders(time).then((data) => {
|
||||
firstListTarget.value = -1;
|
||||
secondListTarget.value = -1;
|
||||
// console.log("所有", data.result.all)
|
||||
// console.log("未来", data.result.future)
|
||||
// console.log("所有", time,uni.getStorageSync('serverUrl'),uni.getStorageSync('nuId'),uni.getStorageSync('elderId'))
|
||||
// console.log("未来", uni.getStorageSync('token'))
|
||||
data.result.current.forEach((element : any) => {
|
||||
element.tagtype = 0
|
||||
})
|
||||
|
|
@ -845,6 +870,7 @@
|
|||
}
|
||||
})
|
||||
downmenuarray.value = [...data.result.history]
|
||||
console.log("aaaaa", downmenuarray.value)
|
||||
timearr.value = Array.from({ length: 24 }, (_, hour) => ({
|
||||
positioning: hour.toString(),
|
||||
children: minuteArr.map(() => ({
|
||||
|
|
|
|||
|
|
@ -884,7 +884,7 @@
|
|||
nuId:nuId
|
||||
}
|
||||
queryCountByType(data).then(res=>{
|
||||
console.log(res)
|
||||
// console.log(res)
|
||||
hldyobj.value = res.result
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@
|
|||
if (len === 10) return '1.3vw' // 恰好10字
|
||||
if (len < 10) return '1.5vw' // 少于10字
|
||||
if (len <= 15) return '1.1vw' // 11~15字
|
||||
return '0.9vw' // 超过15字
|
||||
return '0.9vw' // 超过15字1
|
||||
})
|
||||
onHide(() => {
|
||||
playall.value = false;
|
||||
|
|
|
|||
Loading…
Reference in New Issue