feat: 问卷列表新增类型和状态筛选
This commit is contained in:
parent
c32bbd9124
commit
e34e5a606b
@ -186,3 +186,7 @@ npm run serve
|
||||
|
||||
# Feature
|
||||
[官方Feature](https://github.com/didi/xiaoju-survey/issues/45)
|
||||
|
||||
# CHANGELOG
|
||||
[MAJOR CHANGELOG](https://github.com/didi/xiaoju-survey/issues/48)
|
||||
|
||||
|
@ -19,7 +19,6 @@
|
||||
"@types/koa-bodyparser": "^4.3.10",
|
||||
"@types/koa-router": "^7.4.4",
|
||||
"@types/koa-static": "^4.0.4",
|
||||
"@types/node": "^20.10.8",
|
||||
"@typescript-eslint/eslint-plugin": "^6.15.0",
|
||||
"@typescript-eslint/parser": "^6.15.0",
|
||||
"cross-env": "^7.0.3",
|
||||
|
@ -141,7 +141,7 @@ export default class SurveyManage {
|
||||
}
|
||||
|
||||
private getFilter(filterList: Array<FilterItem>) {
|
||||
const allowFilterField = ['title', 'remark', 'surveyType', 'curStatus.status'];
|
||||
const allowFilterField = ['title', 'remark', 'questionType', 'curStatus.status'];
|
||||
return filterList.reduce((preItem, curItem) => {
|
||||
const condition = curItem.condition.filter(item => allowFilterField.includes(item.field)).reduce((pre, cur) => {
|
||||
switch(cur.comparator) {
|
||||
|
@ -1,11 +1,20 @@
|
||||
<template>
|
||||
<div class="tableview-root">
|
||||
<div class="filter-wrap">
|
||||
<div class="select">
|
||||
<text-select
|
||||
v-for="item in Object.keys(selectOptionsDict)"
|
||||
:effect-fun="onSelectChange"
|
||||
:effect-key="item"
|
||||
:options="selectOptionsDict[item]"
|
||||
/>
|
||||
</div>
|
||||
<div class="search">
|
||||
<text-search
|
||||
placeholder="请输入问卷标题"
|
||||
:value="searchVal"
|
||||
@search="onSearchText" />
|
||||
@search="onSearchText"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<el-table
|
||||
@ -92,7 +101,8 @@ import Tag from './tag';
|
||||
import State from './state';
|
||||
import ToolBar from './toolBar';
|
||||
import TextSearch from './textSearch'
|
||||
import { fieldConfig, thead, noListDataConfig, noSearchDataConfig } from '../config';
|
||||
import TextSelect from './textSelect'
|
||||
import { fieldConfig, thead, noListDataConfig, noSearchDataConfig, selectOptionsDict } from '../config';
|
||||
import { CODE_MAP } from '@/management/api/base';
|
||||
import { QOP_MAP } from '@/management/utils/constant';
|
||||
import { getSurveyList, deleteSurvey } from '@/management/api/survey';
|
||||
@ -112,7 +122,12 @@ export default {
|
||||
total: 0,
|
||||
data: [],
|
||||
currentPage: 1,
|
||||
searchVal: ''
|
||||
searchVal: '',
|
||||
selectOptionsDict,
|
||||
selectValueMap: {
|
||||
questionType: '',
|
||||
'curStatus.status': ''
|
||||
}
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@ -126,11 +141,31 @@ export default {
|
||||
return [
|
||||
{
|
||||
comparator:"",
|
||||
condition:[{
|
||||
"field":"title",
|
||||
"value":this.searchVal,
|
||||
"comparator":"$regex"
|
||||
}]
|
||||
condition:[
|
||||
{
|
||||
field: "title",
|
||||
value: this.searchVal,
|
||||
comparator: "$regex"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
comparator: "",
|
||||
condition: [
|
||||
{
|
||||
field: "curStatus.status",
|
||||
value: this.selectValueMap["curStatus.status"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
comparator: "",
|
||||
condition: [
|
||||
{
|
||||
field: "questionType",
|
||||
value: this.selectValueMap.questionType
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -142,7 +177,9 @@ export default {
|
||||
async init() {
|
||||
this.loading = true;
|
||||
try {
|
||||
const filter = JSON.stringify(this.filter)
|
||||
const filter = JSON.stringify(this.filter.filter(item => {
|
||||
return item.condition[0].field === 'title' || item.condition[0].value
|
||||
}))
|
||||
const res = await getSurveyList(this.currentPage, filter);
|
||||
this.loading = false;
|
||||
if (res.code === CODE_MAP.SUCCESS) {
|
||||
@ -247,6 +284,11 @@ export default {
|
||||
this.searchVal = e
|
||||
this.currentPage = 1
|
||||
this.init()
|
||||
},
|
||||
onSelectChange(selectValue, selectKey){
|
||||
this.selectValueMap[selectKey] = selectValue
|
||||
this.currentPage = 1
|
||||
this.init()
|
||||
}
|
||||
},
|
||||
components: {
|
||||
@ -255,6 +297,7 @@ export default {
|
||||
Tag,
|
||||
ToolBar,
|
||||
TextSearch,
|
||||
TextSelect,
|
||||
State,
|
||||
},
|
||||
};
|
||||
@ -264,8 +307,12 @@ export default {
|
||||
.tableview-root {
|
||||
.filter-wrap{
|
||||
display: flex;
|
||||
justify-content: right;
|
||||
justify-content: space-between;
|
||||
.select{
|
||||
display: flex;
|
||||
}
|
||||
.search{
|
||||
display: flex;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
}
|
||||
@ -302,4 +349,10 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
.el-select-dropdown__wrap{
|
||||
background: #eee;
|
||||
}
|
||||
.el-select-dropdown__item.hover{
|
||||
background: #fff;
|
||||
}
|
||||
</style>
|
||||
|
57
web/src/management/pages/list/components/textButton.vue
Normal file
57
web/src/management/pages/list/components/textButton.vue
Normal file
@ -0,0 +1,57 @@
|
||||
<template>
|
||||
<div class="text-button-root" @click="onClick">
|
||||
<el-button type="text" :icon="currentOption.icon" size="mini">
|
||||
<slot>{{ currentOption.label }}</slot>
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default{
|
||||
name: 'TextButton',
|
||||
data(){
|
||||
return {
|
||||
optionIndex: 0,
|
||||
optionValue: ''
|
||||
}
|
||||
},
|
||||
props: {
|
||||
options: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
effectFun: {
|
||||
type: Function
|
||||
},
|
||||
effectKey: {
|
||||
type: String
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
optionsLength(){
|
||||
return this.options.length
|
||||
},
|
||||
currentOption(){
|
||||
return this.options[this.optionIndex % this.optionsLength]
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
currentOption(newOption){
|
||||
typeof this.effectFun === 'function' && this.effectFun(newOption, this.effectKey)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onClick(){
|
||||
if(this.optionIndex > this.optionsLength){
|
||||
this.optionIndex = 0
|
||||
return
|
||||
}
|
||||
this.optionIndex++
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.el-button{
|
||||
margin-right: 20px;
|
||||
}
|
||||
</style>
|
59
web/src/management/pages/list/components/textSelect.vue
Normal file
59
web/src/management/pages/list/components/textSelect.vue
Normal file
@ -0,0 +1,59 @@
|
||||
<template>
|
||||
<div class="text-select-root">
|
||||
<el-select v-model="selectValue" :placeholder="options.label">
|
||||
<el-option
|
||||
v-for="item in options.value"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'TextSelect',
|
||||
data(){
|
||||
return {
|
||||
selectValue: this.options.default
|
||||
}
|
||||
},
|
||||
props: {
|
||||
options: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
effectFun:{
|
||||
type: Function
|
||||
},
|
||||
effectKey: {
|
||||
type: String
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
selectValue(newSelect){
|
||||
const {effectFun} = this
|
||||
typeof effectFun === 'function' && effectFun(newSelect, this.effectKey)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.el-select{
|
||||
width: 105px;
|
||||
line-height: 35px;
|
||||
margin-right: 20px;
|
||||
::v-deep .el-input__inner{
|
||||
border: none;
|
||||
height: 35px;
|
||||
// line-height: 35px;
|
||||
}
|
||||
::v-deep .el-icon-arrow-up:before{
|
||||
position: relative;
|
||||
top: -2px;
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
@ -72,3 +72,66 @@ export const statusMaps = {
|
||||
removed: '',
|
||||
pausing: '',
|
||||
};
|
||||
|
||||
// 问卷类型
|
||||
export const questionTypeSelect = {
|
||||
label: '问卷类型',
|
||||
value: [
|
||||
{
|
||||
value: '',
|
||||
label: '全部类型'
|
||||
},
|
||||
{
|
||||
value: 'normal',
|
||||
label: '基础调查'
|
||||
},
|
||||
// {
|
||||
// value: 'exam',
|
||||
// label: '在线考试'
|
||||
// },
|
||||
// {
|
||||
// value: 'nps',
|
||||
// label: 'NPS评分'
|
||||
// },
|
||||
{
|
||||
value: 'vote',
|
||||
label: '投票评选'
|
||||
},
|
||||
{
|
||||
value: 'register',
|
||||
label: '在线报名'
|
||||
},
|
||||
],
|
||||
default: ''
|
||||
}
|
||||
|
||||
// 问卷状态
|
||||
export const curStatusSelect = {
|
||||
label: '问卷状态',
|
||||
value: [
|
||||
{
|
||||
value: '',
|
||||
label: '全部状态'
|
||||
},
|
||||
{
|
||||
value: 'new',
|
||||
label: '未发布'
|
||||
},
|
||||
{
|
||||
value: 'published',
|
||||
label: '已发布'
|
||||
},
|
||||
{
|
||||
value: 'editing',
|
||||
label: '修改中'
|
||||
}
|
||||
],
|
||||
default: ''
|
||||
}
|
||||
|
||||
export const selectOptionsDict = Object.freeze({
|
||||
questionType: questionTypeSelect,
|
||||
'curStatus.status': curStatusSelect
|
||||
})
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user