Browse Source

合并冲突

old
jiangyy 4 years ago
parent
commit
b45ecf4e15
  1. 5
      package.json
  2. 4
      src/api/index.js
  3. 229
      src/views/form/statistics/analysis.vue
  4. 192
      src/views/form/statistics/chart.vue
  5. 4
      src/views/form/statistics/index.vue
  6. 232
      src/views/form/statistics/list.vue
  7. 4
      vue.config.js

5
package.json

@ -65,10 +65,7 @@
"not ie <= 8"
],
"lint-staged": {
"src/**/*.{js,vue}": [
"eslint --fix",
"git add"
]
},
"husky": {
"hooks": {

4
src/api/index.js

@ -32,7 +32,9 @@ api.interceptors.request.use(
* 以下代码为示例在登录状态下分别对 post get 请求加上 token 参数
*/
if (store.getters['user/isLogin']) {
request.headers.token = store.state.user.token
request.headers.token = store.state.user.token
// request.headers.token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJhcHAiOiJnb3YiLCJjbGllbnQiOiJ3ZWIiLCJleHAiOjE2MzI5NjYwODEsInVzZXJJZCI6Ijg0ODg3ZDQzMjEzN2EzMGI3YWJhYWM1MDY5ODZkNDYxIiwiaWF0IjoxNjMyMzYxMjgxfQ.CDYJNfuF7gRRDwwmB9dJQjVOj_t_3xdrgwMqxHNAleZuQHkPMu9fI32at2aPjprhN4yBc_KT_3_Yhh30SF7YzA'
// request.headers.Authorization = store.state.user.token
}
signRequest(request)
return request

229
src/views/form/statistics/analysis.vue

@ -5,29 +5,67 @@
:key="index">
<div class="content">
<div class="title">
<span style="font-size: 16px">Q{{ item.label }}{{ item.type }}</span>
<span style="font-size: 16px; font-weight: bold;">Q{{ index + 1 }} {{ item.label }}{{ item.type }}</span>
<div>
<span>图表类型</span>
<el-select v-model="item.chartType"
placeholder="请选择">
<el-option v-for="subItem in options"
:key="subItem.value"
:label="subItem.label"
:value="subItem.value" />
</el-select>
<!-- <div>
<span>图表类型</span>
<el-select v-model="item.chartType" placeholder="请选择">
<el-option
v-for="subItem in options"
:key="subItem.value"
:label="subItem.label"
:value="subItem.value"
/>
</el-select>
</div> -->
</div>
<!-- <line-chart
class="chart"
:chart-option="getCharData(item)"
:width="'90vw'"
/> -->
<div v-if="computedCount(item.type)"
class="cell-type">
<span>共收集 {{ item.detail.collectionTotal }} </span>
<span>有效 {{ item.detail.validTotal }} </span>
<span v-if="item.type === 'NUMBER_INPUT'">总计 {{ item.detail.sumTotal }} </span>
<span v-if="item.type === 'SWITCH'"> {{ item.detail.openTotal }} {{ item.detail.closedTotal }} </span>
</div>
<div v-else-if="item.type === 'RADIO' || item.type === 'CHECKBOX' || item.type === 'SELECT'"
class="cell-wrapper">
<div v-for="(n, i) in item.detail.options"
:key="i"
class="cell">
<div class="cell-label">{{ n.label }}</div>
<div class="cell-value">
<div class="cell-progress">
<el-progress :stroke-width="20"
:show-text="false"
:percentage="computedPercent(n.currentCount, item.detail.totalCount)" />
</div>
<div class="cell-percent">
{{ computedPercent(n.currentCount, item.detail.totalCount).toFixed(2) }}%
</div>
<div class="cell-num">{{ n.currentCount }}</div>
</div>
</div>
</div>
<line-chart class="chart"
:chart-option="getCharData(item)"
:width="'90vw'" />
</div>
<el-divider />
</div>
</div>
<data-empty v-else
style="padding: 20px"
desc="只有单选、多选、下拉框组件可以生成图表" />
<line-chart class="chart"
:chart-option="getCharData(item)"
:width="'90vw'" />
</div>
<data-empty v-else
style="padding: 20px"
desc="暂无数据分析" />
</div>
<data-empty v-else
style="padding: 20px"
desc="只有单选、多选、下拉框组件可以生成图表" />
</div>
</template>
@ -116,76 +154,70 @@ export default {
this.list = res.data
})
},
getCharData (data) {
const config = {
tooltip: {
backgroundColor: 'rgba(255,255,255,0.8)', // rgba
color: 'black',
borderWidth: '1',
borderColor: 'rgb(156,209,255)',
textStyle: {
color: 'black'
mounted () {
this.getData()
},
methods: {
getData () {
// `${process.env.VUE_APP_API_ROOT_TDUCK}/user/project/report/analysis`
// params: { projectKey: this.$route.query.key }
this.$api
.post('/data/aggregator/questionnaire/analysisreport', {
projectKey: this.$route.query.key
})
.then(res => {
this.list = res.data
})
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: [
{
type: 'category',
axisTick: {
alignWithLabel: true
}
return config
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
computedCount(type) {
const arr = ['PROVINCE_CITY', 'NUMBER_INPUT', 'SWITCH', 'INPUT', 'TEXTAREA', 'INPUT_MAP', 'TIME', 'DATE_RANGE', 'DATE', 'TIME_RANGE']
return arr.includes(type)
},
xAxis: [
{
type: 'category',
axisTick: {
alignWithLabel: true
}
}
],
yAxis: [
{
type: 'value'
}
],
series: [
{
name: '数量',
type: 'pie',
barWidth: '40%'
}
]
}
if (['bar', 'line'].includes(data.chartType)) {
config.tooltip.axisPointer = {
type: 'line'
computedPercent(num, count) {
return ((num * 100) / count)
}
config.tooltip.trigger = 'axis'
config.xAxis[0].data = data.fieldName
config.series[0].data = data.data
config.series[0].type = data.chartType
} else {
//
/* if ("ring" === data.chartType) {
config.series[0].radius = ["40%", "70%"];
config.series[0].emphasis = {
label: {
show: true,
fontSize: '25',
fontWeight: 'bold'
}
} else {
//
/* if ("ring" === data.chartType) {
config.series[0].radius = ["40%", "70%"];
config.series[0].emphasis = {
label: {
show: true,
fontSize: '25',
fontWeight: 'bold'
}
}
}else{
delete config.series[0].radius
delete config.series[0].label
delete config.series[0].radius
delete config.series[0].label
} */
config.series[0].data = []
config.series[0].data = []
Object.keys(data.map).forEach(key => {
config.series[0].data.push({ name: key, value: data.map[key] })
})
// config.series[0].data = data.map
}
config.series[0].data.push({ name: key, value: data.map[key] })
})
// config.series[0].data = data.map
}
return config
}
}
}
}
</script>
@ -199,7 +231,7 @@ export default {
width: 100%;
.title {
font-size: 14px;
padding: 0 30px;
// padding: 0 30px;
height: 54px;
line-height: 54px;
width: 100%;
@ -211,4 +243,51 @@ export default {
}
}
}
</style>
</style>
<style lang="scss" scoped>
.cell-type {
padding-left: 10px;
font-size: 14px;
}
.cell-wrapper {
width: 100%;
border: 1px solid #eee;
.cell,
.cell-value {
widows: 100%;
display: flex;
align-items: center;
}
.cell {
justify-content: space-between;
padding: 10px 0;
font-size: 14px;
border-bottom: 1px solid #eee;
.cell-label {
width: 60%;
box-sizing: border-box;
padding-left: 10px;
}
.cell-value {
width: 40%;
.cell-progress {
// flex: 1;
width: 180px;
}
.cell-percent {
margin-left: 10px;
}
.cell-num {
width: 40%;
flex-shrink: 0;
text-align: center;
}
}
}
.cell:last-child {
border-bottom: 0;
}
}
</style>

192
src/views/form/statistics/chart.vue

@ -186,130 +186,88 @@ export default {
type: 'shadow'
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
getProjectStats () {
this.$api.get(`${process.env.VUE_APP_API_ROOT_TDUCK}/user/project/report/stats`, { params: { projectKey: this.activeProjectKey } }).then(res => {
this.projectStats = res.data
if (this.projectStats.completeCount) {
let rate = this.projectStats.completeCount / this.projectStats.viewCount
this.projectStats.completeRate = rate > 1 ? 100 : rate * 100
this.projectStats.avgCompleteFormatStr = timeFormat(this.projectStats.avgCompleteTime)
} else {
this.projectStats.completeRate = 0
this.projectStats.avgCompleteFormatStr = 0
}
})
},
xAxis: {
type: 'value',
interval: 1,
boundaryGap: [0, 0.01]
getProjectSituation () {
this.$api.get(`${process.env.VUE_APP_API_ROOT_TDUCK}/user/project/report/situation`, { params: { projectKey: this.activeProjectKey } }).then(res => {
this.lineChartOptionData.xAxis.data = res.data.map(item => {
return item.createdTime
})
this.lineChartOptionData.series = [{
data: res.data.map(item => {
return item.count
}),
name: '回收数',
stack: '总量',
type: 'line',
areaStyle: {}
}]
})
},
yAxis: {
type: 'category',
data: [0]
//
getProjectSubmitPosition () {
this.$api.get(`${process.env.VUE_APP_API_ROOT_TDUCK}/user/project/report/position`, { params: { projectKey: this.activeProjectKey } }).then(res => {
this.mapChartOptionData.series = [
{
name: '提交数',
type: 'map',
mapType: 'china',
zoom: 1.2,
roam: false,
label: {
show: false,
color: 'rgb(0,0,0)'
},
data: Object.keys(res.data).map(key => {
return { name: key.replace(/省(s?)|市(s?)|\//ig, ''), value: res.data[key] }
})
}
]
})
},
series: [
{
barWidth: 30,
name: '数量',
type: 'bar',
data: [0]
}
]
},
pieChartOptionData: {
tooltip: {
trigger: 'item',
backgroundColor: 'rgba(255,255,255,0.8)', // rgba
color: 'black',
borderWidth: '1',
borderColor: 'rgb(156,209,255)',
textStyle: {
color: 'black'
}
getProjectSubmitSource () {
this.$api.get(`${process.env.VUE_APP_API_ROOT_TDUCK}/user/project/report/source`, { params: { projectKey: this.activeProjectKey } }).then(res => {
if (res.data && res.data.length) {
this.barChartOptionData.yAxis.data = res.data.map(item => {
return item.browserName ? item.browserName : '其他'
})
this.barChartOptionData.series = [
{
barWidth: 30,
name: '数量',
type: 'bar',
data: res.data.map(item => {
return item.count
})
}
]
}
})
},
series: [
{
name: '设备类型',
type: 'pie',
radius: ['50%', '70%'],
avoidLabelOverlap: false,
label: {
show: false,
position: 'center'
},
emphasis: {
label: {
show: true,
fontSize: '30',
fontWeight: 'bold'
}
},
labelLine: {
show: false
},
data: [0]
}
]
}
}
},
created () {
this.activeProjectKey = this.$route.query.key
this.projectChangeHandle()
}, methods: {
projectChangeHandle () {
this.getProjectStats()
this.getProjectSituation()
this.getProjectSubmitPosition()
this.getProjectSubmitDevice()
this.getProjectSubmitSource()
},
getProjectStats () {
this.$api.get(`${process.env.VUE_APP_API_ROOT_TDUCK}/user/project/report/stats`, { params: { projectKey: this.activeProjectKey } }).then(res => {
this.projectStats = res.data
if (this.projectStats.completeCount) {
let rate = this.projectStats.completeCount / this.projectStats.viewCount
this.projectStats.completeRate = rate > 1 ? 100 : rate * 100
this.projectStats.avgCompleteFormatStr = timeFormat(this.projectStats.avgCompleteTime)
} else {
this.projectStats.completeRate = 0
this.projectStats.avgCompleteFormatStr = 0
getProjectSubmitDevice () {
this.$api.get(`${process.env.VUE_APP_API_ROOT_TDUCK}/user/project/report/device`, { params: { projectKey: this.activeProjectKey } }).then(res => {
if (res.data && res.data.length) {
this.pieChartOptionData.series[0].data = res.data.map(item => {
return { value: item.count, name: item.osName ? item.osName : '其他' }
})
}
})
}
})
},
getProjectSituation () {
this.$api.get(`${process.env.VUE_APP_API_ROOT_TDUCK}/user/project/report/situation`, { params: { projectKey: this.activeProjectKey } }).then(res => {
this.lineChartOptionData.xAxis.data = res.data.map(item => {
return item.createdTime
})
this.lineChartOptionData.series = [{
data: res.data.map(item => {
return item.count
}),
name: '回收数',
stack: '总量',
type: 'line',
areaStyle: {}
}]
})
},
//
getProjectSubmitPosition () {
this.$api.get(`${process.env.VUE_APP_API_ROOT_TDUCK}/user/project/report/position`, { params: { projectKey: this.activeProjectKey } }).then(res => {
this.mapChartOptionData.series = [
{
name: '提交数',
type: 'map',
mapType: 'china',
zoom: 1.2,
roam: false,
label: {
show: false,
color: 'rgb(0,0,0)'
},
data: Object.keys(res.data).map(key => {
return { name: key.replace(/省(s?)|市(s?)|\//ig, ''), value: res.data[key] }
})
}
]
})
},
getProjectSubmitSource () {
getProjectSubmitSource() {
this.$api.get(`${process.env.VUE_APP_API_ROOT_TDUCK}/user/project/report/source`, { params: { projectKey: this.activeProjectKey } }).then(res => {
if (res.data && res.data.length) {
this.barChartOptionData.yAxis.data = res.data.map(item => {
@ -328,7 +286,7 @@ export default {
}
})
},
getProjectSubmitDevice () {
getProjectSubmitDevice() {
this.$api.get(`${process.env.VUE_APP_API_ROOT_TDUCK}/user/project/report/device'`, { params: { projectKey: this.activeProjectKey } }).then(res => {
if (res.data && res.data.length) {
this.pieChartOptionData.series[0].data = res.data.map(item => {

4
src/views/form/statistics/index.vue

@ -4,9 +4,9 @@
<el-tab-pane label="列表视图" name="list">
<list />
</el-tab-pane>
<el-tab-pane label="统计视图" name="chart">
<!-- <el-tab-pane label="统计视图" name="chart">
<chart />
</el-tab-pane>
</el-tab-pane> -->
<el-tab-pane label="数据分析" name="analysis">
<analysis />
</el-tab-pane>

232
src/views/form/statistics/list.vue

@ -45,6 +45,14 @@
</template>
</el-table-column>
<el-table-column label="填写人"
prop="realName" />
<el-table-column label="组织/部门/网格"
prop="orgName" />
<el-table-column label="来源"
prop="clientType" />
<!-- <el-table-column label="填写时间" prop="createdTime" /> -->
<el-table-column v-for="col in otherCustomColumns"
:key="col"
:label="projectItemColumns[col]"
@ -61,9 +69,8 @@
{{ scope.row[col] }}
</template>
</el-table-column>
<el-table-column :render-header="renderHeader"
fixed="right"
<!-- :render-header="renderHeader" -->
<el-table-column fixed="right"
width="50">
<template slot-scope="scope">
<el-button size="small"
@ -85,7 +92,7 @@
<div v-for="item in projectItemList"
:key="item.id">
<h4>{{ item.label }}</h4>
<result-item :field-item-id="item.formItemId"
<result-item :field-item-id="Number(item.formItemId)"
:project-item-data="item"
:result-data="activeResultRow" />
<el-divider />
@ -103,6 +110,28 @@
layout="total, prev, pager, next"
@current-change="queryProjectResult" />
</div>
<div>
<div v-for="item in projectItemList"
:key="item.id">
<h4>{{ item.label }}</h4>
<result-item :field-item-id="item.formItemId"
:project-item-data="item"
:result-data="activeResultRow" />
<el-divider />
</div>
</div>
</el-card>
</el-scrollbar>
</el-drawer>
<div style="display: flex; justify-content: center; margin-top: 10px;">
<el-pagination v-if="total>10"
:current-page.sync="queryConditions.current"
:page-size.sync="queryConditions.size"
:total="total"
background
layout="total, prev, pager, next"
@current-change="queryProjectResult" />
</div>
</div>
<div class="custom-col-container">
<el-dialog :visible.sync="customColumnDialogVisible"
@ -234,98 +263,125 @@ export default {
this.projectData = res.data
})
},
conditionFilterHandle () {
this.$refs.dataFilter.showDialogHandle()
},
dataFilterHandle (params, comparisons) {
this.queryConditions.extParams = params
this.queryConditions.extComparisons = comparisons
mounted () {
this.projectKey = this.$route.query.key
this.queryConditions.projectKey = this.projectKey
this.queryProjectResult()
this.queryProjectItems()
this.queryProject()
},
queryProjectResult () {
this.$api.get(`${process.env.VUE_APP_API_ROOT_TDUCK}/user/project/result/page`, { params: this.queryConditions }).then(res => {
let { records, total, size } = res.data
this.projectResultList = records
this.total = total
this.queryConditions.size = size
})
},
saveStatisticsCheckedColumns () {
this.customColumnDialogVisible = false
this.fixedCustomColumns = this.checkedFixedCustomColumns
this.otherCustomColumns = this.checkOtherCustomColumns
this.fixedFormTailColumns = this.checkedFixedTailCustomColumns
saveCheckedColumn(this.projectKey, {
fixedCustomColumns: this.fixedCustomColumns,
otherCustomColumns: this.otherCustomColumns,
fixedCustomTailColumns: this.fixedFormTailColumns
})
},
getDbCheckedColumns () {
let checkedColumn = getCheckedColumn(this.projectKey)
if (!checkedColumn) {
return
}
let { fixedCustomColumns, otherCustomColumns, fixedCustomTailColumns } = checkedColumn
if (fixedCustomColumns) {
this.fixedCustomColumns = fixedCustomColumns
this.checkedFixedCustomColumns = fixedCustomColumns
}
if (otherCustomColumns) {
this.otherCustomColumns = otherCustomColumns
this.checkOtherCustomColumns = otherCustomColumns
}
if (fixedCustomTailColumns) {
this.fixedCustomTailColumns = fixedCustomTailColumns
this.checkedFixedTailCustomColumns = fixedCustomTailColumns
}
},
downloadProjectResultFile () {
if (!this.total) {
this.$message.error('无附件,无法导出')
return
}
this.$api.get(`${process.env.VUE_APP_API_ROOT_TDUCK}/user/project/result/download/file`, {
params: this.queryConditions
}).then(res => {
this.$process({
message: '附件导出中',
key: res.data
methods: {
renderHeader () {
return (
<i class="el-icon-setting" style="color:currentColor"
onClick={() => this.customColumnDialogVisible = true}></i>
)
},
openDetailDrawerHandle (row) {
this.activeResultRow = row
this.detailDrawer = true
},
queryProject () {
this.$api.get(`${process.env.VUE_APP_API_ROOT_TDUCK}/user/project/${this.projectKey}`).then(res => {
this.projectData = res.data
})
})
},
exportProjectResult () {
if (!this.total) {
this.$message.error('无表单有效反馈结果,无法导出')
return
}
this.$api.get(`${process.env.VUE_APP_API_ROOT_TDUCK}user/project/result/export`, {
params: this.queryConditions,
responseType: 'blob'
}).then(res => {
let blob = res
let downloadElement = document.createElement('a')
let href = window.URL.createObjectURL(blob) //
downloadElement.href = href
downloadElement.download = this.projectData.name + this.$dayjs().format('YYYYMMDDHHMM') + '.xls' //
document.body.appendChild(downloadElement)
downloadElement.click() //
document.body.removeChild(downloadElement) //
window.URL.revokeObjectURL(href) // blob
})
},
queryProjectItems () {
this.$api.get(`${process.env.VUE_APP_API_ROOT_TDUCK}/user/project/item/list`, { params: { key: this.projectKey, displayType: false } }).then(res => {
if (res.data) {
res.data.map(item => {
_.set(this.projectItemColumns, `field${item.formItemId}`, item.label)
},
conditionFilterHandle () {
this.$refs.dataFilter.showDialogHandle()
},
dataFilterHandle (params, comparisons) {
this.queryConditions.extParams = params
this.queryConditions.extComparisons = comparisons
this.queryProjectResult()
},
queryProjectResult () {
this.$api.get(`${process.env.VUE_APP_API_ROOT_TDUCK}/user/project/result/page`, { params: this.queryConditions }).then(res => {
let { records, total, size } = res.data
this.projectResultList = records
this.total = total
this.queryConditions.size = size
})
},
saveStatisticsCheckedColumns () {
this.customColumnDialogVisible = false
this.fixedCustomColumns = this.checkedFixedCustomColumns
this.otherCustomColumns = this.checkOtherCustomColumns
this.fixedFormTailColumns = this.checkedFixedTailCustomColumns
saveCheckedColumn(this.projectKey, {
fixedCustomColumns: this.fixedCustomColumns,
otherCustomColumns: this.otherCustomColumns,
fixedCustomTailColumns: this.fixedFormTailColumns
})
},
getDbCheckedColumns () {
let checkedColumn = getCheckedColumn(this.projectKey)
if (!checkedColumn) {
return
}
let { fixedCustomColumns, otherCustomColumns, fixedCustomTailColumns } = checkedColumn
if (fixedCustomColumns) {
this.fixedCustomColumns = fixedCustomColumns
this.checkedFixedCustomColumns = fixedCustomColumns
}
if (otherCustomColumns) {
this.otherCustomColumns = otherCustomColumns
this.checkOtherCustomColumns = otherCustomColumns
}
if (fixedCustomTailColumns) {
this.fixedCustomTailColumns = fixedCustomTailColumns
this.checkedFixedTailCustomColumns = fixedCustomTailColumns
}
},
downloadProjectResultFile () {
if (!this.total) {
this.$message.error('无附件,无法导出')
return
}
this.$api.get(`${process.env.VUE_APP_API_ROOT_TDUCK}/user/project/result/download/file`, {
params: this.queryConditions
}).then(res => {
this.$process({
message: '附件导出中',
key: res.data
})
})
},
exportProjectResult () {
if (!this.total) {
this.$message.error('无表单有效反馈结果,无法导出')
return
}
this.$api.get(`${process.env.VUE_APP_API_ROOT_TDUCK}/user/project/result/export`, {
params: this.queryConditions,
responseType: 'blob'
}).then(res => {
let blob = res
let downloadElement = document.createElement('a')
let href = window.URL.createObjectURL(blob) //
downloadElement.href = href
downloadElement.download = this.projectData.name + this.$dayjs().format('YYYYMMDDHHMM') + '.xls' //
document.body.appendChild(downloadElement)
downloadElement.click() //
document.body.removeChild(downloadElement) //
window.URL.revokeObjectURL(href) // blob
})
},
queryProjectItems () {
this.$api.get(`${process.env.VUE_APP_API_ROOT_TDUCK}/user/project/item/list`, { params: { key: this.projectKey, displayType: false } }).then(res => {
if (res.data) {
res.data.map(item => {
_.set(this.projectItemColumns, `field${item.formItemId}`, item.label)
})
}
this.projectItemList = res.data
this.getDbCheckedColumns()
})
}
this.projectItemList = res.data
this.getDbCheckedColumns()
})
}
})
}
}
}
</script>

4
vue.config.js

@ -15,6 +15,10 @@ module.exports = {
open: true,
port: 8888,
// 开发环境默认开启反向代理,如果不需要请自行注释
// "src/**/*.{js,vue}": [ 校验提交
// "eslint --fix",
// "git add"
// ]
// proxy: {
// '/tduck-api': {
// //target: 'http://localhost:8080/api/',

Loading…
Cancel
Save