| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828 |
- <template>
- <div class="app-container">
- <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="80px">
- <el-form-item label="配分层级" prop="org">
- <el-select v-model="queryParams.org" placeholder="请选择层级" style="width:200px" clearable
- @change="handleLevelChange">
- <el-option v-for="dict in score_level" :key="dict.value" :label="dict.label" :value="dict.value" />
- </el-select>
- </el-form-item>
- <el-form-item label="部门名称" prop="deptId">
- <el-select v-model="queryParams.deptId" placeholder="请选择部门" style="width:150px" clearable filterable
- @change="handleQueryDeptChange">
- <el-option v-for="d in queryDeptOptions" :key="d.deptId" :label="d.deptName" :value="d.deptId" />
- </el-select>
- </el-form-item>
- <el-form-item label="队室/班组" prop="teamId">
- <el-select v-model="queryParams.teamId" placeholder="请选择队室/班组" style="width:150px" clearable filterable
- @change="handleQueryTeamChange">
- <el-option v-for="t in queryTeamOptions" :key="t.id" :label="t.label" :value="t.id" />
- </el-select>
- </el-form-item>
- <el-form-item label="通道/小组" prop="groupId">
- <el-select v-model="queryParams.groupId" placeholder="请选择通道/小组" style="width:150px" clearable filterable
- @change="handleQueryGroupChange">
- <el-option v-for="g in queryGroupOptions" :key="g.id" :label="g.label" :value="g.id" />
- </el-select>
- </el-form-item>
- <el-form-item label="责任人" prop="personId">
- <el-select v-model="queryParams.personId" placeholder="请选择责任人" style="width:150px" clearable filterable>
- <el-option v-for="p in searchPersonOptions" :key="p.userId" :label="p.nickName" :value="p.userId" />
- </el-select>
- </el-form-item>
- <el-form-item label="维度" prop="dimensionId">
- <el-select v-model="queryParams.dimensionId" placeholder="全部维度" clearable style="width:150px">
- <el-option v-for="d in dimensionOptions" :key="d.id" :label="d.name" :value="d.id" />
- </el-select>
- </el-form-item>
- <el-form-item label="来源" prop="sourceType">
- <el-select v-model="queryParams.sourceType" placeholder="全部来源" clearable style="width:120px">
- <el-option label="手动录入" value="1" />
- <el-option label="台账同步" value="2" />
- </el-select>
- </el-form-item>
- <el-form-item label="事件时间">
- <el-date-picker v-model="dateRange" type="daterange" value-format="YYYY-MM-DD" range-separator="-"
- start-placeholder="开始日期" end-placeholder="结束日期" clearable />
- </el-form-item>
- <el-form-item label="扣分类型" prop="scoreType">
- <el-select v-model="queryParams.scoreType" placeholder="全部类型" clearable style="width:150px">
- <el-option v-for="dict in score_type" :key="dict.value" :label="dict.label" :value="dict.value" />
- </el-select>
- </el-form-item>
- <el-form-item label="区域" prop="regionalId">
- <el-select v-model="queryParams.regionalId" placeholder="请选择区域" clearable filterable style="width:200px"
- @change="handleRegionalChange">
- <el-option v-for="item in regionalOptions" :key="item.id" :label="item.name" :value="item.id" />
- </el-select>
- </el-form-item>
- <el-form-item label="工作点" prop="channelId">
- <el-select v-model="queryParams.channelId" placeholder="请选择工作点" clearable filterable style="width:150px">
- <el-option v-for="item in channelOptions" :key="item.id" :label="item.positionName" :value="item.id" />
- </el-select>
- </el-form-item>
- <el-form-item label="岗位" prop="postId">
- <el-tree-select v-model="queryParams.postId" :data="postTreeData"
- :props="{ value: 'postId', label: 'postName', children: 'children' }" clearable filterable placeholder="请选择岗位"
- check-strictly />
- </el-form-item>
- <el-form-item>
- <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
- <el-button icon="Refresh" @click="resetQuery">重置</el-button>
- </el-form-item>
- </el-form>
- <el-row :gutter="10" class="mb8">
- <el-col :span="1.5">
- <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['score:event:add']">新增</el-button>
- </el-col>
- <el-col :span="1.5">
- <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate"
- v-hasPermi="['score:event:edit']">修改</el-button>
- </el-col>
- <el-col :span="1.5">
- <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete"
- v-hasPermi="['score:event:remove']">删除</el-button>
- </el-col>
- <el-col :span="1.5">
- <el-button type="warning" plain icon="Download" @click="handleExport"
- v-hasPermi="['score:event:export']">导出</el-button>
- </el-col>
- <!-- <el-col :span="1.5">
- <el-upload :show-file-list="false" accept=".xlsx,.xls" :auto-upload="false" :on-change="handleImportFile">
- <el-button type="info" plain icon="Upload" v-hasPermi="['score:event:import']">导入</el-button>
- </el-upload>
- </el-col> -->
- <right-toolbar v-model:showSearch="showSearch" @queryTable="getList" />
- </el-row>
- <el-table v-loading="loading" :data="list" @selection-change="handleSelectionChange" style="width: 100%;" fit="true"
- :scrollbar-always-on="true">
- <el-table-column type="selection" width="55" align="center" resizable />
- <el-table-column label="配分层级" align="center" prop="org" width="110" resizable>
- <template #default="{ row }"><dict-tag :options="score_level" :value="row.org" /></template>
- </el-table-column>
- <el-table-column label="事件时间" align="center" prop="eventTime" width="120" resizable>
- <template #default="{ row }">{{ parseTime(row.eventTime, '{y}-{m}-{d}') }}</template>
- </el-table-column>
- <el-table-column label="维度" align="center" prop="dimensionName" width="150" resizable />
- <el-table-column label="二级指标" align="center" prop="level2Name" min-width="250" show-overflow-tooltip resizable />
- <el-table-column label="三级指标" align="center" prop="level3Name" min-width="250" show-overflow-tooltip resizable />
- <el-table-column label="责任人" align="center" prop="personName" width="80" resizable />
- <el-table-column label="部门" align="center" prop="deptName" min-width="120" resizable />
- <el-table-column label="班组" align="center" prop="teamName" min-width="120" resizable />
- <el-table-column label="区域" align="center" prop="regionalName" min-width="200" resizable />
- <el-table-column label="工作点" align="center" prop="channelName" min-width="100" resizable />
- <el-table-column label="岗位" align="center" prop="postName" min-width="190" resizable />
- <el-table-column label="基础分值" align="center" prop="scoreValue" width="90" resizable>
- <template #default="{ row }">
- <span :style="{ color: row.scoreValue > 0 ? '#67c23a' : row.scoreValue < 0 ? '#f56c6c' : '' }">
- {{ row.scoreValue > 0 ? '+' : '' }}{{ row.scoreValue }}
- </span>
- </template>
- </el-table-column>
- <el-table-column label="叠加分" align="center" prop="cascadeScore" width="80" resizable>
- <template #default="{ row }">
- <span v-if="row.cascadeScore" :style="{ color: row.cascadeScore > 0 ? '#67c23a' : '#f56c6c' }">
- {{ row.cascadeScore > 0 ? '+' : '' }}{{ row.cascadeScore }}
- </span>
- <span v-else style="color:#c0c4cc">-</span>
- </template>
- </el-table-column>
- <el-table-column label="总分值" align="center" prop="totalScore" width="90" resizable>
- <template #default="{ row }">
- <strong :style="{ color: row.totalScore > 0 ? '#67c23a' : row.totalScore < 0 ? '#f56c6c' : '' }">
- {{ row.totalScore > 0 ? '+' : '' }}{{ row.totalScore }}
- </strong>
- </template>
- </el-table-column>
- <el-table-column label="来源" align="center" width="90" resizable>
- <template #default="{ row }">
- <el-tag :type="row.sourceType === '1' ? 'primary' : 'warning'" size="small">
- {{ row.sourceType === '1' ? '手动录入' : '台账同步' }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column label="事件描述" min-width="450" align="center" prop="eventDesc" show-overflow-tooltip resizable />
- <el-table-column label="操作" align="center" width="180" resizable fixed="right">
- <template #default="{ row }">
- <el-button link type="primary" icon="Edit" @click="handleUpdate(row)"
- v-hasPermi="['score:event:edit']">修改</el-button>
- <el-button link type="danger" icon="Delete" @click="handleDelete(row)"
- v-hasPermi="['score:event:remove']">删除</el-button>
- </template>
- </el-table-column>
- </el-table>
- <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum"
- v-model:limit="queryParams.pageSize" @pagination="getList" />
- <!-- 新增/修改对话框 -->
- <el-dialog :title="dialogTitle" v-model="dialogVisible" width="680px" append-to-body element-loading-text="加载中...">
- <el-form ref="formRef" :model="form" label-width="100px" v-loading="dialogLoading">
- <el-row :gutter="16">
- <el-col :span="12">
- <el-form-item label="配分层级" prop="org" :rules="rules.org">
- <el-select v-model="form.org" placeholder="请选择层级" style="width:100%" @change="handleFormLevelChange">
- <el-option v-for="dict in score_level" :key="dict.value" :label="dict.label" :value="dict.value" />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="维度" prop="dimensionId" :rules="rules.dimensionId">
- <el-select v-model="form.dimensionId" placeholder="请选择维度" style="width:100%" @change="onDimensionChange">
- <el-option v-for="d in dimensionOptions" :key="d.id" :label="d.name" :value="d.id" />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="二级指标" prop="level2Id">
- <el-select v-model="form.level2Id" placeholder="请选择" style="width:100%" clearable
- @change="onLevel2Change">
- <el-option v-for="n in level2Options" :key="n.id" :label="n.name" :value="n.id" />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="三级指标" prop="level3Id">
- <el-select v-model="form.level3Id" placeholder="请选择" style="width:100%" clearable
- @change="onLevel3Change">
- <el-option v-for="n in level3Options" :key="n.id" :label="n.name" :value="n.id" />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="四级指标">
- <el-select v-model="form.level4Id" placeholder="请选择" style="width:100%" clearable
- @change="onLevel4Change">
- <el-option v-for="n in level4Options" :key="n.id" :label="n.name" :value="n.id" />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="事件时间" prop="eventTime" :rules="rules.eventTime">
- <el-date-picker v-model="form.eventTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss"
- placeholder="请选择事件时间" style="width:100%" />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="区域">
- <el-select v-model="form.regionalId" placeholder="请选择区域" clearable filterable style="width:100%"
- @change="handleFormRegionalChange">
- <el-option v-for="item in regionalOptions" :key="item.id" :label="item.name" :value="item.id" />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="工作点">
- <el-select v-model="form.channelId" placeholder="请选择工作点" clearable filterable style="width:100%">
- <el-option v-for="item in formChannelOptions" :key="item.id" :label="item.name" :value="item.id" />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="部门名称" prop="deptId" :rules="rules.deptId">
- <el-select v-model="form.deptId" placeholder="请选择部门" style="width:100%" clearable filterable
- @change="handleBrigadeChange">
- <el-option v-for="d in deptOptions" :key="d.deptId" :label="d.deptName" :value="d.deptId" />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="队室/班组" prop="teamId" :rules="rules.teamId">
- <el-select v-model="form.teamId" placeholder="请选择队室/班组" style="width:100%" clearable filterable
- @change="handleDepartmentChange">
- <el-option v-for="t in teamOptions" :key="t.id" :label="t.label" :value="t.id" />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="通道/小组" prop="groupId" :rules="rules.groupId">
- <el-select v-model="form.groupId" placeholder="请选择通道/小组" style="width:100%" clearable filterable
- @change="handleGroupChange">
- <el-option v-for="g in groupOptions" :key="g.id" :label="g.label" :value="g.id" />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="责任人" prop="personId" :rules="rules.personId">
- <el-select v-model="form.personId" placeholder="请选择责任人" style="width:100%" clearable filterable
- @change="handlePersonChange">
- <el-option v-for="p in personOptions" :key="p.userId" :label="p.nickName" :value="p.userId" />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="岗位">
- <el-tree-select v-model="form.postId" :data="postTreeData"
- :props="{ value: 'postId', label: 'postName', children: 'children' }" clearable filterable
- placeholder="请选择岗位" style="width:100%" check-strictly />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="基础分值" prop="scoreValue">
- <el-input-number v-model="form.scoreValue" :precision="2" style="width:100%" placeholder="正数=加分 负数=扣分" />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="叠加分值">
- <el-input-number v-model="form.cascadeScore" :precision="2" style="width:100%" placeholder="叠加后果产生的分值" />
- </el-form-item>
- </el-col>
- <el-col :span="24">
- <el-form-item label="事件描述" prop="eventDesc">
- <el-input v-model="form.eventDesc" type="textarea" :rows="3" placeholder="请输入事件描述" />
- </el-form-item>
- </el-col>
- <el-col :span="24">
- <el-form-item label="备注">
- <el-input v-model="form.remark" type="textarea" :rows="2" placeholder="请输入备注" />
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
- <template #footer>
- <el-button @click="dialogVisible = false">取消</el-button>
- <el-button type="primary" @click="submitForm">确定</el-button>
- </template>
- </el-dialog>
- </div>
- </template>
- <script setup>
- import { ref, reactive, computed, watch, onMounted, getCurrentInstance } from 'vue'
- import { ElMessage, ElMessageBox } from 'element-plus'
- import { useRoute } from 'vue-router'
- import { listUser, getDeptOrgInfo, getUserOrgInfo } from '@/api/system/user'
- import { listPosition } from '@/api/system/position'
- import { listAllTree } from '@/api/system/post'
- import {
- listScoreEvent, addScoreEvent, updateScoreEvent, delScoreEvent,
- exportScoreEvent, importScoreEvent
- } from '@/api/score/index'
- import { allDimension, treeIndicator, getDimensionAll } from '@/api/score/index'
- import { listDept } from '@/api/system/dept'
- import { deptTreeSelect } from '@/api/system/user'
- import { parseTime } from '@/utils/ruoyi'
- defineOptions({ name: 'ScoreEvent' })
- const { proxy } = getCurrentInstance()
- const { score_level, score_type } = proxy.useDict('score_level', 'score_type')
- const loading = ref(false), list = ref([]), total = ref(0), showSearch = ref(true)
- const dateRange = ref([]), queryRef = ref(null), formRef = ref(null)
- const dialogVisible = ref(false), dialogTitle = ref(''), dialogLoading = ref(false)
- const single = ref(true), multiple = ref(true), ids = ref([])
- const dimensionOptions = ref([])
- const indicatorTree = ref([]) // 当前维度的指标树(扁平+嵌套)
- const level2Options = ref([])
- const level3Options = ref([])
- const level4Options = ref([])
- const deptOptions = ref([])
- const teamOptions = ref([])
- const groupOptions = ref([])
- const personOptions = ref([])
- const allPersonOptions = ref([]) // 缓存全部人员,避免重复请求
- const queryDeptOptions = ref([])
- const queryTeamOptions = ref([])
- const queryGroupOptions = ref([])
- const queryPersonOptions = ref([])
- const regionalOptions = ref([])
- const channelOptions = ref([])
- const postTreeData = ref([])
- const queryParams = reactive({ pageNum: 1, pageSize: 10, personId: null, personName: '', deptId: null, deptName: '', teamId: null, teamName: '', groupId: null, groupName: '', dimensionId: null, sourceType: '', org: '', scoreType: null, regionalId: null, channelId: null, postId: null })
- const form = reactive({ id: null, dimensionId: null, dimensionName: '', indicatorId: null, level2Id: null, level2Name: '', level3Id: null, level3Name: '', level4Id: null, level4Name: '', eventTime: '', location: '', personId: null, deptName: '', deptId: null, teamId: null, groupId: null, scoreValue: 0, cascadeScore: 0, eventDesc: '', remark: '', org: '', regionalId: null, channelId: null, postId: null })
- const formChannelOptions = ref([])
- const rules = computed(() => {
- return {
- org: [{ required: true, message: '请选择配分层级', trigger: 'submit' }],
- dimensionId: [{ required: true, message: '请选择维度', trigger: 'submit' }],
- eventTime: [{ required: true, message: '请选择事件时间', trigger: 'submit' }],
- scoreValue: [{ required: true, message: '请输入分值', trigger: 'submit' }],
- deptId: form.org === '1' ? [{ required: true, message: '请选择部门', trigger: 'submit' }] : [],
- teamId: form.org === '2' ? [{ required: true, message: '请选择队室/班组', trigger: 'submit' }] : [],
- groupId: form.org === '3' ? [{ required: true, message: '请选择通道/小组', trigger: 'submit' }] : [],
- personId: form.org === '4' ? [{ required: true, message: '请选择责任人', trigger: 'submit' }] : [],
- }
- })
- // 搜索表单责任人选项:未选择部门/班组/小组时使用全量人员,否则使用过滤后的人员
- const searchPersonOptions = computed(() => {
- if (queryParams.deptId || queryParams.teamId || queryParams.groupId) {
- return queryPersonOptions.value
- }
- return personOptions.value
- })
- async function loadDimensions() {
- const r = await allDimension()
- dimensionOptions.value = r.data || []
- }
- async function handleLevelChange() {
- queryParams.dimensionId = null
- queryParams.deptId = null; queryParams.teamId = null; queryParams.groupId = null; queryParams.personId = null
- queryTeamOptions.value = []; queryGroupOptions.value = []; queryPersonOptions.value = []
- const r = await getDimensionAll({ pageNum: 1, pageSize: 100, org: queryParams.org })
- dimensionOptions.value = r.data || []
- }
- async function handleFormLevelChange() {
- form.dimensionId = null
- form.level2Id = null; form.level2Name = ''; form.level3Id = null; form.level3Name = ''; form.level4Id = null; form.level4Name = ''
- form.deptId = null; form.teamId = null; form.groupId = null; form.personId = null
- indicatorTree.value = []
- level2Options.value = []; level3Options.value = []; level4Options.value = []
- teamOptions.value = []; groupOptions.value = []; personOptions.value = []
- const org = form.org
- const r = await getDimensionAll({ pageNum: 1, pageSize: 100, org })
- dimensionOptions.value = r.data || []
- // if (org === '2') {
- await loadAllTeams()
- // } else if (org === '3') {
- await loadAllGroups()
- // } else if (org === '4') {
- await loadAllPersons()
- // }
-
- }
- async function loadAllTeams() {
- const r = await listDept({ deptType: 'MANAGER' })
- teamOptions.value = (r.data || []).map(d => ({ id: d.deptId, label: d.deptName }))
- }
- async function loadDepts() {
- const r = await listDept()
- deptOptions.value = (r.data || []).filter(d => d.deptType === 'BRIGADE')
- }
- async function loadAllGroups() {
- const r = await listDept({ deptType: 'TEAMS' })
- groupOptions.value = (r.data || []).map(d => ({ id: d.deptId, label: d.deptName }))
- }
- async function loadAllPersons() {
- const r = await listUser({ pageSize: 9999 })
- const rows = r.rows || []
- allPersonOptions.value = rows
- personOptions.value = rows
- }
- async function loadRegions() {
- const r = await listPosition({ positionType: 'REGIONAL' })
- regionalOptions.value = r.data || []
- }
- async function handleRegionalChange(val) {
- queryParams.channelId = null
- channelOptions.value = []
- if (val) {
- const r = await listPosition({ parentId: val })
- channelOptions.value = r.data || []
- }
- }
- async function handleFormRegionalChange(val) {
- form.channelId = null
- formChannelOptions.value = []
- if (val) {
- const r = await listPosition({ parentId: val })
- formChannelOptions.value = r.data || []
- }
- }
- async function handleBrigadeChange(val) {
-
- form.teamId = null; form.groupId = null; form.personId = null
- teamOptions.value = []; groupOptions.value = []; personOptions.value = []
- if (val) {
- const r = await deptTreeSelect({ parentId: val })
- teamOptions.value = r.data || []
- }
-
- }
- async function handleDepartmentChange(val) {
- form.groupId = null; form.personId = null
- groupOptions.value = []; personOptions.value = []
- if (val) {
- const r = await deptTreeSelect({ parentId: val })
- groupOptions.value = r.data || []
- }
-
- }
- async function handleGroupChange(val) {
- form.personId = null
- personOptions.value = []
- if (val) {
- const r = await listUser({ deptId: val, pageSize: 9999 })
- personOptions.value = r.rows || []
- } else {
- personOptions.value = [...allPersonOptions.value]
- }
-
- }
- async function handlePersonChange(val) {
- dialogLoading.value = true
- form.deptId = null; form.teamId = null; form.groupId = null
- teamOptions.value = []; groupOptions.value = [];
- if (val) {
- const r = await getUserOrgInfo({ userId: val })
- if (r.data) {
- form.deptId = r.data.deptInfo.brigadeId
- form.teamId = r.data.deptInfo.departmentId
- form.groupId = r.data.deptInfo.teamId
- // 根据部门加载队室/班组选项
- if (form.deptId) {
- const r1 = await deptTreeSelect({ parentId: form.deptId })
- teamOptions.value = r1.data || []
- }
- // 根据队室/班组加载通道/小组选项
- if (form.teamId) {
- const r2 = await deptTreeSelect({ parentId: form.teamId })
- groupOptions.value = r2.data || []
- }
- }
- }
- dialogLoading.value = false
- }
- async function loadQueryDepts() {
- const r = await listDept()
- queryDeptOptions.value = (r.data || []).filter(d => d.deptType === 'BRIGADE')
- }
- async function handleQueryDeptChange(deptId) {
- queryParams.teamId = null; queryParams.groupId = null; queryParams.personId = null
- queryTeamOptions.value = []; queryGroupOptions.value = []; queryPersonOptions.value = []
- if (deptId) {
- const r = await deptTreeSelect({ parentId: deptId })
- queryTeamOptions.value = r.data || []
- }
- }
- async function handleQueryTeamChange(val) {
- queryParams.groupId = null; queryParams.personId = null
- queryPersonOptions.value = []
- const team = queryTeamOptions.value.find(t => t.id === val)
- if (team) {
- const r = await deptTreeSelect({ parentId: team.id })
- queryGroupOptions.value = r.data || []
- } else {
- queryGroupOptions.value = []
- }
- }
- async function handleQueryGroupChange(val) {
- queryParams.personId = null
- const group = queryGroupOptions.value.find(g => g.id === val)
- if (group) {
- const r = await listUser({ deptId: group.id, pageSize: 9999 })
- queryPersonOptions.value = r.rows || []
- } else {
- queryPersonOptions.value = []
- }
- }
- function getList() {
- loading.value = true
- const p = { ...queryParams }
- if (dateRange.value?.length === 2) { p['params[beginTime]'] = dateRange.value[0]; p['params[endTime]'] = dateRange.value[1] }
- listScoreEvent(p).then(r => { list.value = r.rows; total.value = r.total }).finally(() => loading.value = false)
- }
- function handleQuery() { queryParams.pageNum = 1; getList() }
- function resetQuery() {
- dateRange.value = []
- Object.assign(queryParams, {
- pageNum: 1,
- pageSize: 10,
- personId: null,
- personName: '',
- deptId: null,
- deptName: '',
- teamId: null,
- teamName: '',
- groupId: null,
- groupName: '',
- dimensionId: null,
- sourceType: '',
- org: '',
- scoreType: null,
- regionalId: null,
- channelId: null,
- postId: null
- })
- queryTeamOptions.value = []; queryGroupOptions.value = []; queryPersonOptions.value = []; channelOptions.value = []
- queryRef.value?.resetFields()
- handleQuery()
- }
- function handleSelectionChange(sel) { ids.value = sel.map(s => s.id); single.value = sel.length !== 1; multiple.value = !sel.length }
- function resetForm() {
- Object.assign(form, { id: null, dimensionId: null, dimensionName: '', indicatorId: null, level2Id: null, level2Name: '', level3Id: null, level3Name: '', level4Id: null, level4Name: '', eventTime: '', location: '', personId: null, deptName: '', deptId: null, teamId: null, groupId: null, scoreValue: 0, cascadeScore: 0, eventDesc: '', remark: '', org: '', regionalId: null, channelId: null, postId: null })
- level2Options.value = []; level3Options.value = []; level4Options.value = []
- teamOptions.value = []; groupOptions.value = []; personOptions.value = []; formChannelOptions.value = []
- }
- function handleAdd() { resetForm(); dialogTitle.value = '新增配分事项'; dialogVisible.value = true }
- async function handleUpdate(row) {
-
- dialogVisible.value = true
- resetForm()
- const record = row?.id ? row : list.value.find(r => r.id === ids.value[0])
- if (record) {
- Object.assign(form, record)
- const org = String(record.org)
- form.org = org
- // 加载区域和工作点
- if (record.regionalId) {
- await handleFormRegionalChange(record.regionalId)
- }
- // 加载队室/班组和通道/小组
- if (record.deptId) {
- // 先加载队室/班组
- const r = await deptTreeSelect({ parentId: record.deptId })
- teamOptions.value = r.data || []
- if (record.teamId) {
- // 再加载通道/小组
- const r2 = await deptTreeSelect({ parentId: record.teamId })
- groupOptions.value = r2.data || []
- // 最后加载责任人
- if (record.groupId) {
- const r3 = await listUser({ deptId: record.groupId })
- personOptions.value = r3.rows || []
- }
- }
- } else if (org === '2') {
- await loadAllTeams()
- } else if (org === '3') {
- await loadAllGroups()
- } else if (org === '4') {
- await loadAllPersons()
- }
- if (org === '1') {
- form.deptId = record.deptId || null
- } else if (org === '2') {
- form.teamId = record.teamId || null
- if (form.teamId) await handleDepartmentChange(form.teamId)
- } else if (org === '3') {
- form.groupId = record.groupId || null
- if (form.groupId) await handleGroupChange(form.groupId)
- } else if (org === '4') {
- form.personId = record.personId || null
- if (form.personId) await handlePersonChange(form.personId)
- }
- if (record.dimensionId) await onDimensionChange(record.dimensionId, true)
- if (record.level2Id) onLevel2Change(record.level2Id, true)
- if (record.level3Id) onLevel3Change(record.level3Id, true)
- if (record.level4Id) onLevel4Change(record.level4Id, true)
- }
-
- dialogTitle.value = '修改配分事项'
- }
- async function onDimensionChange(dimId, preserveSelection) {
- dialogLoading.value = true
- const dim = dimensionOptions.value.find(d => d.id === dimId)
- if (dim) form.dimensionName = dim.name
- const r = await treeIndicator({ dimensionId: dimId, org: form.org })
- indicatorTree.value = r.data || []
- level2Options.value = indicatorTree.value.filter(item => item.type !== '3').map(n => ({ name: n.name, id: n.id, scoreValue: n.scoreValue }))
- if (!preserveSelection) { form.level2Id = null; form.level2Name = ''; form.level3Id = null; form.level3Name = ''; form.level4Id = null; form.level4Name = ''; form.scoreValue = 0 }
- level3Options.value = []; level4Options.value = []
- if (preserveSelection && form.level2Id) onLevel2Change(form.level2Id, true)
- dialogLoading.value = false
- }
- function onLevel2Change(val, preserveSelection) {
- const node = indicatorTree.value.find(n => n.id === val)
- if (node) {
- form.level2Name = node.name
- if (node.scoreValue !== undefined) form.scoreValue = node.scoreValue
- }
- level3Options.value = node ? (node.children || []).map(n => ({ name: n.name, id: n.id, scoreValue: n.scoreValue })) : []
- if (!preserveSelection) { form.level3Id = null; form.level3Name = ''; form.level4Id = null; form.level4Name = ''; if (node && node.scoreValue === undefined) form.scoreValue = 0 }
- level4Options.value = []
- if (preserveSelection && form.level3Id) onLevel3Change(form.level3Id, true)
- }
- function onLevel3Change(val, preserveSelection) {
- const level2Node = indicatorTree.value.find(n => n.id === form.level2Id)
- const node = level2Node ? (level2Node.children || []).find(n => n.id === val) : null
- if (node) {
- form.level3Name = node.name
- if (node.scoreValue !== undefined) form.scoreValue = node.scoreValue
- }
- level4Options.value = node ? (node.children || []).map(n => ({ name: n.name, id: n.id, scoreValue: n.scoreValue })) : []
- if (!preserveSelection) { form.level4Id = null; form.level4Name = ''; if (node && node.scoreValue === undefined) form.scoreValue = 0 }
- }
- function onLevel4Change(val) {
- const level2Node = indicatorTree.value.find(n => n.id === form.level2Id)
- const level3Node = level2Node ? (level2Node.children || []).find(n => n.id === form.level3Id) : null
- const node = level3Node ? (level3Node.children || []).find(n => n.id === val) : null
- if (node) {
- form.level4Name = node.name
- if (node.scoreValue !== undefined) form.scoreValue = node.scoreValue
- }
- }
- // 递归查找树形结构中的节点
- const findTreeNode = (nodes, targetId, idKey, nameKey) => {
- for (const node of nodes) {
- if (node[idKey] === targetId) {
- return node
- }
- if (node.children) {
- const found = findTreeNode(node.children, targetId, idKey, nameKey)
- if (found) return found
- }
- }
- return null
- }
- async function submitForm() {
- await formRef.value.validate()
- let copyForm = { ...form }
- if (copyForm.personId) {
- const p = personOptions.value.find(p => p.userId === copyForm.personId)
- if (p) copyForm.personName = p.nickName
- }
- if (copyForm.deptId) {
- const d = deptOptions.value.find(d => d.deptId === copyForm.deptId)
- if (d) copyForm.deptName = d.deptName
- }
- if (copyForm.teamId) {
- const t = teamOptions.value.find(t => t.id === copyForm.teamId)
- if (t) copyForm.teamName = t.label
- }
- if (copyForm.groupId) {
- const g = groupOptions.value.find(g => g.id === copyForm.groupId)
- if (g) copyForm.groupName = g.label
- }
- if (copyForm.regionalId) {
- const r = regionalOptions.value.find(r => r.id === copyForm.regionalId)
- if (r) copyForm.regionalName = r.name
- }
- if (copyForm.channelId) {
- const c = formChannelOptions.value.find(c => c.id === copyForm.channelId)
- if (c) copyForm.channelName = c.name || c.positionName
- }
- if (copyForm.postId) {
- const postNode = findTreeNode(postTreeData.value, copyForm.postId, 'postId', 'postName')
- if (postNode) copyForm.postName = postNode.postName
- }
- if (form.id) { await updateScoreEvent(copyForm); ElMessage.success('修改成功') }
- else { await addScoreEvent(copyForm); ElMessage.success('新增成功') }
- dialogVisible.value = false; getList()
- }
- function handleDelete(row) {
- const delIds = row?.id ? [row.id] : ids.value
- ElMessageBox.confirm('确认删除选中的配分事项?', '提示', { type: 'warning' }).then(() => {
- delScoreEvent(delIds.join(',')).then(() => { ElMessage.success('删除成功'); getList() })
- })
- }
- function handleExport() {
- const p = { ...queryParams }
- if (dateRange.value?.length === 2) { p['params[beginTime]'] = dateRange.value[0]; p['params[endTime]'] = dateRange.value[1] }
- // exportScoreEvent(p)
- proxy.download('score/event/export', {
- ...p
- }, `配分事项_${new Date().getTime()}.xlsx`)
- }
- async function handleImportFile(file) {
- try {
- const r = await importScoreEvent(file.raw)
- ElMessage.success(r.msg || '导入成功')
- getList()
- } catch (e) {
- ElMessage.error('导入失败')
- }
- }
- const route = useRoute()
- let isInit = true
- // 监听路由参数,从员工画像跳转时回填查询条件
- watch(() => route.query, (query) => {
- if (query.id) {
- queryParams.personId = Number(query.id)
- }
- if (query.startDate && query.endDate) {
- dateRange.value = [query.startDate, query.endDate]
- }
- // 非初始化时(即路由参数后续变化),主动刷新数据
- if (!isInit && (query.id || query.startDate || query.endDate)) {
- handleQuery()
- }
- isInit = false
- }, { immediate: true })
- // 递归处理岗位树,禁用第一级
- const processPostTree = (nodes, isFirstLevel = true) => {
- return nodes.map(node => {
- const newNode = { ...node, disabled: isFirstLevel }
- if (node.children) {
- newNode.children = processPostTree(node.children, false)
- }
- return newNode
- })
- }
- // 监听通道/小组变化:无值时责任人显示全部人员
- watch(() => form.groupId, (newVal) => {
- if (!newVal) {
- personOptions.value = [...allPersonOptions.value]
- }
- })
- onMounted(() => {
- loadDimensions();
- loadDepts();
- loadQueryDepts();
- loadAllPersons();
- loadRegions();
- listAllTree().then(res => {
- postTreeData.value = processPostTree(res.data || [])
- });
- getList()
- })
- </script>
- <style scoped lang="less">
- /* Element Plus表格横向滚动配置 */
- .table-container :deep(.el-table) {
- width: 100%;
- min-width: 100%;
- }
- .table-container :deep(.el-table .el-table__header-wrapper),
- .table-container :deep(.el-table .el-table__body-wrapper) {
- overflow-x: auto !important;
- }
- </style>
|