初始化

This commit is contained in:
aixianling
2021-12-14 18:36:19 +08:00
parent 9afa4101b6
commit a8dff862d2
327 changed files with 88702 additions and 0 deletions

View File

@@ -0,0 +1,113 @@
<template>
<ai-list v-if="!isShowDetail">
<template slot="title">
<ai-title title="问卷表单" :isShowBottomBorder="false" :instance="instance"></ai-title>
</template>
<template slot="tabs">
<el-tabs v-model="currIndex">
<el-tab-pane v-for="(tab,i) in tabs" :key="i" :label="tab.label">
<component :areaId="areaId" :ref="tab.name" v-if="currIndex == i" :is="tab.comp" @change="onChange" lazy :instance="instance" :dict="dict" :permissions="permissions"/>
</el-tab-pane>
</el-tabs>
</template>
</ai-list>
<Add v-else-if="componentName === 'Add'" :areaId="areaId" :params="params" :instance="instance" :dict="dict" :permissions="permissions" @change="onChange"></Add>
<Statistics v-else-if="componentName === 'Statistics'" :areaId="areaId" :params="params" :instance="instance" :dict="dict" :permissions="permissions" @change="onChange"></Statistics>
</template>
<script>
import FormList from './components/FormList.vue'
import Template from './components/Template'
import Add from './components/Add'
import Statistics from './components/Statistics'
import { mapState } from 'vuex'
export default {
name: 'AppAskForm',
label: '问卷表单',
components: {
FormList,
Add,
Statistics,
Template
},
props: {
instance: Function,
dict: Object,
permissions: Function
},
computed: {
...mapState(['user']),
tabs () {
const tabList = [
{label: '表单列表', name: 'FormList', comp: FormList, permission: ''},
{label: '共享模板', name: 'Template', comp: Template, permission: ''}
].filter(() => {
return true
})
return tabList
}
},
data () {
return {
activeName: 'JoinEvent',
currIndex: '0',
componentName: '',
params: {},
areaId: '',
isShowDetail: false
}
},
created() {
this.areaId = this.user.info.areaId
},
methods: {
changeArea () {
this.$nextTick(() => {
this.$refs[this.tabs[Number(this.currIndex)].name][0].getList()
})
},
onChange (data) {
if (data.type === 'list') {
this.componentName = 'List'
this.isShowDetail = false
this.params = data.params
if (data.isQuote) {
this.currIndex = 0
}
}
if (data.type === 'detail') {
this.componentName = 'Detail'
this.isShowDetail = true
this.params = data.params
}
if (data.type === 'Statistics') {
this.componentName = 'Statistics'
this.isShowDetail = true
this.params = data.params
}
if (data.type === 'add') {
this.componentName = 'Add'
this.isShowDetail = true
this.params = data.params
}
}
}
}
</script>
<style lang="scss" scoped>
</style>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,731 @@
<template>
<ai-detail class="statistics">
<template slot="title">
<ai-title title="数据统计" isShowBack isShowBottomBorder @onBackClick="cancel(false)"></ai-title>
</template>
<template slot="content">
<ai-card title="表单信息">
<template #content>
<ai-wrapper label-width="90px">
<ai-info-item label="表单名称" :value="info.title" isLine></ai-info-item>
<ai-info-item label="发布状态"><span :style="{color: dict.getColor('questionnaireStatus', info.status)}">已发布</span></ai-info-item>
<!-- <ai-info-item label="创建人" openType="userName" :value="info.createUserName"></ai-info-item> -->
<ai-info-item label="创建时间" :value="info.createTime"></ai-info-item>
<ai-info-item label="截止时间" :value="info.periodValidityEndTime ? info.periodValidityEndTime : '永久有效'"></ai-info-item>
<ai-info-item label="提交次数限制" :value="info.commitType === '1' ? '限提交一次' : '不限次数' "></ai-info-item>
</ai-wrapper>
</template>
</ai-card>
<div class="statistics-wrapper">
<div class="statistics-wrapper__title">
<span :class="[currIndex === 0 ? 'active' : '']" @click="currIndex = 0">表单统计</span>
<span :class="[currIndex === 1 ? 'active' : '']" @click="currIndex = 1">居民统计</span>
</div>
<div class="statistics-wrapper__body">
<div v-show="currIndex === 0">
<div class="statistics-wrapper__body--info">
<span></span>
<i>{{ subjectList.length }}</i>
<span>其中</span>
<span v-for="(item, index) in fieldTypeCount" :key="index">
{{ mapType(item.field_type) }}<i>{{ item.c }}</i>{{ fieldTypeCount.length - 1 === index ? '' : '' }}
</span>
</div>
<div class="statistics-wrapper__body--list">
<div class="statistics-wrapper__body--item" v-for="(item, index) in subjectList" :key="index">
<div class="statistics-wrapper__body--top" :style="{borderBottom: ['input', 'textarea', 'upload'].indexOf(item.type) > -1 ? 'none' : '1px solid #DDDDDD'}">
<div class="left">
<h2>{{ item.fieldName }}{{ item.fixedLabel }}</h2>
</div>
<div class="right">
<span></span>
<i>{{ fieldDataCount[`field_${index}`] }}</i>
<span>条数据</span>
</div>
</div>
<div class="statistics-wrapper__body--bottom" v-if="['radio', 'checkbox', 'select'].indexOf(item.type) > -1">
<div class="statistics-wrapper__body--select" v-for="(item, i) in item.options" :key="i">
<div class="left">
<h2>{{ item.label }}</h2>
<span>{{ item.c || 0 }}</span>
</div>
<div class="right">
<div class="progress">
<div :style="{width: `${(((item.c || 0) / fieldDataCount[`field_${index}`]) * 100).toFixed(2)}%`}"></div>
</div>
<i>{{ (((item.c || 0) / fieldDataCount[`field_${index}`]) * 100).toFixed(2) }}%</i>
</div>
</div>
</div>
</div>
</div>
</div>
<div v-show="currIndex === 1" style="padding: 16px;">
<!-- <ai-search-bar>
<template #right>
<el-input
v-model="search.name"
size="small"
placeholder="请输入居民名称"
clearable
@keyup.enter.native="search.current = 1, getList()"
@clear="search.current = 1, search.name = '', getList()"
suffix-icon="iconfont iconSearch">
</el-input>
</template>
</ai-search-bar> -->
<ai-table
class="detail-table__table"
:border="true"
style="margin-top: 4px;"
:tableData="tableData"
:col-configs="colConfigs"
:total="total"
:stripe="false"
:current.sync="search.current"
:size.sync="search.size"
@getList="getList">
<el-table-column slot="userinfo" label="居民" width="260px" align="left">
<template slot-scope="{ row }">
<div class="userinfo">
<img :src="row.avatarUrl || 'https://cdn.cunwuyun.cn/dvcp/h5/defaultAvatar.png'">
<!-- <h3>{{ row.nickName }}</h3> -->
<div class="userinfo-right__top">
<h3><ai-open-data type="userName" :openid="row.nickName"></ai-open-data></h3>
</div>
</div>
</template>
</el-table-column>
<el-table-column slot="options" label="操作" align="center">
<template slot-scope="{ row }">
<div class="table-options">
<el-button type="text" @click="showForm(row.id)">查看表单</el-button>
</div>
</template>
</el-table-column>
</ai-table>
</div>
</div>
<ai-dialog
customFooter
:visible.sync="isShowForm"
@onConfirm="isShowForm = false"
width="800px"
title="表单">
<div class="middle-content form">
<div class="middle-content__wrapper">
<div>
<div class="left-item__item left-item__item--banner" key="banner" v-if="info.headPicture">
<img :src="info.headPicture">
</div>
<div class="left-item__item left-item__item--formname" key="title">
<h2>{{ info.title }}</h2>
</div>
<div class="left-item__item left-item__item--text" key="text">
<p>{{ info.tableExplain }}</p>
</div>
</div>
<div
class="left-item__item components-item"
v-for="(item, i) in targetList"
:key="i">
<div class="left-item__item--title">
<i :style="{opacity: item.required ? 1 : 0}">*</i>
<span>{{ i + 1 }}.</span>
<h2>{{ item.label }}</h2>
</div>
<div class="left-item__item--wrapper">
<template v-if="(item.type === 'radio')" >
<div class="radio-item" v-for="(field, index) in item.options" :key="index" >
<input type="radio" disabled :value="field.label" v-model="formInfo[`field_${i}`]" />
<img :src="field.img[0].url" v-if="field.img.length">
<label>{{ field.label }}</label>
</div>
</template>
<template v-if="item.type === 'upload'">
<img style="width: 100%; height: 100%;" :src="formInfo[`field_${i}`]" v-if="formInfo[`field_${i}`]">
<div class="left-item__item--upload" v-else>
<span>图片</span>
</div>
</template>
<template v-if="item.type === 'select'" >
<el-input resize="none" class="preview" type="textarea" style="color: #333" :placeholder="item.placeholder" v-model="formInfo[`field_${i}`]" disabled></el-input>
<!-- <span>{{ formInfo[`field_${i}`] }}</span> -->
<!-- <textarea :placeholder="item.placeholder" v-model="formInfo[`field_${i}`]" disabled></textarea> -->
<!-- <el-select placeholder="请选择" disabled v-model="formInfo[`field_${i}`]" style="width: 100%;">
<el-option
v-for="(item, index) in item.options"
:key="index"
:label="item.label"
:value="item.label">
</el-option>
</el-select> -->
</template>
<template v-if="(item.type === 'checkbox')" >
<div class="radio-item" v-for="(field, index) in item.options" :key="index" >
<input type="checkbox" disabled :value="field.label" v-model="formInfo[`field_${i}`]" />
<img :src="field.img[0].url" v-if="field.img.length">
<label>{{ field.label }}</label>
</div>
</template>
<template v-if="(item.type === 'input')" >
<div class="text-item">
<input :placeholder="item.placeholder" v-model="formInfo[`field_${i}`]" disabled>
</div>
</template>
<template v-if="(item.type === 'textarea')" >
<div class="textarea-item" resize="none">
<textarea :placeholder="item.placeholder" v-model="formInfo[`field_${i}`]" disabled></textarea>
</div>
</template>
</div>
</div>
</div>
</div>
<template #footer>
<el-button @click="isShowForm = false">关闭</el-button>
</template>
</ai-dialog>
</div>
</template>
</ai-detail>
</template>
<script>
export default {
name: 'Statistics',
props: {
instance: Function,
dict: Object,
params: Object
},
data () {
return {
currIndex: 0,
search: {
name: '',
size: 10,
current: 1
},
info: {},
subjectList: [],
tableData: [],
total: 0,
form: {},
fieldTypeCount: [],
fieldValueDistribution: [],
fieldDataCount: {},
isShowForm: false,
targetList: [],
formInfo: {},
colConfigs: [
{slot: 'userinfo'},
{prop: 'commitTime', label: '提交时间', align: 'center', width: '160px' },
{prop: 'userType', label: '微信类型', align: 'center', width: '100px', formart: v => this.dict.getLabel('wxUserType', v) },
{prop: 'totalScore', label: '分值', align: 'center'}
]
}
},
mounted () {
this.getInfo()
this.getFormInfo()
this.dict.load(['wxUserType']).then(() => {
this.getList()
})
},
methods: {
getList () {
this.instance.post(`/app/appquestionnairetemplate/statisticsResident?id=${this.params.id}`, null, {
params: {
...this.search
}
}).then(res => {
if (res.code == 0) {
this.tableData = res.data.records
this.total = res.data.total
this.$initWxOpenData()
}
})
},
showForm (id) {
this.instance.post(`/app/appquestionnairetemplate/queryDataInfoById?id=${this.params.id}&dataId=${id}`).then(res => {
if (res.code == 0) {
this.formInfo = res.data
this.targetList.forEach((item, index) => {
if (item.type === 'checkbox' && this.formInfo[`field_${index}`]) {
this.formInfo[`field_${index}`] = this.formInfo[`field_${index}`].split(',')
}
})
this.isShowForm = true
}
})
},
mapType (type) {
return {
upload: '上传图片',
input: '单行填空',
textarea: '多行填空',
radio: '单选',
checkbox: '多选',
select: '单下拉框'
}[type]
},
getFormInfo () {
this.instance.post(`/app/appquestionnairetemplate/statisticsTable?id=${this.params.id}`, null, {
params: {
...this.search
}
}).then(res => {
if (res.code == 0) {
this.fieldDataCount = res.data.fieldDataCount
this.fieldTypeCount = res.data.fieldTypeCount
this.fieldValueDistribution = res.data.fieldValueDistribution
this.subjectList = res.data.appQuestionnaireTemplate.fields.map((item, index) => {
const fieldInfo = JSON.parse(item.fieldInfo)
let options = fieldInfo.options
if (['radio', 'checkbox', 'select'].indexOf(item.fieldType) > -1) {
options = fieldInfo.options.map(v => {
res.data.fieldValueDistribution[`field_${index}`].forEach(info => {
if (info.fieldValue === v.label) {
v.c = info.c
}
})
return v
})
}
return {
...item,
...fieldInfo,
options
}
})
}
})
},
getInfo () {
this.instance.post(`/app/appquestionnairetemplate/queryDetailById?id=${this.params.id}`).then(res => {
if (res.code == 0) {
this.info = res.data
this.targetList = res.data.fields.map(item => {
return JSON.parse(item.fieldInfo)
})
this.$initWxOpenData()
}
})
},
cancel (isRefresh) {
this.$emit('change', {
type: 'list',
isRefresh: !!isRefresh
})
}
}
}
</script>
<style scoped lang="scss">
.statistics {
* {
box-sizing: border-box;
font-weight: normal;
font-style: normal;
}
.preview {
::v-deep .el-textarea.is-disabled, ::v-deep .el-textarea__inner {
color: #666!important;
}
}
.form {
.left-item__item--banner {
img {
width: 100%;
height: 235px;
}
.config-item__banner {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
width: 100%;
height: 235px;
line-height: 1;
border: 1px dashed #bbb;
span {
margin-top: 4px;
color: #555555;
font-size: 14px;
}
i {
font-size: 30px;
color: #8899bb;
}
}
}
.left-item__item--formname {
margin: 16px 0 32px;
padding: 0 12px;
color: #333333;
font-size: 15px;
font-weight: normal;
text-align: center;
word-break: break-all;
}
.left-item__item--text {
line-height: 20px;
// margin-bottom: 48px;
padding: 0 12px 20px;
text-align: justify;
color: #666;
font-size: 14px;
word-break: break-all;
}
.components-item {
position: relative;
padding: 16px 16px;
.left-item__item--wrapper {
& > img {
max-width: 300px;
}
}
.left-item__item--upload {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
width: 120px;
height: 120px;
border-radius: 6px;
border: 1px dashed #bbb;
i {
font-size: 24px;
color: #8899bb;
}
span {
margin-top: 4px;
font-size: 12px;
color: #555;
}
}
.text-item {
input {
display: block;
width: 100%;
height: 40px;
border: none;
border-bottom: 1px solid #ddd;
&:focus {
outline: none;
}
&:disabled {
background: #fff;
}
}
}
.textarea-item {
textarea {
width: 100%;
height: 120px;
resize: none;
border: 1px solid #ddd;
padding: 10px;
&:focus {
outline: none;
}
&:disabled {
background: #fff;
}
}
}
.radio-item {
display: flex;
margin-bottom: 10px;
input {
position: relative;
top: 2px;
}
&:last-child {
margin-bottom: 0;
}
label {
margin-left: 10px;
}
img {
width: 60px;
margin-left: 10px;
}
}
}
.left-item__item--title {
display: flex;
margin-bottom: 10px;
i {
position: relative;
top: 3px;
margin-right: 5px;
color: #E22120;
}
span {
position: relative;
top: 3px;
}
h2 {
color: #333333;
font-size: 15px;
}
}
}
.table-tags {
.el-tag {
margin-right: 8px;
margin-bottom: 8px;
border: 1px solid #D0D4DC;
background: #F3F4F7;
border-radius: 4px;
font-size: 13px;
color: #222222;
&:last-child {
margin-right: 0;
}
}
}
h2, h3 {
margin: 0;
}
.userinfo {
display: flex;
align-items: center;
img {
width: 40px;
height: 40px;
margin-right: 8px;
border-radius: 2px;
}
h3 {
font-size: 14px;
font-weight: normal;
color: #222222;
}
.userinfo-right__top {
display: flex;
align-items: center;
margin-bottom: 10px;
cursor: pointer;
white-space: nowrap;
}
span {
padding-left: 8px;
color: #2EA222;
font-size: 14px;
white-space: nowrap;
}
}
.statistics-wrapper {
background: #FFFFFF;
box-shadow: 0px 4px 6px -2px rgba(15, 15, 21, 0.15);
border-radius: 2px;
.statistics-wrapper__title {
display: flex;
align-items: center;
height: 56px;
padding: 0 16px;
border-bottom: 1px solid #EEEEEE;
span {
height: 56px;
line-height: 56px;
color: #888888;
font-size: 16px;
font-weight: 600;
cursor: pointer;
user-select: none;
border-bottom: 3px solid transparent;
&:first-child {
margin-right: 32px;
}
&.active {
color: #222222;
border-color: #2266FF;
}
}
}
.statistics-wrapper__body--list {
padding: 0 40px 20px;
.statistics-wrapper__body--item {
margin-bottom: 20px;
background: #FFFFFF;
border-radius: 4px;
border: 1px solid #DDDDDD;
}
.statistics-wrapper__body--bottom {
padding: 20px;
.statistics-wrapper__body--select {
display: flex;
align-items: center;
justify-content: space-between;
height: 48px;
& > div {
display: flex;
align-items: center;
}
.left {
h2 {
max-width: 384px;
margin-right: 10px;
overflow: hidden;
text-overflow:ellipsis;
white-space: nowrap;
font-size: 12px;
color: #222222;
}
span {
color: #888888;
font-size: 12px;
}
}
.right {
i {
width: 50px;
text-align: right;
color: #2266FF;
font-size: 12px;
}
.progress {
position: relative;
width: 500px;
height: 8px;
margin-right: 10px;
background: #EEEEEE;
border-radius: 5px;
div {
position: absolute;
top: 0;
left: 0;
height: 8px;
background: #2266FF;
border-radius: 5px;
}
}
}
}
}
.statistics-wrapper__body--top {
display: flex;
justify-content: space-between;
align-items: center;
height: 70px;
padding: 0 20px;
background: #FFFFFF;
border-radius: 4px 4px 0px 0px;
border-bottom: 1px solid #DDDDDD;
& > div {
display: flex;
align-items: center;
font-size: 14px;
}
.left {
flex: 1;
h2 {
color: #222222;
font-size: 14px;
}
}
.right {
span {
color: #888888;
}
i {
color: #2266FF;
padding: 0 4px;
}
}
}
}
.statistics-wrapper__body--info {
display: flex;
align-items: center;
height: 70px;
line-height: 1;
padding: 0 40px;
color: #555555;
font-size: 14px;
i {
padding: 0 4px;
font-weight: 600;
font-style: normal;
color: #2266FF;
font-size: 14px;
}
}
}
}
</style>

