|
|
|
|
@ -12,18 +12,43 @@
|
|
|
|
|
<!-- 操作栏 -->
|
|
|
|
|
<div class="action-bar">
|
|
|
|
|
<div class="search-box">
|
|
|
|
|
<el-input v-model="select.title" placeholder="搜索问卷..." style="width:250px;" @input="filterSurveys"
|
|
|
|
|
clearable />
|
|
|
|
|
<el-select v-model="select.status" placeholder="全部状态" style="width:150px;" @change="filterSurveys" clearable>
|
|
|
|
|
<el-input
|
|
|
|
|
v-model="select.title"
|
|
|
|
|
placeholder="搜索问卷..."
|
|
|
|
|
style="width: 250px"
|
|
|
|
|
@input="filterSurveys"
|
|
|
|
|
clearable
|
|
|
|
|
/>
|
|
|
|
|
<el-select
|
|
|
|
|
v-model="select.status"
|
|
|
|
|
placeholder="全部状态"
|
|
|
|
|
style="width: 150px"
|
|
|
|
|
@change="filterSurveys"
|
|
|
|
|
clearable
|
|
|
|
|
>
|
|
|
|
|
<el-option label="草稿" :value="0" />
|
|
|
|
|
<el-option label="已发布" :value="1" />
|
|
|
|
|
</el-select>
|
|
|
|
|
<el-select v-model="select.course_id" placeholder="全部课程" style="width:200px;" @change="filterSurveys"
|
|
|
|
|
clearable>
|
|
|
|
|
<el-option v-for="item in courseList" :label="item.name" :value="item.id" />
|
|
|
|
|
<el-select
|
|
|
|
|
v-model="select.course_id"
|
|
|
|
|
placeholder="全部课程"
|
|
|
|
|
style="width: 200px"
|
|
|
|
|
@change="filterSurveys"
|
|
|
|
|
clearable
|
|
|
|
|
>
|
|
|
|
|
<el-option
|
|
|
|
|
v-for="item in courseList"
|
|
|
|
|
:label="item.name"
|
|
|
|
|
:value="item.id"
|
|
|
|
|
/>
|
|
|
|
|
</el-select>
|
|
|
|
|
</div>
|
|
|
|
|
<el-button type="primary" icon="el-icon-plus" @click="openCreateModal('add')">创建问卷</el-button>
|
|
|
|
|
<el-button
|
|
|
|
|
type="primary"
|
|
|
|
|
icon="el-icon-plus"
|
|
|
|
|
@click="openCreateModal('add')"
|
|
|
|
|
>创建问卷</el-button
|
|
|
|
|
>
|
|
|
|
|
</div>
|
|
|
|
|
<!-- 问卷列表 -->
|
|
|
|
|
<div class="survey-grid">
|
|
|
|
|
@ -31,42 +56,78 @@
|
|
|
|
|
<div v-for="survey in list" :key="survey.id" class="survey-card">
|
|
|
|
|
<div class="survey-header">
|
|
|
|
|
<div>
|
|
|
|
|
<div class="survey-title">{{ survey.title }}</div>
|
|
|
|
|
<span :class="['status-badge', statusClass(survey.status)]">{{ statusText(survey.status) }}</span>
|
|
|
|
|
<el-tooltip
|
|
|
|
|
:content="survey.title"
|
|
|
|
|
placement="top"
|
|
|
|
|
effect="light"
|
|
|
|
|
>
|
|
|
|
|
<div class="survey-title">{{ survey.title }}</div>
|
|
|
|
|
</el-tooltip>
|
|
|
|
|
<span :class="['status-badge', statusClass(survey.status)]">{{
|
|
|
|
|
statusText(survey.status)
|
|
|
|
|
}}</span>
|
|
|
|
|
</div>
|
|
|
|
|
<el-dropdown trigger="click">
|
|
|
|
|
<el-button size="mini" icon="el-icon-more"></el-button>
|
|
|
|
|
<el-dropdown-menu slot="dropdown">
|
|
|
|
|
<el-dropdown-item @click.native="openCreateModal('editor',survey.id)"><i class="el-icon-edit"></i>
|
|
|
|
|
编辑</el-dropdown-item>
|
|
|
|
|
<el-dropdown-item @click.native="viewResults(survey)"><i class="el-icon-data-analysis"></i>
|
|
|
|
|
查看结果</el-dropdown-item>
|
|
|
|
|
<el-dropdown-item
|
|
|
|
|
@click.native="openCreateModal('editor', survey.id)"
|
|
|
|
|
><i class="el-icon-edit"></i> 编辑</el-dropdown-item
|
|
|
|
|
>
|
|
|
|
|
<el-dropdown-item @click.native="viewResults(survey)"
|
|
|
|
|
><i class="el-icon-data-analysis"></i>
|
|
|
|
|
查看结果</el-dropdown-item
|
|
|
|
|
>
|
|
|
|
|
<!-- <el-dropdown-item @click.native="duplicateSurvey(survey.id)"><i class="el-icon-document-copy"></i>
|
|
|
|
|
复制</el-dropdown-item> -->
|
|
|
|
|
<el-dropdown-item divided @click.native="deleteSurvey(survey.id)" style="color:#F56C6C"><i
|
|
|
|
|
class="el-icon-delete"></i> 删除</el-dropdown-item>
|
|
|
|
|
<el-dropdown-item
|
|
|
|
|
divided
|
|
|
|
|
@click.native="deleteSurvey(survey.id)"
|
|
|
|
|
style="color: #f56c6c"
|
|
|
|
|
><i class="el-icon-delete"></i> 删除</el-dropdown-item
|
|
|
|
|
>
|
|
|
|
|
</el-dropdown-menu>
|
|
|
|
|
</el-dropdown>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="survey-meta">
|
|
|
|
|
<div class="meta-item"><i class="el-icon-date"></i> 开始时间:{{ survey.start_time }}</div>
|
|
|
|
|
<div class="meta-item"><i class="el-icon-time"></i> 截止时间:{{ survey.end_time }}</div>
|
|
|
|
|
<div class="meta-item">
|
|
|
|
|
<i class="el-icon-date"></i> 开始时间:{{ survey.start_time }}
|
|
|
|
|
</div>
|
|
|
|
|
<div class="meta-item">
|
|
|
|
|
<i class="el-icon-time"></i> 截止时间:{{ survey.end_time }}
|
|
|
|
|
</div>
|
|
|
|
|
<div class="meta-item" v-if="survey.course">
|
|
|
|
|
<i class="el-icon-link"></i>
|
|
|
|
|
<span class="course-tag">{{ survey.course.name }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="meta-item" v-if="survey.course_content">
|
|
|
|
|
<div class="meta-item" v-if="survey.course_content && survey.course_content.length">
|
|
|
|
|
<i class="el-icon-document"></i>
|
|
|
|
|
<span class="course-tag">{{ survey.course_content.theme }}</span>
|
|
|
|
|
<div class="course-content-list">
|
|
|
|
|
<el-tooltip
|
|
|
|
|
v-for="(content, index) in survey.course_content"
|
|
|
|
|
:key="index"
|
|
|
|
|
:content="`${content.date} ${content.period} | ${content.theme}`"
|
|
|
|
|
placement="top"
|
|
|
|
|
effect="light"
|
|
|
|
|
>
|
|
|
|
|
<span class="course-tag course-content-item">
|
|
|
|
|
{{ content.date }} {{ content.period }} | {{ content.theme }}
|
|
|
|
|
</span>
|
|
|
|
|
</el-tooltip>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="survey-stats">
|
|
|
|
|
<div class="stat-item">
|
|
|
|
|
<div class="stat-number">{{ survey.course_content_evaluation_forms_count }}</div>
|
|
|
|
|
<div class="stat-number">
|
|
|
|
|
{{ survey.course_content_evaluation_forms_count }}
|
|
|
|
|
</div>
|
|
|
|
|
<div class="stat-label">回复数</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="stat-item">
|
|
|
|
|
<div class="stat-number">{{ survey.course_content_evaluation_asks_count }}</div>
|
|
|
|
|
<div class="stat-number">
|
|
|
|
|
{{ survey.course_content_evaluation_asks_count }}
|
|
|
|
|
</div>
|
|
|
|
|
<div class="stat-label">题目数</div>
|
|
|
|
|
</div>
|
|
|
|
|
<!-- <div class="stat-item">
|
|
|
|
|
@ -75,409 +136,472 @@
|
|
|
|
|
</div> -->
|
|
|
|
|
</div>
|
|
|
|
|
<div class="survey-actions">
|
|
|
|
|
<el-button v-if="survey.status==='0'" type="success" size="mini" @click="publishSurvey(survey.id)"><i
|
|
|
|
|
class="el-icon-upload2"></i> 发布</el-button>
|
|
|
|
|
<el-button type="primary" size="mini" @click="previewSurvey(survey)"><i class="el-icon-view"></i>
|
|
|
|
|
预览</el-button>
|
|
|
|
|
<el-button
|
|
|
|
|
v-if="survey.status === '0'"
|
|
|
|
|
type="success"
|
|
|
|
|
size="mini"
|
|
|
|
|
@click="publishSurvey(survey.id)"
|
|
|
|
|
><i class="el-icon-upload2"></i> 发布</el-button
|
|
|
|
|
>
|
|
|
|
|
<el-button
|
|
|
|
|
type="primary"
|
|
|
|
|
size="mini"
|
|
|
|
|
@click="previewSurvey(survey)"
|
|
|
|
|
><i class="el-icon-view"></i> 预览</el-button
|
|
|
|
|
>
|
|
|
|
|
<!-- <el-button type="info" size="mini" @click="shareSurvey(survey.id)"><i class="el-icon-share"></i> 分享</el-button> -->
|
|
|
|
|
<!-- <el-button v-if="survey.responses>0" type="success" size="mini" @click="exportData(survey.id)"><i class="el-icon-download"></i> 导出</el-button> -->
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
<el-empty v-else description="暂无问卷,点击'创建问卷'开始制作您的第一个调查问卷" />
|
|
|
|
|
<el-empty
|
|
|
|
|
v-else
|
|
|
|
|
description="暂无问卷,点击'创建问卷'开始制作您的第一个调查问卷"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="survey-pagination" v-if="list.length">
|
|
|
|
|
<el-pagination background layout="total, sizes, prev, pager, next, jumper" :total="total"
|
|
|
|
|
:page-size="select.page_size" :current-page.sync="select.page" :page-sizes="[6, 12, 24, 48]"
|
|
|
|
|
@size-change="onPageSizeChange" @current-change="onPageChange"
|
|
|
|
|
style="margin: 24px 0 0 0; text-align: right;" />
|
|
|
|
|
<el-pagination
|
|
|
|
|
background
|
|
|
|
|
layout="total, sizes, prev, pager, next, jumper"
|
|
|
|
|
:total="total"
|
|
|
|
|
:page-size="select.page_size"
|
|
|
|
|
:current-page.sync="select.page"
|
|
|
|
|
:page-sizes="[6, 12, 24, 48]"
|
|
|
|
|
@size-change="onPageSizeChange"
|
|
|
|
|
@current-change="onPageChange"
|
|
|
|
|
style="margin: 24px 0 0 0; text-align: right"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<!-- 创建问卷弹窗(合并版) -->
|
|
|
|
|
<SurveyCreateWizard ref="SurveyCreateWizard" @refresh="filterSurveys" />
|
|
|
|
|
<!-- 问卷结果全屏弹窗 -->
|
|
|
|
|
<SurveyResultsDialog :visible.sync="resultsDialogVisible" :surveyData="resultsSurveyData"
|
|
|
|
|
@close="resultsDialogVisible=false" />
|
|
|
|
|
<SurveyResultsDialog
|
|
|
|
|
:visible.sync="resultsDialogVisible"
|
|
|
|
|
:surveyData="resultsSurveyData"
|
|
|
|
|
@close="resultsDialogVisible = false"
|
|
|
|
|
/>
|
|
|
|
|
<!-- 问卷填写/预览全屏弹窗 -->
|
|
|
|
|
<SurveyFillDialog :visible.sync="fillDialogVisible" :surveyData="fillSurveyData" :previewOnly="fillPreviewOnly"
|
|
|
|
|
@close="fillDialogVisible=false" @submit="onFillSubmit" />
|
|
|
|
|
<SurveyFillDialog
|
|
|
|
|
:visible.sync="fillDialogVisible"
|
|
|
|
|
:surveyData="fillSurveyData"
|
|
|
|
|
:previewOnly="fillPreviewOnly"
|
|
|
|
|
@close="fillDialogVisible = false"
|
|
|
|
|
@submit="onFillSubmit"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
import SurveyCreateWizard from './components/SurveyCreateWizard.vue';
|
|
|
|
|
import SurveyResultsDialog from './components/SurveyResultsDialog.vue';
|
|
|
|
|
import SurveyFillDialog from './components/SurveyFillDialog.vue';
|
|
|
|
|
import {
|
|
|
|
|
index as courseApi
|
|
|
|
|
} from "@/api/course/index.js"
|
|
|
|
|
import {
|
|
|
|
|
index,
|
|
|
|
|
destroy,
|
|
|
|
|
save
|
|
|
|
|
} from "@/api/survey/evaluations.js"
|
|
|
|
|
import SurveyCreateWizard from "./components/SurveyCreateWizard.vue";
|
|
|
|
|
import SurveyResultsDialog from "./components/SurveyResultsDialog.vue";
|
|
|
|
|
import SurveyFillDialog from "./components/SurveyFillDialog.vue";
|
|
|
|
|
import { index as courseApi } from "@/api/course/index.js";
|
|
|
|
|
import { index, destroy, save } from "@/api/survey/evaluations.js";
|
|
|
|
|
|
|
|
|
|
export default {
|
|
|
|
|
components: {
|
|
|
|
|
SurveyCreateWizard,
|
|
|
|
|
SurveyResultsDialog,
|
|
|
|
|
SurveyFillDialog
|
|
|
|
|
export default {
|
|
|
|
|
components: {
|
|
|
|
|
SurveyCreateWizard,
|
|
|
|
|
SurveyResultsDialog,
|
|
|
|
|
SurveyFillDialog,
|
|
|
|
|
},
|
|
|
|
|
data() {
|
|
|
|
|
return {
|
|
|
|
|
courseList: [],
|
|
|
|
|
select: {
|
|
|
|
|
page: 1,
|
|
|
|
|
page_size: 6,
|
|
|
|
|
course_id: "",
|
|
|
|
|
title: "",
|
|
|
|
|
status: "",
|
|
|
|
|
},
|
|
|
|
|
list: [],
|
|
|
|
|
total: 0,
|
|
|
|
|
resultsDialogVisible: false,
|
|
|
|
|
resultsSurveyData: null,
|
|
|
|
|
fillDialogVisible: false,
|
|
|
|
|
fillSurveyData: null,
|
|
|
|
|
fillPreviewOnly: false,
|
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
created() {
|
|
|
|
|
this.getCourseList();
|
|
|
|
|
this.filterSurveys();
|
|
|
|
|
},
|
|
|
|
|
methods: {
|
|
|
|
|
// 获取课程
|
|
|
|
|
async getCourseList() {
|
|
|
|
|
const res = await courseApi({
|
|
|
|
|
page: 1,
|
|
|
|
|
page_size: 999,
|
|
|
|
|
});
|
|
|
|
|
this.courseList = res.data;
|
|
|
|
|
},
|
|
|
|
|
data() {
|
|
|
|
|
return {
|
|
|
|
|
courseList: [],
|
|
|
|
|
select: {
|
|
|
|
|
page: 1,
|
|
|
|
|
page_size: 6,
|
|
|
|
|
course_id: '',
|
|
|
|
|
title: '',
|
|
|
|
|
status: '',
|
|
|
|
|
},
|
|
|
|
|
list: [],
|
|
|
|
|
total: 0,
|
|
|
|
|
resultsDialogVisible: false,
|
|
|
|
|
resultsSurveyData: null,
|
|
|
|
|
fillDialogVisible: false,
|
|
|
|
|
fillSurveyData: null,
|
|
|
|
|
fillPreviewOnly: false
|
|
|
|
|
}
|
|
|
|
|
// 获取问卷
|
|
|
|
|
async filterSurveys() {
|
|
|
|
|
const res = await index({
|
|
|
|
|
page: this.select.page,
|
|
|
|
|
page_size: this.select.page_size,
|
|
|
|
|
filter: [
|
|
|
|
|
{
|
|
|
|
|
key: "title",
|
|
|
|
|
op: "like",
|
|
|
|
|
value: this.select.title,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
key: "course_id",
|
|
|
|
|
op: "like",
|
|
|
|
|
value: this.select.course_id,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
key: "status",
|
|
|
|
|
op: "like",
|
|
|
|
|
value: this.select.status,
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
});
|
|
|
|
|
this.list = res.data;
|
|
|
|
|
this.total = res.total;
|
|
|
|
|
},
|
|
|
|
|
created() {
|
|
|
|
|
this.getCourseList()
|
|
|
|
|
onPageChange(page) {
|
|
|
|
|
this.select.page = page;
|
|
|
|
|
this.filterSurveys();
|
|
|
|
|
},
|
|
|
|
|
methods: {
|
|
|
|
|
// 获取课程
|
|
|
|
|
async getCourseList() {
|
|
|
|
|
const res = await courseApi({
|
|
|
|
|
page: 1,
|
|
|
|
|
page_size: 999,
|
|
|
|
|
})
|
|
|
|
|
this.courseList = res.data
|
|
|
|
|
},
|
|
|
|
|
// 获取问卷
|
|
|
|
|
async filterSurveys() {
|
|
|
|
|
const res = await index({
|
|
|
|
|
page: this.select.page,
|
|
|
|
|
page_size: this.select.page_size,
|
|
|
|
|
filter: [{
|
|
|
|
|
key: 'title',
|
|
|
|
|
op: 'like',
|
|
|
|
|
value: this.select.title
|
|
|
|
|
}, {
|
|
|
|
|
key: 'course_id',
|
|
|
|
|
op: 'like',
|
|
|
|
|
value: this.select.course_id
|
|
|
|
|
}, {
|
|
|
|
|
key: 'status',
|
|
|
|
|
op: 'like',
|
|
|
|
|
value: this.select.status
|
|
|
|
|
}]
|
|
|
|
|
})
|
|
|
|
|
this.list = res.data
|
|
|
|
|
this.total = res.total
|
|
|
|
|
},
|
|
|
|
|
onPageChange(page) {
|
|
|
|
|
this.select.page = page;
|
|
|
|
|
this.filterSurveys()
|
|
|
|
|
},
|
|
|
|
|
onPageSizeChange(size) {
|
|
|
|
|
this.select.page_size = size;
|
|
|
|
|
this.select.page = 1;
|
|
|
|
|
this.filterSurveys()
|
|
|
|
|
},
|
|
|
|
|
statusText(status) {
|
|
|
|
|
return {
|
|
|
|
|
0: '草稿',
|
|
|
|
|
1: '已发布'
|
|
|
|
|
} [status] || status;
|
|
|
|
|
},
|
|
|
|
|
statusClass(status) {
|
|
|
|
|
return {
|
|
|
|
|
0: 'status-draft',
|
|
|
|
|
1: 'status-published',
|
|
|
|
|
} [status] || '';
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
openCreateModal(type, id) {
|
|
|
|
|
if (type === 'editor') {
|
|
|
|
|
this.$refs.SurveyCreateWizard.id = id
|
|
|
|
|
}
|
|
|
|
|
this.$refs.SurveyCreateWizard.type = type
|
|
|
|
|
this.$refs.SurveyCreateWizard.courseList = this.courseList
|
|
|
|
|
this.$refs.SurveyCreateWizard.isShow = true
|
|
|
|
|
},
|
|
|
|
|
onPageSizeChange(size) {
|
|
|
|
|
this.select.page_size = size;
|
|
|
|
|
this.select.page = 1;
|
|
|
|
|
this.filterSurveys();
|
|
|
|
|
},
|
|
|
|
|
statusText(status) {
|
|
|
|
|
return (
|
|
|
|
|
{
|
|
|
|
|
0: "草稿",
|
|
|
|
|
1: "已发布",
|
|
|
|
|
}[status] || status
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
statusClass(status) {
|
|
|
|
|
return (
|
|
|
|
|
{
|
|
|
|
|
0: "status-draft",
|
|
|
|
|
1: "status-published",
|
|
|
|
|
}[status] || ""
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
viewResults(survey) {
|
|
|
|
|
this.resultsSurveyData = {
|
|
|
|
|
id: 1,
|
|
|
|
|
title: '问卷1',
|
|
|
|
|
description: '请对本次智能制造专题课程进行评价和反馈',
|
|
|
|
|
status: 'published',
|
|
|
|
|
type: 'feedback',
|
|
|
|
|
bindType: 'course',
|
|
|
|
|
bindCourse: '2025产业加速营 | 智能制造专题',
|
|
|
|
|
createTime: '2025-06-01 10:00',
|
|
|
|
|
deadline: '2025-06-10 23:59',
|
|
|
|
|
responses: 1,
|
|
|
|
|
questions: 6,
|
|
|
|
|
avgScore: 4.6,
|
|
|
|
|
questions: [
|
|
|
|
|
{
|
|
|
|
|
id: 101,
|
|
|
|
|
type: 'single',
|
|
|
|
|
title: '单选框',
|
|
|
|
|
options: ['单选1', '单选2',]
|
|
|
|
|
},
|
|
|
|
|
// {
|
|
|
|
|
// id: 102,
|
|
|
|
|
// type: 'rate',
|
|
|
|
|
// title: '请为本次课程打分',
|
|
|
|
|
// rateMax: 5
|
|
|
|
|
// }
|
|
|
|
|
]
|
|
|
|
|
};
|
|
|
|
|
this.resultsDialogVisible = true;
|
|
|
|
|
},
|
|
|
|
|
previewSurvey(survey) {
|
|
|
|
|
this.fillSurveyData = survey;
|
|
|
|
|
this.fillPreviewOnly = true;
|
|
|
|
|
this.fillDialogVisible = true;
|
|
|
|
|
},
|
|
|
|
|
onFillSubmit(answers) {
|
|
|
|
|
this.$message.success('提交成功!(模拟)');
|
|
|
|
|
this.fillDialogVisible = false;
|
|
|
|
|
},
|
|
|
|
|
publishSurvey(id) {
|
|
|
|
|
openCreateModal(type, id) {
|
|
|
|
|
if (type === "editor") {
|
|
|
|
|
this.$refs.SurveyCreateWizard.id = id;
|
|
|
|
|
}
|
|
|
|
|
this.$refs.SurveyCreateWizard.type = type;
|
|
|
|
|
this.$refs.SurveyCreateWizard.courseList = this.courseList;
|
|
|
|
|
this.$refs.SurveyCreateWizard.isShow = true;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
save({
|
|
|
|
|
id:id,
|
|
|
|
|
status:1
|
|
|
|
|
}).then(res => {
|
|
|
|
|
this.$message({
|
|
|
|
|
type: 'success',
|
|
|
|
|
message: '发布成功',
|
|
|
|
|
duration: 2000
|
|
|
|
|
viewResults(survey) {
|
|
|
|
|
this.resultsSurveyData = {
|
|
|
|
|
id: 1,
|
|
|
|
|
title: "问卷1",
|
|
|
|
|
description: "请对本次智能制造专题课程进行评价和反馈",
|
|
|
|
|
status: "published",
|
|
|
|
|
type: "feedback",
|
|
|
|
|
bindType: "course",
|
|
|
|
|
bindCourse: "2025产业加速营 | 智能制造专题",
|
|
|
|
|
createTime: "2025-06-01 10:00",
|
|
|
|
|
deadline: "2025-06-10 23:59",
|
|
|
|
|
responses: 1,
|
|
|
|
|
questions: 6,
|
|
|
|
|
avgScore: 4.6,
|
|
|
|
|
questions: [
|
|
|
|
|
{
|
|
|
|
|
id: 101,
|
|
|
|
|
type: "single",
|
|
|
|
|
title: "单选框",
|
|
|
|
|
options: ["单选1", "单选2"],
|
|
|
|
|
},
|
|
|
|
|
// {
|
|
|
|
|
// id: 102,
|
|
|
|
|
// type: 'rate',
|
|
|
|
|
// title: '请为本次课程打分',
|
|
|
|
|
// rateMax: 5
|
|
|
|
|
// }
|
|
|
|
|
],
|
|
|
|
|
};
|
|
|
|
|
this.resultsDialogVisible = true;
|
|
|
|
|
},
|
|
|
|
|
previewSurvey(survey) {
|
|
|
|
|
this.fillSurveyData = survey;
|
|
|
|
|
this.fillPreviewOnly = true;
|
|
|
|
|
this.fillDialogVisible = true;
|
|
|
|
|
},
|
|
|
|
|
onFillSubmit(answers) {
|
|
|
|
|
this.$message.success("提交成功!(模拟)");
|
|
|
|
|
this.fillDialogVisible = false;
|
|
|
|
|
},
|
|
|
|
|
publishSurvey(id) {
|
|
|
|
|
save({
|
|
|
|
|
id: id,
|
|
|
|
|
status: 1,
|
|
|
|
|
}).then((res) => {
|
|
|
|
|
this.$message({
|
|
|
|
|
type: "success",
|
|
|
|
|
message: "发布成功",
|
|
|
|
|
duration: 2000,
|
|
|
|
|
});
|
|
|
|
|
this.filterSurveys();
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
shareSurvey(id) {
|
|
|
|
|
const url = `${window.location.origin}/survey-fill.html?id=${id}`;
|
|
|
|
|
if (navigator.clipboard) {
|
|
|
|
|
navigator.clipboard
|
|
|
|
|
.writeText(url)
|
|
|
|
|
.then(() => {
|
|
|
|
|
this.$message.success("问卷链接已复制到剪贴板");
|
|
|
|
|
})
|
|
|
|
|
this.filterSurveys()
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
},
|
|
|
|
|
shareSurvey(id) {
|
|
|
|
|
const url = `${window.location.origin}/survey-fill.html?id=${id}`;
|
|
|
|
|
if (navigator.clipboard) {
|
|
|
|
|
navigator.clipboard.writeText(url).then(() => {
|
|
|
|
|
this.$message.success('问卷链接已复制到剪贴板');
|
|
|
|
|
}).catch(() => {
|
|
|
|
|
this.$prompt('请复制以下链接:', '分享问卷', {
|
|
|
|
|
inputValue: url
|
|
|
|
|
.catch(() => {
|
|
|
|
|
this.$prompt("请复制以下链接:", "分享问卷", {
|
|
|
|
|
inputValue: url,
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
this.$prompt('请复制以下链接:', '分享问卷', {
|
|
|
|
|
inputValue: url
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
exportData(id) {
|
|
|
|
|
this.$message.info('数据导出功能开发中...');
|
|
|
|
|
},
|
|
|
|
|
duplicateSurvey(id) {
|
|
|
|
|
const survey = this.surveys.find(s => s.id === id);
|
|
|
|
|
if (survey) {
|
|
|
|
|
const newSurvey = {
|
|
|
|
|
...survey,
|
|
|
|
|
id: this.surveys.length + 1,
|
|
|
|
|
title: survey.title + ' (副本)',
|
|
|
|
|
status: 'draft',
|
|
|
|
|
createTime: this.formatNow(),
|
|
|
|
|
responses: 0
|
|
|
|
|
};
|
|
|
|
|
this.surveys.unshift(newSurvey);
|
|
|
|
|
this.filterSurveys();
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
deleteSurvey(id) {
|
|
|
|
|
var that = this;
|
|
|
|
|
this.$confirm('确定要删除这个问卷吗?此操作不可恢复。', '提示', {
|
|
|
|
|
type: 'warning'
|
|
|
|
|
}).then(() => {
|
|
|
|
|
|
|
|
|
|
destroy({
|
|
|
|
|
id: id,
|
|
|
|
|
}).then(response => {
|
|
|
|
|
this.$Message.success('删除成功');
|
|
|
|
|
this.filterSurveys()
|
|
|
|
|
}).catch(error => {
|
|
|
|
|
console.log(error)
|
|
|
|
|
reject(error)
|
|
|
|
|
})
|
|
|
|
|
} else {
|
|
|
|
|
this.$prompt("请复制以下链接:", "分享问卷", {
|
|
|
|
|
inputValue: url,
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
formatNow() {
|
|
|
|
|
const d = new Date();
|
|
|
|
|
return `${d.getFullYear()}-${(d.getMonth()+1).toString().padStart(2,'0')}-${d.getDate().toString().padStart(2,'0')} ${d.getHours().toString().padStart(2,'0')}:${d.getMinutes().toString().padStart(2,'0')}`;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
exportData(id) {
|
|
|
|
|
this.$message.info("数据导出功能开发中...");
|
|
|
|
|
},
|
|
|
|
|
duplicateSurvey(id) {
|
|
|
|
|
const survey = this.surveys.find((s) => s.id === id);
|
|
|
|
|
if (survey) {
|
|
|
|
|
const newSurvey = {
|
|
|
|
|
...survey,
|
|
|
|
|
id: this.surveys.length + 1,
|
|
|
|
|
title: survey.title + " (副本)",
|
|
|
|
|
status: "draft",
|
|
|
|
|
createTime: this.formatNow(),
|
|
|
|
|
responses: 0,
|
|
|
|
|
};
|
|
|
|
|
this.surveys.unshift(newSurvey);
|
|
|
|
|
this.filterSurveys();
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
deleteSurvey(id) {
|
|
|
|
|
var that = this;
|
|
|
|
|
this.$confirm("确定要删除这个问卷吗?此操作不可恢复。", "提示", {
|
|
|
|
|
type: "warning",
|
|
|
|
|
}).then(() => {
|
|
|
|
|
destroy({
|
|
|
|
|
id: id,
|
|
|
|
|
})
|
|
|
|
|
.then((response) => {
|
|
|
|
|
this.$Message.success("删除成功");
|
|
|
|
|
this.filterSurveys();
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
console.log(error);
|
|
|
|
|
reject(error);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
formatNow() {
|
|
|
|
|
const d = new Date();
|
|
|
|
|
return `${d.getFullYear()}-${(d.getMonth() + 1)
|
|
|
|
|
.toString()
|
|
|
|
|
.padStart(2, "0")}-${d.getDate().toString().padStart(2, "0")} ${d
|
|
|
|
|
.getHours()
|
|
|
|
|
.toString()
|
|
|
|
|
.padStart(2, "0")}:${d.getMinutes().toString().padStart(2, "0")}`;
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
|
.survey-admin {
|
|
|
|
|
background: #f8f9fa;
|
|
|
|
|
min-height: 100vh;
|
|
|
|
|
}
|
|
|
|
|
.survey-admin {
|
|
|
|
|
background: #f8f9fa;
|
|
|
|
|
min-height: 100vh;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.admin-header {
|
|
|
|
|
background: white;
|
|
|
|
|
padding: 20px 30px;
|
|
|
|
|
border-bottom: 1px solid #e9ecef;
|
|
|
|
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.admin-title {
|
|
|
|
|
font-size: 24px;
|
|
|
|
|
font-weight: 700;
|
|
|
|
|
color: #2c3e50;
|
|
|
|
|
margin: 0;
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
gap: 12px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.admin-main {
|
|
|
|
|
padding: 30px;
|
|
|
|
|
max-width: 1400px;
|
|
|
|
|
margin: 0 auto;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.admin-header {
|
|
|
|
|
background: white;
|
|
|
|
|
padding: 20px 30px;
|
|
|
|
|
border-bottom: 1px solid #e9ecef;
|
|
|
|
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
|
|
|
}
|
|
|
|
|
.action-bar {
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
align-items: center;
|
|
|
|
|
margin-bottom: 24px;
|
|
|
|
|
flex-wrap: wrap;
|
|
|
|
|
gap: 16px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.admin-title {
|
|
|
|
|
font-size: 24px;
|
|
|
|
|
font-weight: 700;
|
|
|
|
|
color: #2c3e50;
|
|
|
|
|
margin: 0;
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
gap: 12px;
|
|
|
|
|
}
|
|
|
|
|
.search-box {
|
|
|
|
|
display: flex;
|
|
|
|
|
gap: 12px;
|
|
|
|
|
align-items: center;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.admin-main {
|
|
|
|
|
padding: 30px;
|
|
|
|
|
max-width: 1400px;
|
|
|
|
|
margin: 0 auto;
|
|
|
|
|
}
|
|
|
|
|
.survey-grid {
|
|
|
|
|
display: grid;
|
|
|
|
|
grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
|
|
|
|
|
gap: 24px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.action-bar {
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
align-items: center;
|
|
|
|
|
margin-bottom: 24px;
|
|
|
|
|
flex-wrap: wrap;
|
|
|
|
|
gap: 16px;
|
|
|
|
|
}
|
|
|
|
|
.survey-card {
|
|
|
|
|
background: white;
|
|
|
|
|
border-radius: 12px;
|
|
|
|
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
|
|
|
padding: 24px;
|
|
|
|
|
transition: all 0.3s ease;
|
|
|
|
|
border: 1px solid #e9ecef;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.search-box {
|
|
|
|
|
display: flex;
|
|
|
|
|
gap: 12px;
|
|
|
|
|
align-items: center;
|
|
|
|
|
}
|
|
|
|
|
.survey-card:hover {
|
|
|
|
|
transform: translateY(-2px);
|
|
|
|
|
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.survey-grid {
|
|
|
|
|
display: grid;
|
|
|
|
|
grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
|
|
|
|
|
gap: 24px;
|
|
|
|
|
}
|
|
|
|
|
.survey-header {
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
align-items: flex-start;
|
|
|
|
|
margin-bottom: 16px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.survey-card {
|
|
|
|
|
background: white;
|
|
|
|
|
border-radius: 12px;
|
|
|
|
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
|
|
|
padding: 24px;
|
|
|
|
|
transition: all 0.3s ease;
|
|
|
|
|
border: 1px solid #e9ecef;
|
|
|
|
|
}
|
|
|
|
|
.survey-title {
|
|
|
|
|
font-size: 18px;
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
color: #2c3e50;
|
|
|
|
|
margin-bottom: 8px;
|
|
|
|
|
line-height: 1.4;
|
|
|
|
|
white-space: nowrap;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
text-overflow: ellipsis;
|
|
|
|
|
max-width: 280px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.survey-card:hover {
|
|
|
|
|
transform: translateY(-2px);
|
|
|
|
|
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
|
|
|
|
|
}
|
|
|
|
|
.survey-meta {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
gap: 8px;
|
|
|
|
|
margin-bottom: 16px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.survey-header {
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
align-items: flex-start;
|
|
|
|
|
margin-bottom: 16px;
|
|
|
|
|
}
|
|
|
|
|
.meta-item {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
gap: 8px;
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
color: #6c757d;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.survey-title {
|
|
|
|
|
font-size: 18px;
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
color: #2c3e50;
|
|
|
|
|
margin-bottom: 8px;
|
|
|
|
|
line-height: 1.4;
|
|
|
|
|
}
|
|
|
|
|
.survey-stats {
|
|
|
|
|
display: grid;
|
|
|
|
|
grid-template-columns: repeat(3, 1fr);
|
|
|
|
|
gap: 12px;
|
|
|
|
|
margin-bottom: 16px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.survey-meta {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
gap: 8px;
|
|
|
|
|
margin-bottom: 16px;
|
|
|
|
|
}
|
|
|
|
|
.stat-item {
|
|
|
|
|
text-align: center;
|
|
|
|
|
padding: 12px;
|
|
|
|
|
background: #f8f9fa;
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.meta-item {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
gap: 8px;
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
color: #6c757d;
|
|
|
|
|
}
|
|
|
|
|
.stat-number {
|
|
|
|
|
font-size: 20px;
|
|
|
|
|
font-weight: 700;
|
|
|
|
|
color: #3498db;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.survey-stats {
|
|
|
|
|
display: grid;
|
|
|
|
|
grid-template-columns: repeat(3, 1fr);
|
|
|
|
|
gap: 12px;
|
|
|
|
|
margin-bottom: 16px;
|
|
|
|
|
}
|
|
|
|
|
.stat-label {
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
color: #6c757d;
|
|
|
|
|
margin-top: 4px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.stat-item {
|
|
|
|
|
text-align: center;
|
|
|
|
|
padding: 12px;
|
|
|
|
|
background: #f8f9fa;
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
}
|
|
|
|
|
.survey-actions {
|
|
|
|
|
display: flex;
|
|
|
|
|
gap: 8px;
|
|
|
|
|
flex-wrap: wrap;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.stat-number {
|
|
|
|
|
font-size: 20px;
|
|
|
|
|
font-weight: 700;
|
|
|
|
|
color: #3498db;
|
|
|
|
|
}
|
|
|
|
|
.status-badge {
|
|
|
|
|
padding: 4px 8px;
|
|
|
|
|
border-radius: 12px;
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.stat-label {
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
color: #6c757d;
|
|
|
|
|
margin-top: 4px;
|
|
|
|
|
}
|
|
|
|
|
.status-draft {
|
|
|
|
|
background: #f8f9fa;
|
|
|
|
|
color: #6c757d;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.survey-actions {
|
|
|
|
|
display: flex;
|
|
|
|
|
gap: 8px;
|
|
|
|
|
flex-wrap: wrap;
|
|
|
|
|
}
|
|
|
|
|
.status-published {
|
|
|
|
|
background: #d4edda;
|
|
|
|
|
color: #155724;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.status-badge {
|
|
|
|
|
padding: 4px 8px;
|
|
|
|
|
border-radius: 12px;
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
}
|
|
|
|
|
.status-closed {
|
|
|
|
|
background: #f8d7da;
|
|
|
|
|
color: #721c24;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.status-draft {
|
|
|
|
|
background: #f8f9fa;
|
|
|
|
|
color: #6c757d;
|
|
|
|
|
}
|
|
|
|
|
.course-tag {
|
|
|
|
|
display: inline-block;
|
|
|
|
|
background: #e3f2fd;
|
|
|
|
|
color: #1976d2;
|
|
|
|
|
padding: 4px 8px;
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
margin-right: 8px;
|
|
|
|
|
margin-bottom: 4px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.status-published {
|
|
|
|
|
background: #d4edda;
|
|
|
|
|
color: #155724;
|
|
|
|
|
}
|
|
|
|
|
.course-content-list {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
gap: 4px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.status-closed {
|
|
|
|
|
background: #f8d7da;
|
|
|
|
|
color: #721c24;
|
|
|
|
|
}
|
|
|
|
|
.course-content-list .course-tag {
|
|
|
|
|
margin-right: 0;
|
|
|
|
|
margin-bottom: 0;
|
|
|
|
|
background: #f0f8ff;
|
|
|
|
|
color: #0066cc;
|
|
|
|
|
border: 1px solid #b3d9ff;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.course-tag {
|
|
|
|
|
display: inline-block;
|
|
|
|
|
background: #e3f2fd;
|
|
|
|
|
color: #1976d2;
|
|
|
|
|
padding: 4px 8px;
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
margin-right: 8px;
|
|
|
|
|
margin-bottom: 4px;
|
|
|
|
|
}
|
|
|
|
|
</style>
|
|
|
|
|
.course-content-item {
|
|
|
|
|
display: block;
|
|
|
|
|
width: 100%;
|
|
|
|
|
white-space: nowrap;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
text-overflow: ellipsis;
|
|
|
|
|
max-width: 300px;
|
|
|
|
|
}
|
|
|
|
|
</style>
|
|
|
|
|
|