Commit 4dbef4bd authored by xj's avatar xj

完成办不成事报表

parent 5dac0bef
......@@ -164,4 +164,20 @@ export function getStatisticSignin(params) {
// 预约人群画像-性别分布
export function getStatisticSexual(params) {
return http.get(`${BASEURL}/admin/statistic/sexual`, params);
}
/**
* 办不成事报表
*/
// 办不成事列表
export function getImpossible(params) {
return http.get(`${BASEURL}/admin/impossible/index`, params);
}
// 统计办不成事和已回复
export function getCountImpossible(params) {
return http.get(`${BASEURL}/admin/impossible/countImpossible`, params);
}
// 办不成事详情
export function getImpossibleInfo(params) {
return http.get(`${BASEURL}/admin/impossible/impossibleInfo`, params);
}
\ No newline at end of file
<template>
<img :src="imgsrc">
</template>
<script>
export default {
props:['src'],
computed:{
imgsrc:function(){
return this.src?`${process.env.VUE_APP_API_BASE_URL}/${this.src}`:require('./thumb.jpg')
}
}
}
</script>
\ No newline at end of file
<template>
<div class="thumb" >
<div v-if="fileType == 'img'">
<img :src="images[index]" v-if="src" @click="show">
<img src="./thumb.jpg" v-else>
</div>
<div v-else>
<a-icon type="play-circle" style="font-size:20px" @click="visible = true"/>
<a-modal
title="详情"
:visible="visible"
:footer="null"
@cancel="visible=false"
>
<video :src="images[0]" style="width:100%;height:100%" controls autoplay v-if="visible"></video>
</a-modal>
</div>
</div>
</template>
<script>
export default {
props:{
src:[String,Array],
index:{
type:Number,
default:0
}
},
data(){
return{
images:[],
fileType:"img",
visible:false
}
},
watch:{
src:{
handler:function(v){
if(v){
if(typeof v == 'string'){
this.images = v.split(",").map(v=>{
return this.publicSrc(v)
})
}else{
this.images = v.map(v=>{
return this.publicSrc(v)
})
}
// 判断视频格式
if(v.search(/mp4/ig)>=0){
this.fileType = 'mp4'
}else{
this.fileType = 'img'
}
}
},
immediate:true
}
},
methods:{
publicSrc(src){
if(src.search(/http/ig)>-1){
return `${src}`
}else{
return `${process.env.VUE_APP_API_BASE_URL}/${src}`
}
},
show(){
this.$viewerApi({
images: this.images,
options: {
initialViewIndex: this.index
},
})
}
}
}
</script>
<style lang="less" scoped>
.thumb{
width: 50px;
// height: 60px;
margin: 0 auto;
cursor: pointer;
img{
display: inline-block;
width: 100%;
height: 100%;
}
}
</style>
\ No newline at end of file
......@@ -232,6 +232,27 @@ const routes = [
},
],
},
{
path: "Impossible",
name: "Impossible",
redirect: "/home/dataManagement/Impossible/ImpossibleForm",
component: () =>
import(
/* webpackChunkName: "oneYardPass" */ "@/views/dataAdmin/components/Impossible/module.vue"
),
meta: { title: "办不成事报表" },
children: [
{
path: "ImpossibleForm",
name: "ImpossibleForm",
component: () =>
import(
/* webpackChunkName: "reportForm" */ "@/views/dataAdmin/components/Impossible/index.vue"
),
meta: { title: "办不成事报表" },
},
],
},
{
path: "AIEfficiency",
name: "AIEfficiency",
......
<template>
<div class="ff p15">
<div class="form-box">
<div class="num-dv">
<a-button :loading="btnLoading" type="success" @click="handleExportTable">
<span>{{ tableSelectedRows.length ? "导出" : "导出全部" }}</span>
</a-button>
<div class="ml20">提交次数:{{ numObj ? numObj.count : 0 }}</div>
<div class="ml20">回复次数:{{ numObj ? numObj.reply_count : 0 }}</div>
</div>
<a-form :model="queryform" layout="inline">
<a-form-item>
<a-checkbox @change="onChange">只看未回复</a-checkbox>
</a-form-item>
<a-form-item>
<a-select v-model="queryform.source" style="width: 140px">
<a-select-option value="">全部来源</a-select-option>
<a-select-option :value="item.value" v-for="item,index in deviceList"
:key="index">{{item.label}}</a-select-option>
</a-select>
</a-form-item>
<a-form-item>
<a-range-picker v-model:value="queryform.time" valueFormat="yyyy-MM-DD" style="width: 270px" />
</a-form-item>
<a-form-item>
<a-input v-model:value="queryform.keyword" placeholder="请输入标题或者名字关键字搜索" style="width: 220px" />
</a-form-item>
<a-form-item>
<a-button type="primary" @click="getlist">搜索</a-button>
</a-form-item>
</a-form>
</div>
<div class="table-box">
<a-table :dataSource="tabledataSource" :columns="tablecolumns" :pagination="pagination" :scroll="{ y: 590 }"
:row-key="(record) => record.id" :row-selection="{
selectedRowKeys: tableSelectedKeys,
onChange: onSelectChange,
}">
<template slot="type" slot-scope="text, record, index">
<div>{{typeList.find(item=>record.type).label}}</div>
</template>
<template slot="valid" slot-scope="text, record, index">
<div>{{record.valid == 1 ? '' : ''}}</div>
</template>
<template slot="secrecy" slot-scope="text, record, index">
<div>{{record.secrecy == 1 ? '' : ''}}</div>
</template>
<template slot="status" slot-scope="text, record, index">
<div>{{record.status == 1 ? '' : ''}}</div>
</template>
<template slot="操作" slot-scope="text, record, index">
<a-button type="link" @click="detail(record)">详情</a-button>
</template>
</a-table>
</div>
<a-drawer title="详情" :visible="visible" width="100%" @close="visible = false">
<div class="content-box">
<div class="content-dv" v-if="detailData">
<div style="margin-bottom: 10px;">建议内容</div>
<a-descriptions layout="vertical" :column="4">
<a-descriptions-item label="问题主题" :span="4">
{{detailData.title}}
</a-descriptions-item>
<a-descriptions-item label="具体问题" :span="4">
{{detailData.content}}
</a-descriptions-item>
<a-descriptions-item label="业务名称" :span="4">
{{detailData.business}}
</a-descriptions-item>
<a-descriptions-item label="办事区县" :span="4">
{{detailData.region}}
</a-descriptions-item>
<a-descriptions-item label="单位名称" :span="4">
{{detailData.dept_name}}
</a-descriptions-item>
<a-descriptions-item label="真实姓名">
{{detailData.name}}
</a-descriptions-item>
<a-descriptions-item label="联系电话">
{{detailData.phone}}
</a-descriptions-item>
<a-descriptions-item label="身份证号">
{{detailData.idcard}}
</a-descriptions-item>
<a-descriptions-item label="电子邮箱">
{{detailData.email}}
</a-descriptions-item>
<a-descriptions-item label="联系地址" :span="4">
{{detailData.address}}
</a-descriptions-item>
<a-descriptions-item label="提交时间" :span="4">
{{detailData.create_time}}
</a-descriptions-item>
</a-descriptions>
</div>
<div class="content-dv" v-if="detailData">
<div style="margin-bottom: 10px;">建议答复</div>
<a-descriptions layout="vertical" :column="1">
<a-descriptions-item label="所属部门">
{{detailData.reply_dept}}
</a-descriptions-item>
<a-descriptions-item label="回复内容">
{{detailData.reply_content}}
</a-descriptions-item>
<a-descriptions-item label="附件">
<div class="img-dv" v-if="detailData.reply_url && detailData.reply_url.length > 0">
<thumbImage :src="item.url" :index="idx" @click="idx = index" fileType="img"
v-for="item,index in detailData.reply_url" :key="index" />
</div>
</a-descriptions-item>
<a-descriptions-item label="回复人">
{{detailData.reply_people}}
</a-descriptions-item>
<a-descriptions-item label="回复时间">
{{detailData.update_time}}
</a-descriptions-item>
</a-descriptions>
</div>
</div>
<div class="btn-dv">
<a-button style="marginRight: 8px" @click="visible = false">
关闭
</a-button>
</div>
</a-drawer>
</div>
</template>
<script>
import {
getImpossible,
getImpossibleInfo,
getCountImpossible
} from '@/api/dataAdmin.js'
import image from '@/components/image/thumbImage'
import {
export2Excel
} from "@/utils/js/exportExcel";
export default {
data() {
return {
idx: 0,
queryform: {
page: 1,
size: 10,
source: '',
keyword: null,
time: null,
reply:''
},
deviceList: [{
label: '微官网',
value: 1
}, {
label: '自助服务系统',
value: 2
}],
btnLoading: false,
tableSelectedKeys: [],
tableSelectedRows: [],
defaultFileList: [],
visible: false,
tablename: "treaty", //接口地址 名称
tablecolumns: [{
title: "序号",
width: "70px",
align: 'center',
customRender: (text, record, index) => `${index+1}`
},
{
title: "问题主题",
dataIndex: "title",
align: 'center',
scopedSlots: {
customRender: (text, record, index) => `${record.title || '--'}`
},
},
{
title: "业务名称",
dataIndex: "business",
align: 'center',
scopedSlots: {
customRender: (text, record, index) => `${record.business || '--'}`
},
},
{
title: "真实姓名",
dataIndex: "name",
align: 'center',
customRender: (text, record, index) => `${record.name || '--'}`
},
{
title: "联系电话",
dataIndex: "phone",
align: 'center',
customRender: (text, record, index) => `${record.phone || '--'}`
},
{
title: "提交日期",
dataIndex: "create_time",
align: 'center',
customRender: (text, record, index) => `${record.create_time || '--'}`
},
{
title: "是否回复",
dataIndex: "status",
align: 'center',
scopedSlots: {
customRender: "status",
},
},
{
title: "回复人",
dataIndex: "reply_name",
align: 'center',
customRender: (text, record, index) => `${record.reply_name || '--'}`
},
{
title: "回复时间",
dataIndex: "update_time",
align: 'center',
customRender: (text, record, index) => `${record.update_time || '--'}`
},
{
title: "所属部门",
dataIndex: "dept_name",
align: 'center',
customRender: (text, record, index) => `${record.dept_name || '--'}`
},
{
title: "操作",
dataIndex: "操作",
scopedSlots: {
customRender: "操作",
},
},
], //表头数据
pagination: {
total: 0,
pageSize: 10, //每页中显示10条数据
showSizeChanger: true,
pageSizeOptions: ["10", "20", "50", "100"], //每页中显示的数据
showTotal: total => `共有 ${total} 条数据`, //分页中显示总的数据
},
tabledataSource: [], //表格数据
columnsSearch: [
], //表格查询条件
detailData: null,
deplist: [],
numObj: null
}
},
async created() {
this.getlist()
let {
data
} = await getCountImpossible()
this.numObj = data
},
methods: {
getlist() {
getImpossible(this.queryform).then(res => {
this.tabledataSource = res.data.data
})
},
onChange(e) {
this.queryform.reply = e.target.checked ? 0 : ''
},
detail(row) {
getImpossibleInfo({
id: row.id
}).then(res => {
this.detailData = res.data
this.visible = true
})
},
// 选中
onSelectChange(keys, rows) {
this.tableSelectedKeys = keys;
const res = new Map();
this.tableSelectedRows = [...this.tableSelectedRows, ...rows]
.filter((v) => {
return !res.has(v.id) && res.set(v.id, 1);
})
.filter((v) => {
return this.tableSelectedKeys.some((val) => v.id == val);
});
},
// 导出
async handleExportTable() {
this.btnLoading = true;
let obj = {
1: "本地打印",
2: "在线提交",
};
let data = [];
if (this.tableSelectedKeys.length && this.tableSelectedRows.length) {
// 深度克隆避免影响页面表格展示
data = this.$_.cloneDeep(this.tableSelectedRows);
data.forEach((item) => {
Object.keys(obj).forEach((keys) => {
if (item.type == keys) {
item.type = obj[keys];
}
});
});
} else {
data = this.$_.cloneDeep(
await getImpossible({
page: 1,
size: -1
})
);
if (!data.length) return;
for (let item of data) {
Object.keys(obj).forEach((key) => {
if (item.type == key) {
item.type = obj[key];
}
});
}
}
export2Excel(
this.tHeader,
this.filterVal,
data,
"填单记录报表" + this.$moment().format("YYYYMMDDHHmmss")
);
this.btnLoading = false;
},
}
}
</script>
<style scoped lang="less">
.form-box {
display: flex;
justify-content: space-between;
margin-bottom: 10px;
.num-dv{
display: flex;
align-items: center;
.ml20{
margin-left: 20px;
}
}
}
.img-dv {
display: flex;
flex-wrap: wrap;
img {
width: 40px;
height: 40px;
margin-right: 10px;
margin-bottom: 10px;
}
}
/deep/.ant-spin-container{
display: block !important;
}
/deep/.ant-drawer-body {
background: #f7f7f7;
padding: 15px;
box-sizing: border-box;
min-height: calc(100vh - 55px);
}
/deep/td {
text-align: left;
}
.btn-dv {
background-color: #fff;
padding: 15px;
margin-top: 20px;
display: flex;
justify-content: flex-end;
}
.content-box {
display: flex;
justify-content: space-between;
width: 100%;
}
.content-dv {
width: calc(50% - 10px);
background: #fff;
border-radius: 10px;
padding: 10px;
}
</style>
\ No newline at end of file
import { deepClone } from "@/utils/js/common.js";
export default {
data() {
return {
defaultInfoForm: {},
modalInfo: {
confirmLoading: false,
visible: false,
title: '用户信息',
width: '30%',
},
}
},
props: {
sourceInfoForm: {
type: Object,
default: () => {
return {
// --------------申报人信息-----------------------
name: "张三",
Gender: "",
Age: "56",
Phone: "13080888888",
yuyuecishu: "12",
paiduicishu: "6",
guanlianyewu: "12",
haxizhi: "3sad54a5f4sda4da4sd4adasdqa1sda1g1d1ada4d4f1fgweqqwq01f4sa4dgds1eqw5e1c2c2vx",
qukuaigaodu: "24292496",
chuangjianshijian: "2022-04-25 18:22",
// --------------业务分析-----------------------
yewuming: '公安户籍类',
guanlianshixiang: [
{
shixiangmingcheng: '事项名称事项名称事项名称事项名称事项名称事项名称',
},
{
shixiangmingcheng: '事项名称事项名称事项名称事项名称事项名称事项名称',
},
{
shixiangmingcheng: '事项名称事项名称事项名称事项名称事项名称事项名称',
},
],
shoulicishu: "12546",
banjiecishu: "12348",
haopinglv: "99.99%",
// --------------工作人员-----------------------
workImgUrl: require('../../../../../assets/images/logo.png'),
workpeople: "刘明洋",
JobNo: "01",
department: '税务局',
PoliticalOutlook: '党员',
workPhone: '13080888888',
Starlevel: '5',
souliyewu: '12247877',
pingjiacishu: '1225454',
};
},
},
},
watch: {
sourceInfoForm: {
handler(newValue, oldValue) {
// console.log(newValue);
// console.log(oldValue);
this.defaultInfoForm = Object.assign({}, deepClone(newValue));
},
deep: true,
},
},
computed: {
},
created() {
setTimeout(() => {
this.defaultInfoForm = Object.assign({}, deepClone(this.sourceInfoForm));
// console.log(this.defaultInfoForm);
}, 0);
},
methods: {
modalClose() {
this.modalInfo.visible = false;
}
},
}
\ No newline at end of file
<template>
<div class="Container">
<div class="main">
<a-tabs v-model="tabsActive" @change="tabsChange" :forceRender="false">
<a-tab-pane
:key="item.path"
v-for="(item, index) of tabsList['children']"
:tab="item['meta']['title']"
>
</a-tab-pane>
</a-tabs>
<router-view style="padding: 0 1rem" />
</div>
</div>
</template>
<script>
import { getItemData } from "@/utils/js/common.js";
import common from "@/mixins/common";
export default {
name: "ImpossibleModule",
mixins: [common],
data() {
return {
tabsActive: undefined,
};
},
computed: {
tabsList() {
return getItemData(this.$router.options.routes, "name", "Impossible");
},
},
mounted() {
this.$nextTick(() => {
this.tabsActive = this.$route.path.substr(
this.$route.path.lastIndexOf("/") + 1
);
});
},
methods: {
tabsChange(val) {
this.$router.push({
path: `/home/dataManagement/Impossible/${val}`,
// query: { testoption: "test001" },
});
},
},
};
</script>
<style lang="less" scoped>
@headerH: 4.5rem;
.Container {
height: 100% !important;
// background: #fac;
background: #f5f5f5;
display: flex;
flex-direction: column;
.main {
// background: #afc;
background: #ffffff;
border-radius: 6px;
flex: 1;
overflow-y: auto;
overflow-x: hidden;
margin: 1.2rem 2rem;
}
&::before {
content: "";
display: block;
width: 100%;
height: @headerH;
background: rgb(59, 135, 255);
background: -moz-linear-gradient(
174deg,
rgba(59, 135, 255, 1) 24%,
rgba(108, 53, 247, 1) 85%
);
background: -webkit-linear-gradient(
174deg,
rgba(59, 135, 255, 1) 24%,
rgba(108, 53, 247, 1) 85%
);
background: linear-gradient(
174deg,
rgba(59, 135, 255, 1) 24%,
rgba(108, 53, 247, 1) 85%
);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#3b87ff",endColorstr="#6c35f7",GradientType=1);
}
/deep/.ant-tabs-nav {
.ant-tabs-tab {
margin: 0 !important;
}
}
/deep/.ant-tabs-tab {
font-size: 1rem !important;
& + .ant-tabs-tab {
margin: 0 !important;
margin-left: 0.7rem !important;
}
}
}
</style>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment