定位提示

dev
lion 2 months ago
parent 92692415eb
commit 72c80c2c8d

@ -676,15 +676,16 @@ export default {
}],
formSelect: {
// company_position: [],
company_type: [],
company_tag:[],
company_type: [],
company_tag:[],
company_scale:[],
company_area: [],
company_industry: [],
company_industry_detail: [],
type: [],
education: [],
sign_from: []
sign_from: [],
from_tag:[]
},
}
@ -697,7 +698,7 @@ export default {
methods: {
getAllPara() {
let number = ['company_type', 'company_area','company_tag','company_scale', 'company_industry', 'company_industry_detail', 'type', 'education',
'sign_from'
'sign_from','from_tag'
]
getparameter({
number: number
@ -727,4 +728,4 @@ export default {
})
}
},
};
};

@ -191,7 +191,7 @@
value: this.select.teacher_id?this.select.teacher_id:''
},{
key: 'direction',
op: 'eq',
op: 'like',
value: this.select.direction?this.select.direction:''
}]
})

@ -382,6 +382,7 @@
this.form.files = res.files ? res.files : []
//
this.form.teacher_introduce = res.teacher ? res.teacher.introduce || '' : ''
this.form.direction = res.direction ? parseInt(res.direction) : ''
// this.form.timeRange = [this.form.start_time ? this.form.start_time : '', this.form.end_time ? this.form
// .end_time : ''
// ]

