Compare commits

..

No commits in common. "ff7e135ef0db4a10cd56d1c22bf35b8fd2b68719" and "6122b1c509fb74e86373db8f88a6a049f0916b64" have entirely different histories.

25 changed files with 264 additions and 1879 deletions

View File

@ -6,28 +6,14 @@
</view> </view>
<view class="order-content"> <view class="order-content">
<view class="order-item"> <view class="order-item">
<image src="./images/icon_service.png" class="order-icon"></image> <image src="./images/icon_service.png" class="order-icon"></image>
<uni-data-select <text class="order-description">加一台麻将机</text>
v-if="!isCallSuccess && workOrderTypeList.length > 0"
class="order-select"
placeholder="请选择服务工单"
v-model="workOrderTypeName"
:localdata="workOrderTypeList"
@change="changeWorkOrderType"
></uni-data-select>
<text v-else class="order-description">{{ workOrderTypeName }}</text>
</view> </view>
<view class="order-line"></view> <view class="order-line"></view>
<view class="order-details"> <view class="order-details">
<view class="detail-item"> <view class="detail-item">
<text class="detail-label">房间号</text> <text class="detail-label">房间号</text>
<input <text class="detail-value">302</text>
v-if="!isCallSuccess"
class="detail-input"
placeholder="请填写房间号"
v-model="roomId"
/>
<text v-else class="detail-value">{{ roomId }}</text>
</view> </view>
<view class="detail-item"> <view class="detail-item">
<text class="detail-label">服务时间</text> <text class="detail-label">服务时间</text>
@ -56,12 +42,12 @@
<text v-else class="detail-value">{{ contactPhone }}</text> <text v-else class="detail-value">{{ contactPhone }}</text>
</view> </view>
</view> </view>
<!-- 呼叫前显示立即呼叫按钮 --> <!-- 呼叫前显示立即呼叫按钮 -->
<button v-if="!isCallSuccess" class="order-button" @click="handleCall"> <button v-if="!isCallSuccess" class="order-button" @click="handleCall">
立即呼叫 立即呼叫
</button> </button>
<!-- 呼叫成功后显示两个按钮 --> <!-- 呼叫成功后显示两个按钮 -->
<view v-else class="order-buttons"> <view v-else class="order-buttons">
<button class="order-button-secondary" @click="viewWorkOrder"> <button class="order-button-secondary" @click="viewWorkOrder">
@ -87,110 +73,69 @@ import { ref, onMounted, nextTick } from "vue";
import { SCROLL_TO_BOTTOM } from "@/constant/constant"; import { SCROLL_TO_BOTTOM } from "@/constant/constant";
import { createWorkOrder, workOrderTypeListForBiz } from "@/request/api/OrderApi"; import { createWorkOrder } from "@/request/api/OrderApi";
const workOrderTypeId = ref('')
const workOrderTypeName = ref('')
const roomId = ref('')
const contactName = ref(""); const contactName = ref("");
const contactPhone = ref(""); const contactPhone = ref("");
const isCallSuccess = ref(false); // const isCallSuccess = ref(false); //
const workOrderId = ref(0); // ID const workOrderId = ref(""); // ID
const workOrderTypeList = ref([])
const changeWorkOrderType = (item) => {
console.log(item)
workOrderTypeId.value = item.value
workOrderTypeName.value = item.text
}
const handleCall = async () => { const handleCall = async () => {
// //
if (!roomId.value.trim()) { if (!contactName.value.trim()) {
uni.showToast({ uni.showToast({
title: '请填写房间号', title: '请填写联系人',
icon: 'none', icon: 'none',
duration: 2000 duration: 2000
}); });
return; return;
} }
if (!contactPhone.value.trim()) {
uni.showToast({
title: '请填写联系电话',
icon: 'none',
duration: 2000
});
return;
}
if (!contactName.value.trim()) { try {
uni.showToast({ const res = await createWorkOrder({
title: '请填写联系人', contactName: contactName.value,
icon: 'none', contactPhone: contactPhone.value,
duration: 2000 workOrderTypeId: '1942741501754765314',
}); roomId: '302',
return; });
}
if (!contactPhone.value.trim()) { if (res.code === 0) {
uni.showToast({ // ID
title: '请填写联系电话', workOrderId.value = res.data?.id || "";
icon: 'none',
duration: 2000 //
}); isCallSuccess.value = true;
return;
}
sendCreateWorkOrder()
};
///
const sendCreateWorkOrder = async () => {
try {
const res = await createWorkOrder({
contactName: contactName.value,
contactPhone: contactPhone.value,
workOrderTypeId: workOrderTypeId.value,
roomId: roomId.value,
});
if (res.code === 0) {
// ID
workOrderId.value = res.data?.id || "";
//
isCallSuccess.value = true;
uni.showToast({
title: '工单创建成功',
icon: 'success',
duration: 2000
});
} else {
uni.showToast({
title: res.message || '创建工单失败',
icon: 'none',
duration: 2000
});
}
} catch (error) {
console.error('创建工单失败:', error);
uni.showToast({ uni.showToast({
title: '网络错误,请重试', title: '工单创建成功',
icon: 'success',
duration: 2000
});
} else {
uni.showToast({
title: res.message || '创建工单失败',
icon: 'none', icon: 'none',
duration: 2000 duration: 2000
}); });
} }
} } catch (error) {
console.error('创建工单失败:', error);
/// uni.showToast({
const getWorkOrderType = async () => { title: '网络错误,请重试',
const res = await workOrderTypeListForBiz() icon: 'none',
if(res.code === 0) { duration: 2000
res.data.forEach((item, index) => { });
workOrderTypeList.value.push({ }
value: item.id, };
text: item.workOrderTypeName,
})
})
if (workOrderTypeList.value.length > 0) {
workOrderTypeId.value = workOrderTypeList.value[0].value
workOrderTypeName.value = workOrderTypeList.value[0].text
}
}
}
// //
const viewWorkOrder = () => { const viewWorkOrder = () => {
@ -228,12 +173,11 @@ const makePhoneCall = () => {
}; };
onMounted(() => { onMounted(() => {
getWorkOrderType() nextTick(() => {
nextTick(() => { setTimeout(() => {
setTimeout(() => { uni.$emit(SCROLL_TO_BOTTOM, true)
uni.$emit(SCROLL_TO_BOTTOM, true) }, 200)
}, 200) });
});
}) })
</script> </script>

View File

@ -107,15 +107,6 @@
border-bottom: 1px solid #ddd; border-bottom: 1px solid #ddd;
} }
.order-select {
border: none;
outline: none;
width: 100%;
font-size: 14px;
color: #999;
border-bottom: 1px solid #ddd;
}
.order-button { .order-button {
width: 280px; width: 280px;
height: 42px; height: 42px;

View File

@ -14,7 +14,7 @@
v-for="(item, index) in thumbnails" v-for="(item, index) in thumbnails"
:key="index" :key="index"
> >
<image :src="item.imageUrl" mode="aspectFill"></image> <image :src="item.photoUrl" mode="aspectFill"></image>
</swiper-item> </swiper-item>
</swiper> </swiper>
@ -39,8 +39,8 @@
:id="`thumbnail-${index}`" :id="`thumbnail-${index}`"
@click="handleThumbnailClick(index)" @click="handleThumbnailClick(index)"
> >
<image :src="thumb.imageUrl" mode="aspectFill"></image> <image :src="thumb.photoUrl" mode="aspectFill"></image>
<text>{{ thumb.name }}</text> <text>{{ thumb.photoName }}</text>
</view> </view>
</view> </view>
</scroll-view> </scroll-view>
@ -106,35 +106,35 @@ const swiperStyle = computed(() => {
// //
const defaultImages = [ const defaultImages = [
{ {
imageUrl: photoUrl:
"https://one-feel-image-bucket.oss-cn-chengdu.aliyuncs.com/DH04006.jpg", "https://fastly.picsum.photos/id/866/654/400.jpg?hmac=z3vI4CYrpnXEgimSlJCDwXRxEa-UDHiRwzGEyB8V-po",
name: "瑶山古寨", photoName: "瑶山古寨",
}, },
{ {
imageUrl: photoUrl:
"https://one-feel-image-bucket.oss-cn-chengdu.aliyuncs.com/DH04002.JPG", "https://fastly.picsum.photos/id/284/654/400.jpg?hmac=89XRCJxYTblKIFGLOp6hJ9U0GC8BQrcnJwE5pG21NAk",
name: "民俗表演", photoName: "民俗表演",
}, },
{ {
imageUrl: photoUrl:
"https://one-feel-image-bucket.oss-cn-chengdu.aliyuncs.com/DH04007.jpg", "https://fastly.picsum.photos/id/281/654/400.jpg?hmac=hcAJB7y2Xz3DVuz6S4XeQZgzaTJ_QWnxtbnaagZL6Fs",
name: "特色美食", photoName: "特色美食",
}, },
{ {
imageUrl: photoUrl:
"https://one-feel-image-bucket.oss-cn-chengdu.aliyuncs.com/DH04014.JPG", "https://fastly.picsum.photos/id/435/654/400.jpg?hmac=TSVDxfo-zXbunxNQK0erSG_nmKcS20xfhbQsCAXLlHo",
name: "传统服饰", photoName: "传统服饰",
}, },
{ {
imageUrl: photoUrl:
"https://one-feel-image-bucket.oss-cn-chengdu.aliyuncs.com/DH04020.JPG", "https://fastly.picsum.photos/id/737/654/400.jpg?hmac=VED05oEK3XB0Aa_DUVoZjTAf0bHjAmNYyJky4lq5vVo",
name: "其他", photoName: "其他",
}, },
]; ];
// 使 // 使
const thumbnails = computed(() => { const thumbnails = computed(() => {
return props.images; return props.images.length ? props.images : defaultImages;
}); });
const handleThumbnailClick = (index) => { const handleThumbnailClick = (index) => {

View File

@ -29,7 +29,7 @@
position: absolute; position: absolute;
left: 12px; left: 12px;
right: 12px; right: 12px;
bottom: 0px; bottom: 36px;
height: 60px; height: 60px;
} }

View File

@ -57,12 +57,6 @@
item.toolCall.componentName === CompName.createWorkOrderCard item.toolCall.componentName === CompName.createWorkOrderCard
" "
/> />
<DetailCardCompontent
v-else-if="
item.toolCall.componentName === ''
"
:toolCall="item.toolCall"
/>
</template> </template>
<template #footer> <template #footer>
@ -146,7 +140,6 @@ import ActivityListComponent from "../module/banner/ActivityListComponent.vue";
import RecommendPostsComponent from "../module/recommend/RecommendPostsComponent.vue"; import RecommendPostsComponent from "../module/recommend/RecommendPostsComponent.vue";
import AttachListComponent from "../module/attach/AttachListComponent.vue"; import AttachListComponent from "../module/attach/AttachListComponent.vue";
import CreateServiceOrder from "@/components/CreateServiceOrder/index.vue"; import CreateServiceOrder from "@/components/CreateServiceOrder/index.vue";
import DetailCardCompontent from "../module/detail/DetailCardCompontent.vue";
import { mainPageData } from "@/request/api/MainPageDataApi"; import { mainPageData } from "@/request/api/MainPageDataApi";
import { import {
conversationMsgList, conversationMsgList,
@ -351,12 +344,12 @@ const initWebSocket = () => {
// //
onError: (error) => { onError: (error) => {
isSessionActive.value = false;
console.error("WebSocket错误:", error); console.error("WebSocket错误:", error);
}, },
// //
onMessage: (data) => { onMessage: (data) => {
console.log("onMessage:", data);
handleWebSocketMessage(data); handleWebSocketMessage(data);
}, },
@ -375,16 +368,12 @@ const initWebSocket = () => {
// WebSocket // WebSocket
const handleWebSocketMessage = (data) => { const handleWebSocketMessage = (data) => {
if(loadingTimer) {
clearInterval(loadingTimer);
loadingTimer = null;
}
const aiMsgIndex = chatMsgList.value.length - 1; const aiMsgIndex = chatMsgList.value.length - 1;
if (!chatMsgList.value[aiMsgIndex] || aiMsgIndex < 0) { if (!chatMsgList.value[aiMsgIndex] || aiMsgIndex < 0) {
return; return;
} }
//console.log("WebSocket:", data); console.log("处理WebSocket消息:", data);
// //
if (data.content && typeof data.content !== "string") { if (data.content && typeof data.content !== "string") {
@ -416,15 +405,6 @@ const handleWebSocketMessage = (data) => {
return; return;
} }
const msg = chatMsgList.value[aiMsgIndex].msg;
console.log('全量消息内容:', msg)
if (!msg || msg === '加载中.' || msg.startsWith('加载中')) {
chatMsgList.value[aiMsgIndex].msg = '未获取到内容,请重试';
if(data.toolCall) {
chatMsgList.value[aiMsgIndex].msg = '';
}
}
// toolCall // toolCall
if (data.toolCall) { if (data.toolCall) {
chatMsgList.value[aiMsgIndex].toolCall = data.toolCall; chatMsgList.value[aiMsgIndex].toolCall = data.toolCall;
@ -464,7 +444,7 @@ const initTypewriterManager = () => {
// //
setTimeout(() => { setTimeout(() => {
scrollTop.value = 99999 + Math.random(); scrollTop.value = 99999 + Math.random();
}, 20); }, 5);
}); });
}, },
// //
@ -512,7 +492,7 @@ const addNoticeListener = () => {
if (value && value.length > 0) { if (value && value.length > 0) {
commonType = "Command.quickBooking"; commonType = "Command.quickBooking";
sendMessage(value, true); sendMessage(value, true);
setTimeoutScrollToBottom(); scrollToBottom();
} }
}); });
}; };
@ -584,6 +564,8 @@ const sendMessage = (message, isInstruct = false) => {
// WebSocket // WebSocket
const sendWebSocketMessage = (messageType, messageContent, options = {}) => { const sendWebSocketMessage = (messageType, messageContent, options = {}) => {
console.error("WebSocket未连接");
const args = { const args = {
conversationId: conversationId.value, conversationId: conversationId.value,
agentId: agentId.value, agentId: agentId.value,
@ -607,6 +589,7 @@ const sendWebSocketMessage = (messageType, messageContent, options = {}) => {
const sendChat = (message, isInstruct = false) => { const sendChat = (message, isInstruct = false) => {
if (!webSocketManager || !webSocketManager.isConnected()) { if (!webSocketManager || !webSocketManager.isConnected()) {
console.error("WebSocket未连接"); console.error("WebSocket未连接");
return; return;
} }

View File

@ -30,7 +30,7 @@ const handleClick = (item) => {
} }
onMounted(() => { onMounted(() => {
tags.value = props.question.split(/[&|;]/).filter(tag => tag.trim() !== '') tags.value = props.question.split('&').filter(tag => tag.trim() !== '')
nextTick(() => { nextTick(() => {
setTimeout(() => { setTimeout(() => {
uni.$emit(SCROLL_TO_BOTTOM, true) uni.$emit(SCROLL_TO_BOTTOM, true)

View File

@ -1,35 +0,0 @@
<template>
<view class="container">
<template v-if="toolCall.picture && toolCall.picture.length > 0">
<ModuleTitle :title="图片详情" />
<ImageSwiper :images="toolCall.picture" />
</template>
<template v-if="toolCall.commodityList">
<DetailCardGoodsContentList :commodityList="toolCall.commodityList" />
</template>
</view>
</template>
<script setup>
import { defineProps } from 'vue'
import ModuleTitle from '@/components/ModuleTitle/index.vue'
import ImageSwiper from '@/components/ImageSwiper/index.vue'
import DetailCardGoodsContentList from './DetailCardGoodsContentList.vue'
const props = defineProps({
toolCall: {
type: Object,
default: {}
}
})
</script>
<style scoped lang="scss">
.container {
width: 100%;
}
</style>

View File

@ -1,198 +0,0 @@
<template>
<view class="container">
<ModuleTitle title="相关商品" />
<view class="container-scroll">
<view class="mk-card-item" v-for="(item, index) in commodityList" :key="`${item.commodityId}-${index}`">
<image class="card-img" :src="item.commodityPhoto" mode="aspectFill" />
<view class="card-content">
<view class="card-title-column">
<text class="card-title">{{ item.commodityName }}</text>
<view class="card-tags" v-for="(tag) in item.commodityTradeRuleList" :key="tag">
<text class="card-tag">{{ tag }}</text>
</view>
</view>
<template v-for="(serviceItem, index) in item.commodityServices" :key="serviceItem.serviceTitle">
<view v-if="index < 3" class="card-desc">· {{ serviceItem.serviceTitle }}</view>
</template>
<view class="card-bottom-row">
<view class="card-price-row">
<text class="card-price-fu"></text>
<text class="card-price">{{ item.specificationPrice }}</text>
<text class="card-unit">/</text>
</view>
<text class="card-btn" @click="placeOrderHandle(item)">下单</text>
</view>
</view>
</view>
</view>
</view>
</template>
<script setup>
import ModuleTitle from '@/components/ModuleTitle/index.vue'
import { defineProps } from 'vue'
const props = defineProps({
commodityList: {
type: Array,
default: []
}
})
///
const placeOrderHandle = (item) => {
uni.navigateTo({
url: `/pages/goods/index?commodityId=${item.commodityId}`,
})
}
</script>
<style lang="scss" scoped>
.container {
margin-bottom: 8px 0;
.container-scroll {
display: flex;
flex-direction: row;
overflow-x: auto;
overflow-y: hidden;
margin: 4px 0;
/* 隐藏滚动条 */
scrollbar-width: none;
&::-webkit-scrollbar {
display: none;
}
.mk-card-item {
position: relative;
display: flex;
flex-direction: column;
align-items: start;
width: 188px;
// height: 244px;
background-color: #ffffff;
border-radius: 10px;
margin-right: 8px;
padding-bottom: 12px;
.card-badge {
position: absolute;
top: 8px;
left: 8px;
background: #ffe7b2;
color: #b97a00;
font-size: 12px;
padding: 2px 8px;
border-radius: 4px;
z-index: 2;
}
.card-img {
width: 188px;
height: 114px;
border-radius: 10px;
object-fit: cover; /* 确保图片不变形,保持比例裁剪 */
flex-shrink: 0; /* 防止图片被压缩 */
}
.card-content {
box-sizing: border-box;
padding: 10px 12px 0 12px;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: start;
width: 100%;
flex: 1; /* 让内容区域占据剩余空间 */
overflow: hidden; /* 防止内容溢出 */
}
.card-title-column {
display: flex;
align-items: start;
flex-direction: column;
width: 100%;
}
.card-title {
font-size: 16px;
font-weight: bold;
color: #222;
width: 100%;
/* 限制标题最多显示两行 */
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
text-overflow: ellipsis;
line-height: 1.4;
max-height: 2.8em; /* 2行的高度 */
}
.card-tags {
display: flex;
flex-direction: row;
align-items: start;
padding: 6px 0;
}
.card-tag {
background: #f5f5f5;
color: #ff6600;
font-size: 12px;
border-radius: 4px;
padding: 0 6px;
margin-left: 2px;
}
.card-desc {
font-size: 13px;
color: #888;
margin-top: 2px;
}
.card-bottom-row {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 8px;
width: 100%;
}
.card-price-row {
.card-price-fu {
color: #ff6600;
font-size: 11px;
font-weight: normal;
}
.card-price {
color: #ff6600;
font-size: 16px;
font-weight: bold;
}
.card-unit {
font-size: 11px;
color: #888;
font-weight: normal;
margin-left: 2px;
}
}
.card-btn {
background: #ff6600;
color: #fff;
font-size: 15px;
border-radius: 20px;
padding: 0 18px;
height: 32px;
line-height: 32px;
}
}
}
}
</style>

View File

@ -21,14 +21,13 @@
themeDTOList.value = res.data.themeDTOList themeDTOList.value = res.data.themeDTOList
nextTick(() => { nextTick(() => {
setTimeout(() => { uni.$emit(SCROLL_TO_BOTTOM, true)
uni.$emit(SCROLL_TO_BOTTOM, true)
}, 300)
}); });
} }
} }
onMounted(() => { onMounted(() => {
console.log('=============')
loadDiscoveryCradComponent() loadDiscoveryCradComponent()
}) })

View File

@ -32,8 +32,7 @@
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.container { .container {
width: 100%;
} }
.container-scroll { .container-scroll {

View File

@ -1,5 +1,4 @@
import { BASE_URL } from "../../constant/base"; import { BASE_URL } from "../../constant/base";
import { goLogin } from "@/hooks/useGoLogin";
/// 请求流式数据的API /// 请求流式数据的API
const API = '/agent/assistant/chat'; const API = '/agent/assistant/chat';
@ -10,197 +9,171 @@ const API = '/agent/assistant/chat';
* @param {Function} onChunk 回调每收到一段数据触发 * @param {Function} onChunk 回调每收到一段数据触发
* @returns {Object} 包含Promise和requestTask的对象 * @returns {Object} 包含Promise和requestTask的对象
*/ */
// 在文件顶部重新设计状态追踪
let requestTask = null; let requestTask = null;
let isAborted = false; let isAborted = false; // 添加终止状态标志
let currentPromiseReject = null; let currentPromiseReject = null; // 保存当前Promise的reject函数
let lastRequestId = null; // 记录上一次请求ID let requestId = 0; // 请求ID用于区分不同的请求
let activeRequestId = null; // 记录当前活动请求ID
/**
* 终止的请求
*/
const stopAbortTask = () => { const stopAbortTask = () => {
console.log("🛑 开始强制终止请求... "); console.log('🛑 开始强制终止请求...');
isAborted = true; isAborted = true; // 立即设置终止标志
// 将当前活动请求ID保存为上一次请求ID // 立即拒绝当前Promise最强制的终止
lastRequestId = activeRequestId; if (currentPromiseReject) {
// 清除当前活动请求ID console.log('🛑 立即拒绝Promise');
activeRequestId = null; currentPromiseReject(new Error('请求已被用户终止'));
currentPromiseReject = null;
}
if (currentPromiseReject) { if (requestTask) {
currentPromiseReject(new Error('请求已被用户终止')); // 先取消所有监听器关键必须在abort之前
currentPromiseReject = null; try {
} if (requestTask.offChunkReceived) {
requestTask.offChunkReceived();
console.log('🛑 已取消 ChunkReceived 监听');
}
} catch (e) {
console.log('🛑 取消 ChunkReceived 监听失败:', e);
}
try {
if (requestTask.offHeadersReceived) {
requestTask.offHeadersReceived();
console.log('🛑 已取消 HeadersReceived 监听');
}
} catch (e) {
console.log('🛑 取消 HeadersReceived 监听失败:', e);
}
if (requestTask) { // 然后终止网络请求
// 先移除监听器,再终止请求 try {
const cleanupListeners = () => { if (requestTask.abort) {
try { requestTask.abort();
if(requestTask.offChunkReceived) { console.log('🛑 已终止网络请求');
console.log("======>offChunkReceived") }
requestTask.offChunkReceived(); } catch (e) {
} console.log('🛑 终止网络请求失败:', e);
if(requestTask.offHeadersReceived) { }
console.log("======>offHeadersReceived")
requestTask.offHeadersReceived();
}
} catch (e) {
console.error('清理事件监听器失败:', e);
}
};
cleanupListeners(); requestTask = null;
}
// 终止请求
try { // 递增请求ID使旧请求的数据无效
if (requestTask.abort) { requestId++;
console.log("======>abort") console.log('🛑 请求强制终止完成新请求ID:', requestId);
requestTask.abort();
}
} catch (e) {
console.log('🛑 终止网络请求失败:', e);
}
requestTask = null;
}
console.log('🛑 请求强制终止完成');
} }
const agentChatStream = (params, onChunk) => { const agentChatStream = (params, onChunk) => {
return new Promise((resolve, reject) => { const promise = new Promise((resolve, reject) => {
const token = uni.getStorageSync('token'); const token = uni.getStorageSync('token');
const requestId = Date.now().toString(); // 生成唯一请求ID let hasError = false;
isAborted = false; // 重置终止状态
// 重置状态
isAborted = false; // 保存当前Promise的reject函数用于强制终止
currentPromiseReject = reject; currentPromiseReject = reject;
// 更新请求ID追踪 // 为当前请求分配ID
lastRequestId = activeRequestId; // 保存上一次请求ID const currentRequestId = ++requestId;
activeRequestId = requestId; // 设置新的活动请求ID console.log("🚀 发送请求内容: ", params, "请求ID:", currentRequestId)
// #ifdef MP-WEIXIN
console.log(`🚀 发送请求 [${requestId}], 上一次请求ID [${lastRequestId}]`); requestTask = uni.request({
url: BASE_URL + API, // 替换为你的接口地址
// 检查数据块是否来自已终止的请求 method: 'POST',
const isStaleData = (dataRequestId) => { data: params,
return dataRequestId === lastRequestId || dataRequestId !== activeRequestId; enableChunked: true,
}; header: {
Accept: 'text/event-stream',
// #ifdef MP-WEIXIN 'Content-Type': 'application/json',
requestTask = uni.request({ Authorization: `Bearer ${token}`, // 如需token可加
url: BASE_URL + API, // 替换为你的接口地址 },
method: 'POST', responseType: 'arraybuffer',
data: params, success(res) {
enableChunked: true, if (!isAborted && requestId === currentRequestId) {
header: { console.log("✅ 请求成功ID:", currentRequestId);
Accept: 'text/event-stream', resolve(res.data);
'Content-Type': 'application/json', } else {
Authorization: `Bearer ${token}`, // 如需token可加 console.log("❌ 请求已过期或终止忽略success回调当前ID:", requestId, "请求ID:", currentRequestId);
}, }
responseType: 'arraybuffer', },
success(res) { fail(err) {
if (!isAborted && !isStaleData(requestId)) { if (!isAborted && requestId === currentRequestId) {
console.log(`✅ 请求 [${requestId}] 成功`); console.log("❌ 请求失败ID:", currentRequestId, "错误:", JSON.stringify(err));
resolve(res.data); reject(err);
} else { } else {
console.log(`❌ 请求 [${requestId}] 已终止或过期忽略success回调`); console.log("❌ 请求已过期或终止忽略fail回调当前ID:", requestId, "请求ID:", currentRequestId);
} }
}, },
fail(err) { complete(res) {
if (!isAborted && activeRequestId === requestId) { if (!isAborted && requestId === currentRequestId && res.statusCode !== 200) {
console.log(`❌ 请求 [${requestId}] 失败:`, JSON.stringify(err)); console.log("❌ 请求完成但状态错误ID:", currentRequestId, "状态:", res.statusCode);
reject(err); if (onChunk) {
} else { onChunk({ error: true, message: '服务器错误', detail: res });
console.log(`❌ 请求 [${requestId}] 已终止或过期忽略fail回调`); }
} reject(res);
}, } else if (requestId !== currentRequestId) {
complete(res) { console.log("❌ 请求已过期或终止忽略complete回调当前ID:", requestId, "请求ID:", currentRequestId);
// 使用 requestId 来验证请求有效性 }
if (!isAborted && activeRequestId === requestId) {
if (res.statusCode !== 200) {
console.log(`❌ 请求 [${requestId}] 完成但状态错误,状态:`, res.statusCode);
if(res.statusCode === 424) {
uni.setStorageSync('token', '');
goLogin();
} }
if (onChunk) { });
onChunk({
error: true, requestTask.onHeadersReceived(res => {
message: '服务器错误', // 检查请求是否已终止或过期
detail: res if (isAborted || requestId !== currentRequestId) {
}); console.log('🚫 Headers已终止或过期忽略当前ID:', requestId, '请求ID:', currentRequestId);
return;
} }
reject(res);
} console.log('📡 onHeadersReceivedID:', currentRequestId, res);
} else { const status = res.statusCode || (res.header && res.header.statusCode);
console.log(`❌ 请求 [${requestId}] ${isAborted ? '已终止' : '已过期'}忽略complete回调`); if (status && status !== 200) {
} hasError = true;
} if (onChunk && !isAborted && requestId === currentRequestId) {
onChunk({ error: true, message: `服务器错误(${status})`, detail: res });
}
if (requestTask && requestTask.abort) {
requestTask.abort();
}
}
});
requestTask.onChunkReceived(res => {
// 第一道防线立即检查请求ID和终止状态
if (isAborted || hasError || requestTask === null || requestId !== currentRequestId) {
console.log('🚫 数据块已终止或过期,忽略 - 第一道检查当前ID:', requestId, '请求ID:', currentRequestId);
return;
}
console.log("📦 onChunkReceivedID:", currentRequestId, res)
const base64 = uni.arrayBufferToBase64(res.data);
let data = '';
try {
data = decodeURIComponent(escape(weAtob(base64)));
} catch (e) {
// 某些平台可能不支持 atob可以直接用 base64
data = base64;
}
// 第二道防线:解析前再次检查
if (isAborted || hasError || requestTask === null || requestId !== currentRequestId) {
console.log('🚫 数据块已终止或过期,忽略 - 第二道检查当前ID:', requestId, '请求ID:', currentRequestId);
return;
}
const messages = parseSSEChunk(data);
messages.forEach(msg => {
// 第三道防线:每个消息处理前都检查
if (onChunk && !isAborted && !hasError && requestTask !== null && requestId === currentRequestId) {
console.log(`parseSSEChunk ${currentRequestId}:`, msg)
onChunk(msg);
} else {
console.log('🚫 消息已终止或过期忽略处理当前ID:', requestId, '请求ID:', currentRequestId);
}
});
});
// #endif
}); });
requestTask.onHeadersReceived(res => { return promise
// 使用 requestId 验证请求有效性
if (isAborted || activeRequestId !== requestId) {
console.log(`🚫 Headers [${requestId}] ${isAborted ? '已终止' : '已过期'},忽略`);
return;
}
console.log(`📡 请求 [${requestId}] Headers接收:`, res);
const status = res.statusCode || (res.header && res.header.statusCode);
if (status && status !== 200) {
console.log(`❌ 请求 [${requestId}] 服务器返回错误状态:`, status);
if (onChunk && !isAborted && activeRequestId === requestId) {
onChunk({
error: true,
message: `服务器错误(${status})`,
detail: res
});
}
// 终止异常请求
if (requestTask && requestTask.abort) {
requestTask.abort();
}
}
});
requestTask.onChunkReceived(res => {
// 立即验证请求有效性
if (isAborted || isStaleData(requestId)) {
console.log(`🚫 数据块 [${requestId}] 已终止或过期,忽略`);
return;
}
const base64 = uni.arrayBufferToBase64(res.data);
let data = '';
try {
data = decodeURIComponent(escape(weAtob(base64)));
} catch (e) {
console.error('Base64解码失败:', e);
return;
}
console.log("📦 onChunkReceivedres:", data)
// 再次验证请求有效性
if (isAborted || activeRequestId !== requestId) {
console.log(`🚫 解析后数据 [${requestId}] 已终止或过期,忽略`);
return;
}
const messages = parseSSEChunk(data);
messages.forEach(msg => {
if (!isAborted && !isStaleData(requestId) && onChunk) {
onChunk(msg);
}
});
});
// #endif
});
} }
// window.atob兼容性处理 // window.atob兼容性处理
@ -253,37 +226,23 @@ const weAtob = (string) => {
// 解析SSE分段数据 // 解析SSE分段数据
const parseSSEChunk = (raw) => { function parseSSEChunk(raw) {
const results = []; // 拆分为多段
const lines = raw.split('\n\n');
// 按一个或多个连续换行分段,表示每一个事件块 const results = [];
const chunks = raw.split(/\n\n+/); lines.forEach(line => {
// 只处理包含 data: 的行
for (const chunk of chunks) { const dataMatch = line.match(/data:(\{.*\})/);
const lines = chunk.split(/\r?\n/); if (dataMatch && dataMatch[1]) {
let dataLines = []; try {
const obj = JSON.parse(dataMatch[1]);
for (const line of lines) { results.push(obj);
if (line.startsWith('data:')) { } catch (e) {
// 提取data:后面的内容并去除首尾空格 // 解析失败忽略
dataLines.push(line.slice(5).trim()); }
} }
} });
return results;
if (dataLines.length > 0) {
// 拼接多行数据
const fullData = dataLines.join('\n');
try {
const obj = JSON.parse(fullData);
results.push(obj);
} catch (e) {
console.warn('⚠️ SSE数据解析失败:', e, '原始数据:', fullData);
// 解析失败忽略
}
}
}
return results;
} }
export { agentChatStream, stopAbortTask } export { agentChatStream, stopAbortTask }

View File

@ -9,13 +9,8 @@ const userWorkOrderList = (args) => {
return request.post("/hotelBiz/workOrder/userWorkOrderList", args); return request.post("/hotelBiz/workOrder/userWorkOrderList", args);
}; };
/// 获取工单类型
const workOrderTypeListForBiz = () => {
return request.get('/hotelBiz/workOrder/workOrderTypeListForBiz', {});
}
/// 创建工单 /// 创建工单
const createWorkOrder = (args) => { function createWorkOrder(args) {
return request.post('/hotelBiz/workOrder/createWorkOrder', args); return request.post('/hotelBiz/workOrder/createWorkOrder', args);
} }
@ -47,7 +42,6 @@ const orderPayNow = (args) => {
export { export {
userOrderList, userOrderList,
userWorkOrderList, userWorkOrderList,
workOrderTypeListForBiz,
createWorkOrder, createWorkOrder,
userOrderDetail, userOrderDetail,
preOrder, preOrder,

View File

@ -1,43 +0,0 @@
## 1.0.102025-04-14
- 修复 清除按钮不展示问题
## 1.0.92025-03-26
- 优化 默认背景为白色与整体组件保持风格统一
## 1.0.82024-03-28
- 修复 在vue2下:style动态绑定导致编译失败的bug
## 1.0.72024-01-20
- 修复 长文本回显超过容器的bug超过容器部分显示省略号
## 1.0.62023-04-12
- 修复 微信小程序点击时会改变背景颜色的 bug
## 1.0.52023-02-03
- 修复 禁用时会显示清空按钮
## 1.0.42023-02-02
- 优化 查询条件短期内多次变更只查询最后一次变更后的结果
- 调整 内部缓存键名调整为 uni-data-select-lastSelectedValue
## 1.0.32023-01-16
- 修复 不关联服务空间报错的问题
## 1.0.22023-01-14
- 新增 属性 `format` 可用于格式化显示选项内容
## 1.0.12022-12-06
- 修复 当where变化时数据不会自动更新的问题
## 0.1.92022-09-05
- 修复 微信小程序下拉框出现后选择会点击到蒙板后面的输入框
## 0.1.82022-08-29
- 修复 点击的位置不准确
## 0.1.72022-08-12
- 新增 支持 disabled 属性
## 0.1.62022-07-06
- 修复 pc端宽度异常的bug
## 0.1.5
- 修复 pc端宽度异常的bug
## 0.1.42022-07-05
- 优化 显示样式
## 0.1.32022-06-02
- 修复 localdata 赋值不生效的 bug
- 新增 支持 uni.scss 修改颜色
- 新增 支持选项禁用(数据选项设置 disabled: true 即禁用)
## 0.1.22022-05-08
- 修复 当 value 为 0 时选择不生效的 bug
## 0.1.12022-05-07
- 新增 记住上次的选项(仅 collection 存在时有效)
## 0.1.02022-04-22
- 初始化

View File

@ -1,562 +0,0 @@
<template>
<view class="uni-stat__select">
<span v-if="label" class="uni-label-text hide-on-phone">{{label + ''}}</span>
<view class="uni-stat-box" :class="{'uni-stat__actived': current}">
<view class="uni-select" :class="{'uni-select--disabled':disabled}">
<view class="uni-select__input-box" @click="toggleSelector">
<view v-if="current" class="uni-select__input-text">{{textShow}}</view>
<view v-else class="uni-select__input-text uni-select__input-placeholder">{{typePlaceholder}}</view>
<view key="clear-button" v-if="current && clear && !disabled" @click.stop="clearVal">
<uni-icons type="clear" color="#c0c4cc" size="24" />
</view>
<view key="arrow-button" v-else>
<uni-icons :type="showSelector? 'top' : 'bottom'" size="14" color="#999" />
</view>
</view>
<view class="uni-select--mask" v-if="showSelector" @click="toggleSelector" />
<view class="uni-select__selector" :style="getOffsetByPlacement" v-if="showSelector">
<view :class="placement=='bottom'?'uni-popper__arrow_bottom':'uni-popper__arrow_top'"></view>
<scroll-view scroll-y="true" class="uni-select__selector-scroll">
<view class="uni-select__selector-empty" v-if="mixinDatacomResData.length === 0">
<text>{{emptyTips}}</text>
</view>
<view v-else class="uni-select__selector-item" v-for="(item,index) in mixinDatacomResData" :key="index"
@click="change(item)">
<text :class="{'uni-select__selector__disabled': item.disable}">{{formatItemName(item)}}</text>
</view>
</scroll-view>
</view>
</view>
</view>
</view>
</template>
<script>
/**
* DataChecklist 数据选择器
* @description 通过数据渲染的下拉框组件
* @tutorial https://uniapp.dcloud.io/component/uniui/uni-data-select
* @property {String} value 默认值
* @property {Array} localdata 本地数据 格式 [{text:'',value:''}]
* @property {Boolean} clear 是否可以清空已选项
* @property {Boolean} emptyText 没有数据时显示的文字 本地数据无效
* @property {String} label 左侧标题
* @property {String} placeholder 输入框的提示文字
* @property {Boolean} disabled 是否禁用
* @property {String} placement 弹出位置
* @value top 顶部弹出
* @value bottom 底部弹出default)
* @event {Function} change 选中发生变化触发
*/
export default {
name: "uni-data-select",
mixins: [uniCloud.mixinDatacom || {}],
props: {
localdata: {
type: Array,
default () {
return []
}
},
value: {
type: [String, Number],
default: ''
},
modelValue: {
type: [String, Number],
default: ''
},
label: {
type: String,
default: ''
},
placeholder: {
type: String,
default: '请选择'
},
emptyTips: {
type: String,
default: '无选项'
},
clear: {
type: Boolean,
default: true
},
defItem: {
type: Number,
default: 0
},
disabled: {
type: Boolean,
default: false
},
// field="_id as value, version as text, uni_platform as label" format="{label} - {text}"
format: {
type: String,
default: ''
},
placement: {
type: String,
default: 'bottom'
}
},
data() {
return {
showSelector: false,
current: '',
mixinDatacomResData: [],
apps: [],
channels: [],
cacheKey: "uni-data-select-lastSelectedValue",
};
},
created() {
this.debounceGet = this.debounce(() => {
this.query();
}, 300);
if (this.collection && !this.localdata.length) {
this.debounceGet();
}
},
computed: {
typePlaceholder() {
const text = {
'opendb-stat-app-versions': '版本',
'opendb-app-channels': '渠道',
'opendb-app-list': '应用'
}
const common = this.placeholder
const placeholder = text[this.collection]
return placeholder ?
common + placeholder :
common
},
valueCom() {
// #ifdef VUE3
return this.modelValue;
// #endif
// #ifndef VUE3
return this.value;
// #endif
},
textShow() {
//
let text = this.current;
return text;
},
getOffsetByPlacement() {
switch (this.placement) {
case 'top':
return "bottom:calc(100% + 12px);";
case 'bottom':
return "top:calc(100% + 12px);";
}
}
},
watch: {
localdata: {
immediate: true,
handler(val, old) {
if (Array.isArray(val) && old !== val) {
this.mixinDatacomResData = val
}
}
},
valueCom(val, old) {
this.initDefVal()
},
mixinDatacomResData: {
immediate: true,
handler(val) {
if (val.length) {
this.initDefVal()
}
}
},
},
methods: {
debounce(fn, time = 100) {
let timer = null
return function(...args) {
if (timer) clearTimeout(timer)
timer = setTimeout(() => {
fn.apply(this, args)
}, time)
}
},
//
query() {
this.mixinDatacomEasyGet();
},
//
onMixinDatacomPropsChange() {
if (this.collection) {
this.debounceGet();
}
},
initDefVal() {
let defValue = ''
if ((this.valueCom || this.valueCom === 0) && !this.isDisabled(this.valueCom)) {
defValue = this.valueCom
} else {
let strogeValue
if (this.collection) {
strogeValue = this.getCache()
}
if (strogeValue || strogeValue === 0) {
defValue = strogeValue
} else {
let defItem = ''
if (this.defItem > 0 && this.defItem <= this.mixinDatacomResData.length) {
defItem = this.mixinDatacomResData[this.defItem - 1].value
}
defValue = defItem
}
if (defValue || defValue === 0) {
this.emit(defValue)
}
}
const def = this.mixinDatacomResData.find(item => item.value === defValue)
this.current = def ? this.formatItemName(def) : ''
},
/**
* @param {[String, Number]} value
* 判断用户给的 value 是否同时为禁用状态
*/
isDisabled(value) {
let isDisabled = false;
this.mixinDatacomResData.forEach(item => {
if (item.value === value) {
isDisabled = item.disable
}
})
return isDisabled;
},
clearVal() {
this.emit('')
this.current = ''
if (this.collection) {
this.removeCache()
}
},
change(item) {
if (!item.disable) {
this.showSelector = false
this.current = this.formatItemName(item)
this.emit(item.value)
}
},
emit(val) {
this.$emit('input', val)
this.$emit('update:modelValue', val)
this.$emit('change', val)
if (this.collection) {
this.setCache(val);
}
},
toggleSelector() {
if (this.disabled) {
return
}
this.showSelector = !this.showSelector
},
formatItemName(item) {
let {
text,
value,
channel_code
} = item
channel_code = channel_code ? `(${channel_code})` : ''
if (this.format) {
//
let str = "";
str = this.format;
for (let key in item) {
str = str.replace(new RegExp(`{${key}}`, "g"), item[key]);
}
return str;
} else {
return this.collection.indexOf('app-list') > 0 ?
`${text}(${value})` :
(
text ?
text :
`未命名${channel_code}`
)
}
},
//
getLoadData() {
return this.mixinDatacomResData;
},
// key
getCurrentCacheKey() {
return this.collection;
},
//
getCache(name = this.getCurrentCacheKey()) {
let cacheData = uni.getStorageSync(this.cacheKey) || {};
return cacheData[name];
},
//
setCache(value, name = this.getCurrentCacheKey()) {
let cacheData = uni.getStorageSync(this.cacheKey) || {};
cacheData[name] = value;
uni.setStorageSync(this.cacheKey, cacheData);
},
//
removeCache(name = this.getCurrentCacheKey()) {
let cacheData = uni.getStorageSync(this.cacheKey) || {};
delete cacheData[name];
uni.setStorageSync(this.cacheKey, cacheData);
},
}
}
</script>
<style lang="scss">
$uni-base-color: #6a6a6a !default;
$uni-main-color: #333 !default;
$uni-secondary-color: #909399 !default;
$uni-border-3: #e5e5e5;
/* #ifndef APP-NVUE */
@media screen and (max-width: 500px) {
.hide-on-phone {
display: none;
}
}
/* #endif */
.uni-stat__select {
display: flex;
align-items: center;
// padding: 15px;
/* #ifdef H5 */
cursor: pointer;
/* #endif */
width: 100%;
flex: 1;
box-sizing: border-box;
}
.uni-stat-box {
background-color: #fff;
width: 100%;
flex: 1;
}
.uni-stat__actived {
width: 100%;
flex: 1;
// outline: 1px solid #2979ff;
}
.uni-label-text {
font-size: 14px;
font-weight: bold;
color: $uni-base-color;
margin: auto 0;
margin-right: 5px;
}
.uni-select {
font-size: 14px;
border: 1px solid $uni-border-3;
box-sizing: border-box;
border-radius: 4px;
padding: 0 5px;
padding-left: 10px;
position: relative;
/* #ifndef APP-NVUE */
display: flex;
user-select: none;
/* #endif */
flex-direction: row;
align-items: center;
border-bottom: solid 1px $uni-border-3;
width: 100%;
flex: 1;
height: 35px;
&--disabled {
background-color: #f5f7fa;
cursor: not-allowed;
}
}
.uni-select__label {
font-size: 16px;
// line-height: 22px;
height: 35px;
padding-right: 10px;
color: $uni-secondary-color;
}
.uni-select__input-box {
height: 35px;
width: 0px;
position: relative;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex: 1;
flex-direction: row;
align-items: center;
}
.uni-select__input {
flex: 1;
font-size: 14px;
height: 22px;
line-height: 22px;
}
.uni-select__input-plac {
font-size: 14px;
color: $uni-secondary-color;
}
.uni-select__selector {
/* #ifndef APP-NVUE */
box-sizing: border-box;
/* #endif */
position: absolute;
left: 0;
width: 100%;
background-color: #FFFFFF;
border: 1px solid #EBEEF5;
border-radius: 6px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
z-index: 3;
padding: 4px 0;
}
.uni-select__selector-scroll {
/* #ifndef APP-NVUE */
max-height: 200px;
box-sizing: border-box;
/* #endif */
}
/* #ifdef H5 */
@media (min-width: 768px) {
.uni-select__selector-scroll {
max-height: 600px;
}
}
/* #endif */
.uni-select__selector-empty,
.uni-select__selector-item {
/* #ifndef APP-NVUE */
display: flex;
cursor: pointer;
/* #endif */
line-height: 35px;
font-size: 14px;
text-align: center;
/* border-bottom: solid 1px $uni-border-3; */
padding: 0px 10px;
}
.uni-select__selector-item:hover {
background-color: #f9f9f9;
}
.uni-select__selector-empty:last-child,
.uni-select__selector-item:last-child {
/* #ifndef APP-NVUE */
border-bottom: none;
/* #endif */
}
.uni-select__selector__disabled {
opacity: 0.4;
cursor: default;
}
/* picker 弹出层通用的指示小三角 */
.uni-popper__arrow_bottom,
.uni-popper__arrow_bottom::after,
.uni-popper__arrow_top,
.uni-popper__arrow_top::after,
{
position: absolute;
display: block;
width: 0;
height: 0;
border-color: transparent;
border-style: solid;
border-width: 6px;
}
.uni-popper__arrow_bottom {
filter: drop-shadow(0 2px 12px rgba(0, 0, 0, 0.03));
top: -6px;
left: 10%;
margin-right: 3px;
border-top-width: 0;
border-bottom-color: #EBEEF5;
}
.uni-popper__arrow_bottom::after {
content: " ";
top: 1px;
margin-left: -6px;
border-top-width: 0;
border-bottom-color: #fff;
}
.uni-popper__arrow_top {
filter: drop-shadow(0 2px 12px rgba(0, 0, 0, 0.03));
bottom: -6px;
left: 10%;
margin-right: 3px;
border-bottom-width: 0;
border-top-color: #EBEEF5;
}
.uni-popper__arrow_top::after {
content: " ";
bottom: 1px;
margin-left: -6px;
border-bottom-width: 0;
border-top-color: #fff;
}
.uni-select__input-text {
// width: 280px;
width: 100%;
color: $uni-main-color;
white-space: nowrap;
text-overflow: ellipsis;
-o-text-overflow: ellipsis;
overflow: hidden;
}
.uni-select__input-placeholder {
color: $uni-base-color;
font-size: 12px;
}
.uni-select--mask {
position: fixed;
top: 0;
bottom: 0;
right: 0;
left: 0;
z-index: 2;
}
</style>

View File

@ -1,88 +0,0 @@
{
"id": "uni-data-select",
"displayName": "uni-data-select 下拉框选择器",
"version": "1.0.10",
"description": "通过数据驱动的下拉框选择器",
"keywords": [
"uni-ui",
"select",
"uni-data-select",
"下拉框",
"下拉选"
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": "^3.1.1"
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
"type": "component-vue"
},
"uni_modules": {
"dependencies": ["uni-load-more"],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y",
"alipay": "n"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "n",
"app-harmony": "u",
"app-uvue": "u"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "u",
"百度": "u",
"字节跳动": "u",
"QQ": "u",
"京东": "u"
},
"快应用": {
"华为": "u",
"联盟": "u"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
}

View File

@ -1,8 +0,0 @@
## DataSelect 下拉框选择器
> **组件名uni-data-select**
> 代码块: `uDataSelect`
当选项过多时,使用下拉菜单展示并选择内容
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-data-select)
#### 如使用过程中有任何问题或者您对uni-ui有一些好的建议欢迎加入 uni-ui 交流群871950839

View File

@ -1,25 +0,0 @@
## 1.3.62024-10-15
- 修复 微信小程序中的getSystemInfo警告
## 1.3.52024-10-12
- 修复 微信小程序中的getSystemInfo警告
## 1.3.42024-10-12
- 修复 微信小程序中的getSystemInfo警告
## 1.3.32022-01-20
- 新增 showText属性 ,是否显示文本
## 1.3.22022-01-19
- 修复 nvue 平台下不显示文本的bug
## 1.3.12022-01-19
- 修复 微信小程序平台样式选择器报警告的问题
## 1.3.02021-11-19
- 优化 组件UI并提供设计资源详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-load-more](https://uniapp.dcloud.io/component/uniui/uni-load-more)
## 1.2.12021-08-24
- 新增 支持国际化
## 1.2.02021-07-30
- 组件兼容 vue3如何创建vue3项目详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 1.1.82021-05-12
- 新增 组件示例地址
## 1.1.72021-03-30
- 修复 uni-load-more 在首页使用时h5 平台报 'uni is not defined' 的 bug
## 1.1.62021-02-05
- 调整为uni_modules目录规范

View File

@ -1,5 +0,0 @@
{
"uni-load-more.contentdown": "Pull up to show more",
"uni-load-more.contentrefresh": "loading...",
"uni-load-more.contentnomore": "No more data"
}

View File

@ -1,8 +0,0 @@
import en from './en.json'
import zhHans from './zh-Hans.json'
import zhHant from './zh-Hant.json'
export default {
en,
'zh-Hans': zhHans,
'zh-Hant': zhHant
}

View File

@ -1,5 +0,0 @@
{
"uni-load-more.contentdown": "上拉显示更多",
"uni-load-more.contentrefresh": "正在加载...",
"uni-load-more.contentnomore": "没有更多数据了"
}

View File

@ -1,5 +0,0 @@
{
"uni-load-more.contentdown": "上拉顯示更多",
"uni-load-more.contentrefresh": "正在加載...",
"uni-load-more.contentnomore": "沒有更多數據了"
}

File diff suppressed because one or more lines are too long

View File

@ -1,84 +0,0 @@
{
"id": "uni-load-more",
"displayName": "uni-load-more 加载更多",
"version": "1.3.6",
"description": "LoadMore 组件,常用在列表里面,做滚动加载使用。",
"keywords": [
"uni-ui",
"uniui",
"加载更多",
"load-more"
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": ""
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
"type": "component-vue"
},
"uni_modules": {
"dependencies": ["uni-scss"],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y",
"alipay": "n"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y"
},
"快应用": {
"华为": "u",
"联盟": "u"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
}

View File

@ -1,14 +0,0 @@
### LoadMore 加载更多
> **组件名uni-load-more**
> 代码块: `uLoadMore`
用于列表中,做滚动加载使用,展示 loading 的各种状态。
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-load-more)
#### 如使用过程中有任何问题或者您对uni-ui有一些好的建议欢迎加入 uni-ui 交流群871950839

View File

@ -342,7 +342,7 @@ export class WebSocketManager {
data: messageStr, data: messageStr,
success: () => { success: () => {
this.stats.messagesSent++; this.stats.messagesSent++;
//console.log("消息发送成功:", messageData); console.log("消息发送成功:", messageData);
}, },
fail: (error) => { fail: (error) => {
console.error("发送消息失败:", error); console.error("发送消息失败:", error);
@ -356,7 +356,7 @@ export class WebSocketManager {
// 标准 WebSocket 环境 // 标准 WebSocket 环境
this.ws.send(messageStr); this.ws.send(messageStr);
this.stats.messagesSent++; this.stats.messagesSent++;
//console.log("消息发送成功:", messageData); console.log("消息发送成功:", messageData);
} }
return true; return true;