View File

@@ -0,0 +1,283 @@
<template>
<ai-list class="template" isTabs>
<template slot="content">
<ai-search-bar bottomBorder>
<template #left>
<ai-select
v-model="search.type"
@change="search.current = 1, getList()"
placeholder="项目类型"
:selectList="$dict.getDict('questionnaireType')">
</ai-select>
</template>
<template #right>
<el-input
v-model="search.title"
size="small"
placeholder="请输入模板名称"
clearable
@keyup.enter.native="search.current = 1, getList()"
@clear="search.current = 1, search.title = '', getList()"
suffix-icon="iconfont iconSearch">
</el-input>
</template>
</ai-search-bar>
<ai-search-bar style="margin-top: 12px;">
<template #left>
<el-button type="primary" @click="isShow = true">新建模板</el-button>
</template>
</ai-search-bar>
<ai-table
:tableData="tableData"
:col-configs="colConfigs"
:total="total"
style="margin-top: 6px;"
:current.sync="search.current"
:size.sync="search.size"
@getList="getList">
<el-table-column slot="type" width="120px" label="项目类型" align="center">
<template slot-scope="{ row }">
<div class="tags-wrapper">
<span class="tags" :class="'type-' + row.type">{{ dict.getLabel('questionnaireType', row.type) }}</span>
</div>
</template>
</el-table-column>
<el-table-column slot="options" width="160px" fixed="right" label="操作" align="center">
<template slot-scope="{ row }">
<div class="table-options">
<el-button type="text" @click="toEdit(row.id, row.type)">编辑</el-button>
<el-button type="text" @click="quote(row.id, row.type)">引用</el-button>
<el-button type="text" @click="remove(row.id)">删除</el-button>
</div>
</template>
</el-table-column>
</ai-table>
<ai-dialog
:visible.sync="isShow"
width="800px"
title="请选择新建模板类型"
@onConfirm="onConfirm">
<div class="type-list">
<div class="type-item" @click="currIndex = 0" :class="[currIndex === 0 ? 'active' : '']">
<svg class="icon" aria-hidden="true">
<use xlink:href="#iconwenjuandiaocha"></use>
</svg>
<span>问卷调查</span>
</div>
<div class="type-item" @click="currIndex = 1" :class="[currIndex === 1 ? 'active' : '']">
<svg class="icon" aria-hidden="true">
<use xlink:href="#iconkaoshiceping"></use>
</svg>
<span>考试测评</span>
</div>
<div class="type-item" @click="currIndex = 2" :class="[currIndex === 2 ? 'active' : '']">
<svg class="icon" aria-hidden="true">
<use xlink:href="#iconbaomingdengji"></use>
</svg>
<span>报名登记</span>
</div>
<div class="type-item" @click="currIndex = 3" :class="[currIndex === 3 ? 'active' : '']">
<svg class="icon" aria-hidden="true">
<use xlink:href="#iconmanyidiaocha"></use>
</svg>
<span>满意调查</span>
</div>
<div class="type-item" @click="currIndex = 4" :class="[currIndex === 4 ? 'active' : '']">
<svg class="icon" aria-hidden="true">
<use xlink:href="#icontoupiaopingxuan"></use>
</svg>
<span>投票评选</span>
</div>
</div>
</ai-dialog>
</template>
</ai-list>
</template>
<script>
export default {
name: 'Template',
props: {
instance: Function,
dict: Object
},
data () {
return {
search: {
current: 1,
status: '',
type: '',
size: 10,
templateType: 1,
title: ''
},
currIndex: 0,
isShow: false,
total: 10,
colConfigs: [
{ prop: 'title', label: '模板名称', align: 'left' },
{ slot: 'type', label: '项目类型', align: 'center' },
{ prop: 'quoteCount', label: '引用次数', align: 'center' },
{ prop: 'createUserName', label: '创建人', align: 'center', openType: 'userName' },
{ prop: 'createUnitName', label: '创建单位', align: 'center', openType: 'departmentName' },
{ prop: 'createTime', label: '创建时间', align: 'center' }
],
tableData: []
}
},
mounted () {
this.getList()
},
methods: {
getList () {
this.instance.post(`/app/appquestionnairetemplate/list`, null, {
params: {
...this.search
}
}).then(res => {
if (res.code == 0) {
this.tableData = res.data.records
this.total = res.data.total
this.$initWxOpenData()
}
})
},
quote (id, type) {
this.$emit('change', {
type: 'add',
params: {
id,
type,
isQuote: true,
templateType: 0
}
})
},
remove (id) {
this.$confirm('确定删除该数据?').then(() => {
this.instance.post(`/app/appquestionnairetemplate/deleteShareTemplate?ids=${id}`).then(res => {
if (res.code == 0) {
this.$message.success('删除成功!')
this.getList()
}
})
})
},
toAdd (id) {
this.$emit('change', {
type: 'Add',
params: {
id
}
})
},
toEdit (id, type) {
this.$emit('change', {
type: 'add',
params: {
id,
type,
templateType: 1
}
})
},
onConfirm () {
this.$emit('change', {
type: 'add',
params: {
id: '',
templateType: 1,
type: this.currIndex
}
})
}
}
}
</script>
<style lang="scss" scoped>
.template {
.tags-wrapper {
display: flex;
justify-content: center;
}
.type-list {
display: flex;
align-items: center;
.type-item {
display: flex;
align-items: center;
justify-content: center;
width: 128px;
height: 64px;
margin-right: 20px;
background: #FFFFFF;
border-radius: 2px;
// box-shadow: 0px 4px 8px 0px rgba(0, 0, 0, 0.08);
border-radius: 2px;
cursor: pointer;
border: 1px solid #E4E8EF;
svg {
width: 24px;
height: 24px;
margin-right: 8px;
}
&.active {
border: 1px solid #2266FF;
}
&:last-child {
margin-right: 0;
}
}
}
.tags {
display: block;
width: 64px;
height: 24px;
line-height: 24px;
text-align: center;
border-radius: 4px;
font-size: 12px;
}
.type-0 {
color: #2266FF;
background: rgba(34, 102, 255, 0.1);
}
.type-1 {
color: rgba(34, 170, 153, 1);
background: rgba(34, 170, 153, 0.1);
}
.type-2 {
color: rgba(248, 180, 37, 1);
background: rgba(248, 180, 37, 0.1);
}
.type-3 {
color: rgba(102, 119, 187, 1);
background: rgba(102, 119, 187, 0.1);
}
.type-4 {
color: rgba(236, 68, 97, 1);
background: rgba(236, 68, 97, 0.1);
}
}
</style>

