You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

716 lines
27 KiB

<template>
<div>
<!-- 统计数据展示 -->
<div class="statistics-row" style="margin: 15px 0; padding: 15px; background: #f5f7fa; border-radius: 4px; display: flex; justify-content: space-around; align-items: center;">
<div class="stat-item" style="text-align: center;">
<div style="font-size: 14px; color: #909399; margin-bottom: 8px;">累计被投企业数</div>
<div style="font-size: 24px; font-weight: bold; color: #409EFF;">{{ statistics.course_signs_invested || 0 }}</div>
</div>
<div class="stat-item" style="text-align: center;">
<div style="font-size: 14px; color: #909399; margin-bottom: 8px;">入学后被投企业数</div>
<div style="font-size: 24px; font-weight: bold; color: #67C23A;">{{ statistics.company_invested_after_enrollment_total || 0 }}</div>
</div>
<div class="stat-item" style="text-align: center;">
<div style="font-size: 14px; color: #909399; margin-bottom: 8px;">今年被投企业数</div>
<div style="font-size: 24px; font-weight: bold; color: #E6A23C;">{{ statistics.company_invested_year_total || 0 }}</div>
</div>
</div>
<div>
<div ref="lxHeader">
<lx-header icon="md-apps" :text="$route.meta.title" style="margin-bottom: 10px; border: 0px; margin-top: 15px">
<div slot="content">
<div class="searchwrap" style="display: flex; align-items: center; flex-wrap: wrap; gap: 10px;">
<div>
<el-input v-model="select.user_name" placeholder="请输入学员名称" style="width: 150px;"></el-input>
</div>
<div>
<el-select v-model="select.is_schoolmate" placeholder="请选择是否校友" clearable style="width: 150px;">
<el-option label="是" :value="1">
</el-option>
<el-option label="否" :value="0">
</el-option>
</el-select>
</div>
<div>
<el-input v-model="select.company_name" placeholder="请输入企业名称" style="width: 200px;"></el-input>
</div>
<div>
<el-select collapse-tags multiple v-model="select.company_tag" placeholder="请选择企业资质" clearable style="width: 200px;">
<el-option v-for="(item,index) in companiesTags" :key="index" :label="item" :value="item">
</el-option>
</el-select>
</div>
<div>
<el-select v-model="select.is_yh_invested" placeholder="请选择集团标签" clearable style="width: 200px;">
<el-option label="被投企业" :value="1">
</el-option>
</el-select>
</div>
<div>
<el-select v-model="select.course_type_id" placeholder="请选择课程体系" clearable style="width: 200px;">
<el-option v-for="item in courseTypeOptions" :key="item.id" :label="item.name" :value="item.id">
</el-option>
</el-select>
</div>
<div>
<el-select
v-model="select.course_name"
placeholder="请输入或选择课程名称"
filterable
allow-create
clearable
style="width: 200px;">
<el-option
v-for="item in courseOptions"
:key="item.id"
:label="item.name"
:value="item.name">
</el-option>
</el-select>
</div>
<div>
<el-date-picker
v-model="select.start_year"
type="year"
placeholder="被投开始年份"
format="yyyy"
value-format="yyyy"
clearable
style="width: 200px;">
</el-date-picker>
</div>
<div>
<el-date-picker
v-model="select.end_year"
type="year"
placeholder="被投结束年份"
format="yyyy"
value-format="yyyy"
clearable
style="width: 200px;">
</el-date-picker>
</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>
<el-button type="primary" size="small" @click="exportExcel">导出</el-button>
</div>
<!-- <div>
<el-button type="primary" size="small" @click="editCompany('add')">新增</el-button>
</div> -->
</div>
</div>
</lx-header>
</div>
</div>
<div>
<xy-table :showIndex="false" :list="list" :total="total" @pageIndexChange="pageIndexChange" @pageSizeChange="pageSizeChange"
:table-item="table_item">
<template v-slot:company_name>
<el-table-column align='left' fixed="left" label="企业名称" width="240" header-align="center">
<template slot-scope="scope">
<div @click="toQicc(scope.row.company_name)" style="color:blue;cursor: pointer;text-decoration: underline;">
{{scope.row.company_name}}
</div>
</template>
</el-table-column>
</template>
<template v-slot:company_legal_representative>
<el-table-column align='center' label="法人代表" width="120" header-align="center">
<template slot-scope="scope">
<div @click="toQicc(scope.row.company_name)" style="color:blue;cursor: pointer;text-decoration: underline;">
{{scope.row.company_legal_representative}}
</div>
</template>
</el-table-column>
</template>
<template v-slot:partners>
<el-table-column align='center' label="股东信息" width="360" header-align="center">
<template slot-scope="scope">
<div v-for="(item,index) in scope.row.partners">
<div style="text-align: left;">
{{index+1}}、{{ item.stockName }}-{{ item.stockPercent }}
</div>
</div>
</template>
</el-table-column>
</template>
<template v-slot:project_users>
<el-table-column align='center' label="管理平台-项目经理-首次出资时间-投资金额" width="360" header-align="center">
<template slot-scope="scope">
<div style="display: flex; align-items: center; justify-content: space-between;">
<div style="flex: 1;">
<div v-for="(item,index) in scope.row.project_users" :key="index">
<div style="text-align: left;">
{{index+1}}、{{ item.groupName }}-{{ item.userName }}-{{ item.investDate }}{{ item.amount ? '-' + item.amount : '' }}
</div>
</div>
</div>
<i v-if="scope.row.project_users && scope.row.project_users.length > 0"
class="el-icon-edit"
style="cursor: pointer; color: #409EFF; margin-left: 10px; font-size: 16px;"
@click="openEditProjectUsers(scope.row)">
</i>
</div>
</template>
</el-table-column>
</template>
<template v-slot:is_yh_invested>
<el-table-column align='center' label="集团标签" width="120" header-align="center">
<template slot-scope="scope">
<div v-if="scope.row.is_yh_invested" style="margin:3px">
<el-tag type="danger">被投企业</el-tag>
</div>
</template>
</el-table-column>
</template>
<template v-slot:users>
<el-table-column align='center' label="学员信息" width="800" header-align="center">
<el-table-column label="学号" width="120" align="center">
<template slot-scope="scope">
<div class="user-item" v-for="(item, uIdx) in (scope.row.users || [])" :key="uIdx">
<template v-if="item.course_signs && item.course_signs.length > 0">
<div v-for="(cs, cIdx) in item.course_signs" :key="cIdx" class="user-cell-row">
<span v-if="cIdx === 0">{{ item.no || '' }}</span>
</div>
</template>
<template v-else>
<div class="user-cell-row">{{ item.no || '' }}</div>
</template>
</div>
</template>
</el-table-column>
<el-table-column label="学员" width="120" align="left">
<template slot-scope="scope">
<div class="user-item" v-for="(item, uIdx) in (scope.row.users || [])" :key="uIdx">
<template v-if="item.course_signs && item.course_signs.length > 0">
<div v-for="(cs, cIdx) in item.course_signs" :key="cIdx" class="user-cell-row">
<span v-if="cIdx === 0">{{ item.name || '' }}</span>
</div>
</template>
<template v-else>
<div class="user-cell-row">{{ item.name || '' }}</div>
</template>
</div>
</template>
</el-table-column>
<el-table-column label="是否校友" width="120" align="left">
<template slot-scope="scope">
<div class="user-item" v-for="(item, uIdx) in (scope.row.users || [])" :key="uIdx">
<el-tag v-if="item.is_schoolmate===1" type="">是</el-tag>
<el-tag v-else type="info">否</el-tag>
</div>
</template>
</el-table-column>
<el-table-column label="职务" width="120" align="left">
<template slot-scope="scope">
<div class="user-item" v-for="(item, uIdx) in (scope.row.users || [])" :key="uIdx">
<template v-if="item.course_signs && item.course_signs.length > 0">
<div v-for="(cs, cIdx) in item.course_signs" :key="cIdx" class="user-cell-row">
<span v-if="cIdx === 0">{{ item.company_position || '' }}</span>
</div>
</template>
<template v-else>
<div class="user-cell-row">{{ item.company_position || '' }}</div>
</template>
</div>
</template>
</el-table-column>
<el-table-column label="课程/入学时间" width="480" align="left">
<template slot-scope="scope">
<div class="user-item" v-for="(item, uIdx) in (scope.row.users || [])" :key="uIdx">
<template v-if="item.course_signs && item.course_signs.length > 0">
<div v-for="(cs, cIdx) in item.course_signs" :key="cIdx" class="user-cell-row">
{{ cs.course && cs.course.name ? cs.course.name : '' }} - {{ cs.course && cs.course.start_date ? cs.course.start_date : '' }}
</div>
</template>
<template v-else>
<div class="user-cell-row"></div>
</template>
</div>
</template>
</el-table-column>
<!-- <el-table-column label="入学时间" width="120" align="left">
<template slot-scope="scope">
<div class="user-item" v-for="(item, uIdx) in (scope.row.users || [])" :key="uIdx">
<template v-if="item.course_signs && item.course_signs.length > 0">
<div v-for="(cs, cIdx) in item.course_signs" :key="cIdx" class="course-row">
{{ cs.course && cs.course.start_date ? cs.course.start_date : '' }}
</div>
</template>
<template v-else>
<div class="course-row"></div>
</template>
</div>
</template>
</el-table-column> -->
</el-table-column>
</template>
<template v-slot:btns>
<el-table-column align='center' fixed="right" label="操作" width="180" header-align="center">
<template slot-scope="scope">
<el-button type="primary" size="small" @click="editCompany('editor',scope.row.id)">编辑</el-button>
<el-popconfirm style="margin:0 10px" @confirm="deleteList(scope.row.id)" title="确定删除吗?">
<el-button type="danger" size="small" slot="reference">删除</el-button>
</el-popconfirm>
</template>
</el-table-column>
</template>
</xy-table>
</div>
<add-company ref="addCompany" @refresh="getList"></add-company>
<!-- 编辑项目经理信息弹窗 -->
<el-dialog
title="编辑项目经理信息"
:visible.sync="editProjectUsersDialogVisible"
width="800px">
<el-table :data="editProjectUsersData" border style="width: 100%">
<el-table-column prop="groupName" label="管理平台" width="150" align="center"></el-table-column>
<el-table-column prop="userName" label="项目经理" width="150" align="center"></el-table-column>
<el-table-column prop="investDate" label="首次出资时间" width="150" align="center"></el-table-column>
<el-table-column label="投资金额" width="200" align="center">
<template slot-scope="scope">
<el-input
v-model="scope.row.amount"
style="width: 100%;"
placeholder="请输入投资金额"
clearable>
</el-input>
</template>
</el-table-column>
</el-table>
<div slot="footer" class="dialog-footer">
<el-button @click="editProjectUsersDialogVisible = false">取消</el-button>
<el-button type="primary" @click="saveProjectUsers"></el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import addCompany from './components/addCompany.vue';
import {
download
} from "@/utils/downloadRequest";
import {
index,
destroy,
companyConfig,
save
} from "@/api/student/schoolmateCompany.js"
import {
index as courseTypeIndex
} from "@/api/course/courseType.js"
import {
index as courseIndex
} from "@/api/course/index.js"
import formMixin from "@/mixin/formMixin.js";
export default {
mixins: [formMixin],
components: {
addCompany
},
data() {
return {
select: {
company_name: '',
is_yh_invested: '',
company_tag: '',
course_name: '',
user_name: '',
is_schoolmate: '',
course_type_id: '',
start_year: '',
end_year: '',
page: 1,
page_size: 10
},
companiesTags:[],
courseTypeOptions: [],
courseOptions: [],
list: [],
total: 0,
statistics: {
course_signs_invested: 0,
company_invested_after_enrollment_total: 0,
company_invested_year_total: 0
},
editProjectUsersDialogVisible: false,
editProjectUsersData: [],
currentEditCompanyId: null,
table_item: [{
type: 'index',
align: 'center',
width: 80,
fixed: 'left'
},{
prop: 'company_name',
label: '企业名称',
align: 'left',
width: 240,
fixed: 'left'
}, {
prop: 'company_tag',
label: '企业资质',
align: 'center',
width: 260
}, {
prop: 'is_yh_invested',
label: '集团标签',
align: 'center',
width: 160,
}
// , {
// prop: 'company_scale',
// label: '企业规模',
// align: 'center',
// width: 120,
// }
, {
prop: 'company_date',
label: '成立时间',
align: 'center',
width: 120,
}, {
prop: 'company_legal_representative',
label: '法人代表',
align: 'center',
width: 120,
}, {
prop: 'partners',
label: '股东信息',
align: 'center',
width: 120,
}, {
prop: 'project_users',
label: '项目经理',
align: 'center',
width: 120,
}, {
prop: 'users',
label: '学员信息',
align: 'center',
width: 240,
}]
}
},
created() {
this.getList()
this.getCompanyConfig()
this.getCourseTypeList()
this.getCourseList()
},
watch: {
'select.course_type_id'(newVal) {
// 当课程体系改变时,重新获取课程列表
this.getCourseList()
// 清空课程名称选择
this.select.course_name = ''
}
},
updated() {
// 在数据更新后,统一设置学员信息列的高度
this.$nextTick(() => {
this.alignUserItemHeights()
})
},
methods: {
exportExcel() {
console.log('导出')
let _export = {}
this.table_item.map(item => {
if (item.type === 'index') {
} else {
if(item.prop === 'is_yh_invested'){
_export['is_yh_invested_text'] = '集团标签'
}else{
_export[item.prop] = item.label
}
}
})
download(
'/api/admin/company/index',
'get', {
export_fields: _export,
page_size: 9999,
page: 1,
is_export:1,
course_name: this.select.course_name,
user_name: this.select.user_name,
is_schoolmate: this.select.is_schoolmate !== '' ? this.select.is_schoolmate : '',
course_type_id: this.select.course_type_id,
start_year: this.select.start_year,
end_year: this.select.end_year,
filter: [{
key: 'company_name',
op: 'like',
value: this.select.company_name
},{
key: 'is_yh_invested',
op: 'like',
value: this.select.is_yh_invested?this.select.is_yh_invested:''
},{
key: 'company_tag',
op: 'like',
value: this.select.company_tag?this.select.company_tag.join(','):''
}]
},
'校友企业信息.xlsx')
},
async getCompanyConfig() {
const res = await companyConfig()
this.companiesTags = res.companiesTags
},
async getCourseTypeList() {
try {
const res = await courseTypeIndex({
page: 1,
page_size: 999
})
if (res && res.data) {
this.courseTypeOptions = res.data
}
} catch (error) {
console.error('获取课程体系列表失败:', error)
}
},
async getCourseList() {
try {
const res = await courseIndex({
page: 1,
page_size: 999,
filter: [{
key: 'type',
op: 'eq',
value: this.select.course_type_id || ''
}]
})
if (res && res.data) {
this.courseOptions = res.data
}
} catch (error) {
console.error('获取课程列表失败:', error)
}
},
toQicc(company_name) {
var url = 'https://www.qcc.com/web/search?key='
if(company_name){
window.open(url+company_name, '_blank')
}
// 'https://www.qcc.com/firm/ffb3379dc6b254336ecd31fc20d1dd30.html'
// https://www.qcc.com/firm/0a07162e2b34a5ee8046d46a1a446ed2.html
},
pageIndexChange(e) {
this.select.page = e
this.getList()
},
pageSizeChange(e) {
this.select.page_size = e
this.select.page = 1
this.getList()
},
editCompany(type, id) {
if (type == 'editor') {
this.$refs.addCompany.id = id
}
this.$refs.addCompany.type = type
this.$refs.addCompany.isShow = true
},
resetSelect() {
this.select.company_name = ''
this.select.is_yh_invested = ''
this.select.company_tag = ''
this.select.course_name = ''
this.select.user_name = ''
this.select.is_schoolmate = ''
this.select.course_type_id = ''
this.select.start_year = ''
this.select.end_year = ''
this.select.page = 1
this.getList()
},
async getList() {
const res = await index({
page_size: this.select.page_size,
page: this.select.page,
course_name: this.select.course_name,
user_name: this.select.user_name,
is_schoolmate: this.select.is_schoolmate !== '' ? this.select.is_schoolmate : '',
course_type_id: this.select.course_type_id,
start_year: this.select.start_year,
end_year: this.select.end_year,
filter: [{
key: 'company_name',
op: 'like',
value: this.select.company_name
},{
key: 'is_yh_invested',
op: 'like',
value: this.select.is_yh_invested?this.select.is_yh_invested:''
},{
key: 'company_tag',
op: 'like',
value: this.select.company_tag?this.select.company_tag.join(','):''
}]
})
this.list = res.data
this.total = res.total
// 保存统计数据
if (res.statistics) {
this.statistics = {
course_signs_invested: res.statistics.course_signs_invested || 0,
company_invested_after_enrollment_total: res.statistics.company_invested_after_enrollment_total || 0,
company_invested_year_total: res.statistics.company_invested_year_total || 0
}
}
// 数据加载后,对齐学员信息列的高度
this.$nextTick(() => {
this.alignUserItemHeights()
})
},
deleteList(id) {
var that = this;
destroy({
id: id
}).then(response => {
this.$Message.success('操作成功');
this.getList()
}).catch(error => {
console.log(error)
reject(error)
})
},
// 打开编辑项目经理信息弹窗
openEditProjectUsers(row) {
this.currentEditCompanyId = row.id
// 深拷贝数组,避免直接修改原数据,并确保每个项目都有 amount 字段
this.editProjectUsersData = (row.project_users || []).map(item => {
return {
...item,
amount: item.amount !== undefined && item.amount !== null ? String(item.amount) : ''
}
})
this.editProjectUsersDialogVisible = true
},
// 保存项目经理信息
saveProjectUsers() {
if (!this.currentEditCompanyId) {
this.$message.error('缺少企业ID')
return
}
save({
id: this.currentEditCompanyId,
project_users: this.editProjectUsersData
}).then(response => {
this.$message.success('保存成功')
this.editProjectUsersDialogVisible = false
this.getList()
}).catch(error => {
console.log(error)
this.$message.error('保存失败')
})
},
// 统一设置学员信息列的高度,确保虚线对齐
alignUserItemHeights() {
this.$nextTick(() => {
// 获取所有表格行
const tableRows = document.querySelectorAll('.el-table__body tbody tr')
if (!tableRows.length) return
tableRows.forEach(row => {
// 获取该行中所有包含 user-item 的单元格
const cells = row.querySelectorAll('td')
const userItemCells = Array.from(cells).filter(cell => {
return cell.querySelector('.user-item') !== null
})
if (userItemCells.length === 0) return
// 获取该行中所有 user-item
const userItems = Array.from(userItemCells).map(cell => {
return Array.from(cell.querySelectorAll('.user-item'))
}).flat()
if (userItems.length === 0) return
// 找到最高的 user-item 高度
let maxHeight = 0
userItems.forEach(item => {
// 重置高度,获取自然高度
item.style.height = 'auto'
item.style.minHeight = 'auto'
const height = item.offsetHeight || item.scrollHeight
if (height > maxHeight) {
maxHeight = height
}
})
// 设置所有 user-item 为相同高度
if (maxHeight > 0) {
userItems.forEach(item => {
item.style.height = `${maxHeight}px`
item.style.minHeight = `${maxHeight}px`
})
}
})
})
},
}
}
</script>
<style lang="scss" scoped>
.searchwrap {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 10px;
&>div {
display: flex;
align-items: center;
span {
min-width: 70px;
}
}
}
/* 校友信息子列每个用户的分隔样式 */
.user-item {
padding: 0;
margin: 0;
line-height: 1.2;
word-break: break-all;
display: flex;
flex-direction: column;
box-sizing: border-box;
border-bottom: 1px dashed #dcdfe6;
}
.user-item:last-child {
border-bottom: none;
}
/* 统一的单元格行样式,确保所有列的行高一致 */
.user-cell-row {
height: 40px;
line-height: 28px;
padding: 6px 0;
margin: 0;
box-sizing: border-box;
display: flex;
align-items: center;
flex-shrink: 0;
}
</style>