张雄 3 years ago
parent e69000485d
commit 90f1f8dad4

74
package-lock.json generated

@ -11,6 +11,7 @@
"ant-design-vue": "^1.7.8", "ant-design-vue": "^1.7.8",
"axios": "^0.24.0", "axios": "^0.24.0",
"core-js": "^3.6.5", "core-js": "^3.6.5",
"echarts": "^5.3.2",
"less": "^4.1.2", "less": "^4.1.2",
"less-loader": "5.0.0", "less-loader": "5.0.0",
"momen": "^0.0.1-security", "momen": "^0.0.1-security",
@ -18,6 +19,7 @@
"qrcodejs2": "^0.0.2", "qrcodejs2": "^0.0.2",
"vue": "^2.6.11", "vue": "^2.6.11",
"vue-router": "^3.5.3", "vue-router": "^3.5.3",
"vuescroll": "^4.17.3",
"vuex": "^3.6.2" "vuex": "^3.6.2"
}, },
"devDependencies": { "devDependencies": {
@ -5854,6 +5856,20 @@
"safer-buffer": "^2.1.0" "safer-buffer": "^2.1.0"
} }
}, },
"node_modules/echarts": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/echarts/-/echarts-5.3.2.tgz",
"integrity": "sha512-LWCt7ohOKdJqyiBJ0OGBmE9szLdfA9sGcsMEi+GGoc6+Xo75C+BkcT/6NNGRHAWtnQl2fNow05AQjznpap28TQ==",
"dependencies": {
"tslib": "2.3.0",
"zrender": "5.3.1"
}
},
"node_modules/echarts/node_modules/tslib": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz",
"integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
},
"node_modules/ee-first": { "node_modules/ee-first": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npm.taobao.org/ee-first/download/ee-first-1.1.1.tgz", "resolved": "https://registry.npm.taobao.org/ee-first/download/ee-first-1.1.1.tgz",
@ -13593,6 +13609,14 @@
"integrity": "sha1-HuO8mhbsv1EYvjNLsV+cRvgvWCU=", "integrity": "sha1-HuO8mhbsv1EYvjNLsV+cRvgvWCU=",
"dev": true "dev": true
}, },
"node_modules/vuescroll": {
"version": "4.17.3",
"resolved": "https://registry.npmjs.org/vuescroll/-/vuescroll-4.17.3.tgz",
"integrity": "sha512-5P3hje/fYjo1eAB0Y8zboLbaq/mnPNczYyZ1aPHHM6wIFKcqal9Mi42CBCZizUnEtoXtbsGlnyLcVbnalTNptA==",
"peerDependencies": {
"vue": "^2.0.0"
}
},
"node_modules/vuex": { "node_modules/vuex": {
"version": "3.6.2", "version": "3.6.2",
"resolved": "https://registry.npmjs.org/vuex/-/vuex-3.6.2.tgz", "resolved": "https://registry.npmjs.org/vuex/-/vuex-3.6.2.tgz",
@ -14335,6 +14359,19 @@
"engines": { "engines": {
"node": ">=0.10.0" "node": ">=0.10.0"
} }
},
"node_modules/zrender": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/zrender/-/zrender-5.3.1.tgz",
"integrity": "sha512-7olqIjy0gWfznKr6vgfnGBk7y4UtdMvdwFmK92vVQsQeDPyzkHW1OlrLEKg6GHz1W5ePf0FeN1q2vkl/HFqhXw==",
"dependencies": {
"tslib": "2.3.0"
}
},
"node_modules/zrender/node_modules/tslib": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz",
"integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
} }
}, },
"dependencies": { "dependencies": {
@ -18934,6 +18971,22 @@
"safer-buffer": "^2.1.0" "safer-buffer": "^2.1.0"
} }
}, },
"echarts": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/echarts/-/echarts-5.3.2.tgz",
"integrity": "sha512-LWCt7ohOKdJqyiBJ0OGBmE9szLdfA9sGcsMEi+GGoc6+Xo75C+BkcT/6NNGRHAWtnQl2fNow05AQjznpap28TQ==",
"requires": {
"tslib": "2.3.0",
"zrender": "5.3.1"
},
"dependencies": {
"tslib": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz",
"integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
}
}
},
"ee-first": { "ee-first": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npm.taobao.org/ee-first/download/ee-first-1.1.1.tgz", "resolved": "https://registry.npm.taobao.org/ee-first/download/ee-first-1.1.1.tgz",
@ -25152,6 +25205,12 @@
"integrity": "sha1-HuO8mhbsv1EYvjNLsV+cRvgvWCU=", "integrity": "sha1-HuO8mhbsv1EYvjNLsV+cRvgvWCU=",
"dev": true "dev": true
}, },
"vuescroll": {
"version": "4.17.3",
"resolved": "https://registry.npmjs.org/vuescroll/-/vuescroll-4.17.3.tgz",
"integrity": "sha512-5P3hje/fYjo1eAB0Y8zboLbaq/mnPNczYyZ1aPHHM6wIFKcqal9Mi42CBCZizUnEtoXtbsGlnyLcVbnalTNptA==",
"requires": {}
},
"vuex": { "vuex": {
"version": "3.6.2", "version": "3.6.2",
"resolved": "https://registry.npmjs.org/vuex/-/vuex-3.6.2.tgz", "resolved": "https://registry.npmjs.org/vuex/-/vuex-3.6.2.tgz",
@ -25740,6 +25799,21 @@
"dev": true "dev": true
} }
} }
},
"zrender": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/zrender/-/zrender-5.3.1.tgz",
"integrity": "sha512-7olqIjy0gWfznKr6vgfnGBk7y4UtdMvdwFmK92vVQsQeDPyzkHW1OlrLEKg6GHz1W5ePf0FeN1q2vkl/HFqhXw==",
"requires": {
"tslib": "2.3.0"
},
"dependencies": {
"tslib": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz",
"integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
}
}
} }
} }
} }

@ -10,6 +10,7 @@
"ant-design-vue": "^1.7.8", "ant-design-vue": "^1.7.8",
"axios": "^0.24.0", "axios": "^0.24.0",
"core-js": "^3.6.5", "core-js": "^3.6.5",
"echarts": "^5.3.2",
"less": "^4.1.2", "less": "^4.1.2",
"less-loader": "5.0.0", "less-loader": "5.0.0",
"momen": "^0.0.1-security", "momen": "^0.0.1-security",

@ -0,0 +1,46 @@
import httpService from "@/request"
// 查询所有的违禁关键字
export function getForbiddenList(params) {
return httpService({
url: `/user/prohibitedKeywords/list`,
method: 'get',
params: params,
})
}
// 添加违禁字
export function addForbidden(params) {
return httpService({
url: `/user/prohibitedKeywords/insert`,
method: 'post',
data: params,
})
}
// 删除违禁字
export function deleteForbidden(params) {
return httpService({
url: `/user/prohibitedKeywords/delete`,
method: 'post',
data: params,
})
}
// 根据id查询违禁字
export function findForbidden(params) {
return httpService({
url: `/user/prohibitedKeywords/findById`,
method: 'get',
params: params,
})
}
// 修改违禁字
export function updateForbidden(params) {
return httpService({
url: `/user/prohibitedKeywords/update`,
method: 'post',
data: params,
})
}

@ -99,4 +99,14 @@ export function delFacilityInfo(params) {
method: 'post', method: 'post',
data: params, data: params,
}) })
} }
//预约
//查询所有的设施设备预约
export function getFacilitiesReserve(params) {
return httpService({
url: `/user/facilitiesReserve/list`,
method: 'get',
params: params,
})
}

@ -0,0 +1,82 @@
import httpService from "@/request"
// 查询所有投票信息
export function getVoteList(params) {
return httpService({
url: `/user/vote/list`,
method: 'get',
params: params,
})
}
// 添加投票信息
export function addVote(params) {
return httpService({
url: `/user/vote/insert`,
method: 'post',
data: params,
})
}
// 删除投票信息
export function deleteVote(params) {
return httpService({
url: `/user/vote/delete`,
method: 'post',
data: params,
})
}
// 根据投票主键id查询投票信息
export function findVote(params) {
return httpService({
url: `/user/vote/findById`,
method: 'get',
params: params,
})
}
// 修改投票信息
export function updateVote(params) {
return httpService({
url: `/user/vote/update`,
method: 'post',
data: params,
})
}
// 发布下架投票
export function releaseVote(params) {
return httpService({
url: `/user/vote/isRelease`,
method: 'get',
params: params,
})
}
// 查询候选项信息(详情页面)
export function getCandidateList(params) {
return httpService({
url: `/user/vote/findCandidateList`,
method: 'get',
params: params,
})
}
// 查询候选人被投票信息(详情页面)
export function getPersonalList(params) {
return httpService({
url: `/user/vote/findPersonnelList`,
method: 'get',
params: params,
})
}
// 即将开始的投票个数
export function getTodayVote(params) {
return httpService({
url: `/user/vote/countVoteExpectedStart`,
method: 'get',
params: params,
})
}

