feat:问卷列表下拉加载更多

This commit is contained in:
du.meimei
2025-03-17 19:39:07 +08:00
parent 55b9f47b25
commit df8368612f
5 changed files with 186 additions and 162 deletions

1
components.d.ts vendored
View File

@@ -32,6 +32,7 @@ declare module 'vue' {
VanGrid: typeof import('vant/es')['Grid'] VanGrid: typeof import('vant/es')['Grid']
VanGridItem: typeof import('vant/es')['GridItem'] VanGridItem: typeof import('vant/es')['GridItem']
VanIcon: typeof import('vant/es')['Icon'] VanIcon: typeof import('vant/es')['Icon']
VanList: typeof import('vant/es')['List']
VanNavBar: typeof import('vant/es')['NavBar'] VanNavBar: typeof import('vant/es')['NavBar']
VanPicker: typeof import('vant/es')['Picker'] VanPicker: typeof import('vant/es')['Picker']
VanPopup: typeof import('vant/es')['Popup'] VanPopup: typeof import('vant/es')['Popup']

View File

@@ -52,8 +52,8 @@
<martrix-question <martrix-question
v-if=" v-if="
element.question_type === 8 || element.question_type === 8 ||
element.question_type === 9 || element.question_type === 9 ||
element.question_type === 10 element.question_type === 10
" "
:element="computedElement(element)" :element="computedElement(element)"
:index="index" :index="index"

View File

@@ -20,7 +20,7 @@ const marketList = ref([]);
const active = ref(null); const active = ref(null);
const marketInfo = ref([]); const marketInfo = ref([]);
const getTableList = async() => { const getTableList = async () => {
const res = await getListScene(); const res = await getListScene();
if (res.data.code === 0) { if (res.data.code === 0) {
res.data.data.forEach((item) => { res.data.data.forEach((item) => {
@@ -31,7 +31,7 @@ const getTableList = async() => {
getMarketInfo(marketList.value[0]); getMarketInfo(marketList.value[0]);
} }
}; };
const getMarketInfo = async(item) => { const getMarketInfo = async (item) => {
const data = marketList.value.filter((market, index) => item === index)[0]; const data = marketList.value.filter((market, index) => item === index)[0];
if (data) { if (data) {
const params = { const params = {

View File

@@ -1,70 +1,77 @@
<template> <template>
<div class="new-survey-container container"> <div class="new-survey-container container">
<div v-for="item in survey" :key="item" class="new-survey_item"> <van-list
<!-- 问卷详情 --> v-model:loading="loading"
<div class="survey_item_info"> :finished="finished"
<div style="position: relative"> finished-text="没有更多了"
<div class="survey_item_info_title"> @load="onLoad"
>
<div v-for="item in survey" :key="item" class="new-survey_item">
<!-- 问卷详情 -->
<div class="survey_item_info">
<div style="position: relative">
<div class="survey_item_info_title">
<el-text>
<b>{{ item.project_name }}</b>
</el-text>
<el-text>{{ item.answer_num }}</el-text>
</div>
<div class="survey_item_info_status">
<el-space spacer="|">
<!--报名签到-->
<div>
<span><img src="" alt="" /></span>
<el-text size="small">{{ item.scene_name }}</el-text>
</div>
<!-- 问卷来源 -->
<div>
<span><img src="" alt="" /></span>
<el-text size="small">{{ item.source === 1 ? '移动端' : 'PC端' }}</el-text>
</div>
<!-- 问卷时间 -->
<div>
<span><img src="" alt="" /></span>
<el-text size="small">{{ item.created_at }}</el-text>
</div>
</el-space>
</div>
<div class="survey_item_status">
<span class="survey_item_info_status_text">-{{ item.status_txt }}-</span>
</div>
</div>
<!--问卷描述-->
<div v-if="item.remarks" class="survey_item_info_desc">
<el-text> <el-text>
<b>{{ item.project_name }}</b> {{ item.remarks }}
</el-text> </el-text>
<el-text>{{ item.answer_num }}</el-text>
</div>
<div class="survey_item_info_status">
<el-space spacer="|">
<!--报名签到-->
<div>
<span><img src="" alt="" /></span>
<el-text size="small">{{ item.scene_name }}</el-text>
</div>
<!-- 问卷来源 -->
<div>
<span><img src="" alt="" /></span>
<el-text size="small">{{ item.source === 1 ? '移动端' : 'PC端' }}</el-text>
</div>
<!-- 问卷时间 -->
<div>
<span><img src="" alt="" /></span>
<el-text size="small">{{ item.created_at }}</el-text>
</div>
</el-space>
</div>
<div class="survey_item_status">
<span class="survey_item_info_status_text">-{{ item.status_txt }}-</span>
</div> </div>
</div> </div>
<!--问卷描述--> <!-- action 功能位置 -->
<div v-if="item.remarks" class="survey_item_info_desc"> <div class="survey_item_action">
<el-text> <!-- <el-space direction="horizontal">-->
{{ item.remarks }} <div>
</el-text> <el-button @click="deleteItem(item)"> 删除</el-button>
<el-button @click="copyItem(item)"> 复制</el-button>
<el-button @click="toPreview(item)" style="border: 2px solid #71b73c">
<el-text style="color: #71b73c">预览</el-text>
</el-button>
<el-button @click="toPublish(item)" color="#6fb937">
<el-text style="color: white">开启投放</el-text>
</el-button>
</div>
<el-dropdown placement="top-end" trigger="click" style="">
<Io5EllipsisHorizontalSharp />
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item>编辑</el-dropdown-item>
<el-dropdown-item>存为模板</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
<!-- </el-space>-->
</div> </div>
</div> </div>
<!-- action 功能位置 --> </van-list>
<div class="survey_item_action">
<!-- <el-space direction="horizontal">-->
<div>
<el-button @click="deleteItem(item)"> 删除</el-button>
<el-button @click="copyItem(item)"> 复制</el-button>
<el-button style="border: 2px solid #71b73c" @click="toPreiview(item)">
<el-text style="color: #71b73c">预览</el-text>
</el-button>
<el-button color="#6fb937" @click="toPublish(item)">
<el-text style="color: white">开启投放</el-text>
</el-button>
</div>
<el-dropdown placement="top-end" trigger="click" style="">
<Io5EllipsisHorizontalSharp />
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item>编辑</el-dropdown-item>
<el-dropdown-item>存为模板</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
<!-- </el-space>-->
</div>
</div>
</div> </div>
</template> </template>
@@ -76,12 +83,22 @@ import { showDialog, showFailToast, showSuccessToast, showToast } from 'vant';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
const router = useRouter(); const router = useRouter();
const survey = ref([]); const survey = ref([]);
const total = ref(0);
const loading = ref(false);
const finished = ref(false);
const form = ref({ const form = ref({
page: 1, page: 0,
pageSize: 10 pageSize: 10
}); });
const fetchSurveys = async() => { const onLoad = () => {
// 异步更新数据
setTimeout(() => {
form.value.page = form.value.page + 1;
fetchSurveys();
}, 500);
};
const fetchSurveys = async () => {
const params = { const params = {
page: form.value.page, page: form.value.page,
per_page: form.value.pageSize, per_page: form.value.pageSize,
@@ -89,7 +106,8 @@ const fetchSurveys = async() => {
}; };
const res = await getSurveysPage(params); const res = await getSurveysPage(params);
if (res.data.code === 0) { if (res.data.code === 0) {
survey.value = res.data.data; survey.value = survey.value.concat(res.data.data);
total.value = res.data.meta.total;
survey.value.forEach((item) => { survey.value.forEach((item) => {
const sceneName = JSON.parse(JSON.stringify(item.scene_name)); const sceneName = JSON.parse(JSON.stringify(item.scene_name));
const nameList = sceneName.split('-'); const nameList = sceneName.split('-');
@@ -102,6 +120,11 @@ const fetchSurveys = async() => {
item.created_at = timeList[0]; item.created_at = timeList[0];
} }
}); });
loading.value = false;
// 数据全部加载完成
if (survey.value.length >= total.value) {
finished.value = true;
}
} else { } else {
// Toast() // Toast()
} }
@@ -112,7 +135,7 @@ const deleteItem = (item) => {
showCancelButton: true, showCancelButton: true,
confirmButtonColor: '#03B03C' confirmButtonColor: '#03B03C'
}) })
.then(async() => { .then(async () => {
const res = await deleteSurveys(item.sn); const res = await deleteSurveys(item.sn);
if (res.data.message) { if (res.data.message) {
showToast(res.data.message); showToast(res.data.message);
@@ -136,7 +159,7 @@ const copyItem = (item) => {
showCancelButton: true, showCancelButton: true,
confirmButtonColor: '#03B03C' confirmButtonColor: '#03B03C'
}) })
.then(async() => { .then(async () => {
const res = await copySurveys(item.sn); const res = await copySurveys(item.sn);
if (res.data.code === 200 || res.data.code === 201) { if (res.data.code === 200 || res.data.code === 201) {
showSuccessToast('复制成功'); showSuccessToast('复制成功');
@@ -150,7 +173,7 @@ const copyItem = (item) => {
// on cancel // on cancel
}); });
}; };
const toPreiview = (item) => { const toPreview = (item) => {
router.push({ router.push({
path: '/preview', path: '/preview',
query: { query: {
@@ -169,7 +192,7 @@ const toPublish = (item) => {
}); });
}; };
onMounted(() => { onMounted(() => {
fetchSurveys(); // fetchSurveys();
}); });
</script> </script>

View File

@@ -675,9 +675,9 @@ async function answer(callback, callbackBeforePage) {
question.error = translatedText.value.ThisIsARequiredQuestion; question.error = translatedText.value.ThisIsARequiredQuestion;
} }
} else if ( } else if (
answer answer &&
&& questionType === 1 questionType === 1 &&
&& Object.keys(answer).findIndex((value) => !answer[value]) !== -1 Object.keys(answer).findIndex((value) => !answer[value]) !== -1
) { ) {
// 单选题 // 单选题
isError = true; isError = true;
@@ -852,51 +852,51 @@ async function answer(callback, callbackBeforePage) {
const { value } = answer; const { value } = answer;
const newValue = value.replace(/\n|\r|\r\n/g, ''); const newValue = value.replace(/\n|\r|\r\n/g, '');
switch (config.text_type) { switch (config.text_type) {
// 字母 // 字母
case 3: case 3:
isError isError =
= config.include_mark === 1 config.include_mark === 1
? !/^[a-zA-Z·~@#¥%……&*()——\-+={}|《》?:“”【】、;‘’,。、`~!@#$%^&*()_\-+=<>?:"{}|,./;'\\[\]]+$/.test( ? !/^[a-zA-Z·~@#¥%……&*()——\-+={}|《》?:“”【】、;‘’,。、`~!@#$%^&*()_\-+=<>?:"{}|,./;'\\[\]]+$/.test(
newValue newValue
) || !newValue.length ) || !newValue.length
: !/^[a-zA-Z]+$/.test(newValue) || !newValue.length; : !/^[a-zA-Z]+$/.test(newValue) || !newValue.length;
question.error = isError ? translatedText.value.PleaseEnterEnglishLetters : ''; question.error = isError ? translatedText.value.PleaseEnterEnglishLetters : '';
break; break;
// 中文 // 中文
case 4: case 4:
isError isError =
= config.include_mark === 1 config.include_mark === 1
? !/^(?:[\u3400-\u4DB5\u4E00-\u9FEA\uFA0E\uFA0F\uFA11\uFA13\uFA14\uFA1F\uFA21\uFA23\uFA24\uFA27-\uFA29]|[\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|[·~@#¥%……&*()——\-+={}|《》?:“”【】、;‘’,。、`~!@#$%^&*()_\-+=<>?:"{}|,./;'\\[\]])+$/.test( ? !/^(?:[\u3400-\u4DB5\u4E00-\u9FEA\uFA0E\uFA0F\uFA11\uFA13\uFA14\uFA1F\uFA21\uFA23\uFA24\uFA27-\uFA29]|[\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|[·~@#¥%……&*()——\-+={}|《》?:“”【】、;‘’,。、`~!@#$%^&*()_\-+=<>?:"{}|,./;'\\[\]])+$/.test(
newValue newValue
) || !newValue.length ) || !newValue.length
: !/^(?:[\u3400-\u4DB5\u4E00-\u9FEA\uFA0E\uFA0F\uFA11\uFA13\uFA14\uFA1F\uFA21\uFA23\uFA24\uFA27-\uFA29]|[\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0])+$/.test( : !/^(?:[\u3400-\u4DB5\u4E00-\u9FEA\uFA0E\uFA0F\uFA11\uFA13\uFA14\uFA1F\uFA21\uFA23\uFA24\uFA27-\uFA29]|[\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0])+$/.test(
newValue newValue
) || !newValue.length; ) || !newValue.length;
question.error = isError ? translatedText.value.PleaseEnterChineseWords : ''; question.error = isError ? translatedText.value.PleaseEnterChineseWords : '';
break; break;
// 邮箱 // 邮箱
case 5: case 5:
isError isError =
= !/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test( !/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(
value value
); );
question.error = isError ? translatedText.value.PleaseEnterACorrectEmail : ''; question.error = isError ? translatedText.value.PleaseEnterACorrectEmail : '';
break; break;
// 手机号 // 手机号
case 6: case 6:
isError = !/^(?:(?:\+|00)86)?1[3-9]\d{9}$/.test(value); isError = !/^(?:(?:\+|00)86)?1[3-9]\d{9}$/.test(value);
question.error = isError ? translatedText.value.PleaseEnterACorrectPhone : ''; question.error = isError ? translatedText.value.PleaseEnterACorrectPhone : '';
break; break;
// 身份证号 // 身份证号
case 7: case 7:
isError isError =
= !/^[1-9]\d{5}(?:18|19|20)\d{2}(?:0[1-9]|10|11|12)(?:0[1-9]|[1-2]\d|30|31)\d{3}[\dXx]$/.test( !/^[1-9]\d{5}(?:18|19|20)\d{2}(?:0[1-9]|10|11|12)(?:0[1-9]|[1-2]\d|30|31)\d{3}[\dXx]$/.test(
value value
); );
question.error = isError ? translatedText.value.PleaseEnterACorrectID : ''; question.error = isError ? translatedText.value.PleaseEnterACorrectID : '';
break; break;
default: default:
break; break;
} }
if (!isError && value.length < config.min && ![1, 2].includes(config.text_type)) { if (!isError && value.length < config.min && ![1, 2].includes(config.text_type)) {
isError = true; isError = true;
@@ -908,54 +908,54 @@ async function answer(callback, callbackBeforePage) {
Object.keys(answer).forEach((key) => { Object.keys(answer).forEach((key) => {
const value = answer[key]; const value = answer[key];
switch (config.text_type) { switch (config.text_type) {
// 字母 // 字母
case 3: case 3:
if ( if (
!/^[a-zA-Z·~@#¥%……&*()——\-+={}|《》?:“”【】、;‘’,。、`~!@#$%^&*()_\-+=<>?:"{}|,./;'\\[\]]+$/.test( !/^[a-zA-Z·~@#¥%……&*()——\-+={}|《》?:“”【】、;‘’,。、`~!@#$%^&*()_\-+=<>?:"{}|,./;'\\[\]]+$/.test(
value value
) )
) { ) {
question.error = translatedText.value.PleaseEnterEnglishLetters; question.error = translatedText.value.PleaseEnterEnglishLetters;
} }
break; break;
// 中文 // 中文
case 4: case 4:
if ( if (
!/^(?:[\u3400-\u4DB5\u4E00-\u9FEA\uFA0E\uFA0F\uFA11\uFA13\uFA14\uFA1F\uFA21\uFA23\uFA24\uFA27-\uFA29]|[\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|[·~@#¥%……&*()——\-+={}|《》?:“”【】、;‘’,。、`~!@#$%^&*()_\-+=<>?:"{}|,./;'\\[\]])+$/.test( !/^(?:[\u3400-\u4DB5\u4E00-\u9FEA\uFA0E\uFA0F\uFA11\uFA13\uFA14\uFA1F\uFA21\uFA23\uFA24\uFA27-\uFA29]|[\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|[·~@#¥%……&*()——\-+={}|《》?:“”【】、;‘’,。、`~!@#$%^&*()_\-+=<>?:"{}|,./;'\\[\]])+$/.test(
value value
) )
) { ) {
question.error = translatedText.value.PleaseEnterChineseWords; question.error = translatedText.value.PleaseEnterChineseWords;
} }
break; break;
// 邮箱 // 邮箱
case 5: case 5:
if ( if (
!/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test( !/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(
value value
) )
) { ) {
question.error = translatedText.value.PleaseEnterACorrectEmail; question.error = translatedText.value.PleaseEnterACorrectEmail;
} }
break; break;
// 手机号 // 手机号
case 6: case 6:
if (!/^(?:(?:\+|00)86)?1[3-9]\d{9}$/.test(value)) { if (!/^(?:(?:\+|00)86)?1[3-9]\d{9}$/.test(value)) {
question.error = translatedText.value.PleaseEnterACorrectPhone; question.error = translatedText.value.PleaseEnterACorrectPhone;
} }
break; break;
// 身份证号 // 身份证号
case 7: case 7:
if ( if (
!/^[1-9]\d{5}(?:18|19|20)\d{2}(?:0[1-9]|10|11|12)(?:0[1-9]|[1-2]\d|30|31)\d{3}[\dXx]$/.test( !/^[1-9]\d{5}(?:18|19|20)\d{2}(?:0[1-9]|10|11|12)(?:0[1-9]|[1-2]\d|30|31)\d{3}[\dXx]$/.test(
value value
) )
) { ) {
question.error = translatedText.value.PleaseEnterACorrectID; question.error = translatedText.value.PleaseEnterACorrectID;
} }
break; break;
default: default:
break; break;
} }
if (!question.error && value.length < config.min && ![1, 2].includes(config.text_type)) { if (!question.error && value.length < config.min && ![1, 2].includes(config.text_type)) {
question.error = translatedText.value.PleaseEnterMoreThanOneCharacters(config.min); question.error = translatedText.value.PleaseEnterMoreThanOneCharacters(config.min);
@@ -1032,14 +1032,14 @@ async function answer(callback, callbackBeforePage) {
currentQuestions.forEach((question, index) => { currentQuestions.forEach((question, index) => {
if (index >= warnStart && index < warnEnd) { if (index >= warnStart && index < warnEnd) {
if (repeat.repeat_type) { if (repeat.repeat_type) {
question.warning question.warning =
= translatedText.value.TheAnswerIsRepeatedMoreThanOneTimesPleaseRevise( translatedText.value.TheAnswerIsRepeatedMoreThanOneTimesPleaseRevise(
repeat.allow_repeat_num, repeat.allow_repeat_num,
repeat.repeat_type repeat.repeat_type
); );
} else { } else {
question.error question.error =
= translatedText.value.TheAnswerIsRepeatedMoreThanOneTimesPleaseRevise( translatedText.value.TheAnswerIsRepeatedMoreThanOneTimesPleaseRevise(
repeat.allow_repeat_num, repeat.allow_repeat_num,
repeat.repeat_type repeat.repeat_type
); );