123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855 |
- <template>
- <div class="record-container">
- <div class="main-content">
- <div class="search-box">
- <div class="flex-box-ce">
- <el-select style="width: 120px;" v-model="params.cycleType" placeholder="请选择周期种类"
- @change="changeCycleType">
- <el-option v-for="item in cycleOptions" :key="item.id" :label="item.name" :value="item.id">
- </el-option>
- </el-select>
- <el-date-picker class="cursor" style="width: 150px; margin-left: 10px;" v-model="params.year"
- type="year" placeholder="选择年" value-format="yyyy" @change="changeYear">
- </el-date-picker>
- <el-date-picker class="cursor" v-if="params.cycleType == '0'"
- style="width: 300px; margin-left: 10px;" v-model="dateRange" type="daterange"
- range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" format="yyyy-MM-dd"
- value-format="yyyy-MM-dd"></el-date-picker>
- <el-select class="cursor" v-if="params.cycleType == '2'" style="width: 150px; margin-left: 10px;"
- v-model="cycleValue" placeholder="请选择半年度" @change="changeCycleValue">
- <el-option label="上半年" value="1">
- </el-option>
- <el-option label="下半年" value="2">
- </el-option>
- </el-select>
- <el-select class="cursor" v-if="params.cycleType == '3'" style="width: 150px; margin-left: 10px;"
- v-model="cycleValue" placeholder="请选择季度" @change="changeCycleValue">
- <el-option label="第一季度" value="1">
- </el-option>
- <el-option label="第二季度" value="2">
- </el-option>
- <el-option label="第三季度" value="3">
- </el-option>
- <el-option label="第四季度" value="4">
- </el-option>
- </el-select>
- <el-select class="cursor" v-if="params.cycleType == '4'" style="width: 150px; margin-left: 10px;"
- v-model="cycleValue" placeholder="请选择月度" @change="changeCycleValue">
- <el-option label="一月" value="1">
- </el-option>
- <el-option label="二月" value="2">
- </el-option>
- <el-option label="三月" value="3">
- </el-option>
- <el-option label="四月" value="4">
- </el-option>
- <el-option label="五月" value="5">
- </el-option>
- <el-option label="六月" value="6">
- </el-option>
- <el-option label="七月" value="7">
- </el-option>
- <el-option label="八月" value="8">
- </el-option>
- <el-option label="九月" value="9">
- </el-option>
- <el-option label="十月" value="10">
- </el-option>
- <el-option label="十一月" value="11">
- </el-option>
- <el-option label="十二月" value="12">
- </el-option>
- </el-select>
- <div class="dept_wdiv flex-box-ce" style="margin: 0 0 0 10px;">
- <div class="dept_inp" @click="show_dept_selector = true">
- <span v-if="deptVisibleName != ''">{{ deptVisibleName }}</span>
- <span v-else style="color: #b9b9b9;">选择部门</span>
- </div>
- <i class="el-icon-arrow-down"></i>
- </div>
- <el-select class="cursor" style="width: 260px; margin-left: 10px;" v-model="selectEmployeeId"
- filterable clearable multiple placeholder="员工姓名搜索" @change="changeEmployeeIds">
- <el-option v-for="item in employees" :key="item.id" :label="item.name"
- :value="item.id"></el-option>
- </el-select>
- </div>
- <el-button type="primary" @click="exportToExcel('过程分析', '#myTable')" size="small"
- :loading="downloadLoading">导出明细</el-button>
- </div>
- <!-- 水平线 -->
- <div class="line"></div>
- <div class="flex-box-ce flex-d-wrap"
- style="justify-content: center; padding: 20px 0; box-sizing: border-box;">
- <div v-for="(item, index) in generalizeList" :key="index" @click="chooseExamineStatus(item.name)"
- class="generalize-item">
- <div class=" fontColorC">{{ item.name }}</div>
- <div style="font-size: 36px; font-weight: 600;margin: 5px 0;">{{ item.val }}</div>
- <div style="width: 60px;height: 2px;" :style="{ backgroundColor: item.color }"></div>
- </div>
- <div v-for="(item, index) in gradeLevels" @click="chooseExamineLevel(item.name)" :key="item.name"
- class="generalize-item">
- <div class="fontColorC">{{ item.name }}</div>
- <div style="font-size: 36px; font-weight: 600;margin: 5px 0;">
- {{tableData.filter(user => user.levelName === item.name).length}}
- </div>
- <div style="width: 60px;height: 2px;" :style="{ backgroundColor: item.color }"></div>
- </div>
- </div>
- <div class="table-box">
- <el-table id="myTable" :data="filteredData" style="width: 100%; height: auto;"
- :header-cell-style="{ background: '#f5f7fa' }" border stripe>
- <el-table-column prop="date" label="考核时间" align="center"></el-table-column>
- <el-table-column prop="employeeName" label="员工姓名" align="center"></el-table-column>
- <el-table-column prop="department" label="部门" width="300" align="center">
- <template slot-scope="scope">
- {{ scope.row.department | formatDeptName }}
- </template>
- </el-table-column>
- <el-table-column prop="status" label="考核状态" align="center">
- <template slot-scope="scope">
- <el-tag v-if="scope.row.status" type="success">
- 已完成
- </el-tag>
- <el-tag v-else="scope.row.status" type="warning">
- 进行中
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column prop="score" label="评分" align="center">
- <template slot-scope="scope">
- <el-tag v-if="!scope.row.score" type="info">
- 未评分
- </el-tag>
- <el-tag v-else>
- {{ scope.row.score }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column prop="levelName" label="等级" align="center">
- <template slot-scope="scope">
- <el-tag type="info">
- {{ scope.row.levelName || '--' }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column label="操作" align="center">
- <template slot-scope="scope">
- <el-button type="text" @click="getTemplateDetails(scope.row)">查看明细</el-button>
- </template>
- </el-table-column>
- </el-table>
- <div style="height: 50px;"></div>
- </div>
- </div>
- <!-- 关联okr -->
- <TargetListComp v-if="targetDialogVisible" :dialogVisible="targetDialogVisible" :ids="okrs"
- @close="closeTargetList">
- </TargetListComp>
- <!-- 部门选择 -->
- <EmployeeSelector :title="'选择部门'" :isChecKedAll="false" :can_select_employee="false" :can_select_dept="true"
- :dept_children="false" :selected="dept_selected" :visible.sync="show_dept_selector"
- @confirm="dept_confirm" />
- <el-dialog title="员工绩效详情" :visible.sync="detailDialogVisible" @close="handleClose" :close-on-click-modal="false"
- :close-on-press-escape="true" center fullscreen :show-close="false">
- <div style=" width: 100%; height: 100%; position: relative;">
- <el-button round style="position: absolute; top: -65px; left: 0px; z-index: 99;"
- @click="detailDialogVisible = false">返回</el-button>
- <!-- 我的考核 -->
- <MyPerformance v-if="detailDialogVisible" :reviewId="reviewId" :sendEmployeeId='sendEmployeeId' />
- </div>
- </el-dialog>
- </div>
- </template>
- <script>
- let that;
- import { mapGetters } from 'vuex';
- import moment from 'moment';
- import TargetListComp from "@/performance/views/assessManagement/TargetListComp.vue"; // 关联OKR弹框
- import EmployeeSelector from '@/components/EmployeeSelector'; // 部门选择
- import MyPerformance from './MyPerformance'; // 我的考核
- import XLSX from 'xlsx';
- import FileSaver from 'file-saver';
- export default {
- components: {
- TargetListComp,
- EmployeeSelector,
- MyPerformance
- },
- data() {
- return {
- employees: this.$getEmployeeMap(), // 员工列表
- isLeftShow: true,
- isRightShow: false,
- employeeName: '',
- targetDialogVisible: false,
- total: 0,
- loading: false,
- checked: [],
- status: -1,
- cycleValue: '1',
- downloadLoading: false,
- show_dept_selector: false,
- deptVisibleName: '',
- dept_selected: { dept: [], employee: [] },
- cycleOptions: [
- { name: "月度", id: '4' },
- { name: "季度", id: '3' },
- { name: "半年度", id: '2' },
- { name: "年度", id: '1' },
- { name: "未定义", id: '0' },
- ],
- options: [
- {
- value: -1,
- label: '全部'
- }, {
- value: '0',
- label: '未完成'
- }, {
- value: '1',
- label: '已完成'
- }
- ],
- reviewId: "",
- sendEmployeeId: "",
- reviewPackageId: 0,
- selectedReviewPackageId: '',
- cateIds: [],
- scoreList: [],
- distributionId: '',
- gradeLevels: [],
- infos: [],
- generalizeList: [
- { name: '考核人数', val: 0, color: '#FF9600' },
- { name: '已结束', val: 0, color: '#409EFF' },
- { name: '进行中', val: 0, color: '#67c23a' },
- { name: '面谈中', val: 0, color: '#f56c6c' },
- // { name: '已取消', val: 0, color: '#5F7294' },
- // { name: '未开始', val: 0, color: '#08EEA1' },
- // { name: '暂停中', val: 0, color: '#f56c6c' }
- ],
- treeData: [],
- singleSelection: true, // 是否单选
- checkedKeys: [],
- defaultProps: {
- children: 'children',
- label: 'label'
- },
- dept_select_id: '',
- keyword: '',
- deptList: [], // 部门列表 - 树形结构
- dept_list: [], // 部门列表
- employeeMap: this.$getEmployeeMap(), // 员工列表
- loading: false,
- total: 0,
- tableData: [],
- filteredData: [],
- selectEmployeeId: [],
- // 周期类型 0-未定义 1-年度 2-半年度 3-季度 4-月度
- params: {
- cycleType: "4",
- startDate: '',
- endDate: '',
- deptIds: '',
- year: ''
- },
- status: '',
- level: '',
- dialogVisible: false,
- organSelectDialog: false,
- gradeLevels: [],
- examineStatus: [
- { label: "考核中", value: "0" },
- { label: "已结束", value: "1" },
- { label: "面谈", value: "2" }
- ],
- userInfo: null,
- isContentLeft: true,
- isContentRight: true,
- chooseUserIds: [],
- employeeName: '',
- isFold: false,
- dateRange: this.getMonthFirstAndLastDay(), // 设置默认值
- detailDialogVisible: false,
- pickerOptions: {
- shortcuts: [{
- text: '最近一周',
- onClick(picker) {
- const end = new Date();
- const start = new Date();
- start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
- picker.$emit('pick', [start, end]);
- }
- }, {
- text: '最近一个月',
- onClick(picker) {
- const end = new Date();
- const start = new Date();
- start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
- picker.$emit('pick', [start, end]);
- }
- }, {
- text: '最近三个月',
- onClick(picker) {
- const end = new Date();
- const start = new Date();
- start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
- picker.$emit('pick', [start, end]);
- }
- }]
- },
- }
- },
- watch: {
- dateRange(v) {
- console.log(v);
- }
- },
- async created() {
- that = this;
- await this.getAllSet();
- this.getDefaultTime();
- },
- //
- computed: {
- ...mapGetters(['user_info']),
- },
- filters: {
- formatDate(val) {
- if (val) return moment(val).format('YYYY-MM-DD')
- else return "--"
- },
- filterProgress(list) {
- if (list && list.length > 0) {
- let sum = 0;
- list.forEach(item => {
- if (item.status == 1) sum += 1 // 完成的个数
- })
- return Number(sum / list.length) * 100
- }
- },
- formatDeptName(val) {
- let str = '';
- if (val && val.length > 0) {
- val.forEach(dept => {
- str += dept.dept_name + ","
- })
- str = str.substr(0, str.length - 1)
- } else {
- str = "--"
- }
- return str
- }
- },
- methods: {
- getMonthFirstAndLastDay() {
- const today = new Date();
- const year = today.getFullYear();
- const month = today.getMonth(); // 月份从 0 开始,需要加 1
- // 获取当月第一天
- const firstDay = new Date(year, month, 1);
- const firstDayStr = this.formatDate(firstDay);
- // 获取当月最后一天
- const lastDay = new Date(year, month + 1, 0); // 下个月的第 0 天是当前月的最后一天
- const lastDayStr = this.formatDate(lastDay);
- // console.log(firstDayStr)
- // console.log(lastDayStr)
-
- return [firstDayStr, lastDayStr];
- },
- formatDate(date) {
- const year = date.getFullYear();
- const month = String(date.getMonth() + 1).padStart(2, '0');
- const day = String(date.getDate()).padStart(2, '0');
- return `${year}-${month}-${day}`;
- },
- // 周期筛选
- changeCycleType(v) {
- if (v !== '0') {
- this.params.startDate = ''
- this.params.endDate = ''
- } else if (v == 1) {
- // console.log("-----------", 'cycleValue' in this.params)
- this.params.year = this.currentYear
- this.cycleValue = ''
- if ('cycleValue' in this.params) delete this.params.cycleValue
- } else if (v == 2) {
- this.params.year = this.currentYear
- this.params = { ...this.params, cycleValue: this.cycleValue }
- } else if (v == 3) {
- this.params.year = this.currentYear
- this.params = { ...this.params, cycleValue: this.cycleValue }
- } else if (v == 4) {
- this.params.year = this.currentYear
- this.params = { ...this.params, cycleValue: this.cycleValue }
- }
- this.getRecords();
- },
- // 周期筛选
- changeDate(v) {
- if (v && v.length > 0) {
- this.dateRange[0] = v[0]
- this.dateRange[1] = v[1]
- this.params.startDate = v[0]
- this.params.endDate = v[1]
- this.getRecords();
- }
- },
- changeYear(v) {
- this.params.year = v;
- this.params.startDate = ''
- this.params.endDate = ''
- this.getRecords();
- },
- changeCycleValue(v) {
- this.params = { ...this.params, cycleValue: this.cycleValue }
- this.getRecords();
- },
- dept_confirm(data) {
- //部门选择
- this.dept_selected = { dept: [], employee: [] };
- this.deptVisibleName = '';
- let deptList_id = [];
- if (data.dept !== null && data.dept.length != 0) {
- this.dept_selected = data;
- data.dept.forEach((element, index) => {
- deptList_id.push(element.dept_id);
- this.deptVisibleName += element.dept_name;
- if (data.dept.length - index > 1) {
- this.deptVisibleName += ',';
- }
- });
- }
- this.params.deptIds = deptList_id.toString()
- this.getRecords();
- },
- // 员工筛选
- changeEmployeeIds(v) {
- this.selectEmployeeId = v
- this.applyFilters();
- },
- // 考核状态筛选
- chooseExamineStatus(name) {
- this.status = name
- this.applyFilters();
- },
- // 考核等级筛选
- chooseExamineLevel(name) {
- this.level = name
- this.applyFilters();
- },
- // 应用筛选条件
- applyFilters() {
- this.filteredData = this.tableData.filter((item) => {
- const employeeMatch = this.selectEmployeeId.length === 0 || this.selectEmployeeId.includes(item.employeeId);
- // let statusMatch = true;
- // if (this.status == '考核人数') statusMatch = true
- // if (this.status == '进行中') statusMatch = item.status == 0
- // if (this.status == '已结束') statusMatch = item.status == 1
- // if (this.status == '面谈中') statusMatch = item.status == 2
- // let levelMatch = !this.level || this.level && item.levelName == this.level
- // console.log(levelMatch)
- return employeeMatch
- // return employeeMatch && statusMatch && levelMatch;
- });
- },
-
- // 时间格式化
- formatDate(val) {
- if (val) return moment(val).format('YYYY-MM-DD')
- else return "--"
- },
- // 隐藏部门菜单
- toggle() {
- this.isFold = !this.isFold
- },
- // 还原部门菜单
- back() {
- this.isLeftShow = true;
- this.isRightShow = false;
- },
- filterNode(value, data) {
- if (!value) return true;
- return data.label.indexOf(value) !== -1;
- },
- handleNodeClick(node) {
- this.dept_select_id = node.id
-
- },
-
- getTemplateDetails(row) {
- this.reviewId = row.reviewId
- this.sendEmployeeId = row.employeeId
- this.detailDialogVisible = true
- // this.$emit('changeCurrentId', { currentId: '2', reviewId })
- },
- // 获取当前时间
- getDefaultTime() {
- const date = new Date();
- this.currentYear = date.getFullYear()
- this.currentMonth = date.getMonth() + 1; // 注意月份从0开始,所以需要加1
- const now = new Date(); // 获取当前时间
- let startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1, 0, 0, 0); // 当前月的第一天
- let endOfMonth = new Date(startOfMonth.getFullYear(), startOfMonth.getMonth() + 1, 0, 23, 59, 59); // 下个月的第一天的前一天,时间设置为 23:59:59
- startOfMonth = this.$moment(startOfMonth).format('YYYY-MM-DD')
- endOfMonth = this.$moment(endOfMonth).format('YYYY-MM-DD')
- // console.log(startOfMonth); // 输出当前月的结束时间
- // console.log(endOfMonth); // 输出当前月的结束时间
- this.params.startDate = startOfMonth
- this.params.endDate = endOfMonth
- this.params.year = this.currentYear + ''
- this.cycleValue = this.currentMonth + ''
- // console.log("当前月" + this.cycleValue);
- this.params = { ...this.params, cycleValue: this.cycleValue }
- this.getRecords();
- },
-
-
- // 获取表格数据
- getRecords() {
- this.loading = true
- this.filteredData = []
- this.tableData = []
- let url = `/performance/statistics/reviews/${this.user_info.site_id}`
- this.$axiosUser("get", url, this.params).then(res => {
- this.tableData = res.data.data.list;
- this.filteredData = this.tableData
- this.filteredData.forEach(item => {
- item.date = this.formatDate(item.startTime) + "至" + this.formatDate(item.endTime)
- })
- let deptMap = JSON.parse(localStorage.getItem("SET_EMPLOYEE_MAP"));
- if (Object.keys(deptMap) && Object.keys(deptMap).length > 0) {
- this.filteredData.forEach(item => {
- const employeeDetails = deptMap[item.employeeId];
- if (employeeDetails) {
- item.department = employeeDetails.employee_detail.dept_list;
- }
- })
- }
-
- this.generalizeList[0].val = this.tableData.length // 总人数
- this.generalizeList[1].val = this.tableData.filter(item => item.status == 1).length // 已结束人数
- this.generalizeList[2].val = this.tableData.filter(item => item.status == 0).length // 进行中人数
- this.generalizeList[3].val = this.tableData.filter(item => item.status == 2).length // 面谈中人数
- this.applyFilters();
- this.loading = false;
- })
- },
-
- // 获取全局等级设置
- async getAllSet() {
- let res = await this.$axiosUser('get', 'api/pro/per/user/base_config')
- let data = res.data.data;
- let levels = data.level_scope.levels;
- let gradeLevels = [];
- let max = 0;//最大值
- let colorList = ['#5F7294', '#08EEA1', '#f56c6c', '#0887EE', '#92EE08', '#f56c6c']
- if (levels && levels.length > 0) {
- levels.forEach((item, index) => {
- var obj;
- if (index == 0) {
- obj = { name: item.name, max: Number(item.value), min: 0 };
- } else {
- obj = { name: item.name, max: Number(item.value), min: max };//当不是第一个等级时,最小值为上一个的最大值
- }
- obj.color = colorList[index]
- max = item.value;
-
- gradeLevels.push(obj);
- })
- this.gradeLevels = gradeLevels
- }
- },
-
- // 查找分数对应的等级
- findGrade(score, gradeLevels) {
- for (let i = 0; i < gradeLevels.length; i++) {
- if (score && score >= gradeLevels[i].min && score && score <= gradeLevels[i].max) {
- return gradeLevels[i].name; // 返回对应的等级描述
- } else if (score && score <= gradeLevels[0].min) {
- return gradeLevels[0].name; // 返回对应的等级描述
- } else if (score && score >= gradeLevels[gradeLevels.length - 1].max) {
- return gradeLevels[gradeLevels.length - 1].name; // 返回对应的等级描述
- }
- }
- return "未评分"; // 如果分数不在任何范围内
- },
- assignLevels(scores, levelConfigs) {
- // 降序排序并去重(假设分数不重复,可省略去重)
- const sortedScores = [...scores].sort((a, b) => b - a);
- const total = sortedScores.length;
- if (total === 0) return [];
- // 归一化处理比例
- const totalRatio = levelConfigs.reduce((sum, cfg) => sum + cfg.ratio, 0);
- const normalized = levelConfigs.map(cfg => cfg.ratio / totalRatio);
- // 计算每个等级的初始人数
- let counts = normalized.map(ratio => Math.floor(total * ratio));
- let remainder = total - counts.reduce((sum, c) => sum + c, 0);
- // 分配剩余人数,按优先级顺序
- let idx = 0;
- while (remainder > 0 && idx < counts.length) {
- counts[idx]++;
- remainder--;
- idx++;
- }
- // 构建结果:按人数切割数组
- let start = 0;
- return counts.map((count, i) => {
- const end = start + count;
- const levelScores = sortedScores.slice(start, end);
- start = end;
- return {
- level: levelConfigs[i].level,
- scores: levelScores
- };
- });
- },
- // 导出表格
- exportToExcel(tableName, elementName) {
- if(!(this.filteredData && this.filteredData.length > 0)) return
- this.downloadLoading = true;
- // 如果未传入文件名,则使用当前时间戳
- if (!tableName) {
- tableName = new Date().getTime();
- }
- // 克隆表格 DOM,避免影响原表格
- const tableDom = document.querySelector(elementName).cloneNode(true);
- const tableHeader = tableDom.querySelector('.el-table__header-wrapper');
- const tableBody = tableDom.querySelector('.el-table__body');
- tableHeader.childNodes[0].append(tableBody.childNodes[1]);
- // 获取表头 DOM
- const headerDom = tableHeader.childNodes[0].querySelectorAll('th');
- // 移除复选框列
- if (headerDom[0].querySelector('.el-checkbox')) {
- headerDom[0].remove();
- }
- // 移除操作列
- for (let key in headerDom) {
- if (headerDom[key].innerText === '操作') {
- headerDom[key].remove();
- }
- }
- // 清理表格中的复选框和按钮
- const tableList = tableHeader.childNodes[0].childNodes[2].querySelectorAll('td');
- for (let key = 0; key < tableList.length; key++) {
- if (tableList[key].querySelector('.el-checkbox') || tableList[key].querySelector('.el-button')) {
- tableList[key].remove();
- }
- }
- // 使用 XLSX 将 DOM 转换为 Excel 文件
- const webBook = XLSX.utils.table_to_book(tableHeader);
- const webOut = XLSX.write(webBook, { bookType: 'xlsx', bookSST: true, type: 'array' });
- try {
- FileSaver.saveAs(new Blob([webOut], { type: 'application/octet-stream' }), `${tableName}.xlsx`);
- } catch (e) {
- console.error(e, webOut);
- }
- this.downloadLoading = false;
- },
- closeTargetList() {
- this.targetDialogVisible = false
- },
- // 打开OKR弹框
- openTargetList(okrs) {
- if (okrs && okrs.length > 0) {
- this.okrs = okrs
- this.targetDialogVisible = true
- } else {
- return this.$message.error("暂无关联okr")
- }
- },
- // 关闭绩效弹框回调事件
- handleClose() {}
- }
- };
- </script>
- <style scoped="scoped" lang="scss">
- .cursor {
- cursor: hand;
- &:hover {
- cursor: hand; /* 鼠标悬停时改为手型指针 */
- }
- }
- /* 默认鼠标样式为箭头指针 */
- .record-container {
- width: 100%;
- height: 100%;
- border-radius: 5px;
- .main-content {
- width: 100%;
- height: 100%;
- display: flex;
- flex-direction: column;
- background: #fff;
- padding: 0 10px;
- box-sizing: border-box;
- .search-box {
- display: flex;
- align-items: center;
- justify-content: space-between;
- width: 100%;
- height: 50px;
- box-sizing: border-box;
- background: #fff;
- .dept_wdiv {
- width: 240px;
- position: relative;
-
- .dept_inp {
- width: 240px;
- z-index: 9;
- height: 36px;
- line-height: 36px;
- border: 1px solid #e0e0e0;
- border-radius: 3px;
- font-size: 12px;
- padding: 0 10px;
- overflow: hidden;
- white-space: nowrap;
- text-overflow: ellipsis;
- cursor: pointer;
- color: #676767;
- }
-
- i {
- position: absolute;
- top: 0;
- right: 0;
- top: 12px;
- right: 10px;
- font-size: 14px;
- color: #b5b5b5;
- }
- }
- }
-
- .line {
- width: 100%;
- height: 1px;
- background: #f1f1f1;
- }
-
- .generalize-item {
- width: 120px;
- margin-bottom: 20px;
- }
-
- .table-box {
- flex: 1;
- width: 100%;
- overflow-y: auto;
- /* 设置滚动条的宽度和背景色 */
- &::-webkit-scrollbar {
- width: 6px;
- height: 6px;
- background-color: #f9f9f9;
- }
-
- /* 设置滚动条滑块的样式 */
- &::-webkit-scrollbar-thumb {
- border-radius: 6px;
- background-color: #c1c1c1;
- }
-
- /* 设置滚动条滑块hover样式 */
- &::-webkit-scrollbar-thumb:hover {
- background-color: #a8a8a8;
- }
-
- /* 设置滚动条轨道的样式 */
- &::-webkit-scrollbar-track {
- box-shadow: inset 0 0 5px rgba(87, 175, 187, 0.1);
- border-radius: 6px;
- background: #ededed;
- }
- }
- }
- }
- </style>
|