@ -3,6 +3,7 @@ import App from './App.vue'
import './styles/index.less'; import './styles/index.less';
import mixins from "@/mixins" import mixins from "@/mixins"
import Antd from 'ant-design-vue'; import Antd from 'ant-design-vue';
import echarts from "echarts";
// import {Cascader} from 'element-ui'; // import {Cascader} from 'element-ui';
// import 'element-ui/lib/theme-chalk/index.css'; // import 'element-ui/lib/theme-chalk/index.css';
// import moment from 'moment'; // import moment from 'moment';
@ -19,6 +20,7 @@ import router from "@/permission";
// Vue.prototype.$moment = moment // Vue.prototype.$moment = moment
const communityCode = store.getters.getCommunityCode; const communityCode = store.getters.getCommunityCode;
Vue.prototype.$baseUrl = process.env.VUE_APP_URL + communityCode + '/manage' Vue.prototype.$baseUrl = process.env.VUE_APP_URL + communityCode + '/manage'
Vue.prototype.$echarts = echarts;
Vue.config.productionTip = false Vue.config.productionTip = false
import commonTable from './components/table' import commonTable from './components/table'
import commonUpload from './components/upload/index.vue' import commonUpload from './components/upload/index.vue'

@ -91,6 +91,15 @@ export default [
component: resolve => require(['@/views/Basic/WorkOrder'], resolve), component: resolve => require(['@/views/Basic/WorkOrder'], resolve),
meta: {title: '工单管理'} meta: {title: '工单管理'}
}, },
{
path: '/Forbidden',
name: "Forbidden",
title: "违禁字管理",
icon: 'stop',
hide: false,
component: resolve => require(['@/views/Basic/Forbidden'], resolve),
meta: {title: '违禁字管理'}
},
// { // {
// path: '/attendance', // path: '/attendance',
// name: "Attendance", // name: "Attendance",

@ -269,16 +269,6 @@ export default [
hide: false, hide: false,
component: resolve => require(['@/views/Operation/Scroll'], resolve), component: resolve => require(['@/views/Operation/Scroll'], resolve),
meta: {title: '问卷调查'}, meta: {title: '问卷调查'},
// children: [
// {
// path: '/Scroll/_addScroll',
// name: "_addScroll",
// title: "新增问卷调查",
// hide: true,
// component: resolve => require(['@/views/Operation/Scroll/_addScroll'], resolve),
// meta: {title: '新增问卷调查'},
// },
// ]
}, },
{ {
path: '/Scroll/addScroll', path: '/Scroll/addScroll',
@ -304,4 +294,13 @@ export default [
component: resolve => require(['@/views/Operation/Scroll/analyze'], resolve), component: resolve => require(['@/views/Operation/Scroll/analyze'], resolve),
meta: {title: '问卷调查报表分析'}, meta: {title: '问卷调查报表分析'},
}, },
{
path: '/Vote',
name: "Vote",
title: "投票管理",
icon: 'bar-chart',
hide: false,
component: resolve => require(['@/views/Operation/Vote'], resolve),
meta: {title: '投票管理'},
},
] ]

@ -0,0 +1,25 @@
export const columns = [
{
title: "违禁关键字",
width: "33%",
dataIndex: "keywords",
},
{
title: "替换字符",
width: "33%",
dataIndex: "replaces",
},
{
title: "操作",
dataIndex: "action",
key: "action",
width: "240",
fixed: "right",
scopedSlots: { customRender: "action" },
},
]
export const rules = {
replaces: [{ required: true, message: "请输入替换的字符", trigger: "blur" }],
keywords: [{ required: true, message: "请输入违禁字", trigger: "blur" }],
}

@ -0,0 +1,236 @@
<template>
<div>
<div class="cardTitle">
<a-space size="large">
<span>违禁字管理</span>
</a-space>
</div>
<div class="search-box">
<a-row>
<a-col :span="20">
<a-space size="large">
<a-input v-model="form.keywords" style="width: 200px" placeholder="违禁关键字"></a-input>
<a-input v-model="form.replaces" style="width: 200px" placeholder="替换字符"></a-input>
<a-button type="primary" @click='getData'> </a-button>
<a-button @click='reset'> </a-button>
</a-space>
</a-col>
</a-row>
</div>
<a-button style="margin: 10px" class="add-btn" @click="detailShow = true;mode = 1">新增违禁字</a-button>
<div class="main">
<a-table :columns="columns" :data-source="tableData"
:pagination="pagination" @change="handlerChange"
:row-selection="{
selectedRowKeys: selectedRowKeys,
onChange: selectionChoosed,
}"
:row-key="
(record, index) => {
return record.id;
}">
<template slot="action" slot-scope="text,record">
<span><a @click=edit(record)>编辑</a></span>
<span><a style="margin-left: 8px;color:red" @click=del(record)>删除</a></span>
</template>
</a-table>
<div class="action">
<a-dropdown :disabled="!hasSelected">
<a-menu slot="overlay" @click="handleMenuClick">
<a-menu-item key="del"> 批量删除 </a-menu-item>
</a-menu>
<a-button> 批量操作 <a-icon type="down" /> </a-button>
</a-dropdown>
<span style="margin-left: 8px">
<template v-if="hasSelected">
{{ `已选择 ${selectedRowKeys.length}` }}
</template>
</span>
</div>
</div>
<a-drawer :title="mode==1?'新增违禁字':'编辑违禁字'" :width="720" :visible="detailShow" :body-style="{ paddingBottom: '60px' }" @close="detailClose">
<div class="drawer-content">
<span>违禁字信息</span>
<a-divider></a-divider>
<a-row>
<a-form-model :model="addForm" :rules="rules">
<a-col :span="12">
<a-form-model-item label="违禁关键字" prop="keywords">
<a-input style="width: 240px" v-model="addForm.keywords"></a-input>
</a-form-model-item>
</a-col>
<a-col :span="12">
<a-form-model-item label="替换字符" prop="replaces">
<a-input style="width: 240px" v-model="addForm.replaces"></a-input>
</a-form-model-item>
</a-col>
</a-form-model>
</a-row>
</div>
<div class="drawer-footer" style="float: left">
<a-button @click="addConfirm" type="primary" :style="{ marginRight: '8px' }">
确认
</a-button>
<a-button @click="detailClose"> </a-button>
</div>
</a-drawer>
</div>
</template>
<script>
import {getForbiddenList, addForbidden, findForbidden, updateForbidden, deleteForbidden} from "@/api/basic/forbidden"
import { rules, columns } from "./depend/config";
export default {
data() {
return {
form: {
keywords: '',
replaces: ''
},
addForm: {
keywords: '',
replaces: ''
},
mode: 1, //1 2
activeId: undefined,
activeName: 0,
rules: rules,
columns: columns,
tableData: [],
pagination: {
current: 1,
total: 0,
pageSize: 10,
showTotal: (total) => `${total}`,
showSizeChanger: true,
showQuickJumper: true,
},
//
detailShow: false,
//
selectedRowKeys: [],
}
},
created() {
this.getData()
},
methods: {
getData() {
let obj = Object.assign(this.form, {pageNum: this.pagination.current,size: this.pagination.pageSize})
getForbiddenList(obj).then(res => {
this.tableData = res.data.rows;
this.pagination.total = res.data.total
})
},
reset() {
this.form = {
keywords: '',
replaces: ''
},
this.getData()
},
handlerChange() {
this.pagination.current = val.current;
this.pagination.pageSize = val.pageSize;
this.getData()
},
detailClose() {
this.addForm = {
name: '',
tel: '',
type: undefined,
status: undefined,
weight: 0,
}
this.detailShow = false
},
//
addConfirm() {
if(this.mode == 1) {
addForbidden(this.addForm).then(res => {
if(res.code === 200){
this.$message.success(res.msg);
this.detailClose()
this.getData()
} else {
this.$message.error(res.msg);
}
})
} else {
let obj = Object.assign(this.addForm, {id: this.activeId})
updateForbidden(obj).then(res => {
if(res.code === 200){
this.$message.success(res.msg);
this.detailClose()
this.getData()
} else {
this.$message.error(res.msg);
}
})
}
},
//
edit(val) {
this.mode = 2;
findForbidden({prohibitedKeywordsId: val.id}).then(res => {
let data = res.data;
this.addForm = {
keywords: data.keywords,
replaces: data.replaces,
},
this.activeId = data.id
})
this.detailShow = true;
},
//
del(val) {
this.$confirm({
title: "是否删除该违禁字?",
icon:'delete',
onOk:async()=>{
let res = await deleteForbidden({prohibitedKeywordsIds: [val.id]})
if(res.code === 200){
this.$message.success(res.msg);
this.getData()
} else {
this.$message.error(res.msg);
}
},
})
},
//
selectionChoosed(val) {
this.selectedRowKeys = val
},
handleMenuClick(data) {
if (data.key === "del") {
this.$confirm({
title: "是否删除选中的违禁字?",
icon:'delete',
onOk:async()=>{
let res = await deleteForbidden({prohibitedKeywordsIds: this.selectedRowKeys})
if(res.code === 200){
this.$message.success(res.msg);
this.selectedRowKeys = [];
this.getData()
} else {
this.$message.error(res.msg);
}
},
})
}
},
},
computed: {
hasSelected() {
return this.selectedRowKeys.length > 0;
},
},
}
</script>
<style lang="less">
.drawer-content {
padding: 16px;
}
</style>

