Files
ysch-question-front/src/views/question/List.vue
T

135 lines
5.5 KiB
Vue

<script setup lang="ts">
import { ref, onMounted } from "vue";
import { useRouter } from "vue-router";
import { Message, Modal } from "view-ui-plus";
import { questionApi, QuestionnaireVo } from "@/api/question";
const router = useRouter();
const loading = ref(false);
const rows = ref<QuestionnaireVo[]>([]);
const statusText = (s: number) => (s === 0 ? "草稿" : s === 1 ? "收集中" : "已结束");
const statusColor = (s: number) => (s === 0 ? "default" : s === 1 ? "success" : "warning");
const load = async () => {
loading.value = true;
try {
rows.value = (await questionApi.list().send()) || [];
} catch (e: any) {
console.error(e);
} finally {
loading.value = false;
}
};
const toEdit = (row: QuestionnaireVo) => router.push({ path: "/edit", query: { id: row.id } });
const toPublish = (row: QuestionnaireVo) => router.push({ path: "/publish", query: { id: row.id } });
const toAnswers = (row: QuestionnaireVo) => router.push({ path: "/answers", query: { id: row.id } });
const toStats = (row: QuestionnaireVo) => router.push({ path: "/stats", query: { id: row.id } });
/** 有回收量再进编辑 → "建议复制新问卷"软引导(已拍板) */
const enterEdit = async (row: QuestionnaireVo) => {
try {
const page = await questionApi.answers(row.id, 1, 1).send();
if (page && page.total > 0) {
Modal.confirm({
title: "该问卷已有回收答卷",
content: "继续编辑会在 FC 侧升版(新版本行),已回收答卷不受影响;若只是想再发一轮,建议「复制新问卷」避免口径混淆。是否继续编辑?",
okText: "继续编辑",
cancelText: "取消",
onOk: () => toEdit(row),
});
return;
}
} catch {
/* 回收量查询失败不阻塞编辑入口 */
}
toEdit(row);
};
const copyQuestionnaire = async (row: QuestionnaireVo) => {
loading.value = true;
try {
// FC copy(新 uuid、version 从 1、deadline 不继承)→ 登记问卷侧新行 → 进编辑
const { fcApi } = await import("@/api/fc");
const copied = await fcApi.copy(row.formUuid, `${row.titleSnapshot || "问卷"}-副本`).send();
const registered = await questionApi.register({
formUuid: copied.formUuid,
formCode: copied.code,
title: copied.name,
anonymous: row.anonymous,
}).send();
Message.success("复制成功,已进入新问卷编辑");
router.push({ path: "/edit", query: { id: registered.id } });
} catch (e: any) {
Message.error(e?.message || "复制失败");
} finally {
loading.value = false;
}
};
const removeQuestionnaire = (row: QuestionnaireVo) => {
Modal.confirm({
title: "删除确认",
content: `删除问卷「${row.titleSnapshot || row.formCode}」?仅移除问卷侧记录,FC 表单与答卷数据不动(可在"未挂接表单"页看到)。`,
onOk: async () => {
await questionApi.softDelete(row.id).send();
Message.success("已删除");
load();
},
});
};
onMounted(load);
</script>
<template>
<div class="page">
<div class="toolbar">
<Button type="primary" @click="router.push('/new')">新建问卷</Button>
<Button @click="router.push('/my')">我的问卷</Button>
<Button @click="router.push('/orphans')">未挂接表单</Button>
<Button :loading="loading" @click="load">刷新</Button>
</div>
<Table :loading="loading" :data="rows" :columns="[
{ title: 'ID', key: 'id', width: 70 },
{ title: '问卷标题', key: 'titleSnapshot', tooltip: true },
{ title: 'FC code', key: 'formCode', width: 150 },
{ title: '受众', key: 'anonymous', width: 90, slot: 'anonymous' },
{ title: '状态', key: 'status', width: 100, slot: 'status' },
{ title: '发布版本', key: 'formVersion', width: 90, slot: 'version' },
{ title: '创建时间', key: 'createTime', width: 170 },
{ title: '操作', slot: 'action', width: 330 },
]">
<template #anonymous="{ row }">
<Tag :color="row.anonymous ? 'purple' : 'blue'">{{ row.anonymous ? '匿名' : '实名' }}</Tag>
</template>
<template #status="{ row }">
<Tag :color="statusColor(row.status)">{{ statusText(row.status) }}</Tag>
</template>
<template #version="{ row }">
{{ row.formVersion != null ? 'v' + row.formVersion : '—' }}
</template>
<template #action="{ row }">
<Button size="small" @click="enterEdit(row)">编辑</Button>
<Button size="small" type="primary" ghost style="margin-left: 6px" @click="toPublish(row)">投放</Button>
<Button size="small" style="margin-left: 6px" @click="toAnswers(row)">回收明细</Button>
<Button size="small" style="margin-left: 6px" @click="toStats(row)">统计</Button>
<Button size="small" style="margin-left: 6px" @click="copyQuestionnaire(row)">复制</Button>
<Button size="small" type="error" ghost style="margin-left: 6px" @click="removeQuestionnaire(row)">删除</Button>
</template>
</Table>
</div>
</template>
<style scoped>
.page {
padding: 16px;
}
.toolbar {
margin-bottom: 12px;
display: flex;
gap: 8px;
}
</style>