ykt-team-wxapp/pages/message/survey-list.vue
2026-01-28 13:38:05 +08:00

447 lines
9.5 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

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

<template>
<view class="survey-page">
<view class="header">
<view class="search-bar">
<uni-icons type="search" size="18" color="#999" />
<input
class="search-input"
v-model="searchName"
placeholder="输入问卷名称搜索"
@input="handleSearch"
/>
</view>
</view>
<view class="content">
<view class="category-sidebar">
<scroll-view scroll-y class="category-scroll">
<view
v-for="cate in categoryList"
:key="cate._id || 'all'"
class="category-item"
:class="{ active: currentCateId === cate._id }"
@click="selectCategory(cate)"
>
{{ cate.label }}
</view>
</scroll-view>
</view>
<view class="survey-list">
<scroll-view
scroll-y
class="survey-scroll"
@scrolltolower="loadMore"
lower-threshold="50"
>
<view
v-if="loading && surveyList.length === 0"
class="loading-container"
>
<uni-icons type="spinner-cycle" size="30" color="#999" />
<text class="loading-text">加载中...</text>
</view>
<view v-else-if="surveyList.length === 0" class="empty-container">
<empty-data :title="emptyText || '暂无问卷'" />
</view>
<view v-else>
<view
v-for="survey in surveyList"
:key="survey._id"
class="survey-item"
>
<view class="survey-content" @click="previewSurvey(survey)">
<text class="survey-title">{{ survey.name }}</text>
<text class="survey-desc">{{
survey.description || "暂无问卷说明"
}}</text>
</view>
<view class="survey-action">
<button
class="send-btn"
size="mini"
type="primary"
@click="sendSurvey(survey)"
>
发送
</button>
</view>
</view>
<view v-if="loading && surveyList.length > 0" class="loading-more">
<uni-icons type="spinner-cycle" size="20" color="#999" />
<text>加载中...</text>
</view>
<view v-if="!loading && surveyList.length >= total" class="no-more">
没有更多了
</view>
</view>
</scroll-view>
</view>
</view>
</view>
</template>
<script setup>
import { ref, onMounted } from "vue";
import {
getSurveyCateList,
getSurveyList,
createSurveyRecord,
} from "@/utils/api.js";
import useAccountStore from "@/store/account.js";
import EmptyData from "@/components/empty-data.vue";
const env = __VITE_ENV__;
const accountStore = useAccountStore();
const corpId = env.MP_CORP_ID;
const userId = ref("");
// 搜索关键词
const searchName = ref("");
let searchTimer = null;
// 分类列表
const categoryList = ref([{ _id: "", label: "全部" }]);
const currentCateId = ref("");
// 问卷列表
const surveyList = ref([]);
const loading = ref(false);
const page = ref(1);
const pageSize = 30;
const total = ref(0);
const emptyText = ref("");
// 获取分类列表
const getCategoryList = async () => {
try {
const res = await getSurveyCateList({ corpId: corpId });
if (res.success && res.list) {
const cates = res.list || [];
categoryList.value = [{ _id: "", label: "全部" }, ...cates];
}
} catch (error) {
console.error("获取分类列表失败:", error);
}
};
// 选择分类
const selectCategory = (cate) => {
currentCateId.value = cate._id || "";
page.value = 1;
surveyList.value = [];
loadSurveyList();
};
// 搜索处理
const handleSearch = () => {
if (searchTimer) {
clearTimeout(searchTimer);
}
searchTimer = setTimeout(() => {
page.value = 1;
surveyList.value = [];
loadSurveyList();
}, 500);
};
// 加载问卷列表
const loadSurveyList = async () => {
if (loading.value) return;
loading.value = true;
try {
const params = {
corpId: corpId,
page: page.value,
pageSize: pageSize,
name: searchName.value.trim(),
status: "enable",
showCount: false,
};
// 如果选择了分类添加分类ID
if (currentCateId.value) {
params.cateIds = [currentCateId.value];
}
const res = await getSurveyList(params);
if (res.success && res) {
const { list = [], total: count = 0 } = res;
if (page.value === 1) {
surveyList.value = list;
} else {
surveyList.value = [...surveyList.value, ...list];
}
total.value = count;
emptyText.value = "暂无问卷信息";
} else {
emptyText.value = res.message || "加载失败";
uni.showToast({
title: res.message || "获取问卷列表失败",
icon: "none",
});
}
} catch (error) {
console.error("加载问卷列表失败:", error);
emptyText.value = "加载失败";
uni.showToast({
title: "加载失败,请重试",
icon: "none",
});
} finally {
loading.value = false;
}
};
// 加载更多
const loadMore = () => {
if (loading.value || surveyList.value.length >= total.value) return;
page.value += 1;
loadSurveyList();
};
// 预览问卷
const previewSurvey = (survey) => {
const timestamp = Date.now();
const previewUrl = `https://www.youcan365.com/surveyDev/#/pages/survey/survey?surveyId=${survey.surveyId}&t=${timestamp}`;
// #ifdef H5
window.open(previewUrl, '_blank');
// #endif
// #ifdef MP-WEIXIN
uni.navigateTo({
url: `/pages/webview/webview?url=${encodeURIComponent(previewUrl)}`
});
// #endif
// #ifdef APP-PLUS
plus.runtime.openURL(previewUrl);
// #endif
};
// 生成随机字符串
const generateRandomString = (length) => {
const chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
let result = "";
for (let i = 0; i < length; i++) {
result += chars.charAt(Math.floor(Math.random() * chars.length));
}
return result;
};
// 发送问卷
const sendSurvey = async (survey) => {
if (loading.value) return;
try {
loading.value = true;
// 获取医生信息
const doctorInfo = accountStore.doctorInfo;
userId.value = doctorInfo?.userid || accountStore.openid;
// 生成发送ID
const sendSurveyId = generateRandomString(10);
// 获取当前聊天的客户信息(从上一页传递)
const pages = getCurrentPages();
const prevPage = pages[pages.length - 2];
// 这里需要从聊天页面获取客户信息
// 暂时使用事件传递方式
uni.$emit("sendSurvey", {
survey: survey,
corpId: corpId,
userId: userId.value,
sendSurveyId: sendSurveyId,
});
uni.showToast({
title: "已选择问卷",
icon: "success",
});
// 延迟返回
setTimeout(() => {
uni.navigateBack();
}, 500);
} catch (error) {
console.error("发送问卷失败:", error);
uni.showToast({
title: error.message || "发送失败",
icon: "none",
});
} finally {
loading.value = false;
}
};
// 返回
const goBack = () => {
uni.navigateBack();
};
onMounted(() => {
getCategoryList();
loadSurveyList();
});
</script>
<style scoped lang="scss">
.survey-page {
display: flex;
flex-direction: column;
height: 100vh;
background-color: #f5f5f5;
}
.header {
background-color: #fff;
padding: 20rpx;
border-bottom: 1px solid #eee;
}
.search-bar {
display: flex;
align-items: center;
background-color: #f5f5f5;
border-radius: 8rpx;
padding: 16rpx 24rpx;
}
.search-input {
flex: 1;
margin-left: 16rpx;
font-size: 28rpx;
}
.content {
flex: 1;
display: flex;
overflow: hidden;
}
.category-sidebar {
width: 200rpx;
background-color: #f8f8f8;
border-right: 1px solid #eee;
}
.category-scroll {
height: 100%;
}
.category-item {
padding: 20rpx 24rpx;
font-size: 28rpx;
color: #333;
text-align: center;
border-bottom: 1px solid #eee;
transition: all 0.3s ease;
position: relative;
}
.category-item.active {
background-color: #fff;
color: #0877f1;
font-weight: bold;
border-left: 4rpx solid #0877f1;
}
.survey-list {
flex: 1;
background-color: #fff;
}
.survey-scroll {
height: 100%;
}
.loading-container,
.empty-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 100rpx 0;
}
.loading-text {
margin-top: 20rpx;
font-size: 28rpx;
color: #999;
}
.survey-item {
display: flex;
align-items: center;
padding: 24rpx 30rpx;
border-bottom: 1px solid #eee;
}
.survey-content {
flex: 1;
display: flex;
flex-direction: column;
margin-right: 20rpx;
}
.survey-title {
font-size: 28rpx;
color: #333;
font-weight: 500;
line-height: 1.5;
margin-bottom: 12rpx;
}
.survey-desc {
font-size: 24rpx;
color: #999;
line-height: 1.4;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.survey-action {
flex-shrink: 0;
}
.send-btn {
font-size: 26rpx;
}
.loading-more,
.no-more {
display: flex;
align-items: center;
justify-content: center;
padding: 30rpx 0;
font-size: 24rpx;
color: #999;
gap: 10rpx;
}
.footer {
background-color: #fff;
padding: 20rpx;
border-top: 1px solid #eee;
}
.cancel-btn {
width: 100%;
background-color: #fff;
color: #333;
border: 1px solid #ddd;
}
</style>