@ -1,59 +1,57 @@
export const columns = [ export const columns = [
{ {
title: "序号", title: "预约时间",
width: "6%", width: "10%",
dataIndex: "id", dataIndex: "createDate",
}, },
{ {
title: "内容", title: "预约编号",
width: "12%", width: "12%",
dataIndex: "content", dataIndex: "code",
}, },
{ {
title: "类型", title: "预约状态",
width: "8%", width: "7%",
dataIndex: "type", dataIndex: "status",
customRender: function (type) { customRender: function (type) {
switch (type) { switch (type) {
case 1: return '咨询' case 1: return '未签到'
case 2: return '建议' case 2: return '已签到'
case 3: return '投诉' case 3: return '已作废'
case 4: return '表扬' case 4: return '已取消'
case 5: return '已结束'
} }
} }
}, },
{ {
title: "发布人", title: "预约人",
width: "9%", width: "7%",
dataIndex: "releaseName", dataIndex: "reservationPerson",
}, },
{ {
title: "发布时间", title: "预约人名称",
width: "12%", width: "7%",
dataIndex: "releaseDate", dataIndex: "reservationPersonName",
}, },
{ {
title: "状态", title: "预约开始时间",
width: "8%", width: "10%",
dataIndex: "status", dataIndex: "reserveStartDate",
customRender: function (status) { },
switch (status) { {
case 3: return '已反馈' title: "预约结束时间",
case 2: return '反馈中' width: "10%",
case 1: return '未反馈' dataIndex: "reserveEndDate",
}
}
}, },
{ {
title: "评分数", title: "用户反馈内容",
width: "10%", width: "10%",
dataIndex: "rate", dataIndex: "feedback",
scopedSlots: { customRender: "rate" },
}, },
{ {
title: "最后一次回复/提问时间", title: "作废原因",
width: "14%", width: "8%",
dataIndex: "lastFeedBackDate", dataIndex: "nullifyReason",
}, },
{ {
title: "操作", title: "操作",
@ -64,6 +62,7 @@ export const columns = [
scopedSlots: { customRender: "action" }, scopedSlots: { customRender: "action" },
}, },
] ]
export const replyColumns = [ export const replyColumns = [
{ {
title: "创建人", title: "创建人",

@ -21,17 +21,18 @@
<a-row> <a-row>
<a-col :span="20"> <a-col :span="20">
<a-space size="large"> <a-space size="large">
<a-input v-model="form.releaseName" style="width: 200px" placeholder="预约编号"></a-input> <a-input v-model="form.code" style="width: 200px" placeholder="预约编号"></a-input>
<a-select v-model="form.status" style="width: 200px" placeholder="预约类型"> <a-select v-model="form.type" style="width: 200px" placeholder="预约类型">
<a-select-option :value="0">未反馈</a-select-option> <a-select-option :value="0">未反馈</a-select-option>
<a-select-option :value="1">反馈中</a-select-option> <a-select-option :value="1">反馈中</a-select-option>
<a-select-option :value="2">已反馈</a-select-option> <a-select-option :value="2">已反馈</a-select-option>
</a-select> </a-select>
<a-select v-model="form.score" style="width: 200px" placeholder="分类"> <a-select v-model="form.facilitiesCategoryId" style="width: 200px" placeholder="分类">
<a-select-option :value="0">差评</a-select-option> <a-select-option :value="0">差评</a-select-option>
<a-select-option :value="1">中评</a-select-option> <a-select-option :value="1">中评</a-select-option>
<a-select-option :value="2">好评</a-select-option> <a-select-option :value="2">好评</a-select-option>
</a-select> </a-select>
<a-input v-model="form.name" style="width: 200px" placeholder="名称"></a-input>
<a-range-picker @change="handlerTime" v-model="selTime" style="width: 240px" value-format="YYYY-MM-DD HH:mm:ss" :placeholder="['创建时间开始','创建时间结束']"></a-range-picker> <a-range-picker @change="handlerTime" v-model="selTime" style="width: 240px" value-format="YYYY-MM-DD HH:mm:ss" :placeholder="['创建时间开始','创建时间结束']"></a-range-picker>
<a-button type="primary" @click='getData'> </a-button> <a-button type="primary" @click='getData'> </a-button>
<a-button @click='reset'> </a-button> <a-button @click='reset'> </a-button>
@ -53,10 +54,10 @@
<template slot="rate" slot-scope="text,record"> <template slot="rate" slot-scope="text,record">
<a-rate :default-value="(record.score/2.0)" disabled allow-half></a-rate> <a-rate :default-value="(record.score/2.0)" disabled allow-half></a-rate>
</template> </template>
<template slot="action" slot-scope="text,record"> <template slot="action">
<span><a @click=detail(record)>详情</a></span> <!-- <span><a @click=detail(record)>详情</a></span>
<span><a style="margin-left: 8px" @click=reply(record)>回复</a></span> <span><a style="margin-left: 8px" @click=reply(record)>回复</a></span>
<span><a style="margin-left: 8px;color:red" @click=del(record)>删除</a></span> <span><a style="margin-left: 8px;color:red" @click=del(record)>删除</a></span> -->
</template> </template>
</a-table> </a-table>
<div class="action"> <div class="action">
@ -125,18 +126,19 @@
</template> </template>
<script> <script>
import { getAdviceList,delAdvice,adviceDetail,replyDetail } from "@/api/operation/recommand" import { getFacilitiesReserve } from "@/api/operation/facility"
import { columns,replyColumns } from "./depend/config"; import { columns,replyColumns } from "./depend/config";
export default { export default {
data() { data() {
return { return {
form: { form: {
type: undefined,
releaseName: '',
releaseDateStart: '',
releaseDateEnd: '',
status: undefined, status: undefined,
score: undefined, code: '',
type: undefined,
facilitiesCategoryId: undefined,
name: '',
createDateStart: '',
createDateEnd: '',
}, },
repForm: { repForm: {
appAdviceId: undefined, appAdviceId: undefined,
@ -179,19 +181,20 @@ export default {
methods: { methods: {
getData() { getData() {
let obj = Object.assign( this.form, {pageNum: this.pagination.current,size: this.pagination.pageSize}) let obj = Object.assign( this.form, {pageNum: this.pagination.current,size: this.pagination.pageSize})
getAdviceList(obj).then(res => { getFacilitiesReserve(obj).then(res => {
this.pagination.total = res.data.total; this.pagination.total = res.data.total;
this.tableData = res.data.rows this.tableData = res.data.rows
}) })
}, },
reset() { reset() {
this.form = { this.form = {
type: undefined,
releaseName: '',
releaseDateStart: undefined,
releaseDateEnd: undefined,
status: undefined, status: undefined,
score: undefined, code: '',
type: undefined,
facilitiesCategoryId: undefined,
name: '',
createDateStart: '',
createDateEnd: '',
}, },
this.selTime = []; this.selTime = [];
this.getData(); this.getData();
@ -216,8 +219,8 @@ export default {
}, },
// //
handlerTime(val) { handlerTime(val) {
this.form.releaseDateStart = val[0]; this.form.createDateStart = val[0];
this.form.releaseDateEnd = val[1]; this.form.createDateEnd = val[1];
}, },
// //
detail(val) { detail(val) {

@ -86,7 +86,6 @@
</a-form-model-item> </a-form-model-item>
</a-form-model> </a-form-model>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
@ -94,7 +93,7 @@
<div style="padding: 20px"> <div style="padding: 20px">
<a-form-model> <a-form-model>
<a-form-model-item label="封面图片设置"> <a-form-model-item label="封面图片设置">
<commonUpload :fileList="fileList" @handleChange="handleChange"></commonUpload>
</a-form-model-item> </a-form-model-item>
<a-form-model-item label="开始日期"> <a-form-model-item label="开始日期">
<a-date-picker v-model="form.beginDate" value-format="YYYY-MM-DD HH:mm:ss"></a-date-picker> <a-date-picker v-model="form.beginDate" value-format="YYYY-MM-DD HH:mm:ss"></a-date-picker>
@ -149,6 +148,7 @@ export default {
topic: '', topic: '',
}, },
questionChoice: [], questionChoice: [],
fileList: [],
// //
isEdit: false, isEdit: false,
activeIndex: undefined, activeIndex: undefined,
@ -260,6 +260,16 @@ export default {
this.questionList = []; this.questionList = [];
this.$router.go(-1); this.$router.go(-1);
}, },
//
handleChange(data) {
this.fileList = data;
this.form.imgUrls = [];
data.forEach(ele => {
if(ele.status == 'done') {
this.form.imgUrls.push(ele.response.data)
}
})
},
} }
} }
</script> </script>

@ -0,0 +1,17 @@
export const columns = [
{
title: "答题人姓名",
width: "20%",
dataIndex: "name",
},
{
title: "答案内容",
width: "50%",
dataIndex: "answer",
},
{
title: "创建时间",
width: "30%",
dataIndex: "createDate",
},
]

@ -5,13 +5,44 @@
<span>问卷调查报表分析</span> <span>问卷调查报表分析</span>
</a-space> </a-space>
</div> </div>
<div class="rep-title">物业服务满意度调查问卷</div> <div class="rep-title">
<span>物业服务满意度调查问卷</span><span style="margin-left:290px"><a-button @click="goBack"></a-button></span>
</div>
<div class="rep-time">{{reportData.beginDate}} {{reportData.endDate}}</div> <div class="rep-time">{{reportData.beginDate}} {{reportData.endDate}}</div>
<div class="rep-number">共收集到<span style="color: rgb(49,98,188)"> {{reportData.answerNum}} </span>份问卷</div> <div class="rep-number">共收集到<span style="color: rgb(49,98,188)"> {{reportData.answerNum}} </span>份问卷</div>
<div class="rep-main">
<div class="rep-item" v-for="(item, index) in repList" :key="index">
<span class="rep-item-title">
{{index+1}}.{{item.topic}}({{item.type==1?'单选题':item.type==2?'多选题':item.type==3?'下拉单选':item.type==4?'判断题':'开放题'}})
</span>
<div :id="index" :style="item.type==5?'width:1px;height:1px;margin-left: 12px':'width: 600px;height: 220px;margin-left: 12px'">
</div>
<div v-if="item.type == 5" style="padding:12px">
<a @click="openQuestionDetail(item,index)"></a>
</div>
</div>
</div>
<a-drawer title="开放题详情"
:width="720"
:visible="drawerShow"
:body-style="{ paddingBottom: '80px' }"
@close="drawerClose">
<div>
<div class="drawer-title">
{{detail.index+1}}.{{detail.topic}}
</div>
<a-table :columns="columns" :data-source="tableData" :pagination="pagination" @change="handlerPage">
</a-table>
</div>
</a-drawer>
</div> </div>
</template> </template>
<script> <script>
import * as echarts from "echarts";
import { columns } from "./config.js";
import {getReport, getAnswerList} from "@/api/operation/scroll" import {getReport, getAnswerList} from "@/api/operation/scroll"
export default { export default {
name: "analyze", name: "analyze",
@ -23,20 +54,132 @@ export default {
beginDate: '', beginDate: '',
endDate: '', endDate: '',
answerNum: 0, answerNum: 0,
} },
repList: [],
ops: {},
//
drawerShow: false,
columns: columns,
tableData: [],
pagination: {
current: 1,
total: 0,
pageSize: 20,
showTotal: (total) => `${total}`,
},
detail: {
activeId: undefined,
topic: '',
index: undefined,
},
} }
}, },
created() { mounted() {
this.id = this.$route.params.id; this.id = this.$route.params.id;
getReport({questionnaireId: this.id}).then(res => { Promise.all([
let data = res.data; this.getData(),
this.reportData = { ]).then(() => {
beginDate: data.beginDate, this.drawChart()
endDate: data.endDate, });
answerNum: data.answerNum },
methods: {
getData() {
return new Promise((resolve, reject) => {
getReport({questionnaireId: this.id}).then(res => {
let data = res.data;
this.reportData = {
beginDate: data.beginDate,
endDate: data.endDate,
answerNum: data.answerNum
};
this.repList = data.questionnaireReportTopicVoList;
resolve(true);
}).catch(() => {
reject(false);
})
})
},
drawChart() {
return new Promise((resolve, reject) => {
for(let i=0;i<this.repList.length;i++) {
if(this.repList[i].type == 5) {
continue
}
let myChart = echarts.init(document.getElementById(i));
let dy = []; let dx = [];
if(this.repList[i].type == 1 || this.repList[i].type == 2 || this.repList[i].type == 3) {
this.repList[i].questionnaireReportTopicChoiceVoList.forEach(ele => {
dy.push(ele.answer);
dx.push(ele.answerNum);
})
} else if (this.repList[i].type == 4) {
dy = ['是','否'];
dx = [this.repList[i].trueNum,this.repList[i].falseNum];
} else {
}
let option = {
yAxis: {
data: dy
},
xAxis: {},
series: [
{
type: 'bar',
data: dx,
barWidth: 20,
itemStyle: {
color: 'rgb(61,147,253)',
},
}
]
};
myChart.setOption(option);
};
resolve(true);
})
},
//
openQuestionDetail(val,index) {
this.detail.activeId = val.id;
this.detail.topic = val.topic;
this.detail.index = index;
let obj = {
pageNum: this.pagination.current,
size: this.pagination.pageSize,
questionnaireTopicId: val.id
} }
console.log(data) getAnswerList(obj).then(res => {
}) this.pagination.total = res.data.total;
this.tableData = res.data.rows
})
this.drawerShow = true;
},
drawerClose() {
this.drawerShow = false;
this.tableData = [];
this.pagination.current = 1;
},
handlerPage(val) {
this.pagination.current = val.current;
let obj = {
pageNum: this.pagination.current,
size: this.pagination.pageSize,
questionnaireTopicId: this.detail.activeId
}
getAnswerList(obj).then(res => {
this.pagination.total = res.data.total;
this.tableData = res.data.rows
})
},
//
goBack() {
this.$router.go(-1)
}
},
watch: {
} }
} }
</script> </script>
@ -62,6 +205,29 @@ export default {
font-size: 14px; font-size: 14px;
font-weight: 400; font-weight: 400;
line-height: 20px; line-height: 20px;
padding: 0px 10px 20px 10px;
}
.rep-main {
padding: 0px 10px 10px 10px; padding: 0px 10px 10px 10px;
.rep-item {
padding: 0px 10px 10px 0px;
.rep-item-title {
font-size: 14px;
font-weight: 500;
line-height: 20px;
color: #333333;
}
.repChart {
width: 600px;
height: 220px;
margin-left: 12px
}
}
}
.drawer-title {
font-size: 18px;
font-weight: 500;
line-height: 25px;
padding: 0px 10px 35px 10px;
} }
</style> </style>

@ -26,7 +26,8 @@
</div> </div>
<div class="question-area-top" style="margin-top: 20px" v-for="(item,index) in form.questionnaireInsertTopicDTOList" :key="index"> <div class="question-area-top" style="margin-top: 20px" v-for="(item,index) in form.questionnaireInsertTopicDTOList" :key="index">
<div class="question-list"> <div class="question-list">
<h4>{{index+1}}.{{item.topic}}</h4><a-tag>{{item.type==1?'单选题':item.type==2?'多选题':item.type==3?'下拉单选':item.type==4?'判断题':'开放题'}}</a-tag> <span style="font-weight: 600">{{index+1}}.{{item.topic}}</span>
<a-tag>{{item.type==1?'单选题':item.type==2?'多选题':item.type==3?'下拉单选':item.type==4?'判断题':'开放题'}}</a-tag>
</div> </div>
<div style="margin-left: 40px" v-if="item.type==1||item.type==3"> <div style="margin-left: 40px" v-if="item.type==1||item.type==3">
<a-radio disabled v-for="(it,id) in item.questionnaireInsertTopicChoiceDTOList" :key="id">{{it.answer}}</a-radio> <a-radio disabled v-for="(it,id) in item.questionnaireInsertTopicChoiceDTOList" :key="id">{{it.answer}}</a-radio>
@ -36,7 +37,7 @@
</div> </div>
<div style="padding: 20px"> <div style="padding: 20px">
<a-button type="primary" style="margin-left: 20px" @click="editQuestionItem(item,index)"></a-button> <a-button type="primary" style="margin-left: 20px" @click="editQuestionItem(item,index)"></a-button>
<a-button style="margin-left: 20px" @click="deleteQuestionItem(index)"></a-button> <a-button style="margin-left: 20px" @click="deleteQuestionItem(item,index)"></a-button>
</div> </div>
</div> </div>
<div class="question-item"> <div class="question-item">
@ -50,12 +51,12 @@
<a-form-model-item :label="'选项'+(index+1)" v-for="(item,index) in questionChoice" :key="index"> <a-form-model-item :label="'选项'+(index+1)" v-for="(item,index) in questionChoice" :key="index">
<div style="display: flex"> <div style="display: flex">
<a-input v-model="item.answer"></a-input> <a-input v-model="item.answer"></a-input>
<a-button @click="deleteChoice(index)" shape="circle" icon="close" /> <a-button @click="deleteChoice(item,index)" shape="circle" icon="close" />
</div> </div>
</a-form-model-item> </a-form-model-item>
</a-form-model> </a-form-model>
<div> <div>
<a-button type="primary" style="margin-left: 20px" @click="questionComfirm(questionCard.type)">{{isEdit==true?'':''}}</a-button> <a-button type="primary" style="margin-left: 20px" @click="questionComfirm(questionCard.type,questionCard.deleteTopicChoiceIds)">{{isEdit==true?'':''}}</a-button>
<a-button style="margin-left: 20px" @click="questionCancel"></a-button> <a-button style="margin-left: 20px" @click="questionCancel"></a-button>
</div> </div>
</div> </div>
@ -66,7 +67,7 @@
</a-form-model-item> </a-form-model-item>
</a-form-model> </a-form-model>
<div> <div>
<a-button type="primary" style="margin-left: 20px" @click="questionComfirm(questionCard.type)">{{isEdit==true?'':''}}</a-button> <a-button type="primary" style="margin-left: 20px" @click="questionComfirm(questionCard.type,questionCard.deleteTopicChoiceIds)">{{isEdit==true?'':''}}</a-button>
<a-button style="margin-left: 20px" @click="questionCancel"></a-button> <a-button style="margin-left: 20px" @click="questionCancel"></a-button>
</div> </div>
</div> </div>
@ -94,7 +95,7 @@
<div style="padding: 20px"> <div style="padding: 20px">
<a-form-model> <a-form-model>
<a-form-model-item label="封面图片设置"> <a-form-model-item label="封面图片设置">
<commonUpload :fileList="fileList" @handleChange="handleChange"></commonUpload>
</a-form-model-item> </a-form-model-item>
<a-form-model-item label="开始日期"> <a-form-model-item label="开始日期">
<a-date-picker v-model="form.beginDate" value-format="YYYY-MM-DD HH:mm:ss"></a-date-picker> <a-date-picker v-model="form.beginDate" value-format="YYYY-MM-DD HH:mm:ss"></a-date-picker>
@ -153,6 +154,7 @@ export default {
deleteTopicChoiceIds: [] deleteTopicChoiceIds: []
}, },
questionChoice: [], questionChoice: [],
fileList: [],
// //
isEdit: false, isEdit: false,
activeIndex: undefined, activeIndex: undefined,
@ -170,7 +172,25 @@ export default {
this.form.beginDate = data.beginDate; this.form.beginDate = data.beginDate;
this.form.endDate = data.endDate; this.form.endDate = data.endDate;
this.form.isRelease = data.isRelease; this.form.isRelease = data.isRelease;
this.form.imgUrls = [];
// this.form.questionnaireInsertTopicDTOList = data.questionnaireFBITopicVoList; // this.form.questionnaireInsertTopicDTOList = data.questionnaireFBITopicVoList;
if (res.data.imgList.length > 0) {
const pic = [];
this.form.imgUrls.push(res.data.imgList[0].url);
for (let item of res.data.imgList) {
let obj = {
name: item.url.split("_")[0] + "." + item.url.split(".")[1],
url: this.$ImgUrl(item.url),
uid: item.url.split("_")[1],
status: "done",
thumbUrl: this.$ImgUrl(item.url),
};
pic.push(obj);
}
this.fileList = pic;
} else {
this.form.imgUrls = [];
}
let arr = []; let arr = [];
data.questionnaireFBITopicVoList.forEach(ele => { data.questionnaireFBITopicVoList.forEach(ele => {
ele.deleteTopicChoiceIds = [] ele.deleteTopicChoiceIds = []
@ -202,7 +222,7 @@ export default {
this.questionCard = obj this.questionCard = obj
}, },
//, //,
questionComfirm(type) { questionComfirm(type,deleteId) {
if(this.isEdit == false) { if(this.isEdit == false) {
if(type == 1 || type == 2 || type == 3) { if(type == 1 || type == 2 || type == 3) {
for(let i = 0;i<this.questionChoice.length;i++) { for(let i = 0;i<this.questionChoice.length;i++) {
@ -236,7 +256,7 @@ export default {
topic: this.questionCard.topic, topic: this.questionCard.topic,
id: this.questionCard.id, id: this.questionCard.id,
questionnaireInsertTopicChoiceDTOList: this.questionChoice, questionnaireInsertTopicChoiceDTOList: this.questionChoice,
deleteTopicChoiceIds: [] deleteTopicChoiceIds: deleteId
}; };
this.form.questionnaireInsertTopicDTOList[this.activeIndex] = obj this.form.questionnaireInsertTopicDTOList[this.activeIndex] = obj
} else { } else {
@ -259,6 +279,8 @@ export default {
this.questionCard = { this.questionCard = {
type: undefined, type: undefined,
topic: '', topic: '',
id: null,
deleteTopicChoiceIds: []
} }
}, },
// //
@ -271,7 +293,8 @@ export default {
this.questionChoice.push(obj) this.questionChoice.push(obj)
}, },
// //
deleteChoice(index) { deleteChoice(item,index) {
this.questionCard.deleteTopicChoiceIds.push(item.id)
this.questionChoice.splice(index,1) this.questionChoice.splice(index,1)
}, },
// //
@ -286,7 +309,8 @@ export default {
} }
}, },
// //
deleteQuestionItem(index) { deleteQuestionItem(item,index) {
this.form.deleteTopicIds.push(item.id)
this.form.questionnaireInsertTopicDTOList.splice(index,1) this.form.questionnaireInsertTopicDTOList.splice(index,1)
}, },
// //
@ -306,6 +330,15 @@ export default {
this.questionList = []; this.questionList = [];
this.$router.go(-1); this.$router.go(-1);
}, },
handleChange(data) {
this.fileList = data;
this.form.imgUrls = [];
data.forEach(ele => {
if(ele.status == 'done') {
this.form.imgUrls.push(ele.response.data)
}
})
},
} }
} }
</script> </script>

@ -0,0 +1,144 @@
export const columns = [
{
title: "投票标题",
width: "12%",
dataIndex: "title",
},
{
title: "投票开始时间",
width: "15%",
dataIndex: "beginDate",
},
{
title: "投票结束时间",
width: "15%",
dataIndex: "endDate",
},
{
title: "投票状态",
width: "8%",
dataIndex: "status",
customRender: function(status) {
switch(status) {
case 1: return '未开始';
case 2: return '进行中';
case 3: return '已结束';
}
}
},
{
title: "投票候选项数量",
width: "10%",
dataIndex: "votePersonnelNum",
},
{
title: "投票结果",
width: "15%",
dataIndex: "voteResult",
},
{
title: "是否发布",
width: "8%",
dataIndex: "isRelease",
scopedSlots: { customRender: "release" },
},
{
title: "操作",
dataIndex: "action",
key: "action",
width: "180",
fixed: "right",
scopedSlots: { customRender: "action" },
},
];
export const detailColumns = [
{
title: "选项名称",
width: "20%",
dataIndex: "name",
},
{
title: "手机号",
width: "20%",
dataIndex: "tel",
},
{
title: "票数",
width: "10%",
dataIndex: "total",
},
{
title: "照片",
width: "20%",
dataIndex: "imgList",
scopedSlots: { customRender: "img" },
},
{
title: "操作",
dataIndex: "action",
key: "action",
width: "120",
fixed: "right",
scopedSlots: { customRender: "action" },
},
]
export const voteColumns = [
{
title: "住户房号",
width: "30%",
dataIndex: "roomList",
scopedSlots: { customRender: "roomList" },
},
{
title: "住户姓名",
width: "15%",
dataIndex: "name",
},
{
title: "手机号",
width: "20%",
dataIndex: "tel",
},
{
title: "投票时间",
width: "35%",
dataIndex: "createDate",
},
];
export const pagination= {
current: 1,
total: 0,
pageSize: 10,
showTotal: (total) => `${total}`,
showSizeChanger: true,
showQuickJumper: true,
};
export const votePagination = {
current: 1,
total: 0,
pageSize: 25,
showTotal: (total) => `${total}`,
showQuickJumper: true,
}
export const form = {
title: '',
content: '',
beginDate: '',
endDate: '',
type: 1,
isRelease: 0,
voteInsertCandidateDTOList: [],
imgUrls: [],
};
export const rules = {
title: [{ required: true, message: "请输入标题", trigger: "blur" }],
content: [{ required: true, message: "请输入内容", trigger: "blur" }],
type: [{ required: true, message: "请选择对象", trigger: "change" }],
isRelease: [{ required: true, message: "请选择是否发布", trigger: "change" }],
}

@ -0,0 +1,280 @@
<template>
<div>
<a-drawer :title="title" :width="720" :visible="show" :body-style="{ paddingBottom: '80px' }" @close="addClose">
<div class="drawer-content">
<span style="font-weight: 600">投票信息</span>
<a-divider></a-divider>
<a-form-model ref="ruleForm" :model="form" :rules="rules">
<a-row>
<a-col :span="12">
<a-form-model-item label="投票标题" prop="title">
<a-input v-model="form.title" placeholder="请输入标题" style="width: 80%"></a-input>
</a-form-model-item>
</a-col>
<a-col :span="12">
<a-form-model-item label="投票时间" :rules="{required: true,message:'请选择日期',trigger:'change'}">
<a-range-picker v-model="selTime" @change="changeTime" value-format="YYYY-MM-DD HH:mm:ss" style="width: 80%"></a-range-picker>
</a-form-model-item>
</a-col>
<a-col :span="12">
<a-form-model-item label="公开人群" prop="type">
<a-select v-model="form.type" placeholder="请选择对象" style="width: 80%">
<a-select-option :value="1">全部</a-select-option>
<a-select-option :value="2">业主</a-select-option>
<a-select-option :value="3">业主亲属</a-select-option>
<a-select-option :value="4">租户</a-select-option>
<a-select-option :value="5">租户亲属</a-select-option>
</a-select>
</a-form-model-item>
</a-col>
<a-col :span="12">
<a-form-model-item label="是否发布" prop="isRelease">
<a-select v-model="form.isRelease" placeholder="请选择" style="width: 80%">
<a-select-option :value="1">发布</a-select-option>
<a-select-option :value="0">不发布</a-select-option>
</a-select>
</a-form-model-item>
</a-col>
<a-col :span="24">
<a-form-model-item label="投票内容" prop="content">
<a-textarea v-model="form.content" placeholder="请输入内容" style="width: 90%"></a-textarea>
</a-form-model-item>
</a-col>
<a-col :span="24">
<a-form-model-item label="图片上传">
<commonUpload :fileList="fileList" @handleChange="handleChange"></commonUpload>
</a-form-model-item>
</a-col>
<a-col :span="24">
<a-form-model-item label="投票选项">
<a-button @click="addVoteItem"></a-button>
<div class="vote-item" v-for="(item,index) in form.voteUpdateCandidateDTOList" :key="index">
<div class="vote-item-title">
<span style="font-weight: 600">选项{{index+1}}</span>
<a @click="deleteVoteItem(item,index)" style="margin-left: 20px">删除</a>
</div>
<a-form-model layout="inline">
<a-form-model-item label="选项名称">
<a-input v-model="item.name"></a-input>
</a-form-model-item>
<a-form-model-item label="手机号">
<a-input v-model="item.tel"></a-input>
</a-form-model-item>
<a-form-model-item>
<a-upload
:action="`${$upload}`"
:multiple="false"
accept=".jpg,.JPG,.png,.PNG,.jpeg,.JPEG"
:headers="uploadHeaders"
@change="voteImgChange"
:file-list="item.defaultFileList"
>
<a-button @click="uploadIndex(index)"> <a-icon type="upload" />点击上传</a-button>
</a-upload>
</a-form-model-item>
</a-form-model>
</div>
</a-form-model-item>
</a-col>
</a-row>
</a-form-model>
</div>
<div class="drawer-footer">
<a-button :style="{ marginRight: '8px' }" @click="addClose">
关闭
</a-button>
<a-button type="primary" @click="submit"> </a-button>
</div>
</a-drawer>
</div>
</template>
<script>
import store from "@/store";
import { findVote, updateVote} from "@/api/operation/vote"
import { form,rules } from "./config.js";
export default {
props: {
show: {
type: Boolean,
default: false,
},
editId: Number,
},
data() {
return {
title: "修改投票",
form: {
title: '',
content: '',
beginDate: '',
endDate: '',
type: 1,
isRelease: 0,
voteUpdateCandidateDTOList: [],
imgUrls: [],
},
rules: rules,
selTime: [],
fileList: [],
rule: [],
activeId: undefined,
deleteId: [], //Id
uploadHeaders: {
"manage-login-token": store.getters.getToken,
},
activeIndex: undefined,
};
},
mounted() {
},
methods: {
addClose() {
this.fileList = [];
this.form = {
title: '',
content: '',
beginDate: '',
endDate: '',
type: 1,
isRelease: 0,
voteInsertCandidateDTOList: [],
imgUrls: [],
};
this.deleteId = [];
this.selTime = [];
this.$emit("addClose");
},
success() {
this.$emit("success");
this.addClose();
},
submit() {
this.$refs.ruleForm.validate(async (valid) => {
if (valid) {
let obj = Object.assign(this.form, {id: this.activeId,deleteVoteCandidateIds: this.deleteId})
updateVote(obj).then(res => {
if(res.code === 200){
this.$message.success(res.msg);
this.success();
} else {
this.$message.error(res.msg);
}
})
}
});
},
//
handleChange(data) {
this.fileList = data;
this.form.imgUrls = [];
data.forEach(ele => {
if(ele.status == 'done') {
this.form.imgUrls.push(ele.response.data)
}
})
},
//
uploadIndex(index) {
this.activeIndex = index
},
voteImgChange(data) {
this.form.voteUpdateCandidateDTOList[this.activeIndex].imgUrls = []
if(data.file.status == 'done') {
this.form.voteUpdateCandidateDTOList[this.activeIndex].imgUrls.push(data.file.response.data)
}
},
//
changeTime(val) {
this.form.beginDate = val[0];
this.form.endDate = val[1];
},
//
addVoteItem() {
let obj = {
id: null,
name: '',
tel: '',
imgUrls: [],
};
this.form.voteUpdateCandidateDTOList.push(obj)
},
//
deleteVoteItem(item,index) {
this.deleteId.push(item.id);
this.form.voteUpdateCandidateDTOList.splice(index,1)
},
},
watch: {
editId: {
handler(val) {
if (val !== null) {
this.title = "修改投票";
this.activeId = val;
findVote({ voteId: val }).then((res) => {
let data = res.data;
//
let arr = []
data.voteFBICandidateVoList.forEach(ele => {
let obj = {
id: ele.id,
name: ele.name,
tel: ele.tel,
imgUrls: [],
}
if(ele.imgList.length > 0) {
obj.imgUrls.push(ele.imgList[0].url);
};
arr.push(obj);
})
////////
this.form = {
title: data.title,
content: data.content,
beginDate: data.beginDate,
endDate: data.endDate,
type: data.type,
isRelease: data.isRelease,
voteUpdateCandidateDTOList: arr,
imgUrls: [],
};
console.log(this.form)
this.selTime = [res.data.beginDate, res.data.endDate];
if (res.data.imgList.length > 0) {
const pic = [];
this.form.imgUrls.push(res.data.imgList[0].url);
for (let item of res.data.imgList) {
let obj = {
name: item.url.split("_")[0] + "." + item.url.split(".")[1],
url: this.$ImgUrl(item.url),
uid: item.url.split("_")[1],
status: "done",
thumbUrl: this.$ImgUrl(item.url),
};
pic.push(obj);
}
this.fileList = pic;
} else {
this.form.imgUrls = [];
}
});
} else {
this.title = "新增投票";
}
},
immediate: true,
},
},
};
</script>
<style lang="less">
.vote-item {
width: 600px;
.vote-item-title {
display: flex;
}
}
</style>

@ -0,0 +1,290 @@
<template>
<div>
<a-drawer :title="title" :width="720" :visible="show" :body-style="{ paddingBottom: '80px' }" @close="addClose">
<div class="drawer-content">
<span style="font-weight: 600">投票信息</span>
<a-divider></a-divider>
<a-form-model ref="ruleForm" :model="form" :rules="rules">
<a-row>
<a-col :span="12">
<a-form-model-item label="投票标题" prop="title">
<a-input v-model="form.title" placeholder="请输入标题" style="width: 80%"></a-input>
</a-form-model-item>
</a-col>
<a-col :span="12">
<a-form-model-item label="投票时间" :rules="{required: true,message:'请选择日期',trigger:'change'}">
<a-range-picker v-model="selTime" @change="changeTime" value-format="YYYY-MM-DD HH:mm:ss" style="width: 80%"></a-range-picker>
</a-form-model-item>
</a-col>
<a-col :span="12">
<a-form-model-item label="公开人群" prop="type">
<a-select v-model="form.type" placeholder="请选择对象" style="width: 80%">
<a-select-option :value="1">全部</a-select-option>
<a-select-option :value="2">业主</a-select-option>
<a-select-option :value="3">业主亲属</a-select-option>
<a-select-option :value="4">租户</a-select-option>
<a-select-option :value="5">租户亲属</a-select-option>
</a-select>
</a-form-model-item>
</a-col>
<a-col :span="12">
<a-form-model-item label="是否发布" prop="isRelease">
<a-select v-model="form.isRelease" placeholder="请选择" style="width: 80%">
<a-select-option :value="1">发布</a-select-option>
<a-select-option :value="0">不发布</a-select-option>
</a-select>
</a-form-model-item>
</a-col>
<a-col :span="24">
<a-form-model-item label="投票内容" prop="content">
<a-textarea v-model="form.content" placeholder="请输入内容" style="width: 90%"></a-textarea>
</a-form-model-item>
</a-col>
<a-col :span="24">
<a-form-model-item label="图片上传">
<commonUpload :fileList="fileList" @handleChange="handleChange"></commonUpload>
</a-form-model-item>
</a-col>
<a-col :span="24">
<a-form-model-item label="投票选项">
<a-button @click="addVoteItem"></a-button>
<div class="vote-item" v-for="(item,index) in form.voteInsertCandidateDTOList" :key="index">
<div class="vote-item-title">
<span style="font-weight: 600">选项{{index+1}}</span>
<a @click="deleteVoteItem(item,index)" style="margin-left: 20px">删除</a>
</div>
<a-form-model layout="inline">
<a-form-model-item label="选项名称">
<a-input v-model="item.name"></a-input>
</a-form-model-item>
<a-form-model-item label="手机号">
<a-input v-model="item.tel"></a-input>
</a-form-model-item>
<a-form-model-item>
<a-upload
:action="`${$upload}`"
:multiple="false"
accept=".jpg,.JPG,.png,.PNG,.jpeg,.JPEG"
:headers="uploadHeaders"
@change="voteImgChange"
>
<a-button @click="uploadIndex(index)"> <a-icon type="upload" />点击上传</a-button>
</a-upload>
</a-form-model-item>
</a-form-model>
</div>
</a-form-model-item>
</a-col>
</a-row>
</a-form-model>
</div>
<div class="drawer-footer">
<a-button :style="{ marginRight: '8px' }" @click="addClose">
关闭
</a-button>
<a-button type="primary" @click="submit"> </a-button>
</div>
</a-drawer>
</div>
</template>
<script>
import store from "@/store";
import { findVote, addVote, updateVote} from "@/api/operation/vote"
import { form,rules } from "./config.js";
export default {
props: {
show: {
type: Boolean,
default: false,
},
editId: Number,
},
data() {
return {
title: "新增投票",
form: form,
rules: rules,
selTime: [],
fileList: [],
rule: [],
activeId: undefined,
deleteId: [], //Id
uploadHeaders: {
"manage-login-token": store.getters.getToken,
},
activeIndex: undefined,
};
},
mounted() {
},
methods: {
addClose() {
this.fileList = [];
this.form = {
title: '',
content: '',
beginDate: '',
endDate: '',
type: 1,
isRelease: 0,
voteInsertCandidateDTOList: [],
imgUrls: [],
};
this.deleteId = [];
this.selTime = [];
this.$emit("addClose");
},
success() {
this.$emit("success");
this.addClose();
},
submit() {
this.$refs.ruleForm.validate(async (valid) => {
if (valid) {
if (this.editId === null) {
addVote(this.form).then(res => {
if(res.code === 200){
this.$message.success(res.msg);
this.success();
} else {
this.$message.error(res.msg);
}
})
} else {
let obj = Object.assign(this.form, {id: this.activeId,deleteVoteCandidateIds: this.deleteId})
console.log(obj)
updateVote(obj).then(res => {
if(res.code === 200){
this.$message.success(res.msg);
this.success();
} else {
this.$message.error(res.msg);
}
})
}
}
});
},
//
handleChange(data) {
this.fileList = data;
this.form.imgUrls = [];
data.forEach(ele => {
if(ele.status == 'done') {
this.form.imgUrls.push(ele.response.data)
}
})
},
//
uploadIndex(index) {
this.activeIndex = index
},
voteImgChange(data) {
this.form.voteInsertCandidateDTOList[this.activeIndex].imgUrls = []
if(data.file.status == 'done') {
this.form.voteInsertCandidateDTOList[this.activeIndex].imgUrls.push(data.file.response.data)
}
},
//
changeTime(val) {
this.form.beginDate = val[0];
this.form.endDate = val[1];
},
//
addVoteItem() {
if(this.editId === null) {
let obj = {
name: '',
tel: '',
imgUrls: [],
};
this.form.voteInsertCandidateDTOList.push(obj)
} else {
let obj = {
id: null,
name: '',
tel: '',
imgUrls: [],
};
this.form.voteInsertCandidateDTOList.push(obj)
}
},
//
deleteVoteItem(item,index) {
this.deleteId.push(item.id);
this.form.voteInsertCandidateDTOList.splice(index,1)
},
},
watch: {
editId: {
handler(val) {
if (val !== null) {
this.title = "修改投票";
this.activeId = val;
findVote({ voteId: val }).then((res) => {
let data = res.data;
//
let arr = []
data.voteFBICandidateVoList.forEach(ele => {
let obj = {
id: ele.id,
name: ele.name,
tel: ele.tel,
imgUrls: [],
}
if(ele.imgList.length > 0) {
obj.imgUrls = ele.imgList[0].url
};
arr.push(obj);
})
////////
this.form = {
title: data.title,
content: data.content,
beginDate: data.beginDate,
endDate: data.endDate,
type: data.type,
isRelease: data.isRelease,
voteInsertCandidateDTOList: arr,
imgUrls: [],
}
this.selTime = [res.data.beginDate, res.data.endDate];
if (res.data.imgList.length > 0) {
const pic = [];
this.form.imgUrls.push(res.data.imgList[0].url);
for (let item of res.data.imgList) {
let obj = {
name: item.url.split("_")[0] + "." + item.url.split(".")[1],
url: this.$ImgUrl(item.url),
uid: item.url.split("_")[1],
status: "done",
thumbUrl: this.$ImgUrl(item.url),
};
pic.push(obj);
}
this.fileList = pic;
} else {
this.form.imgUrls = [];
}
});
} else {
this.title = "新增投票";
}
},
immediate: true,
},
},
};
</script>
<style lang="less">
.vote-item {
width: 600px;
.vote-item-title {
display: flex;
}
}
</style>

@ -0,0 +1,361 @@
<template>
<div>
<div class="cardTitle">
<a-space size="large">
<span>投票管理</span>
</a-space>
</div>
<div class="search-box" v-if="todayVote > 0">
<a-alert :message="'温馨提示:有 '+todayVote+' 个投票即将开始'" type="warning" show-icon />
</div>
<div class="search-box">
<a-row>
<a-col :span="20">
<a-space size="large">
<a-input v-model="form.title" style="width: 200px" placeholder="投票标题"></a-input>
<a-select v-model="form.status" style="width: 200px" placeholder="投票状态">
<a-select-option :value="1">未开始</a-select-option>
<a-select-option :value="2">进行中</a-select-option>
<a-select-option :value="3">已结束</a-select-option>
</a-select>
<a-range-picker v-model="selTime" @change="timeChange" value-format="YYYY-MM-DD HH:mm:ss"></a-range-picker>
<a-button type="primary" @click='getData'> </a-button>
<a-button @click='reset'> </a-button>
</a-space>
</a-col>
</a-row>
</div>
<a-button style="margin: 10px" class="add-btn" @click="addScroll"></a-button>
<div class="main">
<a-table :columns="columns" :data-source="tableData"
:pagination="pagination" @change="handlerChange"
:row-selection="{
selectedRowKeys: selectedRowKeys,
onChange: selectionChoosed,
}"
:row-key="
(record, index) => {
return record.id;
}">
<template slot="release" slot-scope="text,record">
<a-switch checked-children=""
un-checked-children="未发布"
:checked="record.isRelease == 1"
@change="handleRelease(record)">
</a-switch>
</template>
<template slot="action" slot-scope="text,record">
<span><a @click=detail(record)>投票详情</a></span>
<span><a style="margin-left: 8px" @click=edit(record)>编辑</a></span>
<span><a style="margin-left: 8px;color:red" @click=del(record)>删除</a></span>
</template>
</a-table>
<!-- <div class="action">
<a-dropdown :disabled="!hasSelected">
<a-menu slot="overlay" @click="handleMenuClick">
<a-menu-item key="del"> 批量删除 </a-menu-item>
</a-menu>
<a-button> 批量操作 <a-icon type="down" /> </a-button>
</a-dropdown>
<span style="margin-left: 8px">
<template v-if="hasSelected">
{{ `已选择 ${selectedRowKeys.length}` }}
</template>
</span>
</div> -->
</div>
<addForm :show="drawerShow" @success="success" @addClose="addClose" :editId="null"></addForm>
<editForm :show="editDrawerShow" @success="success" @addClose="editClose" :editId="editId"></editForm>
<a-drawer title="投票详情" :width="720" :visible="detailShow" :body-style="{ paddingBottom: '80px' }" @close="detailClose">
<span style="font-weight: 600">投票信息</span>
<a-divider></a-divider>
<a-descriptions :column="2">
<a-descriptions-item label="投票标题">{{detailTotal.title}}</a-descriptions-item>
<a-descriptions-item label="公开人群">
{{detailTotal.type==1?'全部':detailTotal.type==2?'业主':detailTotal.type==3?'业主亲属':detailTotal.type==4?'租户':'租户亲属'}}
</a-descriptions-item>
<a-descriptions-item label="开始时间">{{detailTotal.beginDate}}</a-descriptions-item>
<a-descriptions-item label="结束时间">{{detailTotal.endDate}}</a-descriptions-item>
<a-descriptions-item label="图片" :span="3">
<img :src="$ImgUrl(img.url)" class="contentImg" v-for="(img, index) in detailTotal.imgList" :key="index" />
</a-descriptions-item>
<a-descriptions-item label="内容" :span="3">
{{detailTotal.content}}
</a-descriptions-item>
</a-descriptions>
<a-divider></a-divider>
<a-table :columns="detailColumns" :data-source="detailData" :pagination="false"
:row-key="
(record, index) => {
return record.id;
}">
<template slot="img" slot-scope="text,record">
<img :src="$ImgUrl(img.url)" class="tableImg" v-for="(img, index) in record.imgList" :key="index" />
</template>
<template slot="action" slot-scope="text,record">
<span><a @click=voteDetail(record)>详情</a></span>
</template>
</a-table>
<a-drawer title="投票人列表" :width="720" :visible="voteShow" :body-style="{ paddingBottom: '80px' }" @close="voteShow = false">
<a-table :columns="voteColumns" :data-source="voteData" :pagination="votePagination" @change="votePChange"
:row-key="
(record, index) => {
return record.id;
}">
<template slot="roomList" slot-scope="text,record">
<div v-for="(item,index) in record.roomList" :key="index">
{{item.buildingName}}-{{item.unitName}}单元-{{item.estateName}}-
{{item.identity == 1?'业主':item.identity == 2?'业主亲属':item.identity == 3?'租户':'租户亲属'}}
</div>
</template>
</a-table>
</a-drawer>
</a-drawer>
</div>
</template>
<script>
import { rules, columns, pagination, detailColumns,voteColumns,votePagination } from "./depend/config.js";
import addForm from "./depend/form.vue";
import editForm from "./depend/editForm.vue";
import { getVoteList, deleteVote, releaseVote,findVote, getCandidateList,getPersonalList,getTodayVote} from "@/api/operation/vote"
export default {
components: {
addForm,
editForm,
},
data() {
return {
todayVote: 0,
form: {
title: '',
status: undefined,
beginDate: '',
endDate: ''
},
selTime: [],
rules: rules,
columns: columns,
voteColumns: voteColumns,
detailColumns: detailColumns,
tableData: [],
pagination: pagination,
votePagination: votePagination,
//
selectedRowKeys: [],
//
drawerShow: false,
editId: null,
editDrawerShow: false,
//
detailShow: false,
detailData: [],
detailIndex: undefined,
detailTotal: {
title: '',
content: '',
beginDate: '',
endDate: '',
type: 0,
isRelease: 0,
imgList: [],
},
//
voteShow: false,
voteData: [],
}
},
created() {
getTodayVote().then(res => {
this.todayVote = res.data
})
this.getData()
},
methods: {
getData() {
let obj = Object.assign(this.form, {pageNum: this.pagination.current,size: this.pagination.pageSize})
getVoteList(obj).then(res => {
this.tableData = res.data.rows;
this.pagination.total = res.data.total
})
},
reset() {
this.form = {
title: '',
status: undefined,
beginDate: '',
endDate: ''
},
this.selTime = [],
this.getData()
},
handlerChange() {
this.pagination.current = val.current;
this.pagination.pageSize = val.pageSize;
this.getData()
},
//
edit(val) {
if(val.status == 2) {
this.$confirm({
title: "该活动已经开始投票,不可编辑",
icon:'stop',
})
return false;
} else {
this.editId = val.id;
this.editDrawerShow = true;
}
},
//
handleRelease(val) {
if(val.status == 1 && val.isRelease == 0) {
this.$confirm({
title: "该投票还未开始,是否发布?",
icon:'question',
onOk:async()=>{
let res = await releaseVote({voteId: val.id})
if(res.code === 200){
this.$message.success(res.msg);
this.getData()
} else {
this.$message.error(res.msg);
}
},
})
} else {
releaseVote({voteId: val.id}).then(res => {
if(res.code === 200){
this.$message.success(res.msg);
this.getData()
} else {
this.$message.error(res.msg);
}
})
}
},
//
del(val) {
if(val.status == 2) {
this.$confirm({
title: "该活动已经开始投票,不可删除",
icon:'stop',
});
return false;
} else {
this.$confirm({
title: "是否删除该投票?",
icon:'delete',
onOk:async()=>{
let res = await deleteVote({voteIds: [val.id]})
if(res.code === 200){
this.$message.success(res.msg);
this.getData()
} else {
this.$message.error(res.msg);
}
},
})
}
},
//
selectionChoosed(val) {
this.selectedRowKeys = val
},
handleMenuClick(data) {
if (data.key === "del") {
this.$confirm({
title: "是否删除选中的投票?",
icon:'delete',
onOk:async()=>{
let res = await deleteVote({voteIds: this.selectedRowKeys})
if(res.code === 200){
this.$message.success(res.msg);
this.selectedRowKeys = [];
this.getData()
} else {
this.$message.error(res.msg);
}
},
})
}
},
//
addScroll() {
this.drawerShow = true;
},
addClose() {
this.drawerShow = false;
this.editId = null;
},
editClose() {
this.editDrawerShow = false;
this.editId = null;
},
success() {
this.getData();
},
//
detail(val) {
let obj = {pageNum: 1,size: 20,voteId: val.id}
this.detailIndex = val.id;
findVote({voteId: val.id}).then(res => {
let data = res.data
this.detailTotal = {
title: data.title,
type: data.type,
content: data.content,
beginDate: data.beginDate,
endDate: data.endDate,
isRelease: data.isRelease,
imgList: data.imgList,
}
})
getCandidateList(obj).then(res => {
this.detailData = res.data.rows;
this.detailShow = true;
})
}, //
voteDetail(val) {
let obj = {pageNum: this.votePagination.current,size: this.votePagination.pageSize,voteId: this.detailIndex,voteCandidateId: val.id}
getPersonalList(obj).then(res => {
let data = res.data;
this.voteData = data.rows;
this.voteShow = true;
})
}, //
votePChange(val) {
},
//
detailClose() {
this.detailIndex = undefined
this.detailShow = false
},
//
timeChange(val) {
this.form.beginDate = val[0];
this.form.endDate = val[1];
},
},
computed: {
hasSelected() {
return this.selectedRowKeys.length > 0;
},
},
}
</script>
<style lang="less">
.drawer-content {
padding: 16px;
}
.contentImg {
height: 108px;
width: 194px;
}
.tableImg {
height: 54px;
width: 97px;
}
</style>

15969
yarn.lock

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save