me.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453
  1. <template>
  2. <div class="all" :class="{ bg_fff: skeletonLoad }">
  3. <van-nav-bar title="我的绩效" left-text="返回" left-arrow @click-left="$route_back" />
  4. <div class="overall">
  5. <VanSkeleton :skeLoad="skeletonLoad">
  6. <scroller>
  7. <div class="title">
  8. <span>考核信息</span>
  9. <span class="more-btn" @click="goMorePage()">
  10. 查看更多
  11. <van-icon name="arrow" />
  12. </span>
  13. </div>
  14. <div class="list-box">
  15. <div class="flex-box-ce" style="margin-bottom: 0.2rem;">
  16. <div>
  17. <userImage class="about-me__avatar" :id="showUserInfo.id" :img_url="showUserInfo.img_url" :user_name="showUserInfo.name" fontSize="0.24" width="0.8rem" height="0.8rem"></userImage>
  18. </div>
  19. <div class="user-info">
  20. <div style="margin-bottom: 0.05rem; color: #000;">{{ showUserInfo.name }}</div>
  21. <template v-if="showDeptList && showDeptList.length > 0">
  22. <span v-for="item in showDeptList" :key="item.dept_id">{{ item.dept_name }}&nbsp;</span>
  23. </template>
  24. </div>
  25. </div>
  26. <div class="examine-info">
  27. <div class="info-item flex-box-ce">
  28. 考核周期:&nbsp;&nbsp;&nbsp; <div class="cycle-type">{{ cycleType | formatCycleType }}</div>
  29. </div>
  30. <div class="info-item">
  31. <van-icon name="calendar" />考核时间:&nbsp;&nbsp;&nbsp;{{ startTime | formatDate }} 至 {{ endTime | formatDate }}
  32. </div>
  33. <div class="info-item">
  34. 考核等级:&nbsp;&nbsp;&nbsp; <span style="color: #ff9600;">{{ levelName || '-' }}</span>
  35. </div>
  36. <div class="info-item">
  37. 考核评分:&nbsp;&nbsp;&nbsp; <span style="color: #ff9600;">{{ score == undefined || score == null || score == '' ? '-' : score }}</span>
  38. </div>
  39. </div>
  40. </div>
  41. <div class="title">指标列表</div>
  42. <div class="list-box">
  43. <div class="examine-info" v-for="(item, index) in indicators" :key="item.reviewIndicatorId">
  44. <div class="tips">
  45. <div class="tip-item" v-if="item.okrs && item.okrs.length > 0" @click="goMyTarget(item.okrs)">过程跟踪</div>
  46. <div class="tip-item" @click="goDetails(item)">处理详情</div>
  47. </div>
  48. <div class="info-item flex-box-ce">
  49. <div class="info-item-title">
  50. 审批阶段:
  51. </div>
  52. <div v-if="item.businessStatus !== 'end'" class="review-node">
  53. {{ item.businessStatus | filterNodeStatus }}
  54. </div>
  55. <div v-else class="review-node" style="background-color: #FF9600;">
  56. {{ item.businessStatus | filterNodeStatus }}
  57. </div>
  58. </div>
  59. <div class="info-item flex-box-ce">
  60. <div class="info-item-title">
  61. 指标:
  62. </div>
  63. {{ item.title }}
  64. </div>
  65. <div class="info-item flex-box-ce">
  66. <div class="info-item-title">
  67. 目标:
  68. </div>
  69. {{ item.target || '-' }} {{ item.target && item.unit ? item.unit : '' }}
  70. </div>
  71. <div class="info-item flex-box-ce">
  72. <div class="info-item-title">
  73. 结果值:
  74. </div>
  75. {{ item.result || '-' }}
  76. </div>
  77. <div class="info-item flex-box-ce">
  78. <div class="info-item-title">
  79. 权重:
  80. </div>
  81. {{ item.weight || '-' }}
  82. </div>
  83. <div class="info-item flex-box-ce">
  84. <div class="info-item-title">
  85. 单位:
  86. </div>
  87. {{ item.unit || '-' }}
  88. </div>
  89. <div class="info-item" v-if="item.content">
  90. <div class="info-item-title">
  91. 规则:
  92. </div>
  93. <div class="bg-gray">
  94. {{ item.content }}
  95. </div>
  96. </div>
  97. <div class="info-item" v-if="item.resultFiles && item.resultFiles.length > 0">
  98. <div class="info-item-title" style="width: 2rem;">
  99. 结果值附件:
  100. </div>
  101. <div class="bg-gray">
  102. <div v-for="(item, index) in item.resultFiles">
  103. 附件{{ index + 1}}
  104. </div>
  105. </div>
  106. </div>
  107. <div v-if="index !== indicators.length - 1" class="line"></div>
  108. </div>
  109. </div>
  110. <OperateLogVue v-if="reviewId" :reviewId="reviewId"/>
  111. <div style="width: 100%; height: 1rem;">
  112. </div>
  113. </scroller>
  114. </VanSkeleton>
  115. </div>
  116. </div>
  117. </template>
  118. <script>
  119. import VanSkeleton from '@/performance/components/public/VanSkeleton';
  120. import OperateLogVue from '@/performance/components/public/OperateLog.vue'
  121. import moment from 'moment';
  122. export default {
  123. components: {
  124. VanSkeleton,
  125. OperateLogVue
  126. },
  127. data() {
  128. return {
  129. skeletonLoad: true,
  130. userInfo: this.$userInfo(),
  131. meList: [],
  132. title: "",
  133. startTime: "",
  134. endTime: "",
  135. cycleType: "",
  136. score: 0,
  137. status: '',
  138. levelName: '', // 考核详情信息
  139. detailInfo: null,
  140. indicators: [],
  141. reviewId: '',
  142. employeeId: "",
  143. performList: [],
  144. params: {
  145. keyword: '',
  146. page: 1,
  147. pageSize: 10,
  148. startDate: '',
  149. endDate: '',
  150. employeeId: ''
  151. },
  152. };
  153. },
  154. filters: {
  155. filterNodeStatus(v) {
  156. if (v === 'start') return '开始'
  157. if (v === 'target_confirm') return '确认目标'
  158. if (v === 'result_input') return '录入结果值'
  159. if (v === 'score_self') return '自评'
  160. if (v === 'score_each_other') return '互评'
  161. if (v === 'score') return '评分'
  162. if (v === 'review') return '审批'
  163. if (v === 'cc') return '抄送'
  164. if (v === 'end') return '结束'
  165. },
  166. formatDate(val) {
  167. if (val) return moment(val).format('YYYY-MM-DD')
  168. else return "--"
  169. },
  170. formatCycleType(val) {
  171. if (val == 0) return '自定义'
  172. if (val == 1) return '年度'
  173. if (val == 2) return '半年'
  174. if (val == 3) return '季度'
  175. if (val == 4) return '月度'
  176. else return '--'
  177. },
  178. },
  179. computed: {
  180. showUserInfo() {
  181. return this.$getEmployeeMapItem(this.employeeId);
  182. },
  183. showDeptList() {
  184. return this.$getEmployeeMapItem(this.employeeId).employee_detail.dept_list
  185. }
  186. },
  187. methods: {
  188. getTemplateList() {
  189. let that = this
  190. let url = `/performance/statistics/reviews/${that.$userInfo().site_id}`
  191. // const startOfMonth = moment().startOf('month').format('YYYY-MM-DD') // 当月第一天
  192. // const endOfMonth = moment().endOf('month').format('YYYY-MM-DD'); // 当月最后一天
  193. let requestdata;
  194. if (that.cycleType == '-1') requestdata = { ...that.params }
  195. else requestdata = { ...that.params, cycleType: that.cycleType }
  196. that.$axiosUser('get', url, requestdata).then(res => {
  197. let { data: { data: { list, total }, code } } = res;
  198. if (code == 1) {
  199. if (list && list.length > 0) {
  200. that.performList = list;
  201. let { reviewId } = that.performList[0] || '';
  202. if (reviewId) that.getDetails(reviewId);
  203. }
  204. } else {
  205. that.performList = [];
  206. }
  207. });
  208. },
  209. getDetails(reviewId) {
  210. // reviewId = reviewId ? reviewId : 24
  211. // this.loading = true
  212. let url = `/performance/statistics/review/info/${this.$userInfo().site_id}/${reviewId}`
  213. this.$axiosUser('get', url).then(res => {
  214. this.skeletonLoad = false;
  215. let { data: { reviewId, title, indicators, levelName, startTime, endTime, cycleType, score, status }, code } = res.data
  216. this.reviewId = reviewId
  217. if (code == 1) {
  218. console.log(res)
  219. this.detailInfo = res.data.data;
  220. this.title = title || ''
  221. this.cycleType = cycleType || ''
  222. this.score = score
  223. this.status = status || ''
  224. this.startTime = startTime || ''
  225. this.endTime = endTime || ''
  226. this.levelName = levelName || ''
  227. this.indicators = indicators.reverse() || [];
  228. // 处理附件列表
  229. if (this.tableData && this.tableData.length > 0) {
  230. let resultFiles = []
  231. this.tableData.forEach(item => {
  232. if (item.flow.nodes && item.flow.nodes.length > 0) {
  233. let resultInputNode = item.flow.nodes[1] // 取到结果值节点
  234. if (resultInputNode.tasks && resultInputNode.tasks.length > 0) {
  235. resultInputNode.tasks.forEach(task => {
  236. if (task.files && task.files.length > 0) {
  237. task.files.forEach(file => {
  238. resultFiles.push(file)
  239. })
  240. }
  241. })
  242. item.resultFiles = resultFiles
  243. }
  244. }
  245. })
  246. }
  247. }
  248. });
  249. },
  250. goMorePage() {
  251. this.$router.push("/more")
  252. },
  253. goMyTarget(okrs) {
  254. this.$router.push({name: 'myTarget', query: {ids: JSON.stringify(okrs)}});
  255. },
  256. goDetails(item) {
  257. console.log(item);
  258. let { reviewId, reviewIndicatorId, flow: { nodes } } = item
  259. let showData = {
  260. nodes,
  261. reviewId,
  262. reviewIndicatorId
  263. }
  264. this.$router.push({ path: "/handleDetails", query: {showData: JSON.stringify(showData)} })
  265. },
  266. },
  267. watch: {
  268. // 路由参数变化(浏览器返回/前进、query 变化)也会再次执行
  269. '$route'(to, from) {
  270. let reviewId = this.$route.query.reviewId
  271. this.employeeId = this.$route.query.employeeId
  272. this.employeeId = this.employeeId ? this.employeeId : this.userInfo.id
  273. if(reviewId) {
  274. this.getDetails(reviewId);
  275. }else {
  276. this.getTemplateList()
  277. }
  278. }
  279. },
  280. created() {
  281. let reviewId = this.$route.query.reviewId
  282. this.employeeId = this.$route.query.employeeId
  283. this.employeeId = this.employeeId ? this.employeeId : this.userInfo.id
  284. if(this.reviewId) {
  285. this.getDetails(reviewId);
  286. }else {
  287. this.getTemplateList()
  288. }
  289. },
  290. };
  291. </script>
  292. <style scoped lang="less">
  293. .all {
  294. width: 100%;
  295. height: 100%;
  296. position: relative !important;
  297. background-color: #f5f7fa;
  298. box-sizing: border-box;
  299. .overall {
  300. height: calc(100% - 0.92rem) !important;
  301. position: relative;
  302. overflow-y: scroll;
  303. }
  304. }
  305. .title {
  306. margin: 0.2rem 0;
  307. padding: 0 0.2rem;
  308. box-sizing: border-box;
  309. font-size: 0.3rem;
  310. font-weight: 600;
  311. display: flex;
  312. align-items: center;
  313. justify-content: space-between;
  314. .more-btn {
  315. font-weight: normal;
  316. color: #0597ff;
  317. display: flex;
  318. align-items: center;
  319. justify-content: center;
  320. i {
  321. margin: 0.06rem 0 0 0.02rem;
  322. }
  323. }
  324. }
  325. .list-box {
  326. width: 96%;
  327. padding: 0.24rem;
  328. font-size: 0.32rem;
  329. background-color: #fff;
  330. border-radius: 5px;
  331. box-sizing: border-box;
  332. margin: 0.24rem auto;
  333. .add-task-title {
  334. font-weight: 600;
  335. font-size: 0.32rem;
  336. }
  337. .user-info {
  338. font-size: 0.28rem;
  339. color: #89919F !important;
  340. margin: 0 0 0 0.2rem;
  341. }
  342. .cycle-type {
  343. padding: 0.08rem;
  344. border-radius: 0.1rem;
  345. color: #26a2ff;
  346. box-sizing: border-box;
  347. background-color: #ecf5ff;
  348. }
  349. .examine-info {
  350. font-size: 0.28rem;
  351. position: relative;
  352. .tips {
  353. position: absolute;
  354. top: 0.1rem;
  355. right: -0.2rem;
  356. .tip-item {
  357. padding: 0.1rem;
  358. border-top-left-radius: 0.1rem;
  359. border-bottom-left-radius: 0.1rem;
  360. color: #26a2ff;
  361. z-index: 999;
  362. box-sizing: border-box;
  363. background-color: #ecf5ff;
  364. margin-bottom: 0.1rem;
  365. }
  366. }
  367. .info-item {
  368. margin-bottom: 0.2rem;
  369. color: #89919F !important;
  370. .info-item-title {
  371. width: 1.4rem;
  372. color: #000;
  373. }
  374. .review-node {
  375. padding: 0.01rem 0.1rem;
  376. color: #fff;
  377. border-radius: 2px;
  378. font-size: 0.26rem;
  379. background-color: #67c23a;
  380. margin-left: 0.14rem;
  381. }
  382. }
  383. .line {
  384. width: 100%;
  385. margin: 0.5rem auto;
  386. height: 1px;
  387. background-color: #f1f1f1;
  388. }
  389. }
  390. }
  391. .bg-gray {
  392. background-color: #f5f5f5;
  393. padding: 0.2rem;
  394. box-sizing: border-box;
  395. margin: 0.1rem;
  396. color: #999;
  397. border-radius: 5px;
  398. }
  399. </style>