123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722 |
- <template>
- <el-container style="height: 100%;">
- <el-main v-if="reviewInfo">
- <el-card style="height: 10%;margin-bottom: 20px;">
- <el-row type="flex" justify="space-between" align="center">
- <el-col>
- <WaStstistics
- title="考核表"
- :value="reviewInfo.title"
- />
- </el-col>
- <el-col>
- <WaStstistics
- title="周期种类"
- :value="cycleMap[reviewInfo.cycleType] || '--'"
- />
- </el-col>
- <el-col>
- <WaStstistics
- title="考核时间"
- :value="timeScope"
- />
- </el-col>
- <el-col>
- <WaStstistics
- title="考核状态"
- :value="statusMap[reviewInfo.status] || '--'"
- />
- </el-col>
- <el-col>
- <WaStstistics
- title="评分"
- :value="reviewInfo.score === null ? '--' : reviewInfo.score"
- />
- </el-col>
- <el-col>
- <WaStstistics
- title="考核中的指标"
- :value="reviewInfo.indicators.length > 0 ? (reviewInfo.indicators.length - indicatorEnd) : '--'"
- />
- </el-col>
- <el-col>
- <WaStstistics
- title="考核完成的指标"
- :value="indicatorEnd"
- />
- </el-col>
- <el-col
- v-if="reviewInfo.interviews && reviewInfo.interviews.length > 0"
- >
- <el-dropdown trigger="click">
- <el-button
- type="text"
- >
- 面谈记录
- </el-button>
- <el-dropdown-menu>
- <el-dropdown-item
- v-for="interview in reviewInfo.interviews"
- :key="interview.interviewId"
- >
- <span @click="openInterview(interview.interviewId)">
- {{ interview.createTime }}
- </span>
- </el-dropdown-item>
- </el-dropdown-menu>
- </el-dropdown>
- </el-col>
- </el-row>
- </el-card>
- <el-card style="height: calc(90% - 20px); position: relative; " >
- <Seal
- v-if="reviewInfo.levelName"
- :text="reviewInfo.levelName"
- :size="100"
- font-size="24px"
- :top="10"
- :left="20"
- :rotate="-30"
- :z-index="100"
- />
- <div class="flex-box-end" style="margin-bottom: 10px;">
- <el-switch
- v-model="showNode"
- active-text="显示考核节点"
- inactive-text="隐藏考核节点"
- />
- </div>
- <el-table
- :data="indicators"
- >
- <el-table-column
- prop="title"
- label="指标"
- fixed="left"
- show-overflow-tooltip
- align="center"
- />
- <el-table-column
- prop="content"
- label="规则"
- show-overflow-tooltip
- align="center"
- />
- <el-table-column
- prop="target"
- label="目标"
- align="center"
- >
- <template slot-scope="scope">
- {{ scope.row.target === null ? '--' : (scope.row.unit ? `${scope.row.target} ${scope.row.unit}` : scope.row.target) }}
- </template>
- </el-table-column>
- <el-table-column
- prop="result"
- label="结果"
- align="center"
- >
- <template slot-scope="scope">
- {{ scope.row.result === null ? '--' : (scope.row.unit ? `${scope.row.result} ${scope.row.unit}` : scope.row.result) }}
- </template>
- </el-table-column>
- <el-table-column
- prop="weight"
- label="权重"
- align="center"
- >
- <template slot-scope="scope">
- {{ scope.row.weight ? `${scope.row.weight} %` : '--' }}
- </template>
- </el-table-column>
- <el-table-column
- prop="businessStatus"
- label="考核状态"
- align="center"
- >
- <template slot-scope="scope">
- <el-link
- :type="scope.row.businessStatus === 'end' ? 'primary' : 'warning'"
- >
- {{ indicatorStatusMap[scope.row.businessStatus] || '--' }}
- </el-link>
- </template>
- </el-table-column>
- <el-table-column
- prop="score"
- label="得分"
- align="center"
- />
- <el-table-column
- v-if="showNode"
- prop="targetConfirms"
- label="目标确认"
- align="center"
- >
- <template slot-scope="scope">
- <el-link
- v-if="!scope.row.targetConfirms.enable"
- type="info"
- >
- 禁用
- </el-link>
- <el-link
- v-else-if="scope.row.targetConfirms.tasks.length <= 0"
- type="info"
- >
- 未开始
- </el-link>
- <template v-else >
- <div @click="openTasks(scope.row.targetConfirms.tasks,'目标确认任务',scope.row.unit)">
- <el-link
- v-if="scope.row.targetConfirms.finishCount > 0"
- type="primary"
- style="margin-right: 5px;"
- icon="el-icon-check"
- >
- {{ scope.row.targetConfirms.finishCount }}
- </el-link>
- <el-link
- v-if="scope.row.targetConfirms.runningCount > 0"
- type="warning"
- icon="el-icon-warning"
- >
- {{ scope.row.targetConfirms.runningCount }}
- </el-link>
- </div>
- </template>
- </template>
- </el-table-column>
- <el-table-column
- v-if="showNode"
- prop="resultInput"
- label="结果录入"
- >
- <template slot-scope="scope">
- <el-link
- v-if="!scope.row.resultInput.enable"
- type="info"
- >
- 禁用
- </el-link>
- <el-link
- v-else-if="scope.row.resultInput.tasks.length <= 0"
- type="info"
- >
- 未开始
- </el-link>
- <template v-else >
- <div @click="openTasks(scope.row.resultInput.tasks,'结果录入任务',scope.row.unit)">
- <el-link
- v-if="scope.row.resultInput.finishCount > 0"
- type="primary"
- style="margin-right: 5px;"
- icon="el-icon-check"
- >
- {{ scope.row.resultInput.finishCount }}
- </el-link>
- <el-link
- v-if="scope.row.resultInput.runningCount > 0"
- type="warning"
- icon="el-icon-warning"
- >
- {{ scope.row.resultInput.runningCount }}
- </el-link>
- </div>
- </template>
- </template>
- </el-table-column>
- <el-table-column
- v-if="showNode"
- prop="scoreSelf"
- label="自评"
- >
- <template slot-scope="scope">
- <el-link
- v-if="!scope.row.scoreSelf.enable"
- type="info"
- >
- 禁用
- </el-link>
- <el-link
- v-else-if="scope.row.scoreSelf.tasks.length <= 0"
- type="info"
- >
- 未开始
- </el-link>
- <template v-else >
- <div @click="openTasks(scope.row.scoreSelf.tasks,'自评任务',scope.row.unit)">
- <el-link
- v-if="scope.row.scoreSelf.finishCount > 0"
- type="primary"
- style="margin-right: 5px;"
- icon="el-icon-check"
- >
- {{ scope.row.scoreSelf.finishCount }}
- </el-link>
- <el-link
- v-if="scope.row.scoreSelf.runningCount > 0"
- type="warning"
- icon="el-icon-warning"
- >
- {{ scope.row.scoreSelf.runningCount }}
- </el-link>
- </div>
- </template>
- </template>
- </el-table-column>
- <el-table-column
- v-if="showNode"
- prop="scoreEachOther"
- label="互评"
- >
- <template slot-scope="scope">
- <el-link
- v-if="!scope.row.scoreEachOther.enable"
- type="info"
- >
- 禁用
- </el-link>
- <el-link
- v-else-if="scope.row.scoreEachOther.tasks.length <= 0"
- type="info"
- >
- 未开始
- </el-link>
- <template v-else >
- <div @click="openTasks(scope.row.scoreEachOther.tasks,'互评任务',scope.row.unit)">
- <el-link
- v-if="scope.row.scoreEachOther.finishCount > 0"
- type="primary"
- style="margin-right: 5px;"
- icon="el-icon-check"
- >
- {{ scope.row.scoreEachOther.finishCount }}
- </el-link>
- <el-link
- v-if="scope.row.scoreEachOther.runningCount > 0"
- type="warning"
- icon="el-icon-warning"
- >
- {{ scope.row.scoreEachOther.runningCount }}
- </el-link>
- </div>
- </template>
- </template>
- </el-table-column>
- <el-table-column
- v-if="showNode"
- prop="scores"
- label="评分"
- >
- <template slot-scope="scope">
- <el-link
- v-if="!scope.row.scores.enable"
- type="info"
- >
- 禁用
- </el-link>
- <el-link
- v-else-if="scope.row.scores.tasks.length <= 0"
- type="info"
- >
- 未开始
- </el-link>
- <template v-else >
- <div @click="openTasks(scope.row.scores.tasks,'评分任务',scope.row.unit)">
- <el-link
- v-if="scope.row.scores.finishCount > 0"
- type="primary"
- style="margin-right: 5px;"
- icon="el-icon-check"
- >
- {{ scope.row.scores.finishCount }}
- </el-link>
- <el-link
- v-if="scope.row.scores.runningCount > 0"
- type="warning"
- icon="el-icon-warning"
- >
- {{ scope.row.scores.runningCount }}
- </el-link>
- </div>
- </template>
- </template>
- </el-table-column>
- <el-table-column
- v-if="showNode"
- prop="reviews"
- label="审批"
- >
- <template slot-scope="scope">
- <el-link
- v-if="!scope.row.reviews.enable"
- type="info"
- >
- 禁用
- </el-link>
- <el-link
- v-else-if="scope.row.reviews.tasks.length <= 0"
- type="info"
- >
- 未开始
- </el-link>
- <template v-else >
- <div @click="openTasks(scope.row.reviews.tasks,'审批任务',scope.row.unit)">
- <el-link
- v-if="scope.row.reviews.finishCount > 0"
- type="primary"
- style="margin-right: 5px;"
- icon="el-icon-check"
- >
- {{ scope.row.reviews.finishCount }}
- </el-link>
- <el-link
- v-if="scope.row.reviews.runningCount > 0"
- type="warning"
- icon="el-icon-warning"
- >
- {{ scope.row.reviews.runningCount }}
- </el-link>
- </div>
- </template>
- </template>
- </el-table-column>
- </el-table>
- </el-card>
- </el-main>
- <el-dialog
- v-if="tasksInfo.title"
- :visible.sync="showTasks"
- :title="tasksInfo.title"
- center
- append-to-body
- >
- <div style="max-height: 600px; overflow-y: auto;">
- <el-card
- v-if="tasksInfo.tasks"
- v-for="task in tasksInfo.tasks"
- :key="task.taskId"
- style="margin-bottom: 20px;"
- >
- <el-descriptions
- border
- :column="3"
- :title="task.assigneeName"
- size="mini"
- direction="vertical"
- >
- <el-descriptions-item label="任务状态">{{ task.state === 'completed' ? '已处理' : '待处理' }}</el-descriptions-item>
- <el-descriptions-item
- v-if="task.score !== null"
- label="评分"
- >
- {{ task.score }}
- </el-descriptions-item>
- <el-descriptions-item
- v-if="task.result !== null"
- label="结果"
- >
- {{ tasksInfo.unit ? `${task.result} ${tasksInfo.unit}` : task.result }}
- </el-descriptions-item>
- <el-descriptions-item
- label="评论"
- >
- {{ task.comment }}
- </el-descriptions-item>
- </el-descriptions>
- </el-card>
- </div>
- </el-dialog>
- </el-container>
- </template>
- <script>
- import WaStstistics from "./tool/WaStstistics.vue";
- import moment from "moment";
- import Template from "../../examine/components/Template.vue";
- import Seal from "./tool/Seal.vue";
- import PerInterview from "./PerInterview.vue";
- export default {
- name: "PerReviewDetail",
- components: {PerInterview, Seal, Template, WaStstistics},
- props: {
- reviewId:{
- type: Number,
- required: true
- }
- },
- data(){
- return {
- userInfo:this.$userInfo(),
- loading:false,
- reviewInfo:null,
- cycleMap:{
- 0:'未定义',
- 1:'年度',
- 2:'半年度',
- 3:'季度',
- 4:'月度',
- },
- statusMap:{
- 0:'考核中',
- 1:'已结束',
- 2:'面谈',
- },
- indicatorStatusMap:{
- start:'进入考核',
- target_confirm:'目标确认中',
- result_input:'结果录入中',
- score_self:'自评中',
- score_each_other:'互评中',
- score:'评分中',
- review:'审批中',
- cc:'抄送',
- end:'已结束',
- },
- showNode:false,
- showTasks:false,
- tasks:[],
- tasksInfo:{
- title:'',
- unit:'',
- tasks:[]
- },
- }
- },
- computed:{
- timeScope(){
- if (!this.reviewInfo || !this.reviewInfo.startTime || !this.reviewInfo.endTime) return '--';
- return moment(this.reviewInfo.startTime).format('YY/MM/DD') + ' ~ ' + moment(this.reviewInfo.endTime).format('YY/MM/DD');
- },
- indicatorEnd(){
- if (!this.reviewInfo || this.reviewInfo.indicators.length <= 0) return '--';
- return this.reviewInfo.indicators.filter(indicator => indicator.businessStatus === 'end').length;
- },
- indicators(){
- return !this.reviewInfo ? [] : this.reviewInfo.indicators.map(item => {
- const indicator = {
- reviewIndicatorId:item.reviewIndicatorId,
- reviewTitle:item.reviewTitle,
- title:item.title,
- content:item.content,
- target:item.target,
- result:item.result,
- score:item.score,
- unit:item.unit,
- weight:item.weight,
- businessStatus:item.businessStatus,
- targetConfirms:null,
- resultInput:null,
- scoreSelf:null,
- scoreEachOther:null,
- scores:null,
- reviews:null,
- cc:null,
- };
- item.flow.nodes.forEach(node => {
- switch (node.type){
- case 'targetConfirms':
- const targetConfirms = {
- enable:node.enable,
- tasks:[],
- runningCount:0,
- finishCount:0,
- }
- if (node.children && node.children.length > 0){
- node.children.forEach(child => {
- if (child.tasks && child.tasks.length > 0) {
- child.tasks.forEach(task => {
- targetConfirms.tasks.push(task);
- if (task.state === 'completed'){
- targetConfirms.finishCount ++;
- }else {
- targetConfirms.runningCount ++;
- }
- })
- }
- })
- }
- indicator.targetConfirms = targetConfirms;
- break;
- case 'resultInput':
- const resultInput = {
- enable:node.enable,
- tasks:[],
- runningCount:0,
- finishCount:0,
- }
- if (node.tasks && node.tasks.length > 0){
- node.tasks.forEach(task => {
- resultInput.tasks.push(task);
- if (task.state === 'completed'){
- resultInput.finishCount ++;
- }else {
- resultInput.runningCount ++;
- }
- })
- }
- indicator.resultInput = resultInput;
- break;
- case 'scoreSelf':
- const scoreSelf = {
- enable:node.enable,
- tasks:[],
- runningCount:0,
- finishCount:0,
- }
- if (node.tasks && node.tasks.length > 0){
- node.tasks.forEach(task => {
- scoreSelf.tasks.push(task);
- if (task.state === 'completed'){
- scoreSelf.finishCount ++;
- }else {
- scoreSelf.runningCount ++;
- }
- })
- }
- indicator.scoreSelf = scoreSelf;
- break;
- case 'scoreEachOther':
- const scoreEachOther = {
- enable:node.enable,
- tasks:[],
- runningCount:0,
- finishCount:0,
- }
- if (node.tasks && node.tasks.length > 0){
- node.tasks.forEach(task => {
- scoreEachOther.tasks.push(task);
- if (task.state === 'completed'){
- scoreEachOther.finishCount ++;
- }else {
- scoreEachOther.runningCount ++;
- }
- })
- }
- indicator.scoreEachOther = scoreEachOther;
- break;
- case 'scores':
- const scores = {
- enable:node.enable,
- tasks:[],
- runningCount:0,
- finishCount:0,
- }
- if (node.children && node.children.length > 0){
- node.children.forEach(child => {
- if (child.tasks && child.tasks.length > 0) {
- child.tasks.forEach(task => {
- scores.tasks.push(task);
- if (task.state === 'completed'){
- scores.finishCount ++;
- }else {
- scores.runningCount ++;
- }
- })
- }
- })
- }
- indicator.scores = scores;
- break;
- case 'reviews':
- const reviews = {
- enable:node.enable,
- tasks:[],
- runningCount:0,
- finishCount:0,
- }
- if (node.children && node.children.length > 0){
- node.children.forEach(child => {
- if (child.tasks && child.tasks.length > 0) {
- child.tasks.forEach(task => {
- reviews.tasks.push(task);
- if (task.state === 'completed'){
- reviews.finishCount ++;
- }else {
- reviews.runningCount ++;
- }
- })
- }
- })
- }
- indicator.reviews = reviews;
- break;
- case 'cc':
- const cc = {
- enable:node.enable,
- tasks:[],
- runningCount:0,
- finishCount:0,
- }
- indicator.cc = cc;
- break;
- }
- });
- return indicator;
- });
- }
- },
- watch:{
- reviewId(v){
- if (v) this.initData();
- }
- },
- methods:{
- initData(){
- if (this.loading || !this.reviewId) return;
- this.loading = true;
- this.showNode = false;
- this.reviewInfo = null;
- Promise.all([
- this.$axiosUser('get',`/performance/statistics/review/info/${this.userInfo.site_id}/${this.reviewId}`)
- ])
- .then(([reviewRes]) =>{
- if (reviewRes.data.code !== 1) throw new Error(reviewRes.data.message);
- this.reviewInfo = reviewRes.data.data || null;
- })
- .catch(err => {
- console.warn(err);
- })
- .finally(() => {
- this.loading = false;
- })
- },
- openTasks(tasks,title,unit){
- if (!tasks || tasks.length <= 0) return;
- this.tasksInfo.tasks = tasks;
- this.tasksInfo.title = title || '任务信息';
- this.tasksInfo.unit = unit || '';
- this.showTasks = true;
- },
- openInterview(interviewId){
- if (!interviewId || !this.reviewInfo) return;
- window.open(`#/per/interview/${this.reviewId}/${interviewId}`);
- },
- },
- mounted() {
- this.initData();
- }
- }
- </script>
- <style scoped lang="scss">
- </style>
|