Przeglądaj źródła

满意度调查问卷代码同步

CHINAMI-P698360\Administrator 1 rok temu
rodzic
commit
9b4646905d

+ 34 - 0
src/views/platform/examination/constants.js

@@ -70,6 +70,21 @@ export const questionType = [
     }
 ]
 
+export const surveyQuestionType = [
+    {
+        label: '单选题',
+        value: '单选题'
+    },
+    {
+        label: '多选题',
+        value: '多选题'
+    },
+    {
+        label: '问答题',
+        value: '问答题'
+    }
+]
+
 export const rateType = {
     '单选题': '自动',
     '多选题': '自动',
@@ -105,6 +120,25 @@ export const defaultOptions = [
     }
 ]
 
+export const surveyDefaultOptions = [
+    {
+        value: 'A',
+        content: ''
+    },
+    {
+        value: 'B',
+        content: ''
+    },
+    {
+        value: 'C',
+        content: ''
+    },
+    {
+        value: 'D',
+        content: ''
+    }
+]
+
 export const statusOption = [
     {
         label: '未发布',

+ 436 - 0
src/views/platform/examination/question/survey.vue

@@ -0,0 +1,436 @@
+<template>
+    <el-dialog
+        :title="title"
+        :visible.sync="dialogVisible"
+        :close-on-click-modal="false"
+        :close-on-press-escape="false"
+        append-to-body
+        width="60%"
+        class="dialog question-dialog"
+        top="6vh"
+        @close="closeDialog"
+    >
+        <el-form
+            ref="form"
+            :label-width="formLabelWidth"
+            :model="form"
+            :rules="rules"
+            class="question-form"
+            :class="readonly ? 'readonly-form' : ''"
+            @submit.native.prevent
+        >
+            <div class="inline-item" style="margin-bottom:16px">
+                <el-form-item label="题型:" prop="ti_xing_">
+                    <el-select
+                        v-model="form.ti_xing_"
+                        filterable
+                        width="100%"
+                        placeholder="请选择题型"
+                        :disabled="readonly"
+                    >
+                        <el-option
+                            v-for="item in surveyQuestionType"
+                            :key="item.value"
+                            :label="item.label"
+                            :value="item.value"
+                        />
+                    </el-select>
+                </el-form-item>
+            </div>
+            <el-form-item label="题干:" prop="ti_gan_">
+                <el-input
+                    v-model="form.ti_gan_"
+                    type="textarea"
+                    :maxlength="512"
+                    :rows="2"
+                    :autosize="readonly"
+                    :disabled="readonly"
+                    placeholder="请输入题干内容"
+                />
+            </el-form-item>
+
+            <template v-if="['单选题', '多选题'].includes(form.ti_xing_)">
+                <el-form-item
+                    v-for="(item, index) in optionList"
+                    :key="`${item.value}${index}`"
+                    class="option-item"
+                >
+                    <template slot="label">
+                        <div class="custom-label">{{ `选项${item.value}:` }}</div>
+                    </template>
+                    <el-input
+                        v-model="item.content"
+                        type="textarea"
+                        :rows="1"
+                        :autosize="readonly"
+                        :disabled="readonly"
+                        placeholder="请输入选项内容,最多可配置8个选项"
+                    />
+                    <div class="operate-btn">
+                        <el-button
+                            v-if="index === 0 && optionList.length < 8"
+                            type="primary"
+                            :tabindex="-1"
+                            icon="el-icon-plus"
+                            circle
+                            @click="addOption"
+                        />
+                        <el-button
+                            v-else-if="index === optionList.length - 1"
+                            type="danger"
+                            :tabindex="-1"
+                            icon="el-icon-delete"
+                            circle
+                            @click="subOption"
+                        />
+                    </div>
+                </el-form-item>
+            </template>
+            <el-form-item label="是否必填:" prop="shi_fou_bi_tian_">
+                <el-radio-group v-model="form.shi_fou_bi_tian_" :disabled="readonly">
+                    <el-radio-button label="是">是</el-radio-button>
+                    <el-radio-button label="否">否</el-radio-button>
+                </el-radio-group>
+            </el-form-item>
+            <el-form-item label="备注:" prop="bei_zhu_">
+                <el-input
+                    v-model="form.bei_zhu_"
+                    type="textarea"
+                    :rows="2"
+                    :autosize="readonly"
+                    :disabled="readonly"
+                    placeholder="请输入题目备注信息"
+                />
+            </el-form-item>
+        </el-form>
+        <div slot="footer" class="el-dialog--center">
+            <ibps-toolbar
+                :actions="toolbars"
+                @action-event="handleActionEvent"
+            />
+        </div>
+    </el-dialog>
+</template>
+
+<script>
+import ActionUtils from '@/utils/action'
+import { surveyQuestionType, surveyDefaultOptions } from '../constants'
+export default {
+    components: {
+        IbpsImage: () => import('@/business/platform/file/image')
+    },
+    props: {
+        visible: {
+            type: Boolean,
+            default: false
+        },
+        // 题目数据
+        quesData: {
+            type: Object,
+            default: () => ({})
+        },
+        readonly: {
+            type: Boolean,
+            default: false
+        }
+    },
+    data () {
+        const { userList = [], deptList = [], userId, level = {}, position } = this.$store.getters || {}
+        const defaultType = surveyQuestionType.length ? surveyQuestionType[0].value : ''
+        return {
+            userId,
+            userList,
+            surveyQuestionType,
+            deptList: deptList.filter(i => i.depth === 4),
+            title: '',
+            formLabelWidth: '120px',
+            dialogVisible: this.visible,
+            dialogLoading: false,
+            form: {
+                bian_zhi_bu_men_: position && position.split(',').at(-1),
+                bian_zhi_ren_: userId,
+                bian_zhi_shi_jian: this.$common.getDateNow(19),
+                di_dian_: level.second || level.first,
+                ti_gan_: '',
+                ti_xing_: defaultType,
+                bei_zhu_: '',
+                xuan_xiang_: '',
+                pai_xu_: 0,
+                shi_fou_bi_tian_: '是'
+            },
+            questionTags: [],
+            toolbars: [
+                {
+                    key: 'submit',
+                    icon: 'ibps-icon-save',
+                    label: '保存',
+                    hidden: () => {
+                        return this.readonly
+                    }
+                },
+                {
+                    key: 'submitAndContinue',
+                    icon: 'ibps-icon-send',
+                    label: '保存并继续',
+                    type: 'warning',
+                    hidden: () => {
+                        return this.readonly || this.isEdit
+                    }
+                },
+                {
+                    key: 'reset',
+                    icon: 'ibps-icon-refresh',
+                    label: '重置',
+                    type: 'info',
+                    hidden: () => {
+                        return this.readonly || this.isEdit
+                    }
+                },
+                { key: 'cancel', label: '关闭' }
+            ],
+            rules: {
+                ti_gan_: [{ required: true, message: this.$t('validate.required') }],
+                ti_xing_: [{ required: true, message: this.$t('validate.required') }]
+            },
+            optionList: JSON.parse(JSON.stringify(surveyDefaultOptions))
+        }
+    },
+    computed: {
+        isEdit () {
+            return this.quesData.$index >= 0
+        }
+    },
+    watch: {
+        visible: {
+            handler (val, oldVal) {
+                this.dialogVisible = this.visible
+            }
+            // immediate: true
+        }
+    },
+    mounted () {
+        this.getData()
+    },
+    methods: {
+        addOption () {
+            this.optionList.push({
+                value: String.fromCharCode(this.optionList[0].value.charCodeAt(0) + this.optionList.length),
+                radio: null,
+                checkbox: [],
+                content: ''
+            })
+        },
+        subOption () {
+            this.optionList.pop()
+        },
+        changeQuestionType () {
+            this.optionList = JSON.parse(JSON.stringify(surveyDefaultOptions))
+        },
+        handleActionEvent ({ key }) {
+            switch (key) {
+                case 'submit':
+                    this.handleSubmit(key)
+                    break
+                case 'submitAndContinue':
+                    this.handleSubmit(key)
+                    break
+                case 'reset':
+                    this.resetForm()
+                    break
+                case 'cancel':
+                    this.closeDialog()
+                    break
+                default:
+                    break
+            }
+        },
+        // 获取题库数据
+        getData () {
+            this.title = this.readonly ? '题目详情' : this.isEdit ? '编辑题目' : '添加题目'
+            if (this.isEdit) {
+                Object.assign(this.form, this.quesData.row)
+                if (this.form.ti_xing_ === '单选题' || this.form.ti_xing_ === '多选题') {
+                    const options = this.form.xuan_xiang_ ? JSON.parse(this.form.xuan_xiang_) : {}
+                    this.optionList = []
+                    Object.keys(options).forEach(key => {
+                        this.optionList.push({
+                            value: key,
+                            content: options[key]
+                        })
+                    })
+                }
+            }
+        },
+        handleSubmit (action) {
+            this.$refs.form.validate(async (valid) => {
+                if (!valid) {
+                    return ActionUtils.saveErrorMessage()
+                }
+                // 验证选项、答案内容(未被表单校验)
+                const { ti_xing_: questionType } = this.form
+                if (['单选题', '多选题'].includes(questionType)) {
+                    const emptyIndex = this.optionList.findIndex(item => !item.content)
+                    if (emptyIndex !== -1) {
+                        const tip2 = `选项${(String.fromCharCode('A'.charCodeAt(0) + emptyIndex))}内容为空,请填写后再保存!`
+                        return ActionUtils.saveErrorMessage(tip2)
+                    }
+                }
+                this.getSubmitData()
+                this.submitForm(action)
+            })
+        },
+        getSubmitData () {
+            const options = {}
+            this.optionList.forEach(item => {
+                options[item.value] = item.content
+            })
+            switch (this.form.ti_xing_) {
+                case '单选题':
+                    this.form.xuan_xiang_ = JSON.stringify(options)
+                    break
+                case '多选题':
+                    this.form.xuan_xiang_ = JSON.stringify(options)
+                    break
+                case '问答题':
+                    this.form.xuan_xiang_ = ''
+                    break
+                default:
+                    break
+            }
+        },
+        submitForm (action) {
+            if (action === 'submit') {
+                this.closeDialog(false, { ...this.quesData, row: this.form })
+            } else {
+                this.closeDialog(true, { ...this.quesData, row: this.form })
+                this.resetForm()
+            }
+        },
+        resetForm () {
+            this.$refs.form.resetFields()
+            this.changeQuestionType()
+        },
+        // 关闭当前窗口
+        closeDialog (visible = false, data) {
+            this.$emit('close', visible, data)
+        }
+    }
+}
+</script>
+<style lang="scss" scoped>
+    .question-dialog {
+        ::v-deep {
+            .el-rate{
+                padding: 6px 0 0 0;
+            }
+            .el-dialog {
+                min-width: 1080px;
+            }
+            .el-dialog__body {
+                height: calc(88vh - 200px);
+            }
+            .el-form-item {
+                margin-bottom: 14px !important;
+                &:last-child {
+                    margin-bottom: 0 !important;
+                }
+                .el-form-item__label {
+                    font-size: 14px !important;
+                }
+            }
+            .el-form-item--small .el-form-item__error {
+                padding-top: 6px;
+            }
+            .el-radio-button__orig-radio {
+                &:disabled + .el-radio-button__inner {
+                    color: #606266;
+                }
+                &:disabled:checked + .el-radio-button__inner {
+                    color: #fff;
+                    background-color: #409EFF;
+                }
+            }
+        }
+        .readonly-form {
+            ::v-deep {
+                .el-radio, .el-checkbox, .el-radio-button, .el-input, .el-select, .el-textarea, .el-input-number, .el-button, .el-upload {
+                    pointer-events: none;
+                }
+            }
+        }
+        .qustion-tag {
+            margin-right: 10px;
+            height: 32px;
+            line-height: 30px;
+            ::v-deep {
+                .el-icon-close {
+                    top: 0px;
+                }
+            }
+        }
+        .button-new-tag {
+            height: 32px;
+            line-height: 30px;
+            padding-top: 0;
+            padding-bottom: 0;
+        }
+        .input-new-tag {
+            width: 100px;
+            vertical-align: bottom;
+        }
+        .question-form {
+            padding: 20px;
+        }
+        .ibps-image {
+            font-size: 0;
+            ::v-deep {
+                .el-upload--picture-card {
+                    font-size: 24px;
+                }
+            }
+        }
+        .inline-item {
+            display: flex;
+            .el-form-item {
+                flex: 1;
+                .el-select {
+                    width: 100%;
+                }
+            }
+        }
+        .mb-20 {
+            margin-bottom: 20px;
+        }
+        .option-item {
+            ::v-deep {
+                .el-form-item__content {
+                    display: flex;
+                    .el-input {
+                        flex: 1;
+                    }
+                    .el-radio-group, .el-checkbox-group {
+                        width: 100px;
+                        margin-left: 10px;
+                        line-height: 28px;
+                        .el-radio {
+                            line-height: 28px;
+                        }
+                    }
+                    .operate-btn {
+                        width: 32px;
+                        min-width: 32px;
+                        margin-left: 10px;
+                        line-height: 30px;
+                    }
+                }
+            }
+            .custom-label {
+                &::before {
+                    content: '*';
+                    color: #F56C6C;
+                    margin-right: 4px;
+                }
+            }
+        }
+    }
+</style>

+ 770 - 0
src/views/platform/examination/questionBank/survey.vue

@@ -0,0 +1,770 @@
+<template>
+    <el-dialog
+        :title="title"
+        :visible.sync="dialogVisible"
+        :close-on-click-modal="false"
+        :close-on-press-escape="false"
+        append-to-body
+        width="60%"
+        class="dialog paper-dialog"
+        top="6vh"
+        @close="closeDialog"
+    >
+        <el-form
+            ref="form"
+            :label-width="formLabelWidth"
+            :model="form"
+            :rules="rules"
+            class="paper-form"
+            :class="readonly ? 'readonly-form' : ''"
+            @submit.native.prevent
+        >
+            <el-form-item label="问卷名称:" prop="wen_juan_ming_che">
+                <el-input
+                    v-model="form.wen_juan_ming_che"
+                    type="text"
+                    :maxlength="128"
+                    :disabled="readonly"
+                />
+            </el-form-item>
+            <el-form-item label="问候语:" prop="wen_hou_yu_">
+                <el-input
+                    v-model="form.wen_hou_yu_"
+                    type="textarea"
+                    :disabled="readonly"
+                />
+            </el-form-item>
+            <el-form-item label="备注:" prop="bei_zhu_">
+                <el-input
+                    v-model="form.bei_zhu_"
+                    type="textarea"
+                    :disabled="readonly"
+                />
+            </el-form-item>
+        </el-form>
+        <div class="question-table">
+            <div class="table-title">
+                <span>问卷试题信息</span>
+                <div class="table-btn">
+                    <el-button v-if="!readonly" type="success" size="mini" icon="el-icon-plus" @click="addItems">添加</el-button>
+                    <el-button v-if="!readonly" type="primary" size="mini" icon="ibps-icon-sign-in" @click="importQuestions">导入题目</el-button>
+                    <el-button v-if="!readonly" type="primary" size="mini" icon="ibps-icon-sign-in" @click="exportQuestions">导出题目</el-button>
+                    <el-button v-if="!readonly" type="danger" size="mini" icon="el-icon-delete" @click="removeItems">删除</el-button>
+                </div>
+            </div>
+            <el-table
+                ref="elTable"
+                :data="showPaperList"
+                border
+                stripe
+                highlight-current-row
+                style="width: 100%"
+                max-height="400px"
+                class="exam-table"
+                @selection-change="handleSelectionChange"
+            >
+                <el-table-column
+                    v-if="!readonly"
+                    width="50"
+                    type="selection"
+                />
+                <el-table-column label="序号" type="index" :index="showIndex" width="60" />
+                <el-table-column
+                    prop="pai_xu_"
+                    label="排序"
+                    width="100"
+                >
+                    <template slot-scope="{row}">
+                        <el-input v-if="!readonly" v-model.number="row.pai_xu_" type="number" size="mini" />
+                        <span v-else>{{ row.pai_xu_ }}</span>
+                    </template>
+                </el-table-column>
+                <el-table-column
+                    prop="ti_gan_"
+                    label="题干"
+                    min-width="150"
+                >
+                    <!-- <template slot-scope="scope">
+                        <el-popover trigger="hover" placement="top">
+                            <div class="question-info">
+                                <div class="left">
+                                    <div class="question-info-item">
+                                        <div class="label">出题人</div>
+                                        <div class="value">{{ transformUser(scope.row.creator) }}</div>
+                                    </div>
+                                    <div class="question-info-item">
+                                        <div class="label">选项类型</div>
+                                        <div class="value">{{ scope.row.optionType || '—' }}</div>
+                                    </div>
+                                    <div class="question-info-item">
+                                        <div class="label">评分方式</div>
+                                        <div class="value">{{ scope.row.rateType }}</div>
+                                    </div>
+                                    <div class="question-info-item">
+                                        <div class="label">评分人</div>
+                                        <div class="value">{{ transformUser(scope.row.rater) }}</div>
+                                    </div>
+                                    <div class="question-info-item">
+                                        <div class="label">标签</div>
+                                        <div class="value">{{ scope.row.quesTag }}</div>
+                                    </div>
+                                    <div class="question-info-item">
+                                        <div class="label">状态</div>
+                                        <div class="value">{{ scope.row.quesState }}</div>
+                                    </div>
+                                </div>
+                                <div class="right">
+                                    <ibps-image
+                                        :value="showImgs(scope,3)"
+                                        height="180"
+                                        width="180"
+                                        :disabled="true"
+                                    />
+                                </div>
+
+                            </div>
+                            <div slot="reference" class="name-wrapper">{{ scope.row.content }}</div>
+                        </el-popover>
+                    </template> -->
+                </el-table-column>
+                <el-table-column
+                    prop="ti_xing_"
+                    label="题型"
+                    width="70"
+                />
+                <el-table-column
+                    prop="shi_fou_bi_tian_"
+                    label="是否必填"
+                    width="100"
+                />
+                <el-table-column
+                    fixed="right"
+                    label="操作"
+                    width="100"
+                >
+                    <template slot-scope="scope">
+                        <el-button
+                            v-if="!readonly"
+                            type="text"
+                            size="medium"
+                            @click="handleColumnAction(scope, false)"
+                        >修改</el-button>
+                        <!-- <el-button
+                            v-if="!readonly"
+                            type="text"
+                            style="color: #f56c6c;"
+                            size="medium"
+                            @click="handleRemove(scope.row)"
+                        >删除</el-button> -->
+                        <el-button
+                            v-if="readonly"
+                            type="text"
+                            style="color: #909399;"
+                            size="medium"
+                            @click="handleColumnAction(scope, true)"
+                        >详情</el-button>
+                    </template>
+                </el-table-column>
+            </el-table>
+
+            <el-pagination
+                style="margin-top: 5px; padding-bottom: 10px"
+                :current-page="currentPage"
+                :page-sizes="[10, 20,30, 50,100]"
+                :page-size="pageSize"
+                layout="prev,pager,next,jumper,sizes,->,total"
+                :total="questionData.length"
+                @size-change="handleSizeChange"
+                @current-change="handleCurrentChange"
+            />
+
+        </div>
+        <div slot="footer" class="el-dialog--center">
+            <ibps-toolbar
+                :actions="toolbars"
+                @action-event="handleActionEvent"
+            />
+        </div>
+        <ques-edit
+            v-if="questionDialogVisible"
+            :visible.sync="questionDialogVisible"
+            :ques-data="quesData"
+            :readonly="quesReadonly"
+            @close="questionDialogClose"
+        />
+        <input id="" ref="file" style="display:none" type="file" name="" accept=".xlsx,.xls" @change="handleUploadChange">
+    </el-dialog>
+</template>
+
+<script>
+import xlsx from 'xlsx'
+import fs from 'file-saver'
+import dayjs from 'dayjs'
+import { surveyQuestionType } from '../constants'
+import ActionUtils from '@/utils/action'
+export default {
+    components: {
+        QuesEdit: () => import('../question/survey'),
+        IbpsCustomDialog: () => import('@/business/platform/data/templaterender/custom-dialog'),
+        IbpsImage: () => import('@/business/platform/file/image')
+    },
+    props: {
+        visible: {
+            type: Boolean,
+            default: false
+        },
+        id: {
+            type: String,
+            default: ''
+        },
+        readonly: {
+            type: Boolean,
+            default: false
+        }
+    },
+    data () {
+        const { userList = [], deptList = [], userId, level = {}, position } = this.$store.getters || {}
+        return {
+            multipleSelection: [],
+            pageSize: 10,
+            currentPage: 1,
+            userList,
+            level: level.second || level.first,
+            deptList: deptList.filter(i => i.depth === 4),
+            title: this.readonly ? '问卷明细' : this.id ? '编辑问卷' : '创建问卷',
+            formLabelWidth: '150px',
+            dialogVisible: this.visible,
+            dialogLoading: false,
+            questionData: [],
+            quesData: {},
+            questionDialogVisible: false,
+            quesId: '',
+            quesIdList: [],
+            quesReadonly: false,
+            form: {
+                bian_zhi_bu_men_: position && position.split(',').at(-1),
+                bian_zhi_ren_: userId,
+                bian_zhi_shi_jian: this.$common.getDateNow(19),
+                di_dian_: level.second || level.first,
+                wen_juan_ming_che: '',
+                wen_hou_yu_: '',
+                bei_zhu_: ''
+            },
+            toolbars: [
+                {
+                    key: 'submit',
+                    icon: 'ibps-icon-save',
+                    label: '保存',
+                    hidden: () => {
+                        return this.readonly
+                    }
+                },
+                { key: 'cancel', label: '关闭' }
+            ],
+            rules: {
+                wen_juan_ming_che: [{ required: true, message: this.$t('validate.required') }]
+            },
+            questionColumns: {
+                'ti_xing_': '*题型',
+                'ti_gan_': '*题干',
+                'xuan_xiang_': '选项',
+                'shi_fou_bi_tian_': '是否必填',
+                'bei_zhu_': '备注',
+                'pai_xu_': '排序'
+            }
+
+        }
+    },
+    computed: {
+        formId () {
+            return this.id
+        },
+        showPaperList () {
+            const start = (this.currentPage - 1) * this.pageSize
+            const end = start + this.pageSize
+            return this.questionData.slice(start, end)
+        }
+    },
+    watch: {
+        visible: {
+            handler (val, oldVal) {
+                this.dialogVisible = this.visible
+            }
+            // immediate: true
+        }
+    },
+    mounted () {
+        this.getData()
+    },
+    methods: {
+        // 转换对象的key
+        switchKey (data, originalObj) {
+            const result = []
+            data.forEach(item => {
+                const obj = {}
+                for (const key in originalObj) {
+                    // 对日期格式的数据做兼容处理
+                    if (item[originalObj[key]] instanceof Date) {
+                        obj[key] = dayjs(item[originalObj[key]]).add(8, 'hour').format('YYYY-MM-DD') || ''
+                    } else {
+                        obj[key] = String(item[originalObj[key]] || '').trim().replace(/\r/g, '')
+                    }
+                }
+                result.push(obj)
+            })
+            return result
+        },
+        importQuestions () {
+            this.$refs.file.click()
+        },
+        async handleUploadChange (file) {
+            try {
+                const dataBinary = await this.readFile(file.target.files[0])
+                file.target.value = null // 注意上传后要将input的值设为空
+                const workBook = xlsx.read(dataBinary, { type: 'binary', cellDates: true })
+                const workSheet = workBook.Sheets[workBook.SheetNames[0]]
+                const data = xlsx.utils.sheet_to_json(workSheet)
+                const importData = this.switchKey(data, this.questionColumns)
+                this.switchImportData(importData)
+                this.questionData.push(...importData)
+                this.$message.success('导入题目成功!')
+            } catch (error) {
+                this.$message.warning(error?.message || '导入失败!')
+            }
+        },
+        switchImportData (data) {
+            for (let i = 0; i < data.length; i++) {
+                const item = data[i]
+                const t = surveyQuestionType.find(t => t.label === item.ti_xing_)
+                if (!t) throw new Error(`第${i + 1}行题型不合法!`)
+                if (!item.ti_gan_) throw new Error(`第${i + 1}行缺少题干信息!`)
+                if (!item.shi_fou_bi_tian_ || item.shi_fou_bi_tian_ !== '否') item.shi_fou_bi_tian_ = '是'
+                if (item.ti_xing_ === '问答题') item.xuan_xiang_ = ''
+                item.pai_xu_ = +(item.pai_xu_ || 0)
+                if (isNaN(item.pai_xu_)) item.pai_xu_ = 0
+                if (item.xuan_xiang_) {
+                    const arr = item.xuan_xiang_.split('\n') || []
+                    const obj = {}
+                    for (let j = 0; j < arr.length; j++) {
+                        const code = String.fromCharCode('A'.charCodeAt() + j)
+                        const o = arr[j]
+                        obj[code] = o
+                    }
+                    item.xuan_xiang_ = JSON.stringify(obj)
+                } else if (item.ti_xing_ === '单选题' || item.ti_xing_ === '多选题') {
+                    throw new Error(`第${i + 1}行至少需要一个选项`)
+                }
+
+                item.bian_zhi_bu_men_ = this.form.bian_zhi_bu_men_
+                item.bian_zhi_ren_ = this.form.bian_zhi_ren_
+                item.bian_zhi_shi_jian = this.$common.getDateNow(19)
+                item.di_dian_ = this.form.di_dian_
+            }
+        },
+        switchExportData (data) {
+            const exportData = JSON.parse(JSON.stringify(data))
+            for (let i = 0; i < exportData.length; i++) {
+                const item = exportData[i]
+                if (item.xuan_xiang_) {
+                    const t = JSON.parse(item.xuan_xiang_)
+                    item.xuan_xiang_ = Object.values(t).join('\n')
+                }
+            }
+            return exportData
+        },
+        getTimeStamp () {
+            return dayjs().format('YYYYMMDDHHmmss')
+        },
+        async exportQuestions () {
+            const exportData = await this.switchExportData(this.multipleSelection)
+            this.xlsx(exportData, this.questionColumns, '问卷题目' + this.getTimeStamp())
+            this.$message.success('导出题目成功!')
+        },
+        questionDialogClose (visible, scope) {
+            this.questionDialogVisible = visible
+            if (scope) {
+                const data = JSON.parse(JSON.stringify(scope.row))
+                if (scope.$index >= 0) {
+                    this.$set(this.questionData, scope.$index, data)
+                } else {
+                    this.questionData.push(data)
+                }
+            }
+        },
+        addItems () {
+            this.quesData = {}
+            this.questionDialogVisible = true
+        },
+        // 默认展示三张图片
+        showImgs (scope, showNumber = 3) {
+            if (scope.row.img) {
+                return JSON.parse(scope.row.img).slice(0, showNumber)
+            }
+            return ''
+        },
+        // 分页连续序号
+        showIndex (index) {
+            return index + 1 + (this.currentPage - 1) * this.pageSize
+        },
+        // 当前页码改变
+        handleCurrentChange (val) {
+            this.currentPage = val
+        },
+        // 页码选择器改变
+        handleSizeChange (val) {
+            this.pageSize = val
+            this.currentPage = 1
+        },
+        changeLimit (e) {
+            this.form.xian_kao_ci_shu_ = e === '1' ? 1 : '不限'
+        },
+        transformUser (user) {
+            const idList = user.split(',')
+            const { userList = [] } = this.$store.getters
+            const nameList = idList.map(id => {
+                const user = userList.find(u => u.userId === id) || {}
+                return user.userName || '-'
+            })
+            return nameList.join(',')
+        },
+        handleColumnAction (scope, readonly) {
+            this.quesReadonly = readonly
+            this.questionDialogVisible = true
+            this.quesData = scope
+        },
+        handleRemove (row) {
+            this.$confirm('确定要删除该题目吗?删除操作将在问卷信息保存后生效', '提示', {
+                confirmButtonText: '确定',
+                cancelButtonText: '取消',
+                type: 'warning'
+            }).then(() => {
+                this.questionData = this.questionData.filter(item => item.quesId !== row.quesId)
+            })
+        },
+        handleActionEvent ({ key }) {
+            switch (key) {
+                case 'submit':
+                    this.handleSubmit()
+                    break
+                case 'cancel':
+                    this.closeDialog()
+                    break
+                default:
+                    break
+            }
+        },
+        // 获取问卷数据
+        async getData () {
+            if (this.$utils.isEmpty(this.formId)) {
+                return
+            }
+            const sql = `select * from t_myddcwjb where id_='${this.formId}'`
+            const { variables: { data = [] } = {}} = await this.$common.request('sql', sql)
+            data.length && (this.form = data[0])
+
+            const sql2 = `select * from t_myddcwjtmb where parent_id_='${this.formId}' order by pai_xu_+0 asc`
+            const { variables: { data: data2 = [] } = {}} = await this.$common.request('sql', sql2)
+            data2.length && (this.questionData = data2) && (this.quesIdList = data2.map(i => i.id_))
+        },
+        handleSubmit () {
+            this.$refs.form.validate(async (valid) => {
+                if (valid) {
+                    await this.submitForm()
+                } else {
+                    ActionUtils.saveErrorMessage()
+                }
+            })
+        },
+        async submitForm () {
+            if (this.formId) {
+                await this.goUpdate()
+            } else {
+                await this.goAdd()
+            }
+            this.closeDialog(true)
+        },
+        async goUpdate () {
+            const updateParamsRecord = {
+                tableName: 't_myddcwjb',
+                updList: [{
+                    where: {
+                        id_: this.formId
+                    },
+                    param: {
+                        wen_juan_ming_che: this.form.wen_juan_ming_che,
+                        wen_hou_yu_: this.form.wen_hou_yu_,
+                        bei_zhu_: this.form.bei_zhu_
+                    }
+                }]
+            }
+            await this.$common.request('update', updateParamsRecord)
+
+            const updateArr = []
+            const deleteArr = []
+            const addArr = []
+            this.questionData.forEach(i => {
+                if (i.id_) {
+                    updateArr.push(i)
+                } else {
+                    addArr.push(i)
+                }
+            })
+            this.quesIdList.forEach(i => {
+                const t = updateArr.find(item => item.id_ === i)
+                if (!t) deleteArr.push(i)
+            })
+
+            // 增
+            const addParams = {
+                tableName: 't_myddcwjtmb',
+                paramWhere: addArr.map(i => ({
+                    ...i,
+                    parent_id_: this.formId
+                }))
+            }
+            addArr.length > 0 && (await this.$common.request('add', addParams))
+            // 删
+            const params = {
+                tableName: 't_myddcwjtmb',
+                paramWhere: {
+                    id_: deleteArr.join(',')
+                }
+            }
+            deleteArr.length > 0 && (await this.$common.request('delete', params))
+            // 改
+            const updateParamsRecord2 = {
+                tableName: 't_myddcwjtmb',
+                updList: updateArr.map(i => ({
+                    where: {
+                        id_: i.id_
+                    },
+                    param: {
+                        ti_gan_: i.ti_gan_,
+                        ti_xing_: i.ti_xing_,
+                        bei_zhu_: i.bei_zhu_,
+                        xuan_xiang_: i.xuan_xiang_,
+                        pai_xu_: i.pai_xu_,
+                        shi_fou_bi_tian_: i.shi_fou_bi_tian_
+                    }
+                }))
+            }
+
+            updateArr.length > 0 && (await this.$common.request('update', updateParamsRecord2))
+            this.$message.success('编辑问卷成功!')
+        },
+        async goAdd () {
+            // 新增问卷
+            const addParams = {
+                tableName: 't_myddcwjb',
+                paramWhere: [this.form]
+            }
+            const { variables: { cont }} = await this.$common.request('add', addParams)
+            if (cont.length > 0) {
+                if (this.questionData.length > 0) {
+                    // 给问卷新增题目
+                    const addParams2 = {
+                        tableName: 't_myddcwjtmb',
+                        paramWhere: this.questionData.map(i => ({
+                            ...i,
+                            parent_id_: cont[0].id_
+                        }))
+                    }
+                    await this.$common.request('add', addParams2)
+                }
+                this.$message.success('新增问卷成功!')
+            }
+        },
+        // table复选框
+        handleSelectionChange (val) {
+            this.multipleSelection = val
+        },
+        // 批量删除
+        removeItems () {
+            if (this.multipleSelection.length === 0) {
+                return this.$message.warning('请选择需要删除的题目!')
+            }
+            this.$confirm('确定要删除所选中的题目吗?删除操作将在问卷信息保存后生效', '提示', {
+                confirmButtonText: '确定',
+                cancelButtonText: '取消',
+                type: 'warning'
+            }).then(() => {
+                this.questionData = this.questionData.filter(item => !this.multipleSelection.includes(item))
+                this.multipleSelection = []
+            })
+        },
+        // 关闭当前窗口
+        closeDialog (refresh) {
+            this.$emit('update:visible', false, refresh)
+        },
+        updateData (data) {
+            this.questionData = data
+        },
+        xlsx (json, fields, filename = '.xlsx') { // 导出xlsx
+            json.forEach(item => {
+                for (const i in item) {
+                    if (fields.hasOwnProperty(i)) {
+                        item[fields[i]] = item[i]
+                    }
+                    delete item[i] // 删除原先的对象属性
+                }
+            })
+            const sheetName = filename // excel的文件名称
+            const wb = xlsx.utils.book_new() // 工作簿对象包含一SheetNames数组,以及一个表对象映射表名称到表对象。XLSX.utils.book_new实用函数创建一个新的工作簿对象。
+            const ws = xlsx.utils.json_to_sheet(json, { header: Object.values(fields) }) // 将JS对象数组转换为工作表。
+            wb.SheetNames.push(sheetName)
+            wb.Sheets[sheetName] = ws
+            const defaultCellStyle = { font: { name: 'Verdana', sz: 13, color: 'FF00FF88' }, fill: { fgColor: { rgb: 'FFFFAA00' }}}// 设置表格的样式
+            const wopts = { bookType: 'xlsx', bookSST: false, type: 'binary', cellStyles: true, defaultCellStyle: defaultCellStyle, showGridLines: false } // 写入的样式
+            const wbout = xlsx.write(wb, wopts)
+            const blob = new Blob([this.s2ab(wbout)], { type: 'application/octet-stream' })
+            fs.saveAs(blob, filename + '.xlsx')
+        },
+        s2ab (s) {
+            let buf
+            if (typeof ArrayBuffer !== 'undefined') {
+                buf = new ArrayBuffer(s.length)
+                const view = new Uint8Array(buf)
+                for (let i = 0; i !== s.length; ++i) view[i] = s.charCodeAt(i) & 0xff
+                return buf
+            } else {
+                buf = new Array(s.length)
+                for (let i = 0; i !== s.length; ++i) buf[i] = s.charCodeAt(i) & 0xFF
+                return buf
+            }
+        },
+        /* 读取文件 将文件转换为二进制 */
+        readFile (file) {
+            return new Promise(resolve => {
+                const reader = new FileReader()
+                reader.readAsBinaryString(file)
+                reader.onload = ev => {
+                    resolve(ev.target.result)
+                }
+            })
+        }
+    }
+}
+</script>
+<style lang="scss" scoped>
+    .paper-dialog {
+        ::v-deep {
+            .el-dialog {
+                min-width: 1080px;
+            }
+            .el-dialog__body {
+                height: calc(88vh - 200px);
+            }
+            .el-form-item {
+                margin-bottom: 14px !important;
+                &:last-child {
+                    margin-bottom: 0 !important;
+                }
+                .el-form-item__label {
+                    font-size: 14px !important;
+                }
+            }
+            .el-form-item--small .el-form-item__error {
+                padding-top: 6px;
+            }
+        }
+        .readonly-form {
+            ::v-deep {
+                .el-radio, .el-checkbox, .el-radio-button, .el-input, .el-select, .el-textarea, .el-input-number {
+                    pointer-events: none;
+                }
+            }
+        }
+        .paper-form {
+            padding: 20px 20px 14px 20px;
+        }
+        .inline-item {
+            ::v-deep {
+                .el-radio-group {
+                    margin-right: 20px;
+                }
+            }
+            .time {
+                display: inline-block;
+            }
+        }
+        .unit {
+            display: inline-block;
+            margin: 0 20px 0 5px;
+        }
+        .question-table {
+            margin-bottom: 20px;
+            padding: 0 20px;
+            ::v-deep {
+                .el-table {
+                    th {
+                        font-size: 14px !important;
+                        text-align: center;
+                    }
+                    td {
+                        font-size: 14px !important;
+                    }
+                    .el-table__row {
+                        cursor: pointer;
+                    }
+                }
+            }
+            .question-select {
+                display: flex;
+                align-items: center;
+                .label {
+                    width: 138px;
+                    padding-right: 12px;
+                    text-align: right;
+                }
+                .custom-dialog {
+                    flex: 1;
+                }
+                margin-bottom: 10px;
+            }
+            .table-title {
+                font-size: 16px;
+                font-weight: 600;
+                margin: 20px 0 10px;
+                display: flex;
+                justify-content: space-between;
+                align-items: center;
+            }
+        }
+    }
+    .question-info {
+        overflow:auto;
+        max-width: 536px;
+        display: flex;
+        .question-info-item {
+            display: flex;
+            margin-bottom: 10px;
+            max-width: 200px;
+            font-size: 14px;
+            .label {
+                width: 100px;
+                font-size: 14px;
+                color: #606266;
+                text-align: left;
+            }
+            .value {
+                font-weight: 600;
+                overflow: hidden;
+                text-overflow: ellipsis;
+                white-space: nowrap;
+            }
+        }
+        .right{
+            display: flex;
+            margin-left: 20px;
+            .ibps-image{
+                font-size: 0;
+                ::v-deep{
+                    .list-group{
+                        display: flex;
+                    }
+                }
+
+            }
+        }
+    }
+</style>

+ 96 - 0
src/views/platform/examination/survey/all.vue

@@ -0,0 +1,96 @@
+<template>
+    <div class="all">
+        <el-table
+            ref="elTable"
+            :data="tableData"
+            border
+            stripe
+            highlight-current-row
+            style="width: 100%"
+            max-height="400px"
+            class="exam-table"
+        >
+            <el-table-column
+                prop="xu_hao_"
+                label="序号"
+                width="50"
+            />
+            <el-table-column
+                prop="ti_gan_"
+                label="题干"
+                min-width="200"
+            />
+            <el-table-column
+                v-for="(item,index) in xuanXiangCount"
+                :key="index"
+                :prop="`xuan_xiang_${index+1}`"
+                :label="`选项${index+1}`"
+                width="100"
+            />
+        </el-table>
+
+    </div>
+</template>
+
+<script>
+export default {
+    props: {
+        statisItemData: {
+            type: Object,
+            default: () => ({})
+        }
+    },
+    data () {
+        return {
+            // tableData: []
+        }
+    },
+    computed: {
+        tableData () {
+            // console.log('statisItemData', this.statisItemData)
+            const arr = []
+            let xu_hao_ = 1
+            for (const key in this.statisItemData) {
+                const val = this.statisItemData[key]
+                const obj = {}
+                if (val[0].xuan_xiang_) {
+                    const t = Object.keys(JSON.parse(val[0].xuan_xiang_)).length
+                    for (let i = 1; i <= 8; i++) {
+                        if (i <= t) {
+                            obj[`xuan_xiang_${i}`] = (val.filter(item => item.da_an_.includes(String.fromCharCode('A'.charCodeAt() + i - 1))).length / val.length * 100).toFixed(2) + ' %'
+                        } else {
+                            obj[`xuan_xiang_${i}`] = '/'
+                        }
+                    }
+                }
+                if (val[0].ti_xing_ === '单选题' || val[0].ti_xing_ === '多选题') {
+                    arr.push({
+                        xu_hao_: xu_hao_,
+                        ti_gan_: val[0].ti_gan_,
+                        ...obj
+                    })
+                }
+                xu_hao_++
+            }
+            // console.log('arr', arr)
+            return arr
+        },
+        // 计算最长选项
+        xuanXiangCount () {
+            let ans = 4
+            for (const key in this.statisItemData) {
+                const val = this.statisItemData[key]
+                if (val[0].xuan_xiang_) {
+                    const t = JSON.parse(val[0].xuan_xiang_)
+                    ans = Math.max(Object.keys(t).length, ans)
+                }
+            }
+            return ans
+        }
+    },
+    mounted () {
+
+    }
+
+}
+</script>

+ 127 - 0
src/views/platform/examination/survey/itemEchart.vue

@@ -0,0 +1,127 @@
+<template>
+    <div class="echart" style="width:100%">
+        <div class="pie" style="width: 50%;height:420px;">
+            <div ref="echart1" style="width: 100%;height:100%;" />
+        </div>
+        <div class="bar" style="width: 50%;height:420px;">
+            <div ref="echart2" style="width: 100%;height:100%" />
+        </div>
+    </div>
+</template>
+
+<script>
+import * as echarts from 'echarts'
+export default {
+    props: {
+        statisItemData: {
+            type: Array,
+            default: () => []
+        }
+    },
+    data () {
+        return {
+
+        }
+    },
+    mounted () {
+        const echart1 = echarts.init(this.$refs.echart1)
+        const echart2 = echarts.init(this.$refs.echart2)
+        const option1 = this.formatData1()
+        const option2 = this.formatData2()
+        echart1.setOption(option1)
+        echart2.setOption(option2)
+        echart1.resize()
+        echart2.resize()
+    },
+    methods: {
+        formatData1 () {
+            let t = {}
+            const data = []
+            if (this.statisItemData[0].xuan_xiang_) {
+                t = JSON.parse(this.statisItemData[0].xuan_xiang_)
+                let cnt = 1
+                for (const key in t) {
+                    data.push({
+                        value: this.statisItemData.filter(item => item.da_an_.includes(key)).length,
+                        name: `选项${cnt}`
+                    })
+                    cnt++
+                }
+            }
+            return {
+                title: {
+                    // text: this.statisItemData[0].ti_gan_,
+                    subtext: this.statisItemData[0].ti_gan_,
+                    left: 'center'
+                },
+                tooltip: {
+                    trigger: 'item'
+                },
+                legend: {
+                    orient: 'vertical',
+                    left: 'left'
+                },
+                series: [
+                    {
+                        // name: 'Access From',
+                        type: 'pie',
+                        radius: '50%',
+                        data: data,
+                        emphasis: {
+                            itemStyle: {
+                                shadowBlur: 10,
+                                shadowOffsetX: 0,
+                                shadowColor: 'rgba(0, 0, 0, 0.5)'
+                            }
+                        }
+                    }
+                ]
+            }
+        },
+        formatData2 () {
+            let t = {}
+            const data = []
+            if (this.statisItemData[0].xuan_xiang_) {
+                t = JSON.parse(this.statisItemData[0].xuan_xiang_)
+                let cnt = 1
+                for (const key in t) {
+                    data.push({
+                        value: this.statisItemData.filter(item => item.da_an_.includes(key)).length,
+                        name: `选项${cnt}`
+                    })
+                    cnt++
+                }
+            }
+            return {
+                tooltip: {
+                    trigger: 'item'
+                },
+                xAxis: {
+                    type: 'category',
+                    name: '选项',
+                    data: data.map(item => item.name)
+                },
+                yAxis: {
+                    type: 'value',
+                    name: '人数',
+                    minInterval: 1
+                },
+                series: [
+                    {
+                        data: data.map(item => item.value),
+                        type: 'bar',
+                        barWidth: 30
+                    }
+                ]
+            }
+        }
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+    .echart{
+        display: flex;
+        justify-content: center;
+    }
+</style>

+ 115 - 0
src/views/platform/examination/survey/itemTable.vue

@@ -0,0 +1,115 @@
+<template>
+    <div class="item-table">
+        <el-table
+            v-if="statisItemData[0].ti_xing_==='单选题' || statisItemData[0].ti_xing_==='多选题'"
+            ref="elTable"
+            :data="tableData"
+            border
+            stripe
+            highlight-current-row
+            style="width: 100%"
+            max-height="400px"
+            class="exam-table"
+        >
+            <el-table-column
+                prop="xx"
+                label="选项"
+                width="100"
+            />
+            <el-table-column
+                prop="xuan_xiang_"
+                label="选项内容"
+                min-width="200"
+            />
+            <el-table-column
+                prop="xiao_ji_"
+                label="小计"
+                width="100"
+            />
+            <el-table-column
+                prop="bi_li_"
+                label="比例"
+                width="100"
+            />
+        </el-table>
+
+        <el-table
+            v-else
+            ref="elTable2"
+            :data="tableData"
+            border
+            stripe
+            highlight-current-row
+            style="width: 100%"
+            max-height="400px"
+            class="exam-table"
+        >
+            <el-table-column
+                type="index"
+                label="序号"
+                width="50"
+            />
+
+            <el-table-column
+                prop="hui_da_"
+                label="回答"
+            />
+        </el-table>
+
+    </div>
+</template>
+
+<script>
+export default {
+    props: {
+        statisItemData: {
+            type: Array,
+            default: () => []
+        }
+    },
+    data () {
+        return {
+            // tableData: []
+        }
+    },
+    computed: {
+        tableData () {
+            let arr = []
+            if (this.statisItemData[0].ti_xing_ === '单选题' || this.statisItemData[0].ti_xing_ === '多选题') {
+                if (this.statisItemData[0].xuan_xiang_) {
+                    let ind = 1
+                    const t = JSON.parse(this.statisItemData[0].xuan_xiang_)
+                    const notChoice = this.statisItemData.filter(item => !item.da_an_).length // 未选项
+                    const validCnt = this.statisItemData.length - notChoice
+                    for (const key in t) {
+                        const cnt = this.statisItemData.filter(item => item.da_an_.includes(key)).length
+                        arr.push({
+                            xx: `选项${ind}`,
+                            xuan_xiang_: t[key],
+                            xiao_ji_: cnt,
+                            bi_li_: validCnt > 0 ? (cnt / (validCnt) * 100).toFixed(2) + '%' : '0.00%'
+                        })
+                        ind++
+                    }
+                    if (notChoice > 0) {
+                        arr.push({
+                            xx: `未选`,
+                            xuan_xiang_: '/',
+                            xiao_ji_: notChoice,
+                            bi_li_: '/'
+                        })
+                    }
+                }
+            } else {
+                arr = this.statisItemData.map(item => ({ hui_da_: item.da_an_ }))
+            }
+            // console.log('item-arr', arr)
+
+            return arr
+        }
+    },
+    mounted () {
+    }
+
+}
+</script>

+ 284 - 0
src/views/platform/examination/survey/statistics.vue

@@ -0,0 +1,284 @@
+<template>
+    <el-dialog
+        v-loading="loading"
+        :title="title"
+        :visible.sync="dialogVisible"
+        :close-on-click-modal="false"
+        :close-on-press-escape="false"
+        :show-close="false"
+        append-to-body
+        fullscreen
+        class="dialog paper-detail-dialog"
+        top="0"
+    >
+        <div slot="title" class="dialog-title">
+            <span class="dialogtitle">{{ title }}</span>
+            <div>
+                <ibps-toolbar :actions="toolbars" @action-event="handleActionEvent" />
+            </div>
+        </div>
+        <div class="container">
+            <div class="left" :style="{width:initWidth}">
+                <div class="header">
+                    <div class="header-name">
+                        调查名称:{{ diao_cha_ming_che }}
+                    </div>
+                    <div class="header-left">
+                        <span>调查对象:</span>
+                        <div>
+                            <el-select
+                                v-model="diao_cha_dui_xian"
+                                filterable
+                                width="100%"
+                                size="mini"
+                            >
+                                <el-option
+                                    v-for="(v,k) in statisData"
+                                    :key="k"
+                                    :label="k"
+                                    :value="k"
+                                />
+                            </el-select>
+                        </div>
+                    </div>
+                    <div class="header-right">
+                        <span>统计时间:</span>
+                        <div>
+                            {{ $common.getDateNow(19) }}
+                        </div>
+                    </div>
+                </div>
+                <div class="title" style="margin-left:8px">统计总览</div>
+                <div class="all" style="margin-bottom:20px">
+                    <All :statis-item-data="showData" />
+                </div>
+                <div class="title" style="margin-left:8px">统计详情</div>
+                <div v-for="(v,k,ind) in showData" :key="k" class="every">
+                    <div class="table-title">
+                        <div class="desc">
+                            {{ ind+1 }}.{{ v[0].ti_gan_ }}
+                        </div>
+                        <div class="shown">
+                            有效数量/总数量:{{ v.filter(i=>i.da_an_).length }}/{{ v.length }}
+                        </div>
+                    </div>
+                    <div class="item-table">
+                        <ItemTable :statis-item-data="v" />
+                    </div>
+                    <div v-if="v[0].ti_xing_==='单选题' || v[0].ti_xing_==='多选题'" class="item-echart">
+                        <ItemEchart :statis-item-data="v" />
+                    </div>
+                </div>
+
+            </div>
+        </div>
+    </el-dialog>
+</template>
+
+<script>
+import _ from 'lodash'
+import ibpsUserSelector from '@/business/platform/org/selector'
+import All from './all.vue'
+import ItemTable from './itemTable.vue'
+import ItemEchart from './itemEchart.vue'
+
+export default {
+    components: {
+        ibpsUserSelector, All, ItemTable, ItemEchart
+    },
+    props: {
+        id_: {
+            type: String,
+            default: ''
+        },
+        dialogVisible: {
+            type: Boolean,
+            default: false
+        },
+        diao_cha_ming_che: {
+            type: String,
+            default: ''
+        }
+    },
+    data () {
+        const { userId, position, level } = this.$store.getters
+        return {
+            statisData: {},
+            diao_cha_dui_xian: '',
+            filter: [{
+                descVal: '2',
+                includeSub: true,
+                old: 'position',
+                partyId: this.$store.getters.userInfo.employee.positions,
+                partyName: '',
+                scriptContent: '',
+                type: 'user',
+                userType: 'position'
+            }],
+            userId: userId,
+            position: position,
+            level: level.second || level.first,
+            loading: false,
+            title: '满意度调查统计',
+            toolbars: [
+                // { key: 'save', label: '保存' },
+                { key: 'cancel', label: '退出', type: 'danger' }
+            ],
+            initWidth: '60%',
+            isEdit: false,
+            isFinished: false,
+            readonly: false,
+            preParams: {},
+            Ids: [],
+            form: {
+            },
+            rules: {
+
+            }
+        }
+    },
+    computed: {
+        showData () {
+            return this.statisData?.[this.diao_cha_dui_xian] || {}
+        }
+    },
+    watch: {
+
+    },
+    mounted () {
+        this.init()
+    },
+    methods: {
+        handleActionEvent ({ key }) {
+            switch (key) {
+                case 'cancel':
+                    this.closeDialog(true)
+                    break
+                // case 'save':
+                //     this.goSave('close')
+                //     break
+                default:
+                    break
+            }
+        },
+
+        // 获取人员部门
+        getPersonPosition (id) {
+            const userList = this.$store.getters.userList
+            const bianzhiUserid = userList.find(i => i.userId === id)
+            if (bianzhiUserid) {
+                return bianzhiUserid.positionId
+            }
+        },
+        checkRequired (flag) {
+        },
+        // 刷新
+        async goRefresh () {
+        },
+        // 关闭当前窗口
+        closeDialog (needRefresh) {
+            this.$emit('update:dialogVisible', false, needRefresh)
+        },
+        async init () {
+            this.initWidth = window.innerWidth > 1600 ? '60%' : '80%'
+            console.log('id_', this.id_)
+            const sql = `select a.*,b.diao_cha_dui_xian,b.diao_cha_ming_che FROM t_myddcjlxq a LEFT JOIN t_myddcjl b on a.parent_id_=b.id_ where b.diao_cha_id_='${this.id_}' and b.shi_fou_guo_shen_='已完成' ORDER BY b.create_time_ desc`
+            const { variables: { data = [] } = {}} = await this.$common.request('sql', sql)
+            const res = _.groupBy(data, 'diao_cha_dui_xian')
+            for (const key in res) {
+                const val = res[key]
+                res[key] = _.groupBy(val, 'ti_mu_id_')
+            }
+            this.statisData = res
+            this.diao_cha_dui_xian = Object.keys(res)?.[0] || ''
+            console.log('res', res)
+        }
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+.paper-detail-dialog {
+    ::v-deep {
+        .el-dialog__header {
+            text-align: center;
+        }
+    }
+.dialog-title{
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    div{
+        z-index: 99999999;
+        position: absolute;
+        right:8vw;
+    }
+    .dialogtitle{
+        font-size: 22px;
+        font-family: SimHei;
+        font-weight: bold;
+        color: #222;
+    }
+}
+.container {
+        display: flex;
+        width: 100%;
+        justify-content: center;
+        .el-row{
+            margin: 0 !important;
+        }
+        .required{
+            color: #606266 !important;
+            &::before{
+                content: '*';
+                margin: 0 4px 0 -7.5px;
+                color: #F56C6C;
+            }
+        }
+        .left{
+            height: calc(100vh - 100px);
+            box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+            padding:20px;
+            overflow-y: auto;
+            .item{
+                width: 100%;
+            }
+            .title{
+                margin: 16px 0 6px -16px;
+            }
+            .header{
+                display: flex;
+                justify-content: space-between;
+                align-items: center;
+                .header-left{
+                    display: flex;
+                    align-items: center;
+                }
+                .header-right{
+                    display: flex;
+                    align-items: center;
+                }
+                margin-bottom: 20px;
+            }
+            .every{
+                margin-bottom: 20px;
+            }
+            .table-title{
+                display: flex;
+                justify-content: space-between;
+                align-items: center;
+            }
+        }
+    }
+}
+    ::v-deep {
+        .el-form-item__label{
+            text-align: left;
+            font-size: 12px !important;
+        }
+        .el-form-item__content{
+            font-size: 12px !important;
+            display: flex;
+        }
+    }
+</style>