@ -84,9 +84,17 @@
<h5 class="table-title">
<i class="el-icon-reading"></i> 课程分类明细统计
</h5>
<el-button type="success" @click="exportCourseData" class="btn-export">
<i class="el-icon-download"></i> 导出数据
</el-button>
<div class="table-header-right">
<el-button type="primary" @click="exportCoursePersonData" class="btn-export">
<i class="el-icon-download"></i> 导出人员明细
</el-button>
<el-button type="warning" @click="exportCourseOpenData" class="btn-export">
<i class="el-icon-download"></i> 导出开课明细
</el-button>
<el-button type="success" @click="exportCourseData" class="btn-export">
<i class="el-icon-download"></i> 导出数据
</el-button>
</div>
</div>
<div class="detail-table">
<el-table :data="courseDetailData" :span-method="objectSpanMethod" :header-cell-style="headerCellStyle">
@ -128,9 +136,12 @@
import { index as courseTypeIndex } from '@/api/course/courseType.js'
import { courseChart } from '@/api/homeChart.js'
import * as XLSX from "xlsx";
import { download } from "@/utils/downloadRequest";
import formMixin from "@/mixin/formMixin.js";
export default {
name: 'Statistics',
mixins: [formMixin],
components: {},
data() {
return {
@ -146,43 +157,37 @@ export default {
studentStats: [
{
icon: 'el-icon-user-solid',
value: '1,247',
value: '0',
label: '报名人数(未去重)',
cardClass: 'student-card-1'
},
{
icon: 'el-icon-s-check',
value: '1,156',
value: '0',
label: '培养人数(未去重)',
cardClass: 'student-card-2'
},
{
icon: 'el-icon-s-custom',
value: '892',
value: '0',
label: '培养人数(已去重)',
cardClass: 'student-card-3'
},
{
icon: 'el-icon-date',
value: '56',
value: '0',
label: '开课场次',
cardClass: 'student-card-4'
},
{
icon: 'el-icon-c-scale-to-original',
value: '89',
value: '0',
label: '开课天数',
cardClass: 'student-card-5'
}
],
courseDetailData: [],
regionData: [
{ region: '吴中区', totalPeople: 125, uniquePeople: 98 },
{ region: '相城区', totalPeople: 82, uniquePeople: 65 },
{ region: '昆山市', totalPeople: 74, uniquePeople: 58 },
{ region: '太仓市', totalPeople: 74, uniquePeople: 62 },
{ region: '姑苏区', totalPeople: 65, uniquePeople: 52 }
]
regionData: []
}
},
mounted() {
@ -367,6 +372,136 @@ export default {
}
},
//
exportCoursePersonData() {
try {
// ID
const courseTypeIds = this.filterForm.selectedCourses.length > 0
? this.filterForm.selectedCourses.join(',')
: ''
//
const startDate = this.formatDate(this.filterForm.startDate)
const endDate = this.formatDate(this.filterForm.endDate)
//
const exportFields = {
'course.type_detail.name': '课程体系',
'course.name': '课程名称',
'status_text': '审核状态',
'created_at': '报名时间'
// 'user.name': '',
// 'user.sex': '',
// 'user.no': '',
// 'user.idcard': '',
// 'user.mobile': '',
// 'user.birthday': '',
// 'user.email': '',
// 'user.company_name': '',
// 'user.company_position': '',
}
this.selectFormList.map(item => {
if (item.prop === 'index') {
} else {
exportFields['user.'+item.field] = item.name
}
})
// API
download(
'/api/admin/course-signs/index',
'get',
{
export_fields: exportFields,
is_export: 1,
page: 1,
page_size: 9999,
start_date: startDate,
end_date: endDate,
course_type_id: courseTypeIds,
clear: 1
},
this.generateFileName('人员明细')
)
this.$message.success('人员明细导出任务已开始,请稍后查看下载文件')
} catch (error) {
console.error('导出失败:', error)
this.$message.error('导出失败,请重试')
}
},
//
exportCourseOpenData() {
try {
// ID
const courseTypeIds = this.filterForm.selectedCourses.length > 0
? this.filterForm.selectedCourses.join(',')
: ''
//
const startDate = this.formatDate(this.filterForm.startDate)
const endDate = this.formatDate(this.filterForm.endDate)
//
const exportFields = {
'type_detail.name': '课程体系',
'name': '课程名称',
'status_text': '发布状态',
'date_status': '课程状态',
'sign_date_status': '报名状态',
'is_virtual_text': '是否为虚拟课程',
'url_title': '资讯链接',
'year': '所属年份',
'start_date': '课程开始日期',
'end_date': '课程结束日期',
'total': '开课人数',
'sign_start_date': '报名开始日期',
'sign_end_date': '报名截止日期',
'address_detail': '签到地点',
'is_fee_text': '课程类型',
'is_arrange_text': '是否排课',
'show_txl_text': '是否显示通讯录',
'show_mobile_text': '是否显示联系方式',
'auto_schoolmate_text': '已审核学员是否自动进入校友库',
'course_signs_count':'目前报名人数',
'sign_wait_total':'待审核人数',
'sign_pass_total':'审核通过人数',
'sign_fault_total':'审核不通过人数',
'sign_prepare_total':'备选人数',
'sign_cancel_total':'已取消人数',
'sign_give_up_total':'主动放弃人数',
'sign_black_total':'黑名单人数',
}
// API
download(
'/api/admin/courses/index',
'get',
{
export_fields: exportFields,
'show_relation[0]':'typeDetail',
is_export: 1,
page: 1,
page_size: 9999,
start_date: startDate,
end_date: endDate,
course_type_id: courseTypeIds
},
this.generateFileName('开课明细')
)
this.$message.success('开课明细导出任务已开始,请稍后查看下载文件')
} catch (error) {
console.error('导出失败:', error)
this.$message.error('导出失败,请重试')
}
},
//
exportRegionData() {
if (!this.regionData || this.regionData.length === 0) {
@ -420,6 +555,35 @@ export default {
}
},
//
generateFileName(type) {
//
let courseTypeLabels = ''
if (this.filterForm.selectedCourses.length > 0) {
const selectedCourseTypes = this.courseOptions.filter(option =>
this.filterForm.selectedCourses.includes(option.value)
)
courseTypeLabels = selectedCourseTypes.map(course => course.label).join('、')
} else {
courseTypeLabels = '全部课程体系'
}
//
let timeText = ''
if (this.filterForm.timeRange === 'all') {
timeText = '全周期'
} else {
//
const startDate = this.formatDate(this.filterForm.startDate)
const endDate = this.formatDate(this.filterForm.endDate)
timeText = `${startDate}_${endDate}`
}
// + + +
const fileName = `${courseTypeLabels}${type}_${timeText}.xlsx`
return fileName
},
//
updateStatisticsData(data) {
// API

@ -13,7 +13,6 @@
filterable
remote
reserve-keyword
allow-create
default-first-option
placeholder="请输入企业名称搜索"
:remote-method="searchCompany"
@ -25,34 +24,34 @@
<el-option
v-for="item in companySearchResults"
:key="item.id"
:label="item.enterpriseName"
:value="item.enterpriseName">
:label="item.name"
:value="item.name">
</el-option>
</el-select>
</div>
</div>
</template>
<template v-slot:company_attribute>
<template v-slot:company_industry>
<div class="xy-table-item">
<div class="xy-table-item-label" style="font-weight: bold">
<span style="color: red;font-weight: bold;padding-right: 4px;">*</span>企业资质
</div>
<div class="xy-table-item-content">
<el-select v-model="form.company_attribute" placeholder="请选择企业资质" clearable style="width: 100%;">
<el-option v-for="(item,index) in formSelect.company_industry" :key="index" :label="item.value" :value="item.value">
<el-select v-model="form.company_industry" placeholder="请选择企业资质" clearable style="width: 100%;">
<el-option v-for="(item,index) in formSelect.company_type" :key="index" :label="item.value" :value="item.value">
</el-option>
</el-select>
</div>
</div>
</template>
<template v-slot:tag>
<template v-slot:company_tag>
<div class="xy-table-item">
<div class="xy-table-item-label" style="font-weight: bold">
<span style="color: red;font-weight: bold;padding-right: 4px;"></span>集团标签
</div>
<div class="xy-table-item-content">
<el-select v-model="form.tag" placeholder="请选择集团标签" clearable style="width: 100%;">
<el-select v-model="form.company_tag" placeholder="请选择集团标签" clearable style="width: 100%;">
<el-option v-for="(item,index) in formSelect.company_tag" :key="index" :label="item.value" :value="item.value">
</el-option>
</el-select>
@ -207,8 +206,8 @@
id: '',
form: {
company_name: '',
company_attribute: '',
tag: '',
company_industry: '',
company_tag: '',
is_yh_invested: '',
company_scale: '',
company_date: '',
@ -229,14 +228,14 @@
required: true,
message: '请输入企业名称'
}],
company_attribute: [{
company_industry: [{
required: true,
message: '请选择企业资质'
}],
tag: [{
required: true,
message: '请选择集团标签'
}]
// company_tag: [{
// required: true,
// message: ''
// }]
}
}
},
@ -297,7 +296,7 @@
const selectedCompany = this.companySearchResults.find(item => item.enterpriseName === value)
if (selectedCompany) {
//
// this.form.company_attribute = selectedCompany.attribute
// this.form.company_industry = selectedCompany.attribute
}
}
},
@ -326,8 +325,8 @@
this.type = "add"
this.form = {
company_name: '',
company_attribute: '',
tag: '',
company_industry: '',
company_tag: '',
is_yh_invested: '',
company_scale: '',
company_date: '',

@ -1,8 +1,8 @@
<template>
<div>
<xy-dialog ref="dialog" :width="70" :is-show.sync="isShow" :type="'form'" :title="type === 'add' ? '新增学员' : '编辑学员'"
:form="form" :rules='rules' @submit="submit">
<template v-slot:username>
<template>
<div>
<xy-dialog ref="dialog" :width="70" :is-show.sync="isShow" :type="'form'" :title="type === 'add' ? '新增学员' : '编辑学员'"
:form="form" :rules='rules' @submit="submit">
<template v-slot:username>
<div class="xy-table-item">
<div class="xy-table-item-label" style="font-weight: bold">
<span style="color: red;font-weight: bold;padding-right: 4px;">*</span>姓名
@ -10,7 +10,7 @@
<div class="xy-table-item-content">
<el-input v-model="form.username" placeholder="请输入姓名" clearable style="width: 100%;"></el-input>
</div>
</div>
</div>
</template>
<template v-slot:sex>
<div class="xy-table-item">
@ -57,6 +57,19 @@
</div>
</div>
</template>
<template v-slot:from>
<div class="xy-table-item">
<div class="xy-table-item-label" style="font-weight: bold">
<span style="color: red;font-weight: bold;padding-right: 4px;"></span>学员标签
</div>
<div class="xy-table-item-content">
<el-select v-model="fromList" multiple placeholder="请选择学员标签" clearable style="width: 100%;">
<el-option v-for="(item,index) in formSelect.from_tag" :key="index" :label="item.value" :value="item.value">
</el-option>
</el-select>
</div>
</div>
</template>
<template v-slot:education>
<div class="xy-table-item">
<div class="xy-table-item-label" style="font-weight: bold">
@ -326,32 +339,34 @@
</el-select>
</div>
</div>
</template>
</xy-dialog>
</div>
</template>
<script>
import formMixin from "@/mixin/formMixin.js";
import {
</template>
</xy-dialog>
</div>
</template>
<script>
import formMixin from "@/mixin/formMixin.js";
import {
show,
save
} from '@/api/student/index.js'
export default {
mixins: [formMixin],
data() {
return {
isShow: false,
type: 'add',
save
} from '@/api/student/index.js'
export default {
mixins: [formMixin],
data() {
return {
isShow: false,
type: 'add',
rules: {},
typeList:[],
companyTypeList:[],
fromList:[],
form:{
username:'',
sex:"",
birthday:"",
mobile:"",
idcard:"",
from:'',
education:'',
introduce:'',
company_name:'',
@ -376,10 +391,10 @@
valuation:'',
market_value:"",
is_yuanhe:''
}
}
},
methods: {
}
}
},
methods: {
submit() {
if(this.id){
this.form.id = this.id
@ -389,6 +404,9 @@
this.form.type = this.typeList.join(",")
this.form.company_type = this.companyTypeList.join(",")
this.form.name = this.form.username
this.form.from = this.fromList.join(",")
console.log("this.form",this.fromList,this.form.from)
// return
save(this.form).then(res => {
this.$message({
type: 'success',
@ -408,8 +426,9 @@
this.form = this.base.requestToForm(res,this.form)
this.typeList = res.type?res.type.split(","):[],
this.companyTypeList = res.company_type?res.company_type.split(","):[]
this.fromList = res.from?res.from.split(","):[]
})
},
},
},
watch: {
isShow(newVal) {
@ -422,12 +441,14 @@
this.type = 'add'
this.typeList = []
this.companyTypeList = []
this.fromList = []
this.form = {
username:'',
sex:"",
birthday:"",
mobile:"",
idcard:"",
from:'',
education:'',
introduce:'',
company_name:'',
@ -456,10 +477,10 @@
this.$refs['dialog'].reset()
}
},
}
}
</script>
<style lang="scss" scoped>
}
}
</script>
<style lang="scss" scoped>
</style>

@ -154,6 +154,7 @@
<el-button type="primary" size="small" @click="select.page=1,getList()"></el-button>
<el-button type="primary" size="small" @click="resetSelect"></el-button>
<el-button type="primary" size="small" @click="importTable"></el-button>
<el-button type="primary" size="small" @click="exportExcel"></el-button>
<el-button type="primary" size="small" @click="updateSchoolmates(1)"></el-button>
<el-button type="primary" size="small" @click="updateSchoolmates(0)"></el-button>
</div>
@ -253,7 +254,23 @@
<el-tag v-else type="info">
</el-tag>
</template>
</el-table-column>
</template>
<template v-slot:from>
<el-table-column align='center' label="学员标签" width="120" header-align="center">
<template slot-scope="scope">
<div v-if="scope.row.from">
<el-tag
v-for="tag in getStudentTags(scope.row.from)"
:key="tag"
style="margin: 2px;"
>
{{ tag }}
</el-tag>
</div>
<span v-else></span>
</template>
</el-table-column>
</template>
@ -291,6 +308,9 @@
import {
index as indexTypes
} from "@/api/course/courseType.js"
import {
download
} from "@/utils/downloadRequest";
export default {
mixins: [myMixins, formMixin],
components: {
@ -412,6 +432,11 @@
align: 'center',
width: 120,
}, {
prop: 'from',
label: '学员标签',
align: 'center',
width: 120,
},{
prop: 'is_schoolmate',
label: '是否校友库学员',
align: 'center',
@ -460,7 +485,53 @@
this.select.end_birthday = ''
}
},
exportExcel() {
let _export = {
'all_course': '课程名称'
}
this.selectFormList.map(item => {
if (item.prop === 'index') {
} else {
_export[item.field] = item.name
}
})
download(
'/api/admin/users/study',
'get', {
export_fields: _export,
keyword: this.select.keyword,
name: this.select.name,
year:this.select.year?this.select.year:'',
mobile: this.select.mobile,
company_name: this.select.company_name,
school: this.select.school,
start_birthday: this.select.start_birthday,
end_birthday: this.select.end_birthday,
start_company_date: this.select.start_company_date,
end_company_date: this.select.end_company_date,
course_name: this.select.course_name,
company_has_share: this.select.company_has_share,
company_need_fund: this.select.company_need_fund,
company_position: this.select.company_position,
company_area: this.select.company_area,
company_type: this.select.company_type,
company_industry: this.select.company_industry,
is_vip: this.select.is_vip,
courses_end_date: this.select.courses_end_date,
is_schoolmate: this.select.is_schoolmate,
is_black: this.select.is_black,
education: this.select.education,
type: this.select.type,
status: this.select.status,
course_type: this.select.course_type,
has_openid: this.select.has_openid,
is_export: 1,
page: 1,
page_size: 99999
},
`学员信息.xlsx`)
},
importTable(row) {
// this.$refs.imports.tableData = {
// 'data[course_id]': row.course_id,
@ -688,6 +759,10 @@
page_size: 999
})
this.courseTypeList = res.data
},
getStudentTags(tags) {
if (!tags) return [];
return tags.split(',').map(tag => tag.trim());
}
},
watch: {

@ -9,6 +9,20 @@
<div>
<el-input v-model="select.company_name" placeholder="请输入企业名称"></el-input>
</div>
<div>
<el-select v-model="select.company_industry" placeholder="请选择企业资质" clearable style="width: 100%;">
<el-option v-for="(item,index) in formSelect.company_type" :key="index" :label="item.value" :value="item.value">
</el-option>
</el-select>
</div>
<div>
<el-select v-model="select.company_tag" placeholder="请选择集团标签" clearable style="width: 100%;">
<el-option label="被投企业" value="被投企业">
</el-option>
<el-option v-for="(item,index) in formSelect.company_tag" :key="index" :label="item.value" :value="item.value">
</el-option>
</el-select>
</div>
<div>
<el-button type="primary" size="small" @click="select.page=1,getList()"></el-button>
<el-button type="primary" size="small" @click="resetSelect"></el-button>
@ -54,12 +68,13 @@
</template>
</el-table-column>
</template>
<template v-slot:company_attribute>
<el-table-column align='center' label="企业资质" width="120" header-align="center">
<template v-slot:company_industry>
<el-table-column align='center' label="企业资质" width="160" header-align="center">
<template slot-scope="scope">
<div v-for="item in formSelect.company_industry">
<el-tag v-if="item.value===scope.row.company_attribute"
:type="item.remark?item.remark:''">{{scope.row.company_attribute}}</el-tag>
<div v-for="item in formSelect.company_type">
<div v-if="item.value===scope.row.company_industry">
<el-tag :type="item.remark?item.remark:''">{{scope.row.company_industry}}</el-tag>
</div>
</div>
</template>
</el-table-column>
@ -71,8 +86,8 @@
<el-tag type="danger">被投企业</el-tag>
</div>
<div v-for="item in formSelect.company_tag">
<el-tag v-if="item.value===scope.row.tag" style="margin:3px"
:type="item.remark?item.remark:''">{{scope.row.tag}}</el-tag>
<el-tag v-if="item.value===scope.row.company_tag" style="margin:3px"
:type="item.remark?item.remark:''">{{scope.row.company_tag}}</el-tag>
</div>
</template>
</el-table-column>
@ -147,6 +162,8 @@
return {
select: {
company_name: '',
company_industry: '',
company_tag: '',
page: 1,
page_size: 10
},
@ -164,10 +181,10 @@
width: 240,
fixed: 'left'
}, {
prop: 'company_attribute',
prop: 'company_industry',
label: '企业资质',
align: 'center',
width: 180
width: 260
}, {
prop: 'tag',
label: '集团标签',
@ -243,6 +260,8 @@
resetSelect() {
this.select.company_name = ''
this.select.company_industry = ''
this.select.company_tag = ''
this.select.page = 1
this.getList()
},
@ -254,6 +273,14 @@
key: 'company_name',
op: 'like',
value: this.select.company_name
},{
key: 'company_industry',
op: 'like',
value: this.select.company_industry
},{
key: 'company_tag',
op: 'like',
value: this.select.company_tag
}]
})

Loading…
Cancel
Save