job.vue 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862
  1. <template>
  2. <div class="all">
  3. <div>
  4. <div class="left-main" v-if="$getRole(1)">
  5. <!-- <div class="title">快捷入口</div> -->
  6. <div class="flex-box-ce" v-if="entranceList.length > 0">
  7. <div class="entrance flex-box-ce" v-for="(item, index) in entranceList" :key="index" @click="openUrl(item)">
  8. <img :src="item.image" />
  9. <span>{{ item.name }}</span>
  10. </div>
  11. </div>
  12. <div v-else><div style="text-align: center; margin: 0 20px;" class="fontColorC">暂无相关权限</div></div>
  13. </div>
  14. <!-- 待办 -->
  15. <div class="flex-box">
  16. <div class="flex-1 dispose-left">
  17. <el-tabs v-model="activeName" class="tabs">
  18. <el-tab-pane :title="tab.title" :name="tab.name" style="max-height: 350px;overflow-y: auto;" class="scroll-bar" :key="tab.name" v-for="(tab, index) in editableTabs" v-loading="loading">
  19. <span slot="label" v-if="tab.num > 0">
  20. <el-badge :value="tab.num" :max="999">
  21. <span>{{ tab.title }}</span>
  22. </el-badge>
  23. </span>
  24. <span slot="label" v-else>
  25. <div style="position: relative;vertical-align: middle;display: inline-block;">
  26. <span>{{ tab.title }}</span>
  27. </div>
  28. </span>
  29. <template v-if="activeName!=10">
  30. <template v-if="agencyList.length > 0">
  31. <div class="flex-box-ce item" v-for="(item, index) in agencyList" :key="index" @click="openDetail(1, item)">
  32. <template v-if="item.userInfo">
  33. <userImage :img_url="item.userInfo.img_url" :user_name="item.userInfo.name" fontSize="14" width="40px" height="40px"></userImage>
  34. </template>
  35. <div class="flex-1 font-flex-word content">
  36. <div style="max-width: 700px;" class="font-flex-word">{{ item.content }}</div>
  37. </div>
  38. <div class="fontColorB">{{ item.update_time }}</div>
  39. </div>
  40. <div class="more" >
  41. <span @click="$router.push({ name: 'backlog', query: { activeName: activeName } })">
  42. 查看更多
  43. <i class="el-icon-d-arrow-right"></i>
  44. </span>
  45. </div>
  46. </template>
  47. <NoData v-else content="暂无内容" :isSolt="true">
  48. <div class="fontColorC" style="text-align: center;">
  49. 暂无内容,
  50. <span class="blue" style="cursor: pointer;" @click="$router.push({ name: 'backlog', query: { selectIndex: 1 } })">去查看已处理的</span>
  51. </div>
  52. </NoData>
  53. </template>
  54. <template v-else>
  55. <template v-if="plcList.length > 0">
  56. <div class="flex-box-ce item" v-for="(item, index) in plcList" :key="index" @click="openAffirm(item)">
  57. <userImage :img_url="$userInfo().img_url" :user_name="$userInfo().name" fontSize="14" width="40px" height="40px"></userImage>
  58. <div class="flex-1 font-flex-word content">
  59. <div style="max-width: 700px;" class="font-flex-word">{{ item.package_name }}【{{ item.level_name }}】的绩效评分和等级,需要你检查确认</div>
  60. </div>
  61. <div class="fontColorB">{{ item.ct }}</div>
  62. </div>
  63. </template>
  64. <NoData v-else content="暂无内容"></NoData>
  65. </template>
  66. </el-tab-pane>
  67. </el-tabs>
  68. </div>
  69. <div style="width: 300px;margin-left: 10px;padding: 20px 10px;" class="dispose-left">
  70. <div style="border-bottom: 1px solid #f1f1f1;margin-bottom: 15px;">
  71. <el-badge :value="messageNum" :max="999" v-if="messageNum > 0">
  72. <div class="message-title">
  73. <svg-icon icon-class="#icon-tongzhi" class="orange"></svg-icon>
  74. 未读消息
  75. </div>
  76. </el-badge>
  77. <div class="message-title" v-else>
  78. <svg-icon icon-class="#icon-tongzhi" class="orange"></svg-icon>
  79. 未读消息
  80. </div>
  81. </div>
  82. <template v-if="messageList.length > 0">
  83. <div class="item" v-for="(item, index) in messageList" :key="index" @click="openDetail(2, item)">
  84. <div class="flex-box" v-if="item.type == 4">
  85. <div style="width: 25px;padding-top: 6px;"><i class="el-icon-download orange"></i></div>
  86. <span class="message-content flex-1">{{ item.content }}</span>
  87. </div>
  88. <div class="flex-box" v-else>
  89. <div style="width: 25px;padding-top: 6px;"><i class="el-icon-bell orange"></i></div>
  90. <span class="message-content flex-1">{{ item.content }}</span>
  91. </div>
  92. </div>
  93. <div class="more">
  94. <span @click="$router.push({ name: 'unread' })">
  95. 查看更多
  96. <i class="el-icon-d-arrow-right"></i>
  97. </span>
  98. </div>
  99. </template>
  100. <NoData v-else content="暂无内容" :isSolt="true">
  101. <div class="fontColorC" style="text-align: center;">
  102. 暂无内容,
  103. <span class="blue" style="cursor: pointer;" @click="$router.push({ name: 'unread', query: { selectIndex: 1 } })">去查看已读的</span>
  104. </div>
  105. </NoData>
  106. </div>
  107. </div>
  108. <!-- 管理 -->
  109. <div style="margin: 10px 0;" class="gl-all" v-loading="staffLoad">
  110. <div class="flex-box" style="margin-bottom: 20px;">
  111. <el-cascader
  112. v-model="headValue"
  113. :options="options"
  114. :show-all-levels="false"
  115. :props="{ expandTrigger: 'hover', label: 'name', value: 'id', children: 'list' }"
  116. ></el-cascader>
  117. <div style="margin-left:10px;width:200px;"><JxSearch :screen="2" title="请输入名称搜索" @confirm="searchList"></JxSearch></div>
  118. </div>
  119. <el-tabs v-model="glIndex">
  120. <el-tab-pane :label="item.title" :name="item.name" v-for="(item, index) in glIist" :key="index">
  121. <el-table :data="glDataList" v-loading="glLoading" :header-cell-style="{ background: '#EDF4FF' }">
  122. <el-table-column prop="name" label="被考核人">
  123. <template slot-scope="scope">
  124. <div class="flex-box-ce">
  125. <userImage
  126. :id="scope.row.userInfo.id"
  127. :user_name="scope.row.userInfo.name"
  128. :img_url="scope.row.userInfo.img_url"
  129. width="35px"
  130. height="35px"
  131. fontSize="12px"
  132. ></userImage>
  133. <span style="margin-left: 10px; line-height: 50px;">{{ scope.row.userInfo.name }}</span>
  134. <span style="margin-left: 10px; line-height: 50px;" class="orange" v-if="scope.row.has_finish">已归档</span>
  135. </div>
  136. </template>
  137. </el-table-column>
  138. <el-table-column prop="name" label="部门">
  139. <template slot-scope="scope">
  140. <div v-if="scope.row.dept_list.length > 0">
  141. <span v-for="(item, index) in scope.row.dept_list" :key="index">
  142. {{ item.dept_name }}
  143. <span v-if="scope.row.dept_list.length - index > 1">,</span>
  144. </span>
  145. </div>
  146. <span v-else>--</span>
  147. </template>
  148. </el-table-column>
  149. <el-table-column prop="package_name" label="考核时段"></el-table-column>
  150. <template v-if="glIndex == '1'">
  151. <el-table-column prop="name" label="管理记录" >
  152. <template slot-scope="scope">
  153. <span v-if="scope.row.count_record == 0" class="fontColorB">无管理记录</span>
  154. <span v-else class="blue" style="cursor: pointer;" @click="openTx(scope.row)">{{ scope.row.count_record }}条管理记录</span>
  155. </template>
  156. </el-table-column>
  157. <el-table-column prop="name" label="执行计划">
  158. <template slot-scope="scope">
  159. <template v-if="scope.row.action_update">
  160. <div v-if="returnStr(scope.row.action_update).indexOf('今天') >= 0" class="actionText orange">{{ returnStr(scope.row.action_update) }}</div>
  161. <div v-else-if="returnStr(scope.row.action_update).indexOf('昨天') >= 0" class="actionText green">{{ returnStr(scope.row.action_update) }}</div>
  162. <div v-else class="actionText">{{ returnStr(scope.row.action_update) }}</div>
  163. </template>
  164. <div></div>
  165. </template>
  166. </el-table-column>
  167. </template>
  168. <template v-else>
  169. <el-table-column prop="status" label="评分进度">
  170. <template slot-scope="scope">
  171. <span v-if="scope.row.status == 0" class="orange">未到评分节点</span>
  172. <span v-if="scope.row.status == 1" class="blue">待我评分</span>
  173. <span v-if="scope.row.status == 2" class="green">我已评分</span>
  174. <span v-if="scope.row.status == 3" class="green">已被其他管理评分</span>
  175. </template>
  176. </el-table-column>
  177. <el-table-column prop="score_info" label="评分">
  178. <template slot-scope="scope">
  179. <div v-if="scope.row.score_info.length > 0">
  180. <div v-for="(item, index) in returnPoint(scope.row)" :key="index">
  181. <div style="margin-top: 5px;" v-if="item.pointList.length > 0">
  182. {{ item.name }}:
  183. <span class="blue">{{ item.pointList.toString() }}</span>
  184. </div>
  185. <div v-else>--</div>
  186. </div>
  187. </div>
  188. <div v-else>--</div>
  189. </template>
  190. </el-table-column>
  191. </template>
  192. <el-table-column label="操作">
  193. <template slot-scope="scope">
  194. <el-button @click="openTx(scope.row)" type="text" v-if="glIndex == '1' && !scope.row.has_finish">填写管理记录</el-button>
  195. <el-button @click="openDetail2(scope.row)" type="text">查看详情</el-button>
  196. <el-button @click="openDetail2(scope.row)" type="text" v-if="glIndex == '2' && scope.row.status == 1">去评分</el-button>
  197. </template>
  198. </el-table-column>
  199. </el-table>
  200. <div class="more">
  201. <span @click="$router.push({ name: glIndex == 1 ? 'management' : 'score', query: { headValue: JSON.stringify(headValue) } })">
  202. 查看更多
  203. <i class="el-icon-d-arrow-right"></i>
  204. </span>
  205. </div>
  206. </el-tab-pane>
  207. </el-tabs>
  208. </div>
  209. <!-- 常见问题 -->
  210. <div class="wt">
  211. <div class="flex-box-ce"><div class="wt-title flex-1">常见问题</div></div>
  212. <div class="wts" v-for="(item, index) in issueList" :key="index">
  213. <div class="flex-box-ce wt-item">
  214. <span class="fontColorC flex-box-ce">
  215. <span class="zmBox">Q</span>
  216. 问题:
  217. </span>
  218. <span class="flex-1">{{ item.title }}</span>
  219. </div>
  220. <div class="flex-box wt-item">
  221. <span class="fontColorC flex-box">
  222. <span class="zmBox" style="background-color: #8E9296;">A</span>
  223. 回答:
  224. </span>
  225. <span class="flex-1">{{ item.content }}</span>
  226. </div>
  227. </div>
  228. </div>
  229. </div>
  230. <!-- 跟踪管理 -->
  231. <TrackManagement
  232. :showDrawer.sync="isTrack"
  233. :isCz="has_finish ? true : false"
  234. :id="employeeID"
  235. :apList="apList"
  236. :recordMemberIds="recordMemberIds"
  237. :assessId="employee_id"
  238. @confirm="getManagement"
  239. ></TrackManagement>
  240. </div>
  241. </template>
  242. <script>
  243. import ECharts from 'echarts';
  244. import moment from 'moment';
  245. import TrackManagement from '@/performance/components/public/TrackManagement';
  246. import JxSearch from '@/performance/components/public/JxSearch';
  247. export default {
  248. name: 'job',
  249. components: { JxSearch, TrackManagement },
  250. data() {
  251. return {
  252. day: moment().format('YYYY-MM-DD'),
  253. editableTabs: [
  254. { title: '全部待办', name: '0', num: 0 },
  255. { title: '目标制定', name: '1', num: 0 },
  256. { title: '目标确认', name: '2', num: 0 },
  257. { title: '结果录入', name: '4', num: 0 },
  258. { title: '评分', name: '5', num: 0 },
  259. { title: '审批', name: '9', num: 0 },
  260. { title: '绩效确认', name: '10', num: 0 }
  261. ],
  262. userInfo: this.$userInfo(),
  263. entranceList: [],
  264. agencyList: [], //待办列表
  265. agencyNum: 0,
  266. messageList: [], //消息列表
  267. messageNum: 0,
  268. activeName: '0',
  269. loading: false,
  270. // 管理相关
  271. options: [], //
  272. headValue: [],
  273. glIndex: '1',
  274. glIist: [{ name: '1', title: '我管理的' }, { name: '2', title: '我评分的' }],
  275. glLoading: false,
  276. glDataList: [],
  277. package_id: '', //考核包ID
  278. name: '', //搜索Name
  279. pendingList: [], //提供给考核详情上下切换人员列表
  280. issueList: [
  281. {
  282. title: '新绩效可以解决什么问题?',
  283. content:
  284. '1、告别低效绩效考核,让绩效管理流程化;2、进度轻松管控,每个节点进度清晰可见;3、考核目标批量派发,评分流程自定义;4、员工按目标执行计划,上级跟踪管理做好过程管控记录;5、绩效统计图表分析,告别繁杂数据工作'
  285. },
  286. {
  287. title: '如何快速上手并使用新绩效?',
  288. content:
  289. '1、建立考核模板(把考核目标相同的人员分组,定考核模板,设计考核流程);2、根据考核周期,发起考核;3、针对每个员工进行考核管理、跟踪及评分;4、查看报表并进行结果分析'
  290. },
  291. {
  292. title: '新绩效和原有的绩效有何关联和区别吗?',
  293. content:
  294. '原有绩效以任务为主,重点关注任务是否完成,仅支持月度考核;新绩效支持任意周期的考核,以目标结果为导向,以员工执行计划和跟踪管理记录来关注过程,拥有完善的目标制定、在线评分和审批流程,绩效目标清单一目了然。'
  295. }
  296. ],
  297. isTrack: false,
  298. apList: [], //管理记录源数据
  299. employee_id: 0, //被考核人ID
  300. employeeID: 0,
  301. staffLoad: false,
  302. recordMemberIds: [],
  303. has_finish: 0 ,//是否归档
  304. plcList:[],
  305. };
  306. },
  307. activated() {
  308. // this.setMenu();
  309. this.getAgencyNum();
  310. this.getAgency();
  311. this.getMessage();
  312. this.glIndex == '1' ? this.getManagement() : this.getScorerRecord();
  313. this.getPlc();
  314. },
  315. created() {
  316. this.setMenu();
  317. this.getAgencyNum();
  318. },
  319. mounted() {
  320. this.getAgency();
  321. this.getMessage();
  322. this.assessTree();
  323. },
  324. watch: {
  325. activeName(val) {
  326. if(val==10){
  327. this.getPlc();
  328. }else{
  329. this.getAgencyNum();
  330. this.getAgency();
  331. }
  332. },
  333. glIndex(val) {
  334. this.glDataList = [];
  335. if (this.headValue.length != 0) {
  336. val == '1' ? this.getManagement() : this.getScorerRecord();
  337. }
  338. },
  339. headValue(val) {
  340. this.package_id = val[val.length - 1];
  341. this.glIndex == '1' ? this.getManagement() : this.getScorerRecord();
  342. }
  343. },
  344. methods: {
  345. openAffirm(item){
  346. this.$router.push({ path: '/affirm', query: { pl_id: item.id,level_name:item.level_name,package_id: item.package_id } });
  347. },
  348. getPlc() {
  349. this.$axiosUser('get', '/api/pro/per/package/plc/list', {status: 0, page: 1, page_size: 1000 }).then(res => {
  350. this.plcList= res.data.data.list
  351. })
  352. },
  353. returnStr(time) {
  354. let date = `${time}000`;
  355. let res = moment(Number(date)).format('YYYY/MM/DD HH:mm');
  356. return this.fnTime(res);
  357. },
  358. fnTime(time) {
  359. let staer = time.slice(0, 11);
  360. let ptime = new Date(time).getTime();
  361. const twentyFourHours = 24 * 60 * 60 * 1000;
  362. const fortyEightHours = 24 * 60 * 60 * 1000 * 2;
  363. const today=moment().format('YYYY/MM/DD');
  364. const todayTime = new Date(today).getTime();
  365. const yesterdayTime = new Date(todayTime - twentyFourHours).getTime();
  366. const lastYesterdayTime = new Date(todayTime - fortyEightHours).getTime();
  367. if (ptime >= todayTime) {
  368. return '今天 ' + time.split(' ')[1] + ' 更新了执行计划';
  369. } else if (ptime < todayTime && yesterdayTime <= ptime) {
  370. return '昨天 ' + time.split(' ')[1] + ' 更新了执行计划';
  371. } else if (ptime < yesterdayTime && lastYesterdayTime <= ptime) {
  372. return '前天 ' + time.split(' ')[1] + ' 更新了执行计划';
  373. } else if (this.dateSum(this.day, staer) > 30) {
  374. return '近30天无计划更新';
  375. } else {
  376. return time + ' 更新了执行计划';
  377. }
  378. },
  379. dateSum(sDate1, sDate2) {
  380. //sDate1和sDate2是2008-12-13格式
  381. var aDate, oDate1, oDate2, iDays;
  382. aDate = sDate1.split('-');
  383. oDate1 = new Date(aDate[1] + '-' + aDate[2] + '-' + aDate[0]); //转换为12-13-2008格式
  384. aDate = sDate2.split('-');
  385. oDate2 = new Date(aDate[1] + '-' + aDate[2] + '-' + aDate[0]);
  386. iDays = parseInt(Math.abs(oDate1 - oDate2) / 1000 / 60 / 60 / 24); //把相差的毫秒数转换为天数
  387. return iDays;
  388. },
  389. returnPoint(item) {
  390. let id = item.node_info.id;
  391. let stats = item.status;
  392. let arr = [{ name: '上级评分', pointList: [] }, { name: '特定指标评分', pointList: [] }];
  393. item.score_info.forEach(e => {
  394. if (stats == 0) {
  395. if (e.node_id < id) {
  396. if (e.node_code == 'score_supervisor') {
  397. //上级评分
  398. if (e.node_id == id && stats == 1) {
  399. arr[0].pointList.push(e.point + '(暂存)');
  400. } else {
  401. arr[0].pointList.push(e.point);
  402. }
  403. } else {
  404. //指定评分呢
  405. if (e.node_id == id && stats == 1) {
  406. arr[1].pointList.push(e.point + '(暂存)');
  407. } else {
  408. arr[1].pointList.push(e.point);
  409. }
  410. }
  411. }
  412. } else {
  413. if (e.node_id <= id) {
  414. if (e.node_code == 'score_supervisor') {
  415. //上级评分
  416. if (e.node_id == id && stats == 1) {
  417. arr[0].pointList.push(e.point + '(暂存)');
  418. } else {
  419. arr[0].pointList.push(e.point);
  420. }
  421. } else {
  422. //指定评分呢
  423. if (e.node_id == id && stats == 1) {
  424. arr[1].pointList.push(e.point + '(暂存)');
  425. } else {
  426. arr[1].pointList.push(e.point);
  427. }
  428. }
  429. }
  430. }
  431. });
  432. return arr;
  433. },
  434. openTx(item) {
  435. this.employee_id = item.employee_id;
  436. this.employeeID = item.record_id;
  437. this.has_finish = item.record_id;
  438. this.employeeDet(item.record_id, () => {
  439. this.isTrack = true;
  440. });
  441. },
  442. employeeDet(id, callBack) {
  443. this.staffLoad = true;
  444. this.$axiosUser('get', '/api/pro/per/package/employee/info', { id: id })
  445. .then(res => {
  446. let data = res.data.data;
  447. this.apList = data.dimension;
  448. this.recordMemberIds = data.record_member_ids;
  449. callBack && callBack();
  450. })
  451. .finally(() => {
  452. this.staffLoad = false;
  453. });
  454. },
  455. openDetail2(item) {
  456. this.$router.push({
  457. path: '/staffAssDet',
  458. query: {
  459. assID: this.package_id,
  460. employeeID: item.record_id,
  461. employeeIDs: item.employee_id
  462. }
  463. });
  464. },
  465. //我管理记录
  466. getManagement() {
  467. if (this.headValue.length == 0) {
  468. return false;
  469. }
  470. this.glLoading = true;
  471. this.$axiosUser('get', '/api/pro/per/package/management_record', { package_id: this.package_id || 0, name: this.name, page: 1, page_size: 5 })
  472. .then(res => {
  473. let list = res.data.data.list;
  474. list.forEach(item => {
  475. if (item.employee_id) {
  476. //当是导入导出时,显示登录者
  477. item.userInfo = this.$getEmployeeMapItem(item.employee_id);
  478. if (this.$getEmployeeMapItem(item.employee_id).employee_detail) {
  479. item.dept_list = this.$getEmployeeMapItem(item.employee_id).employee_detail.dept_list;
  480. }
  481. }
  482. });
  483. this.glDataList = list;
  484. })
  485. .finally(() => {
  486. this.glLoading = false;
  487. });
  488. },
  489. //我评分的
  490. getScorerRecord() {
  491. if (this.headValue.length == 0) {
  492. return false;
  493. }
  494. this.glLoading = true;
  495. this.$axiosUser('get', '/api/pro/per/package/score_record', { package_id: this.package_id || 0, name: this.name, page: 1, page_size: 5 })
  496. .then(res => {
  497. let list = res.data.data.list;
  498. list.forEach(item => {
  499. if (item.employee_id) {
  500. //当是导入导出时,显示登录者
  501. item.userInfo = this.$getEmployeeMapItem(item.employee_id);
  502. if (this.$getEmployeeMapItem(item.employee_id).employee_detail) {
  503. item.dept_list = this.$getEmployeeMapItem(item.employee_id).employee_detail.dept_list;
  504. }
  505. }
  506. });
  507. this.glDataList = list;
  508. })
  509. .finally(() => {
  510. this.glLoading = false;
  511. });
  512. },
  513. //搜索
  514. searchList(data) {
  515. this.name = data;
  516. this.glIndex == '1' ? this.getManagement() : this.getScorerRecord();
  517. },
  518. //请求绩效树
  519. assessTree() {
  520. this.$axiosUser('get', '/api/pro/per/package/tree').then(res => {
  521. if (res.data.code == 1) {
  522. this.options = res.data.data;
  523. let headValue = [];
  524. this.options.some(item => {
  525. if (item.list.length > 0) {
  526. headValue.push(item.id);
  527. headValue.push(item.list[0].id);
  528. return true;
  529. }
  530. });
  531. if (headValue.length > 0) {
  532. this.headValue = headValue;
  533. }
  534. }
  535. });
  536. },
  537. openDetail(index, item) {
  538. if (index == 1) {
  539. if (item.type == 1) {
  540. this.$router.push({
  541. path: '/staffAssDet',
  542. query: {
  543. assID: item.remark.package_id,
  544. employeeID: item.remark.packageEmployee_id,
  545. employeeIDs: item.remark.employee_id,
  546. pendingList: JSON.stringify(this.pendingList),
  547. activeName: this.activeName,
  548. }
  549. });
  550. } else if(item.node_type == 4){
  551. let name=item.content.split(',')[0]
  552. let query={
  553. pe_ids:JSON.stringify(item.pe_ids.concat(item.done_pe_ids)),
  554. name:name,
  555. pendingList: JSON.stringify(this.pendingList),
  556. package_id:item.package_id,
  557. activeName: this.activeName,
  558. };
  559. this.$router.push({path:'/staffAssDet',query: query});
  560. // let name=item.content.split(',')[0]
  561. // this.$router.push({ name: 'resultSetAll', query: { pe_ids:JSON.stringify(item.pe_ids),name:name}});
  562. }else{
  563. this.$router.push({ name: 'resultSet', query: { id: item.remark.packageEmployee_id, packageName: item.remark.package_name } });
  564. }
  565. } else {
  566. this.disposeMessage(item);
  567. }
  568. },
  569. // 处理未读信息
  570. disposeMessage(item) {
  571. if (item.type == 1 || item.type == 2) {
  572. this.$router.push({
  573. path: '/staffAssDet',
  574. query: {
  575. assID: item.remark.package_id,
  576. employeeID: item.remark.packageEmployee_id,
  577. employeeIDs: item.remark.employee_id
  578. }
  579. });
  580. } else if (item.type == 3) {
  581. //导入
  582. } else {
  583. //导出
  584. window.open(this.$serverdomain + item.remark.file_path);
  585. }
  586. this.$axiosUser('post', '/api/pro/per/package/msg/cc', { id: item.id, type: item.type, employee_id: item.employee_id }).then(res => {});
  587. },
  588. //待办数量
  589. getAgencyNum() {
  590. this.$axiosUser('get', '/api/pro/per/package/msg/agency_num', { status: 0 },'v2').then(res => {
  591. let data = res.data.data;
  592. this.editableTabs = [
  593. // { title: '全部待办', name: '0', num: data.all_total },
  594. { title: '全部待办', name: '0', num: 0 },
  595. { title: '目标制定', name: '1', num: data.target },
  596. { title: '目标确认', name: '2', num: data.confirm },
  597. { title: '结果录入', name: '4', num: data.result_value },
  598. { title: '评分', name: '5', num: data.score },
  599. { title: '审批', name: '9', num: data.review },
  600. { title: '绩效确认', name: '10', num: data.level_confirm }
  601. ];
  602. });
  603. },
  604. //待办
  605. getAgency() {
  606. this.loading = true;
  607. this.$axiosUser('get', '/api/pro/per/package/msg/agency', { node_type: this.activeName, status: 0, page: 1, page_size: 10 },'v2')
  608. .then(res => {
  609. let list = res.data.data.list;
  610. let pendingList = [];
  611. list.forEach(item => {
  612. if(item.node_type==4){
  613. let userInfo = this.$getEmployeeMapItem(item.first_employee_id);
  614. item.userInfo = userInfo;
  615. let name=item.content.split(',')[0]
  616. pendingList.push({ name: userInfo.name,img_url:userInfo.img_url,package_name:name,pe_ids:item.pe_ids.concat(item.done_pe_ids),employeeID:'结果',package_id:item.package_id});
  617. return false
  618. }
  619. if (item.remark.employee_id) {
  620. //被考核人
  621. let userInfo = this.$getEmployeeMapItem(item.remark.employee_id);
  622. item.userInfo = userInfo;
  623. pendingList.push({ name: userInfo.name, img_url: userInfo.img_url, employeeID: item.remark.packageEmployee_id, package_name: item.remark.package_name });
  624. }
  625. if (item.employee_id) {
  626. //当是导入导出时,显示登录者
  627. item.userInfo2 = this.$getEmployeeMapItem(item.employee_id);
  628. }
  629. });
  630. this.pendingList = pendingList;
  631. this.agencyList = list.slice(0, 5);
  632. this.agencyNum = res.data.data.total;
  633. })
  634. .finally(() => {
  635. this.loading = false;
  636. });
  637. },
  638. //消息列表
  639. getMessage() {
  640. this.$axiosUser('get', '/api/pro/per/package/msg/cc', { status: 0, page: 1, page_size: 5 }).then(res => {
  641. let list = res.data.data.list;
  642. list.forEach(item => {
  643. if (item.remark.employee_id) {
  644. //被考核人
  645. item.userInfo = this.$getEmployeeMapItem(item.remark.employee_id);
  646. }
  647. if (item.employee_id) {
  648. //当是导入导出时,显示登录者
  649. item.userInfo2 = this.$getEmployeeMapItem(item.employee_id);
  650. }
  651. });
  652. this.messageList = list;
  653. this.messageNum = res.data.data.total;
  654. });
  655. },
  656. openUrl(item) {
  657. // let leg = this.$getCache('performance_routers').length;
  658. // if (item.name == '考核模板') {
  659. // this.$setCache('activeIndex', leg - 1);
  660. // this.$setCache('setUrlName', null);
  661. // }
  662. // if (item.name == '指标库') {
  663. // this.$setCache('activeIndex', leg - 1);
  664. // this.$setCache('setUrlName', 'indexSet');
  665. // }
  666. this.$router.push({ path: item.url });
  667. },
  668. setMenu() {
  669. let entranceList = [];
  670. if (this.$isAuthoritys_jx([this.$7, this.$8, this.$9, this.$10, this.$11])) {
  671. entranceList.push({ name: '考核明细', image: 'static/images/1.png', url: '/assessManagement' });
  672. }
  673. if (this.$isAuthoritys_jx([this.$13, this.$14])) {
  674. entranceList.push({ name: '考核表', image: 'static/images/2.png', url: '/evaluateSet' });
  675. }
  676. if (this.$isAuthoritys_jx(this.$7)) {
  677. entranceList.push({ name: '发起考核', image: 'static/images/3.png', url: '/sponsorAssess' });
  678. }
  679. // if (this.$isAuthoritys_jx(this.$12)) {
  680. // entranceList.push({ name: '指标库', image: 'static/images/4.png', url: '/IndexSet' });
  681. // }
  682. this.entranceList = entranceList;
  683. }
  684. }
  685. };
  686. </script>
  687. <style scoped="scoped">
  688. .actionText {
  689. }
  690. .zmBox {
  691. width: 18px;
  692. height: 18px;
  693. background-color: #f26c69;
  694. color: #fff;
  695. text-align: center;
  696. line-height: 18px;
  697. font-size: 12px;
  698. border-radius: 50%;
  699. margin-right: 10px;
  700. }
  701. .more {
  702. text-align: right;
  703. color: #909399;
  704. font-size: 14px;
  705. padding: 16px 0px 0 0px;
  706. }
  707. .more span {
  708. cursor: pointer;
  709. }
  710. .more span:hover {
  711. color: #409EFF;
  712. }
  713. .dispose-left ::v-deep.el-badge__content.is-fixed {
  714. position: absolute;
  715. top: 20px;
  716. right: -2px;
  717. }
  718. .tabs ::v-deep.el-badge__content.is-fixed {
  719. position: absolute;
  720. top: 50%;
  721. right: -2px;
  722. }
  723. .all {
  724. font-size: 14px;
  725. border-radius: 4px;
  726. }
  727. .item {
  728. font-size: 14px;
  729. cursor: pointer;
  730. padding: 5px;
  731. }
  732. .item:hover {
  733. background-color: #f5f7fa;
  734. }
  735. .content {
  736. padding: 0 10px;
  737. }
  738. .message-content {
  739. overflow: hidden;
  740. text-overflow: ellipsis;
  741. word-break: break-all;
  742. display: -webkit-box;
  743. -webkit-line-clamp: 2;
  744. -webkit-box-orient: vertical;
  745. line-height: 22px;
  746. }
  747. .message-title {
  748. height: 40px;
  749. line-height: 40px;
  750. font-size: 16px;
  751. font-weight: normal;
  752. position: relative;
  753. padding: 0 5px;
  754. }
  755. .open-detail {
  756. cursor: pointer;
  757. }
  758. .dispose-left,
  759. .gl-all {
  760. background-color: #fff;
  761. padding: 20px;
  762. border-radius: 5px;
  763. }
  764. .left-main {
  765. background-color: #fff;
  766. padding: 20px;
  767. border-radius: 5px;
  768. margin-bottom: 10px;
  769. }
  770. .title {
  771. font-size: 14px;
  772. margin-bottom: 15px;
  773. border-bottom: 1px solid #ebebeb;
  774. padding-bottom: 16px;
  775. }
  776. .wt {
  777. padding: 15px;
  778. border-radius: 4px;
  779. border-radius: 5px;
  780. background-color: #fff;
  781. }
  782. .wt-title {
  783. font-size: 14px;
  784. }
  785. .wts {
  786. margin-top: 20px;
  787. line-height: 25px;
  788. font-size: 14px;
  789. }
  790. .tabss {
  791. position: absolute;
  792. right: 0px;
  793. top: 146px;
  794. cursor: pointer;
  795. z-index: 999;
  796. }
  797. .entrance {
  798. padding: 15px;
  799. border-radius: 4px;
  800. border: 1px solid #ebebeb;
  801. font-size: 14px;
  802. width: 200px;
  803. color: #222;
  804. margin: 0 12px;
  805. cursor: pointer;
  806. }
  807. .entrance:hover {
  808. background-color: #f5f7fa;
  809. }
  810. .entrance img {
  811. width: 30px;
  812. height: 30px;
  813. border-radius: 2px;
  814. margin-right: 10px;
  815. }
  816. .flex-5 {
  817. position: relative;
  818. }
  819. ::v-deep .el-tabs__nav-wrap::after {
  820. content: '';
  821. position: absolute;
  822. left: 0;
  823. bottom: 0;
  824. width: 100%;
  825. height: 1px !important;
  826. background-color: #e4e7ed;
  827. z-index: 1;
  828. }
  829. /* 右边 */
  830. .gg-img {
  831. width: 100%;
  832. height: 100px;
  833. border-radius: 5px;
  834. margin-top: 20px;
  835. }
  836. .echarts {
  837. border-radius: 4px;
  838. padding: 10px;
  839. }
  840. .echarts-header {
  841. margin: 10px 0;
  842. }
  843. #eChart {
  844. height: 300px;
  845. width: 100%;
  846. }
  847. </style>