View File

@@ -0,0 +1,181 @@
export const components = [
{
type: 'options',
tips: '(可重复添加)',
label: '选项',
children: [
{
type: 'radio',
label: '单选',
fixedLabel: '单选',
value: '',
points: '',
icon: 'iconradio',
isShowPoints: false,
required: true,
hasAnswer: false,
answer: '',
pointType: '0',
pointDict: [
{
dictName: '此题有唯一答案和分值',
dictValue: '0'
},
{
dictName: '每个选项都有对应分值',
dictValue: '1'
}
],
options: [
{
label: '选项1',
value: '',
point: '',
img: []
},
{
label: '选项2',
value: '',
point: '',
img: []
}
],
title: ''
},
{
type: 'checkbox',
label: '多选',
fixedLabel: '多选',
points: '',
icon: 'iconcheck_box',
isShowPoints: false,
required: true,
hasAnswer: false,
answer: [],
value: [],
pointType: '0',
pointDict: [
{
dictName: '此题有唯一答案和分值',
dictValue: '0'
},
{
dictName: '每个选项都有对应分值',
dictValue: '1'
},
{
dictName: '答对几项得几分,答错不得分',
dictValue: '2'
}
],
options: [
{
label: '选项1',
value: '',
point: '',
img: []
},
{
label: '选项2',
point: '',
value: '',
img: []
}
],
title: ''
},
{
type: 'select',
label: '单下拉框',
fixedLabel: '单下拉框',
value: '',
points: '',
icon: 'iconSelect',
isShowPoints: false,
required: true,
hasAnswer: false,
answer: '',
pointType: '0',
pointDict: [
{
dictName: '此题有唯一答案和分值',
dictValue: '0'
},
{
dictName: '每个选项都有对应分值',
dictValue: '1'
}
],
options: [
{
label: '选项1',
value: '',
point: '',
img: []
},
{
label: '选项2',
value: '',
point: '',
img: []
}
],
title: ''
}
]
},
{
type: 'input',
tips: '(可重复添加)',
label: '填空',
children: [
{
type: 'input',
label: '单行填空',
fixedLabel: '单行填空',
value: '',
pointType: '0',
icon: 'icontext_box',
isShowPoints: false,
points: '',
required: true,
hasAnswer: false,
placeholder: '请输入...',
answer: ''
},
{
type: 'textarea',
label: '多行填空',
fixedLabel: '多行填空',
pointType: '0',
icon: 'icontext_area',
points: '',
isShowPoints: false,
required: true,
hasAnswer: false,
answer: '',
placeholder: '请输入...',
value: ''
}
]
},
{
type: 'annex',
tips: '(可重复添加)',
label: '附件',
children: [
{
type: 'upload',
label: '上传图片',
fixedLabel: '上传图片',
value: '',
icon: 'iconpic',
isShowPoints: false,
points: '',
required: true,
hasAnswer: false,
answer: ''
}
]
}
];