first commit

This commit is contained in:
2026-08-26 14:25:17 +08:00
commit 06debfd1fc
10595 changed files with 1836924 additions and 0 deletions
@@ -0,0 +1,749 @@
<!--#
layout("/layouts/platform.html"){
#-->
<style>
.dashboard-title {
font-size: 22px;
font-weight: 600;
color: #217050;
}
.dashboard-cards {
margin: 20px 0;
}
.dashboard-charts {
margin-bottom: 20px;
}
.statistic-card .card-header {
font-size: 14px;
color: #606266;
}
.statistic-card .card-content {
text-align: center;
padding: 10px 0;
}
.statistic-card .statistic-value {
font-size: 30px;
font-weight: 600;
color: #217050;
margin-bottom: 10px;
}
.statistic-card .statistic-footer {
display: flex;
justify-content: space-around;
font-size: 14px;
color: #909399;
}
.chart-card .card-header {
display: flex;
justify-content: space-between;
align-items: center;
}
.chart-container {
height: 300px;
width: 100%;
padding: 10px 0;
}
.chart-container-large {
height: 400px;
}
.range-slider-container {
display: flex;
align-items: center;
width: 300px;
}
.range-slider-container .el-slider {
margin-right: 15px;
flex: 1;
}
.range-display {
width: 70px;
text-align: center;
color: #606266;
}
.filter-container {
padding-top: 10px;
}
</style>
<div id="app" v-cloak>
<el-card shadow="never">
<div slot="header" class="clearfix">
<span class="dashboard-title">单身教工统计分析</span>
<el-divider></el-divider>
</div>
<el-form :inline="true" class="filter-container">
<el-form-item label="工会">
<el-select v-model="filterForm.unionId" placeholder="选择工会" clearable>
<el-option v-for="item in unionOptions" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item label="性别">
<el-select v-model="filterForm.sex" placeholder="选择性别" clearable>
<el-option label="男" value="男"></el-option>
<el-option label="女" value="女"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="fetchData">筛选</el-button>
<el-button @click="resetFilter">重置</el-button>
</el-form-item>
</el-form>
</el-card>
<!-- 总体统计卡片 -->
<el-row :gutter="20" class="dashboard-cards">
<el-col :span="6">
<el-card shadow="hover" class="statistic-card">
<div slot="header" class="card-header">
<i class="el-icon-user"></i>
单身教工总人数
</div>
<div class="card-content">
<div class="statistic-value">{{statistics.totalCount || 0}}</div>
<div class="statistic-footer">
<span>男:{{statistics.maleCount || 0}}</span>
<span>女:{{statistics.femaleCount || 0}}</span>
</div>
</div>
</el-card>
</el-col>
<el-col :span="6">
<el-card shadow="hover" class="statistic-card">
<div slot="header" class="card-header">
<i class="el-icon-school"></i>
平均年龄
</div>
<div class="card-content">
<div class="statistic-value">{{statistics.averageAge || 0}}</div>
<div class="statistic-footer">
<span>最小:{{statistics.minAge || 0}}岁</span>
<span>最大:{{statistics.maxAge || 0}}岁</span>
</div>
</div>
</el-card>
</el-col>
<el-col :span="6">
<el-card shadow="hover" class="statistic-card">
<div slot="header" class="card-header">
<i class="el-icon-reading"></i>
高学历占比
</div>
<div class="card-content">
<div class="statistic-value">{{statistics.highEduPercent || '0%'}}</div>
<div class="statistic-footer">
<span>硕士及以上人数:{{statistics.highEduCount || 0}}</span>
</div>
</div>
</el-card>
</el-col>
<el-col :span="6">
<el-card shadow="hover" class="statistic-card">
<div slot="header" class="card-header">
<i class="el-icon-office-building"></i>
工会数量
</div>
<div class="card-content">
<div class="statistic-value">{{statistics.unionCount || 0}}</div>
<div class="statistic-footer">
<span>单位数量:{{statistics.unitCount || 0}}</span>
</div>
</div>
</el-card>
</el-col>
</el-row>
<!-- 图表区域 -->
<el-row :gutter="20" class="dashboard-charts">
<el-col :span="12">
<el-card shadow="hover" class="chart-card">
<div slot="header" class="card-header">
<span>性别分布</span>
<el-radio-group v-model="chartTypes.gender" size="mini" @change="renderGenderChart">
<el-radio-button label="pie">饼图</el-radio-button>
<el-radio-button label="column">柱状图</el-radio-button>
</el-radio-group>
</div>
<div id="genderChart" class="chart-container"></div>
</el-card>
</el-col>
<el-col :span="12">
<el-card shadow="hover" class="chart-card">
<div slot="header" class="card-header">
<span>年龄分布</span>
<el-radio-group v-model="chartTypes.age" size="mini" @change="renderAgeChart">
<el-radio-button label="column">柱状图</el-radio-button>
<el-radio-button label="line">折线图</el-radio-button>
</el-radio-group>
</div>
<div id="ageChart" class="chart-container"></div>
</el-card>
</el-col>
</el-row>
<el-row :gutter="20" class="dashboard-charts">
<el-col :span="12">
<el-card shadow="hover" class="chart-card">
<div slot="header" class="card-header">
<span>学历分布</span>
<el-radio-group v-model="chartTypes.education" size="mini" @change="renderEducationChart">
<el-radio-button label="pie">饼图</el-radio-button>
<el-radio-button label="column">柱状图</el-radio-button>
</el-radio-group>
</div>
<div id="educationChart" class="chart-container"></div>
</el-card>
</el-col>
<el-col :span="12">
<el-card shadow="hover" class="chart-card">
<div slot="header" class="card-header">
<span>收入情况分布</span>
<el-radio-group v-model="chartTypes.income" size="mini" @change="renderIncomeChart">
<el-radio-button label="pie">饼图</el-radio-button>
<el-radio-button label="column">柱状图</el-radio-button>
</el-radio-group>
</div>
<div id="incomeChart" class="chart-container"></div>
</el-card>
</el-col>
</el-row>
<el-row :gutter="20" class="dashboard-charts">
<el-col :span="24">
<el-card shadow="hover" class="chart-card">
<div slot="header" class="card-header">
<span>单位及工会分布</span>
<el-radio-group v-model="chartTypes.unit" size="mini" @change="renderUnitChart">
<el-radio-button label="bar">条形图</el-radio-button>
<el-radio-button label="treemap">矩形树图</el-radio-button>
</el-radio-group>
</div>
<div id="unitChart" class="chart-container chart-container-large"></div>
</el-card>
</el-col>
</el-row>
</div>
<script nonce="${cspNonce!}">
new Vue({
el: "#app",
store,
data() {
return {
pageForm: {},
filterForm: {
unionId: "",
sex: "",
age: [20, 65]
},
unionOptions: [],
chartTypes: {
gender: "pie",
age: "column",
education: "pie",
income: "column",
unit: "bar"
},
charts: {},
teacherData: [],
statistics: {
totalCount: 0,
maleCount: 0,
femaleCount: 0,
averageAge: 0,
minAge: 0,
maxAge: 0,
highEduCount: 0,
highEduPercent: "0%",
unionCount: 0,
unitCount: 0
}
}
},
methods: {
fetchData() {
this.$axios.post("/platform/singleTeacher/chart/list", this.filterForm).then((res) => {
if (res.code === 0) {
this.teacherData = res.data
this.processData()
}
})
},
resetFilter() {
this.filterForm = {
unionId: "",
sex: "",
age: [20, 65]
}
this.fetchData()
},
processData() {
this.calculateStatistics()
this.renderCharts()
},
calculateStatistics() {
const data = this.teacherData
// 总数统计
this.statistics.totalCount = data.length
// 性别统计
this.statistics.maleCount = data.filter((item) => item.sex === "男").length
this.statistics.femaleCount = data.filter((item) => item.sex === "女").length
// 年龄统计
const ages = data.map((item) => this.calculateAge(item.birthday)).filter((age) => age !== null)
if (ages.length > 0) {
this.statistics.averageAge = Math.round(ages.reduce((a, b) => a + b, 0) / ages.length)
this.statistics.minAge = Math.min(...ages)
this.statistics.maxAge = Math.max(...ages)
}
// 学历统计
const highEdu = ["硕士研究生毕业", "博士研究生毕业"]
this.statistics.highEduCount = data.filter((item) => highEdu.includes(item.education)).length
this.statistics.highEduPercent = data.length > 0 ? Math.round((this.statistics.highEduCount / data.length) * 100) + "%" : "0%"
// 工会和单位统计
const unions = new Set(data.map((item) => item.unionName))
const units = new Set(data.map((item) => item.unitName))
this.statistics.unionCount = unions.size
this.statistics.unitCount = units.size
},
renderCharts() {
this.$nextTick(() => {
this.renderGenderChart()
this.renderAgeChart()
this.renderEducationChart()
this.renderIncomeChart()
this.renderUnitChart()
})
},
// 计算年龄
calculateAge(birthday) {
if (!birthday) return null
const birthDate = new Date(birthday)
const today = new Date()
let age = today.getFullYear() - birthDate.getFullYear()
const m = today.getMonth() - birthDate.getMonth()
if (m < 0 || (m === 0 && today.getDate() < birthDate.getDate())) {
age--
}
return age
},
// 性别分布图
renderGenderChart() {
const container = document.getElementById("genderChart")
if (!container) return
if (this.charts.genderChart) {
this.charts.genderChart.destroy()
}
const genderData = this.getGenderDistribution()
if (this.chartTypes.gender === "pie") {
this.charts.genderChart = new G2Plot.Pie("genderChart", {
data: genderData,
angleField: "value",
colorField: "type",
radius: 0.8,
label: {
type: "outer",
content: "{name}: {percentage}"
},
legend: { position: "right" },
interactions: [{ type: "element-active" }],
color: ["#217050", "#5fad85"]
})
} else {
this.charts.genderChart = new G2Plot.Column("genderChart", {
data: genderData,
xField: "type",
yField: "value",
label: {
position: "top"
},
color: ({ type }) => {
if (type === "男") return "#217050"
return "#5fad85"
},
columnWidthRatio: 0.4
})
}
this.charts.genderChart.render()
},
// 年龄分布图
renderAgeChart() {
const container = document.getElementById("ageChart")
if (!container) return
if (this.charts.ageChart) {
this.charts.ageChart.destroy()
}
const ageData = this.getAgeDistribution()
const commonConfig = {
data: ageData,
xField: "range",
yField: "count",
meta: {
range: { alias: "年龄段" },
count: { alias: "人数" }
},
color: "#217050",
xAxis: {
label: {
autoHide: false,
autoRotate: true
}
}
}
if (this.chartTypes.age === "column") {
this.charts.ageChart = new G2Plot.Column("ageChart", {
...commonConfig,
label: {
position: "top"
}
})
} else {
this.charts.ageChart = new G2Plot.Line("ageChart", {
...commonConfig,
smooth: true,
point: {
size: 5,
shape: "diamond"
}
})
}
this.charts.ageChart.render()
},
// 学历分布图
renderEducationChart() {
const container = document.getElementById("educationChart")
if (!container) return
if (this.charts.educationChart) {
this.charts.educationChart.destroy()
}
const educationData = this.getEducationDistribution()
if (this.chartTypes.education === "pie") {
this.charts.educationChart = new G2Plot.Pie("educationChart", {
data: educationData,
angleField: "count",
colorField: "education",
radius: 0.8,
label: {
type: "outer",
content: "{name}: {percentage}"
},
interactions: [{ type: "element-active" }],
legend: { position: "right" },
color: ["#217050", "#5fad85", "#89d0af", "#c2e6d4", "#136343"]
})
} else {
this.charts.educationChart = new G2Plot.Column("educationChart", {
data: educationData,
xField: "education",
yField: "count",
label: {
position: "top"
},
color: "#217050",
xAxis: {
label: {
autoHide: false,
autoRotate: true
}
}
})
}
this.charts.educationChart.render()
},
// 收入分布图
renderIncomeChart() {
const container = document.getElementById("incomeChart")
if (!container) return
if (this.charts.incomeChart) {
this.charts.incomeChart.destroy()
}
const incomeData = this.getIncomeDistribution()
if (this.chartTypes.income === "pie") {
this.charts.incomeChart = new G2Plot.Pie("incomeChart", {
data: incomeData,
angleField: "count",
colorField: "income",
radius: 0.8,
label: {
type: "outer",
content: "{name}: {percentage}"
},
interactions: [{ type: "element-active" }],
legend: { position: "right" },
color: ["#217050", "#5fad85", "#89d0af", "#c2e6d4", "#136343"]
})
} else {
this.charts.incomeChart = new G2Plot.Column("incomeChart", {
data: incomeData,
xField: "income",
yField: "count",
label: {
position: "top"
},
color: "#217050",
xAxis: {
label: {
autoHide: false,
autoRotate: true
}
}
})
}
this.charts.incomeChart.render()
},
// 单位工会分布图
renderUnitChart() {
const container = document.getElementById("unitChart")
if (!container) return
if (this.charts.unitChart) {
this.charts.unitChart.destroy()
}
const unitData = this.getUnitDistribution()
if (this.chartTypes.unit === "bar") {
this.charts.unitChart = new G2Plot.Bar("unitChart", {
data: unitData,
xField: "count",
yField: "unit",
seriesField: "unionName",
isStack: true,
legend: {
position: "top-right"
},
color: ["#217050", "#5fad85", "#89d0af", "#c2e6d4", "#136343"],
label: {
position: "middle",
layout: [{ type: "interval-adjust-position" }]
}
})
} else {
const processedData = this.getTreemapData()
this.charts.unitChart = new G2Plot.Treemap("unitChart", {
data: processedData,
colorField: "value",
legend: false,
color: ["#e8f5e9", "#c2e6d4", "#89d0af", "#5fad85", "#217050"]
})
}
this.charts.unitChart.render()
},
// 获取性别分布数据
getGenderDistribution() {
const data = this.teacherData
const genderCount = {}
data.forEach((item) => {
const gender = item.sex || "未知"
genderCount[gender] = (genderCount[gender] || 0) + 1
})
return Object.keys(genderCount).map((key) => ({
type: key,
value: genderCount[key]
}))
},
// 获取年龄分布数据
getAgeDistribution() {
const data = this.teacherData
const ageRanges = {
"25岁以下": 0,
"26-30岁": 0,
"31-35岁": 0,
"36-40岁": 0,
"41-45岁": 0,
"46-50岁": 0,
"51岁以上": 0
}
data.forEach((item) => {
if (!item.birthday) return
const age = this.calculateAge(item.birthday)
if (age <= 25) ageRanges["25岁以下"]++
else if (age <= 30) ageRanges["26-30岁"]++
else if (age <= 35) ageRanges["31-35岁"]++
else if (age <= 40) ageRanges["36-40岁"]++
else if (age <= 45) ageRanges["41-45岁"]++
else if (age <= 50) ageRanges["46-50岁"]++
else ageRanges["51岁以上"]++
})
return Object.keys(ageRanges).map((key) => ({
range: key,
count: ageRanges[key]
}))
},
// 获取学历分布数据
getEducationDistribution() {
const data = this.teacherData
const educationCount = {}
data.forEach((item) => {
const education = item.education || "未知"
educationCount[education] = (educationCount[education] || 0) + 1
})
return Object.keys(educationCount).map((key) => ({
education: key,
count: educationCount[key]
}))
},
// 获取收入分布数据
getIncomeDistribution() {
const data = this.teacherData
const incomeCount = {}
data.forEach((item) => {
const income = item.monthlyIncome || "未知"
incomeCount[income] = (incomeCount[income] || 0) + 1
})
return Object.keys(incomeCount).map((key) => ({
income: key,
count: incomeCount[key]
}))
},
// 获取单位分布数据
getUnitDistribution() {
const data = this.teacherData
const unitData = []
data.forEach((item) => {
const unit = item.unitName || "未知单位"
const union = item.unionName || "未知工会"
const existingUnit = unitData.find((u) => u.unit === unit && u.unionName === union)
if (existingUnit) {
existingUnit.count++
} else {
unitData.push({
unit,
unionName: union,
count: 1
})
}
})
return unitData.sort((a, b) => a.count - b.count)
},
// 矩形树图数据处理
getTreemapData() {
const data = this.teacherData
const unionMap = {}
// 按工会和单位分组统计
data.forEach((item) => {
const union = item.unionName || "未知工会"
const unit = item.unitName || "未知单位"
if (!unionMap[union]) {
unionMap[union] = {
name: union,
value: 0,
children: {}
}
}
unionMap[union].value++
if (!unionMap[union].children[unit]) {
unionMap[union].children[unit] = {
name: unit,
value: 0
}
}
unionMap[union].children[unit].value++
})
// 转换为G2Plot需要的格式
const result = {
name: "root",
children: []
}
Object.keys(unionMap).forEach((union) => {
const unionData = unionMap[union]
const children = []
Object.keys(unionData.children).forEach((unit) => {
children.push({
name: unit,
value: unionData.children[unit].value
})
})
result.children.push({
name: union,
value: unionData.value,
children
})
})
return result
}
},
mounted() {
this.$businessTool.listUnion().then((res) => (this.unionOptions = res))
this.fetchData()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,293 @@
const formEdit = {
template: /*language=HTML*/ `
<el-dialog :title="formData.id ? '编辑单身教工信息' : '新增单身教工信息'" :visible.sync="visible" width="65%"
append-to-body>
<el-form ref="form" :model="formData" :rules="rules" label-width="120px" size="small"
class="single-teacher-form">
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="选择用户" prop="userId" v-if="!formData.id">
<el-select
v-model="formData.userId"
filterable
remote
reserve-keyword
placeholder="请输入关键词搜索用户"
:remote-method="remoteSearchUsers"
:loading="userSearchLoading"
style="width: 100%"
@change="handleUserChange">
<el-option
v-for="item in userOptions"
:key="item.id"
:label="item.username + '(' + item.loginname + ')'"
:value="item.id">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="用户信息" v-else>
<el-input v-model="formData.username" disabled></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="联系方式" prop="mobile">
<el-input v-model="formData.mobile" placeholder="请输入联系方式"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="出生年月" prop="birthday">
<el-date-picker
v-model="formData.birthday"
type="date"
placeholder="选择日期"
format="yyyy-MM-dd"
value-format="yyyy-MM-dd"
style="width: 100%">
</el-date-picker>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="身高(cm)" prop="height">
<el-input v-model="formData.height" placeholder="请输入身高"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="籍贯" prop="nativePlace">
<el-input v-model="formData.nativePlace" placeholder="请输入籍贯"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="学历" prop="education">
<dict-select style="width: 100%" placeholder="请选择学历" v-model="formData.education"
code="USER_EDUCATION"></dict-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="婚姻状况" prop="maritalStatus">
<el-select v-model="formData.maritalStatus" placeholder="请选择婚姻状况"
style="width: 100%">
<el-option label="未婚" value="未婚"></el-option>
<el-option label="离婚" value="离婚"></el-option>
<el-option label="丧偶" value="丧偶"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="月收入" prop="monthlyIncome">
<el-select v-model="formData.monthlyIncome" placeholder="请选择月收入范围"
style="width: 100%">
<el-option label="5000以下" value="5000以下"></el-option>
<el-option label="5000-8000" value="5000-8000"></el-option>
<el-option label="8000-10000" value="8000-10000"></el-option>
<el-option label="10000-15000" value="10000-15000"></el-option>
<el-option label="15000以上" value="15000以上"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="住房情况" prop="housingSituation">
<el-select v-model="formData.housingSituation" placeholder="请选择住房情况"
style="width: 100%">
<el-option label="已购房" value="已购房"></el-option>
<el-option label="租房" value="租房"></el-option>
<el-option label="与父母同住" value="与父母同住"></el-option>
<el-option label="单位宿舍" value="单位宿舍"></el-option>
<el-option label="其他" value="其他"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-form-item label="兴趣爱好" prop="hobby">
<el-input v-model="formData.hobby" placeholder="请输入兴趣爱好,多个用逗号分隔"></el-input>
</el-form-item>
<el-form-item label="形象照片" prop="photo" class="avatar-container">
<file-upload
:value.sync="formData.photo"
:upload_number="1"
upload_mode="image"
upload_result_category="interval"
upload_result_type="url"
></file-upload>
</el-form-item>
<el-form-item label="生活照片" prop="picFiles" class="gallery-container">
<file-upload
:value.sync="formData.picFiles"
:upload_number="5"
upload_mode="image"
upload_result_category="array"
upload_result_type="url"
></file-upload>
</el-form-item>
<el-form-item label="交友意向" prop="intentionFriends">
<el-input type="textarea" v-model="formData.intentionFriends" :rows="3"
placeholder="请描述您的交友意向"></el-input>
</el-form-item>
<el-form-item label="个人介绍" prop="introduction">
<el-input type="textarea" v-model="formData.introduction" :rows="4"
placeholder="请简要介绍一下自己"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="visible = false">取 消</el-button>
<el-button type="primary" @click="submitForm" :loading="loading">确 定</el-button>
</div>
</el-dialog>
`,
data() {
return {
visible: false,
loading: false,
userSearchLoading: false,
userOptions: [],
formData: {
userId: "",
userName: "",
birthday: "",
mobile: "",
height: "",
hometown: "",
education: "",
hobby: "",
monthlyIncome: "",
housingSituation: "",
picFiles: [],
photo: "",
maritalStatus: "",
intentionFriends: "",
introduction: ""
},
rules: {
userId: [{ required: true, message: "请选择用户", trigger: ["change", "blur"] }],
mobile: [
{ required: true, message: "请输入联系方式", trigger: ["change", "blur"] },
{ pattern: /^1[3-9]\d{9}$/, message: "请输入正确的手机号码", trigger: ["change", "blur"] }
],
birthday: [{ required: true, message: "请选择出生年月", trigger: ["change", "blur"] }],
height: [{ pattern: /^\d{2,3}$/, message: "请输入正确的身高", trigger: ["change", "blur"] }],
education: [{ required: true, message: "请选择学历", trigger: ["change", "blur"] }],
maritalStatus: [{ required: true, message: "请选择婚姻状况", trigger: ["change", "blur"] }],
introduction: [{ required: true, message: "请填写个人介绍", trigger: ["change", "blur"] }]
}
}
},
methods: {
onOpen(data) {
this.visible = true
this.loading = false
this.userOptions = [] // 清空用户选项
if (data && data.id) {
this.formData = JSON.parse(JSON.stringify(data))
this.formData.picFiles = JSON.parse(this.formData.picFiles)
} else {
this.formData = {
userId: "",
userName: "",
birthday: "",
mobile: "",
height: "",
nativePlace: "",
education: "",
hobby: "",
monthlyIncome: "",
housingSituation: "",
picFiles: [],
photo: "",
maritalStatus: "",
intentionFriends: "",
introduction: ""
}
}
this.$nextTick(() => {
if (this.$refs.form) {
this.$refs.form.clearValidate()
}
})
},
// 远程搜索用户
remoteSearchUsers(query) {
if (query !== "") {
this.userSearchLoading = true
this.$axios
.post("/platform/singleTeacher/ledger/queryNotSingleTeacher", { key: query })
.then((res) => {
if (res.code === 0) {
this.userOptions = res.data || []
} else {
this.$message.error(res.msg || "搜索用户失败")
}
})
.finally(() => {
this.userSearchLoading = false
})
} else {
this.userOptions = []
}
},
// 用户选择变更
handleUserChange(userId) {
const selectedUser = this.userOptions.find((item) => item.id === userId)
if (selectedUser) {
// 自动填充一些基础信息
this.formData.userName = selectedUser.name
this.formData.mobile = selectedUser.mobile || ""
this.formData.birthday = selectedUser.birthday || ""
this.formData.education = selectedUser.education || ""
this.formData.nativePlace = selectedUser.nativePlace || ""
}
},
submitForm() {
this.$refs.form.validate((valid) => {
if (valid) {
this.loading = true
// 构建提交的数据
const submitData = { ...this.formData }
// 发送请求
const url = submitData.id ? "/platform/singleTeacher/ledger/update" : "/platform/singleTeacher/ledger/insert"
this.$axios
.post(url, { singleTeacher: JSON.stringify(submitData) })
.then((res) => {
if (res.code === 0) {
this.$message.success(submitData.id ? "修改成功" : "添加成功")
this.visible = false
this.$emit("refresh")
} else {
this.$message.error(res.msg || "操作失败")
}
})
.finally(() => {
this.loading = false
})
}
})
}
},
style: /*language=CSS*/ `
`
}
@@ -0,0 +1,157 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<el-card shadow="never">
<search @search="doSearch">
<search-item label="姓名工号">
<el-input placeholder="请输入姓名或者工号" clearable v-model="pageForm.searchKeyword"></el-input>
</search-item>
<search-item label="所属工会">
<el-select v-model="pageForm.unionId" placeholder="请选择所属工会" clearable style="width: 100%">
<el-option v-for="item in unionOptions" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
</search-item>
<search-item label="所属单位">
<el-select placeholder="请选择所属单位" style="width: 100%" v-model="pageForm.unitId" clearable
filterable>
<el-option v-for="item in unitOptions" :label="item.name" :value="item.id"></el-option>
</el-select>
</search-item>
<search-item label="性别">
<el-select v-model="pageForm.sex" placeholder="请选择性别" clearable style="width: 100%">
<el-option label="男" value="男"></el-option>
<el-option label="女" value="女"></el-option>
</el-select>
</search-item>
<search-item label="年龄区间">
<div style="display: flex; align-items: center">
<el-slider v-model="pageForm.age" range show-stops :max="100" style="flex: 1; padding: 0 12px"></el-slider>
<div style="width: 70px; flex-shrink: 0; text-align: right">{{ pageForm.age ? pageForm.age.join('-') : '' }}</div>
</div>
</search-item>
<search-item label="婚姻状况">
<el-select v-model="pageForm.marriage" placeholder="请选择婚姻状况" clearable style="width: 100%">
<el-option label="未婚" value="未婚"></el-option>
<el-option label="已婚" value="已婚"></el-option>
<el-option label="离异" value="离异"></el-option>
<el-option label="丧偶" value="丧偶"></el-option>
</el-select>
</search-item>
<search-item label="学历">
<el-select clearable placeholder="请选择学历"
style="width: 100%;"
v-model="pageForm.education">
<el-option :label="item.name" :value="item.code"
v-for="item in dict.type.USER_EDUCATION"></el-option>
</el-select>
</search-item>
<search-item label="人员类型">
<el-select clearable placeholder="请选择人员类型"
style="width: 100%;"
v-model="pageForm.personType">
<el-option :label="item.name" :value="item.code"
v-for="item in dict.type.USER_PERSON_TYPE"></el-option>
</el-select>
</search-item>
<search-item label="在职状态">
<el-select clearable placeholder="请选择在职状态"
style="width: 100%;"
v-model="pageForm.userState">
<el-option :label="item.name" :value="item.code"
v-for="item in dict.type.USER_STATE"></el-option>
</el-select>
</search-item>
</search>
</el-card>
<el-card shadow="never">
<table-tool>
<el-button size="mini" type="primary" icon="el-icon-plus" @click="$refs.formEditRef.onOpen()">新增</el-button>
<el-button size="mini" type="primary" icon="el-icon-download" @click="exportExcel">导出</el-button>
</table-tool>
<el-table :data="tableData">
<el-table-column type="index" width="50px" label="序号" :index="indexMethod" fixed="left"></el-table-column>
<el-table-column prop="username" label="姓名" width="100" sortable="custom" fixed="left"></el-table-column>
<el-table-column prop="loginname" label="工号" width="100" sortable="custom"></el-table-column>
<el-table-column prop="sex" label="性别" width="100" sortable="custom"></el-table-column>
<el-table-column prop="mobile" label="手机号码" width="120"></el-table-column>
<el-table-column prop="birthday" label="出生日期" width="120" sortable="custom"></el-table-column>
<el-table-column prop="education" label="学历" width="150" show-overflow-tooltip></el-table-column>
<el-table-column prop="maritalStatus" label="婚姻状况" width="120" sortable="custom"></el-table-column>
<el-table-column prop="unitName" label="单位名称" width="180" show-overflow-tooltip sortable="custom"></el-table-column>
<el-table-column prop="unionName" label="工会名称" width="150" show-overflow-tooltip sortable="custom"></el-table-column>
<el-table-column prop="introduction" label="介绍" show-overflow-tooltip></el-table-column>
<el-table-column label="操作" width="150" fixed="right">
<template slot-scope="scope">
<el-button type="primary" size="mini" @click="$refs.formEditRef.onOpen(scope.row)">编辑</el-button>
<el-button type="danger" size="mini" @click="onDelete(scope.row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<form-edit ref="formEditRef" @refresh="doSearch"></form-edit>
</div>
<script nonce="${cspNonce!}">
<!--#include("formEdit.js"){}#-->
new Vue({
el: "#app",
store,
mixins: [initTableMixins],
dicts: ["USER_STATE", "USER_PERSON_TYPE", "USER_EDUCATION"],
components: {
"form-edit": formEdit
},
data() {
return {
unionOptions: [],
unitOptions: [],
pageForm: {
age: [0, 100]
}
}
},
methods: {
pageData() {
this.$axios.post("/platform/singleTeacher/ledger/pageData", { pageForm: JSON.stringify(this.pageForm) }).then((res) => {
if (res.code === 0) {
this.tableData = res.data.list
this.pageForm.totalCount = res.data.totalCount
}
})
},
onDelete(id) {
this.$confirm("您确定要删除吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(async () => {
const { code, msg } = await this.$axios.post("/platform/singleTeacher/ledger/delete", { id: id })
if (code === 0) {
this.$message.success(msg)
this.doSearch()
}
})
.catch(() => {})
},
exportExcel() {
this.$downLoad("/platform/singleTeacher/ledger/exportExcel", { pageForm: JSON.stringify(this.pageForm) })
}
},
created() {
this.pageData()
this.$businessTool.listUnion().then((res) => (this.unionOptions = res))
this.$businessTool.listUnit().then((res) => (this.unitOptions = res))
}
})
</script>
<!--#
}
#-->