目录代码整合
This commit is contained in:
1739
packages/work/AppAskForm/components/Add.vue
Normal file
1739
packages/work/AppAskForm/components/Add.vue
Normal file
File diff suppressed because it is too large
Load Diff
1089
packages/work/AppAskForm/components/FormList.vue
Normal file
1089
packages/work/AppAskForm/components/FormList.vue
Normal file
File diff suppressed because it is too large
Load Diff
761
packages/work/AppAskForm/components/Statistics.vue
Normal file
761
packages/work/AppAskForm/components/Statistics.vue
Normal file
@@ -0,0 +1,761 @@
|
||||
<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="创建人" :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
|
||||
v-throttle="() => {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> -->
|
||||
<el-tooltip effect="dark"
|
||||
:content="row.corpName ? row.nickName + '@' + row.corpFullName : row.nickName + ''"
|
||||
placement="top">
|
||||
<div class="userinfo-right__top">
|
||||
<h3>{{ row.corpName ? row.nickName : row.nickName }}</h3>
|
||||
<span class="ellipsis">{{ row.corpName ? '@' + row.corpName : '' }}</span>
|
||||
</div>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column slot="tags" label="标签" align="center" width="240px">
|
||||
<template slot-scope="{ row }">
|
||||
<div class="table-tags" v-if="row.tagNames">
|
||||
<el-tag type="info" v-for="(item, index) in row.tagNames.split(',')" size="medium" :key="index">
|
||||
{{ item }}
|
||||
</el-tag>
|
||||
</div>
|
||||
<span v-else></span>
|
||||
</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: 'residentName', label: '真实姓名', align: 'center', width: '100px'},
|
||||
{prop: 'commitTime', label: '提交时间', align: 'center', width: '160px'},
|
||||
{
|
||||
prop: 'userType',
|
||||
label: '微信类型',
|
||||
align: 'center',
|
||||
width: '100px',
|
||||
formart: v => this.dict.getLabel('wxUserType', v)
|
||||
},
|
||||
{prop: 'wxUserNames', label: '所属员工', align: 'center', width: '100px'},
|
||||
{slot: 'tags', label: '标签', align: 'center', width: '268px'},
|
||||
{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
|
||||
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
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)
|
||||
})
|
||||
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
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: 0 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 0 0;
|
||||
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>
|
||||
282
packages/work/AppAskForm/components/Template.vue
Normal file
282
packages/work/AppAskForm/components/Template.vue
Normal file
@@ -0,0 +1,282 @@
|
||||
<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
|
||||
v-throttle="() => {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'},
|
||||
{prop: 'createUnitName', label: '创建单位', align: 'center'},
|
||||
{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
|
||||
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
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;
|
||||
// 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>
|
||||
181
packages/work/AppAskForm/components/config.js
Normal file
181
packages/work/AppAskForm/components/config.js
Normal 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: ''
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
Reference in New Issue
Block a user