screen.vue 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062
  1. <template>
  2. <div style="height: 100%;width: 100%;">
  3. <div class="screenBox back" v-if="isPCa">
  4. <el-alert v-if="isShowError" :title="errorMsg" type="error"></el-alert>
  5. <div v-if="result.company" style="height: 100%;">
  6. <header>
  7. <div style="height: 3rem;padding: 0 2rem;font-size: 20px;" class="zhuColor flex-box-ce">
  8. <div class="flex-1 flex-box-ce">
  9. <img :src="result.company.logo" class="logo" />
  10. <div>{{ result.company.name }}</div>
  11. </div>
  12. <div style="width: 400px;"></div>
  13. <div class="flex-1 flex-box-end flex-box-ce">
  14. <div>{{ nowTime }}</div>
  15. <el-tooltip class="item" effect="dark" content="全屏" placement="bottom">
  16. <!-- <i class="el-icon-help" style="cursor: pointer;" @click="fullScreen"></i> -->
  17. <img src="./assets/image/qp.png" class="logo" style="width: 24px;height: 24px;margin-left: 10px;cursor: pointer;" @click="fullScreen"/>
  18. </el-tooltip>
  19. <el-tooltip class="item" effect="dark" content="退出" placement="bottom">
  20. <img src="./assets/image/quit.png" class="logo" style="width: 24px;height: 24px;margin-left: 10px;cursor: pointer;" @click="quit"/>
  21. </el-tooltip>
  22. </div>
  23. </div>
  24. <div class="zhuColor title" style="width: 400px;margin: 0 auto;height: 20px;text-align: center;">
  25. <span>{{ result.title }}</span>
  26. </div>
  27. </header>
  28. <div style="height: 10px;"></div>
  29. <div class="flex-box" style="height: calc(100% - 128px);padding: 16px;padding-bottom: 0;">
  30. <div class="flex-2 box" id="left">
  31. <div class="boxTitle">{{ result.ranking.name }}</div>
  32. <div class="ranking" style="border-radius: 8px;margin: 16px;margin-top: 0px;">
  33. <template v-if="result.ranking.list.length>0">
  34. <div style="margin-bottom: 8px;border-radius: 8px;box-shadow: 0 8px 8px #191E48;margin-top: 16px;">
  35. <div v-for="(item, index) in ranking(result.ranking.list, 1)" :key="index" class="flex-box-ce rankingItem">
  36. <div class="flex-1 flex-box-ce">
  37. <template v-if="item.rank < 4">
  38. <div v-if="item.rank == 1" class="index"><img src="./assets/image/1.png" /></div>
  39. <div v-if="item.rank == 2" class="index"><img src="./assets/image/2.png" /></div>
  40. <div v-if="item.rank == 3" class="index"><img src="./assets/image/3.png" /></div>
  41. </template>
  42. <userImage :user_name="item.employee.name" :img_url="item.employee.img_url" width="54px" height="54px" style="margin: 0 18px;"></userImage>
  43. <div>
  44. <div style="font-size: 20px;margin-bottom: 5px;">{{ item.employee.name }}</div>
  45. <div class="fontColorT" style="font-size: 14px;" v-if="item.dept_list.length>0">
  46. {{item.dept_list[0].dept_name}} <span v-if="item.dept_list.length>1">...</span>
  47. </div>
  48. </div>
  49. </div>
  50. <div class="num">{{ item.s_point }}</div>
  51. </div>
  52. </div>
  53. <vue-seamless-scroll :data="result.ranking.list" class="seamless-warp" :style="{height:h1+'px'}" :class-option="classOption">
  54. <div v-for="(item, index) in ranking(result.ranking.list, 2)" :key="index" class="flex-box-ce rankingItem">
  55. <div class="flex-1 flex-box-ce">
  56. <div style="font-size: 20px;width: 36px;text-align: center;">{{ item.rank }}</div>
  57. <userImage :user_name="item.employee.name" :img_url="item.employee.img_url" width="54px" height="54px" style="margin: 0 18px;"></userImage>
  58. <div>
  59. <div style="font-size: 20px;margin-bottom: 5px;">{{ item.employee.name }}</div>
  60. <div class="fontColorT" style="font-size: 14px;" v-if="item.dept_list.length>0">
  61. {{item.dept_list[0].dept_name}}<span v-if="item.dept_list.length>1">...</span>
  62. </div>
  63. </div>
  64. </div>
  65. <div class="num">{{ item.s_point }}</div>
  66. </div>
  67. </vue-seamless-scroll>
  68. </template>
  69. <div v-else style="height: 200px;text-align: center;line-height: 200px;color: #fff;">
  70. 暂无数据
  71. </div>
  72. </div>
  73. </div>
  74. <div class="flex-3" style="margin: 0 16px;height: 100%;">
  75. <div class="flex-box-ce numBox" style="margin-bottom: 16px;">
  76. <div class="flex-1 flex-box-v flex-center-center" style="border-radius: 12px;margin-right: 16px;background-image: linear-gradient(to top, #2537F7 0%, #258CF6 100%);" @click="endVal = 5123">
  77. <div style="font-size: 2rem;margin-bottom: 1rem;">今日奖分</div>
  78. <div style="font-size: 4.2rem;font-weight: 600;letter-spacing:8px;position: relative;">
  79. <countTo :startVal="startVal" separator="" :endVal="result.center.all_add_point" :duration="3000"></countTo>
  80. </div>
  81. </div>
  82. <div class="flex-1 flex-box-v flex-center-center" style="border-radius: 12px;background-image: linear-gradient(to top, #6342E9 0%, #8468F3 100%);">
  83. <div style="font-size: 2rem;margin-bottom: 1rem;">今日人次</div>
  84. <div style="font-size: 4.2rem;font-weight: 600;letter-spacing:8px">
  85. <countTo :startVal="startVal" separator="" :endVal="result.center.count" :duration="3000"></countTo>
  86. </div>
  87. </div>
  88. </div>
  89. <div style="background-color: rgba(23, 30, 72, 0.3); border-radius: 8px;position: relative;">
  90. <div class="boxTitle" style="margin-bottom: 30px;">积分制运用活跃度</div>
  91. <div class="flex-box-ce" style="position: absolute;color:#fff;font-size:16px;right: 20px;top:108px">
  92. <span style="height: 2px;width: 30px;background-color: #E6A23C;"></span>
  93. 基准标尺</div>
  94. <div ref="ManagerSAwardChart" class="chart" :style="{height:h2+'px'}"></div>
  95. </div>
  96. </div>
  97. <div class="flex-2 box">
  98. <div class="boxTitle">{{ result.event.name }}</div>
  99. <div class="ranking">
  100. <template v-if="result.event.list.length">
  101. <vue-seamless-scroll :data="returnEvent(result.event.list)" class="seamless-warp" style="margin: 16px;" :style="{height:h3+'px'}" :class-option="classOption">
  102. <div v-for="(item, index) in returnEvent(result.event.list)" :key="item.id" class="flex-box rankingItem" style="margin-bottom: 10px;background-color: #1B3A70">
  103. <div class="main-right flex-1">
  104. <div class="context">{{ $moment.unix(item.event_time).format('YYYY-MM-DD') }}-{{ item.remark.customize ? item.remark.customize : item.remark.rule }}</div>
  105. <div class="flex-box flex-v-ce">
  106. <div class="name flex-1">{{ item.employee.name }}</div>
  107. <div class="da" v-if="item.point > 0">+{{ item.point }} <span style="color: #01EEFE;">{{ item.pt_id == 3 ? 'B分' : 'A分' }}</span></div>
  108. <div class="red da" v-else>{{ item.point }} <span style="color: #01EEFE;">{{ item.pt_id == 3 ? 'B分' : 'A分' }}</span></div>
  109. </div>
  110. </div>
  111. </div>
  112. </vue-seamless-scroll>
  113. </template>
  114. <div v-else style="height: 200px;text-align: center;line-height: 200px;color: #fff;">
  115. 暂无数据
  116. </div>
  117. </div>
  118. </div>
  119. </div>
  120. <div style="text-align: center;padding: 6px 0;font-size: 16px;color: #ccc;">@功道云积分制-提供技术支持</div>
  121. </div>
  122. <div class="data-all" v-else style="height: 100%;">
  123. <i class="el-icon-loading" style="margin-top: 15%;width: 150px;margin-bottom: 10px;color: #fff;font-size: 64px;"></i>
  124. <div style="color: #fff;">管理执行难,就用功道云</div>
  125. </div>
  126. <el-dialog title="输入密码" :visible.sync="isShowCode" width="450px" :show-close="false" :close-on-click-modal="false" :close-on-press-escape="false">
  127. <div style="margin: 10px 0;">
  128. <el-input style="width: 300px;" v-model="code" placeholder="请输入随机密码"></el-input>
  129. <div class="yellow">密码可在系统后台 “访问大屏” 功能中获取</div>
  130. </div>
  131. <div class="flex-box-end"><el-button type="primary" :disabled="isShowlog" :loading="isShowlog" @click="opneWebSocket()">确定</el-button></div>
  132. </el-dialog>
  133. </div>
  134. <div v-else style="height: 100%;" class="back">
  135. <el-alert v-if="isShowError" :title="errorMsg" type="error"></el-alert>
  136. <div v-if="result.company" style="height: 100%;">
  137. <header>
  138. <div style="height: 2.4rem;padding: 0 1rem;font-size: 14px;" class="zhuColor flex-box-ce">
  139. <div class="flex-1 flex-box-ce">
  140. <img :src="result.company.logo" class="logo" style="width: 1.4rem;height: 1.4rem;" />
  141. <div>{{ result.company.name }}</div>
  142. </div>
  143. <div style="width: 260px;"></div>
  144. <div class="flex-1 flex-box-end flex-box-ce">
  145. <div>{{ nowTime }}</div>
  146. <el-tooltip class="item" effect="dark" content="全屏" placement="bottom">
  147. <img src="./assets/image/qp.png" class="logo" style="width: 24px;height: 24px;margin-left: 10px;cursor: pointer;" @click="fullScreen"/>
  148. </el-tooltip>
  149. <el-tooltip class="item" effect="dark" content="退出" placement="bottom">
  150. <img src="./assets/image/quit.png" class="logo" style="width: 24px;height: 24px;margin-left: 10px;cursor: pointer;" @click="quit"/>
  151. </el-tooltip>
  152. </div>
  153. </div>
  154. <div class="zhuColor title2" style="width: 260px;margin: 0 auto;height: 14px;text-align: center;">
  155. <span style="font-size: 20px;top: -1rem;">{{ result.title }}</span>
  156. </div>
  157. </header>
  158. <div style="height: 10px;"></div>
  159. <div class="flex-box" style="height: calc(100% - 92px);padding: 0 10px;">
  160. <div class="flex-2 box" id="left">
  161. <div class="boxTitle2">{{ result.ranking.name }}</div>
  162. <div class="ranking" style="border-radius: 8px;margin: 10px;">
  163. <template v-if="result.ranking.list.length>0">
  164. <div style="box-shadow: 0 5px 5px #1d2242;margin-bottom: 5px;border-radius: 8px;">
  165. <div v-for="(item, index) in ranking(result.ranking.list, 1)" :key="index" class="flex-box-ce rankingItem">
  166. <div class="flex-1 flex-box-ce">
  167. <template v-if="item.rank < 4">
  168. <div v-if="item.rank == 1" class="index2"><img src="./assets/image/1.png" /></div>
  169. <div v-if="item.rank == 2" class="index2"><img src="./assets/image/2.png" /></div>
  170. <div v-if="item.rank == 3" class="index2"><img src="./assets/image/3.png" /></div>
  171. </template>
  172. <userImage :user_name="item.employee.name" :img_url="item.employee.img_url" width="30px" height="30px" style="margin: 0 6px;"></userImage>
  173. <div>
  174. <div style="font-size: 14px;">{{ item.employee.name }}</div>
  175. <div class="fontColorT" style="font-size: 12px;margin-top: 5px;" v-if="item.dept_list.length>0">
  176. {{item.dept_list[0].dept_name}} <span v-if="item.dept_list.length>1">...</span>
  177. </div>
  178. </div>
  179. </div>
  180. <div class="num" style="font-size: 14px;">{{ item.s_point }}</div>
  181. </div>
  182. </div>
  183. <vue-seamless-scroll :data="result.ranking.list" class="seamless-warp" :style="{height:h4+'px'}" :class-option="classOption">
  184. <div v-for="(item, index) in ranking(result.ranking.list, 2)" :key="index" class="flex-box-ce rankingItem">
  185. <div class="flex-1 flex-box-ce">
  186. <div style="font-size: 14px;width: 1.4rem;text-align: center;">{{ item.rank }}</div>
  187. <userImage :user_name="item.employee.name" :img_url="item.employee.img_url" width="30px" height="30px" style="margin: 0 6px;"></userImage>
  188. <div>
  189. <div style="font-size: 14px;">{{ item.employee.name }}</div>
  190. <div class="fontColorT" style="font-size: 12px;margin-top: 5px;" v-if="item.dept_list.length>0">
  191. {{item.dept_list[0].dept_name}} <span v-if="item.dept_list.length>1">...</span>
  192. </div>
  193. </div>
  194. </div>
  195. <div class="num" style="font-size: 14px;">{{ item.s_point }}</div>
  196. </div>
  197. </vue-seamless-scroll>
  198. </template>
  199. <div v-else style="height: 200px;text-align: center;line-height: 200px;color: #fff;">
  200. 暂无数据
  201. </div>
  202. </div>
  203. </div>
  204. <div class="flex-3" style="margin: 0 10px;height: 100%;">
  205. <div class="flex-box-ce numBox" style="margin-bottom: 10px">
  206. <div class="flex-1 flex-box-v flex-center-center" style="border-radius: 12px;margin-right: 16px;background-image: linear-gradient(to top, #2537F7 0%, #258CF6 100%);height: 5rem;" @click="endVal = 5123">
  207. <div style="font-size: 0.9rem;margin-bottom: 0.4rem;">今日奖分</div>
  208. <div style="font-size: 2rem;font-weight: 600;letter-spacing:8px;position: relative;">
  209. <countTo :startVal="startVal" separator="" :endVal="result.center.all_add_point" :duration="3000"></countTo>
  210. </div>
  211. </div>
  212. <div class="flex-1 flex-box-v flex-center-center" style="border-radius: 12px;background-image: linear-gradient(to top, #6342E9 0%, #8468F3 100%);height: 5rem;">
  213. <div style="font-size: 0.9rem;margin-bottom: 0.4rem;">今日人次</div>
  214. <div style="font-size: 2rem;font-weight: 600;letter-spacing:8px">
  215. <countTo :startVal="startVal" separator="" :endVal="result.center.count" :duration="3000"></countTo>
  216. </div>
  217. </div>
  218. </div>
  219. <div style="background-color: rgba(23, 30, 72, 0.3); border-radius: 8px;position: relative;">
  220. <div class="boxTitle2" >积分制运用活跃度</div>
  221. <div class="flex-box-ce" style="position: absolute;color:#fff;font-size:12px;right: 10px;top:72px">
  222. <span style="height: 2px;width: 20px;background-color: #E6A23C;"></span>
  223. 基准标尺</div>
  224. <div ref="ManagerSAwardChart" class="chart" style="position: relative;top: 20px;" :style="{height:h5+'px'}"></div>
  225. </div>
  226. </div>
  227. <div class="flex-2 box">
  228. <div class="boxTitle2">{{ result.event.name }}</div>
  229. <div class="ranking">
  230. <template v-if="result.event.list.length">
  231. <vue-seamless-scroll :data="returnEvent(result.event.list)" style="margin: 10px;" class="seamless-warp" :style="{height:h6+'px'}" :class-option="classOption">
  232. <div v-for="(item, index) in returnEvent(result.event.list)" :key="item.id" class="flex-box rankingItem" style="margin-bottom: 10px;background-color: #1B3A70">
  233. <div class="main-right2 flex-1">
  234. <div class="context">{{ $moment.unix(item.event_time).format('YYYY-MM-DD') }}-{{ item.remark.customize ? item.remark.customize : item.remark.rule }}</div>
  235. <div class="flex-box flex-v-ce">
  236. <div class="name flex-1">{{ item.employee.name }}</div>
  237. <div style="font-size: 16px;" v-if="item.point > 0">+{{ item.point }} <span style="color: #01EEFE;">{{ item.pt_id == 3 ? 'B分' : 'A分' }}</span></div>
  238. <div style="font-size: 16px;" class="red " v-else>{{ item.point }} <span style="color: #01EEFE;">{{ item.pt_id == 3 ? 'B分' : 'A分' }}</span></div>
  239. </div>
  240. </div>
  241. </div>
  242. </vue-seamless-scroll>
  243. </template>
  244. <div v-else style="height: 200px;text-align: center;line-height: 200px;color: #fff;">
  245. 暂无数据
  246. </div>
  247. </div>
  248. </div>
  249. </div>
  250. <div style="text-align: center;padding: 6px 0;font-size: 8px;color:#C0C4CC;">@功道云积分制-提供技术支持</div>
  251. </div>
  252. <div class="data-all" v-else style="height: 100%;">
  253. <i class="el-icon-loading" style="margin-top: 15%;width: 150px;margin-bottom: 10px;color: #fff;font-size: 64px;"></i>
  254. <div style="color: #fff;">管理执行难,就用功道云</div>
  255. </div>
  256. <el-dialog title="输入密码" :visible.sync="isShowCode" width="450px" :show-close="false" :close-on-click-modal="false" :close-on-press-escape="false">
  257. <div style="margin: 10px 0;">
  258. <el-input style="width: 300px;" v-model="code" placeholder="请输入随机密码"></el-input>
  259. <div class="yellow">密码可在系统后台 “访问大屏” 功能中获取</div>
  260. </div>
  261. <div class="flex-box-end"><el-button type="primary" :disabled="isShowlog" :loading="isShowlog" @click="opneWebSocket()">确定</el-button></div>
  262. </el-dialog>
  263. </div>
  264. </div>
  265. </template>
  266. <script>
  267. import vueSeamlessScroll from 'vue-seamless-scroll';
  268. import ScaleBox from '@/components/ScaleBox.vue';
  269. import countTo from 'vue-count-to';
  270. export default {
  271. name: 'screen',
  272. components: { vueSeamlessScroll, ScaleBox, countTo },
  273. data() {
  274. return {
  275. startVal: 0,
  276. endVal: 321,
  277. nowTime: '',
  278. // 长连接结果
  279. result: {}, //提交的返回结果集合
  280. code: '',
  281. isShowCode: false,
  282. isDp:false,
  283. isShowlog:false,
  284. h1:'',
  285. h2:'',
  286. h3:'',
  287. errorMsg:'',
  288. isShowError:false,
  289. isPCa:true,
  290. h4:'',
  291. h5:'',
  292. h6:'',
  293. preview:false,
  294. };
  295. },
  296. computed: {
  297. classOption() {
  298. return {
  299. step: 0.5, // 数值越大速度滚动越快
  300. limitMoveNum: 2, // 开始无缝滚动的数据量 this.dataList.length
  301. hoverStop: true, // 是否开启鼠标悬停stop
  302. direction: 1, // 0向下 1向上 2向左 3向右
  303. openWatch: true, // 开启数据实时监控刷新dom
  304. singleHeight: 0, // 单步运动停止的高度(默认值0是无缝不停止的滚动) direction => 0/1
  305. singleWidth: 0, // 单步运动停止的宽度(默认值0是无缝不停止的滚动) direction => 2/3
  306. waitTime: 1000 // 单步运动停止的时间(默认值1000ms)
  307. };
  308. }
  309. },
  310. created() {
  311. this.isPCa=this.IsPC()
  312. },
  313. mounted() {
  314. if(this.$route.query.preview){
  315. this.preview=true;
  316. this.isShowCode = true;
  317. }else{
  318. if (this.$getCache('code')) {
  319. this.code = this.$getCache('code');
  320. this.opneWebSocket()
  321. } else {
  322. this.isShowCode = true;
  323. }
  324. }
  325. this.nowTimes();
  326. window.addEventListener('resize', this.selfAdaption);
  327. },
  328. methods: {
  329. IsPC() {
  330. var userAgentInfo = navigator.userAgent;
  331. var Agents = ["Android", "iPhone","SymbianOS", "Windows Phone","iPad", "iPod"];
  332. var flag = true;
  333. for (var v = 0; v < Agents.length; v++) {
  334. if (userAgentInfo.indexOf(Agents[v]) > 0) {
  335. flag = false;
  336. break;
  337. }
  338. }
  339. return flag;
  340. },
  341. quit(){
  342. if(!this.preview){
  343. this.$removeCache('code');
  344. }
  345. this.result={};
  346. this.code='';
  347. this.isShowCode = true;
  348. this.$socketApi.closewebsocket()
  349. },
  350. opneWebSocket() {
  351. this.isShowlog=true;
  352. this.$socketApi.closewebsocket()
  353. if (!this.code) {
  354. this.$message.error('请输入密码');
  355. this.isShowlog=false;
  356. return false;
  357. }
  358. this.$socketApi.sendData({ type: 'screen', code: this.code }, this.onmessageWS);
  359. },
  360. onmessageWS(e) {
  361. this.isShowlog=false;
  362. console.log(e);
  363. if (e.type == 'screen') {
  364. if (e.code != 1) {
  365. this.result={};
  366. if(e.code=='-2'||e.code=='-3'){
  367. if(!this.isShowCode){
  368. this.$alert('密码已被修改或过期,请重新输入密码', '密码错误', {
  369. confirmButtonText: '确定',
  370. callback: action => {
  371. this.isShowCode = true;
  372. }
  373. });
  374. }else{
  375. this.$message.error('密码错误');
  376. }
  377. }
  378. if(e.code=='-4'){
  379. this.$message.error('窗口链接数量超过限制');
  380. this.quit();
  381. }
  382. } else {
  383. if(!this.preview){
  384. this.$setCache('code', this.code);
  385. }
  386. this.isShowCode = false;
  387. this.result = e.result.result;
  388. this.$nextTick(()=>{
  389. this.isPCa? this.ManagerSAwardCharts2():this.ManagerSAwardCharts()
  390. this.selfAdaption();
  391. })
  392. }
  393. }
  394. // 中途断开
  395. if (e.type == 'break'||e.type == 'error') {
  396. this.isShowError=true;
  397. this.errorMsg=e.msg;
  398. setTimeout(()=>{
  399. this.isShowError=false;
  400. },3000)
  401. }
  402. },
  403. //管理者奖扣统计
  404. ManagerSAwardCharts() {
  405. //管理着奖扣统计表
  406. const chart = this.$refs.ManagerSAwardChart;
  407. let ratio_date=this.result.active.list.ratio_date;
  408. let ratio_get=this.result.active.list.ratio_get;
  409. let ratio_set=this.result.active.list.ratio_set;
  410. if (chart) {
  411. const myChart = this.$echarts.init(chart);
  412. let option = {
  413. tooltip: {
  414. trigger: 'axis',
  415. axisPointer: {
  416. type: 'shadow'
  417. },
  418. formatter: function(a) {
  419. let list = [];
  420. let listItem = '';
  421. for (var i = 0; i < a.length; i++) {
  422. list.push(
  423. '<i style="display: inline-block;width: 10px;height: 10px;background: ' +
  424. a[i].color +
  425. ';margin-right: 5px;border-radius: 50%;}"></i><span style=" display:inline-block;">' +
  426. a[i].seriesName +
  427. '</span>&nbsp:' +
  428. a[i].value+'%'
  429. );
  430. }
  431. listItem = list.join('<br>');
  432. return '<div class="showBox"><div>' + a[0].name + '</div>' + listItem + '</div>';
  433. }
  434. },
  435. legend: {
  436. textStyle: {
  437. color: '#fff',
  438. fontSize: '12',
  439. },
  440. left: '0%',
  441. // data:['上上周','上周','本周'],
  442. data: ratio_date
  443. },
  444. color: [
  445. {
  446. type: 'linear',
  447. x: 0,
  448. y: 0,
  449. x2: 0,
  450. y2: 1,
  451. colorStops: [{ offset: 0, color: '#F8E908' },{ offset: 1, color: '#19286D' }
  452. ]
  453. },
  454. {
  455. type: 'linear',
  456. x: 0,
  457. y: 0,
  458. x2: 0,
  459. y2: 1,
  460. colorStops: [{ offset: 0, color: '#00F8FF' }, { offset: 1, color: '#19286D' }]
  461. },
  462. {
  463. type: 'linear',
  464. x: 0,
  465. y: 0,
  466. x2: 0,
  467. y2: 1,
  468. colorStops: [{ offset: 0, color: '#B117F1' }, { offset: 1, color: '#19286D' }]
  469. }
  470. ],
  471. xAxis: {
  472. type: 'category',
  473. axisLabel: {
  474. show: true,
  475. textStyle: {
  476. color: '#fff',
  477. fontSize: '12'
  478. }
  479. },
  480. data: ['获得积分的人员占比', '执行奖扣的管理者占比']
  481. },
  482. yAxis: {
  483. type: 'value',
  484. max: 100, //取100为最大刻度
  485. axisLabel: {
  486. show: true,
  487. formatter: '{value}%',
  488. textStyle: {
  489. color: '#fff'
  490. }
  491. }
  492. },
  493. series: [
  494. {
  495. type: 'bar',
  496. name: ratio_date[0],
  497. stack: 'Total',
  498. label: {
  499. show: true,
  500. position: 'top',
  501. color:'#fff',
  502. formatter: '{c}%',
  503. fontSize: '12'
  504. },
  505. data: [ratio_get[0], ratio_set[0]]
  506. },
  507. {
  508. type: 'bar',
  509. label: {
  510. show: true,
  511. position: 'top',
  512. color:'#fff',
  513. formatter: '{c}%',
  514. fontSize: '12'
  515. },
  516. name: ratio_date[1],
  517. data: [ratio_get[1], ratio_set[1]]
  518. },
  519. {
  520. type: 'bar',
  521. label: {
  522. show: true,
  523. position: 'top',
  524. color:'#fff',
  525. formatter: '{c}%',
  526. fontSize: '12'
  527. },
  528. name: ratio_date[2],
  529. data: [ratio_get[2], ratio_set[2]],
  530. },
  531. {
  532. type: 'bar',
  533. name: '大啊',
  534. data: [],
  535. markLine: {
  536. silent: true,
  537. data: [
  538. {
  539. silent: false, //鼠标悬停事件 true没有,false有
  540. lineStyle: {
  541. //警戒线的样式 ,虚实 颜色
  542. type: 'solid',
  543. color: '#E6A23C'
  544. },
  545. label: {
  546. position: 'end',
  547. formatter: '标尺',
  548. fontSize: '10'
  549. },
  550. // yAxis: 80
  551. yAxis: this.result.active.base_ratio // 警戒线的标注值,可以有多个yAxis,多条警示线 或者采用 {type : 'average', name: '平均值'},type值有 max min average,分为最大,最小,平均值
  552. }
  553. ]
  554. }
  555. },
  556. ]
  557. };
  558. myChart.setOption(option);
  559. }
  560. },
  561. //管理者奖扣统计
  562. ManagerSAwardCharts2() {
  563. //管理着奖扣统计表
  564. const chart = this.$refs.ManagerSAwardChart;
  565. let ratio_date=this.result.active.list.ratio_date;
  566. let ratio_get=this.result.active.list.ratio_get;
  567. let ratio_set=this.result.active.list.ratio_set;
  568. if (chart) {
  569. const myChart = this.$echarts.init(chart);
  570. let option = {
  571. tooltip: {
  572. trigger: 'axis',
  573. axisPointer: {
  574. type: 'shadow'
  575. },
  576. formatter: function(a) {
  577. let list = [];
  578. let listItem = '';
  579. for (var i = 0; i < a.length; i++) {
  580. list.push(
  581. '<i style="display: inline-block;width: 10px;height: 10px;background: ' +
  582. a[i].color +
  583. ';margin-right: 5px;border-radius: 50%;}"></i><span style=" display:inline-block;">' +
  584. a[i].seriesName +
  585. '</span>&nbsp:' +
  586. a[i].value+'%'
  587. );
  588. }
  589. listItem = list.join('<br>');
  590. return '<div class="showBox"><div>' + a[0].name + '</div>' + listItem + '</div>';
  591. }
  592. },
  593. legend: {
  594. textStyle: {
  595. color: '#fff',
  596. fontSize: '16',
  597. },
  598. left: '3%',
  599. // data:['上上周','上周','本周'],
  600. data: ratio_date
  601. },
  602. color: [
  603. {
  604. type: 'linear',
  605. x: 0,
  606. y: 0,
  607. x2: 0,
  608. y2: 1,
  609. colorStops: [{ offset: 0, color: '#F8E908' },{ offset: 1, color: '#19286D' }
  610. ]
  611. },
  612. {
  613. type: 'linear',
  614. x: 0,
  615. y: 0,
  616. x2: 0,
  617. y2: 1,
  618. colorStops: [{ offset: 0, color: '#00F8FF' }, { offset: 1, color: '#19286D' }]
  619. },
  620. {
  621. type: 'linear',
  622. x: 0,
  623. y: 0,
  624. x2: 0,
  625. y2: 1,
  626. colorStops: [{ offset: 0, color: '#B117F1' }, { offset: 1, color: '#19286D' }]
  627. }
  628. ],
  629. xAxis: {
  630. type: 'category',
  631. axisLabel: {
  632. show: true,
  633. textStyle: {
  634. color: '#fff',
  635. fontSize: '16'
  636. }
  637. },
  638. data: ['获得积分的人员占比', '执行奖扣的管理者占比']
  639. },
  640. yAxis: {
  641. type: 'value',
  642. max: 100, //取100为最大刻度
  643. axisLabel: {
  644. show: true,
  645. formatter: '{value}%',
  646. textStyle: {
  647. color: '#fff'
  648. }
  649. }
  650. },
  651. series: [
  652. {
  653. type: 'bar',
  654. name: ratio_date[0],
  655. label: {
  656. show: true,
  657. position: 'top',
  658. formatter: '{c}%',
  659. color:'#fff',
  660. fontSize: '14'
  661. },
  662. data: [ratio_get[0], ratio_set[0]]
  663. },
  664. {
  665. type: 'bar',
  666. name: ratio_date[1],
  667. label: {
  668. show: true,
  669. position: 'top',
  670. formatter: '{c}%',
  671. color:'#fff',
  672. fontSize: '14'
  673. },
  674. data: [ratio_get[1], ratio_set[1]]
  675. },
  676. {
  677. type: 'bar',
  678. name: ratio_date[2],
  679. label: {
  680. show: true,
  681. position: 'top',
  682. formatter: '{c}%',
  683. color:'#fff',
  684. fontSize: '14'
  685. },
  686. data: [ratio_get[2], ratio_set[2]],
  687. },
  688. {
  689. type: 'bar',
  690. name: '大啊',
  691. data: [],
  692. markLine: {
  693. silent: true,
  694. data: [
  695. {
  696. silent: false, //鼠标悬停事件 true没有,false有
  697. lineStyle: {
  698. //警戒线的样式 ,虚实 颜色
  699. type: 'solid',
  700. color: '#E6A23C'
  701. },
  702. label: {
  703. position: 'end',
  704. formatter: '标尺',
  705. fontSize: '14'
  706. },
  707. // yAxis: 80
  708. yAxis: this.result.active.base_ratio // 警戒线的标注值,可以有多个yAxis,多条警示线 或者采用 {type : 'average', name: '平均值'},type值有 max min average,分为最大,最小,平均值
  709. }
  710. ]
  711. }
  712. },
  713. ]
  714. };
  715. myChart.setOption(option);
  716. }
  717. },
  718. //echarts自适应
  719. selfAdaption() {
  720. let height=document.getElementById('left').offsetHeight;
  721. this.h1=height-344;
  722. this.h2=height-358;
  723. this.h3=height-108;
  724. this.h4=height-234;
  725. this.h5=height-168;
  726. this.h6=height-72;
  727. this.$nextTick(()=>{
  728. var myChart1 = this.$echarts.init(this.$refs.ManagerSAwardChart);
  729. myChart1.resize();
  730. })
  731. },
  732. timeFormate(timeStamp) {
  733. let year = new Date(timeStamp).getFullYear();
  734. let month = new Date(timeStamp).getMonth() + 1 < 10 ? '0' + (new Date(timeStamp).getMonth() + 1) : new Date(timeStamp).getMonth() + 1;
  735. let date = new Date(timeStamp).getDate() < 10 ? '0' + new Date(timeStamp).getDate() : new Date(timeStamp).getDate();
  736. let hh = new Date(timeStamp).getHours() < 10 ? '0' + new Date(timeStamp).getHours() : new Date(timeStamp).getHours();
  737. let mm = new Date(timeStamp).getMinutes() < 10 ? '0' + new Date(timeStamp).getMinutes() : new Date(timeStamp).getMinutes();
  738. let ss = new Date(timeStamp).getSeconds() < 10 ? '0' + new Date(timeStamp).getSeconds() : new Date(timeStamp).getSeconds();
  739. let week = new Date(timeStamp).getDay();
  740. let weeks = ['日', '一', '二', '三', '四', '五', '六'];
  741. let getWeek = '星期' + weeks[week];
  742. this.nowTime = year + '年' + month + '月' + date + '日' + ' ' + hh + ':' + mm + ':' + ss + ' ' + getWeek;
  743. }, // 实时刷新当前时间,格式化
  744. nowTimes() {
  745. this.timeFormate(new Date());
  746. setInterval(this.nowTimes, 1000);
  747. this.clear();
  748. },
  749. clear() {
  750. clearInterval(this.nowTimes);
  751. this.nowTimes = null;
  752. },
  753. fullScreen(){
  754. if(this.isDp){
  755. this.exitScreen();
  756. this.isDp=false;
  757. return false
  758. }
  759. this.isDp=true;
  760. var el = document.documentElement;
  761. var rfs = el.requestFullScreen || el.webkitRequestFullScreen || el.mozRequestFullScreen || el.msRequestFullscreen;
  762. if(typeof rfs != "undefined" && rfs) {
  763. rfs.call(el);
  764. };
  765. return;
  766. },
  767. exitScreen(){
  768. if (document.exitFullscreen) {
  769. document.exitFullscreen();
  770. }
  771. else if (document.mozCancelFullScreen) {
  772. document.mozCancelFullScreen();
  773. }
  774. else if (document.webkitCancelFullScreen) {
  775. document.webkitCancelFullScreen();
  776. }
  777. else if (document.msExitFullscreen) {
  778. document.msExitFullscreen();
  779. }
  780. if(typeof cfs != "undefined" && cfs) {
  781. cfs.call(el);
  782. }
  783. },
  784. returnEvent(list) {
  785. return list;
  786. },
  787. ranking(arr, index) {
  788. if (index == 1) {
  789. return arr.filter(item => {
  790. return item.rank < 4;
  791. });
  792. } else {
  793. return arr.filter(item => {
  794. return item.rank >= 4;
  795. });
  796. }
  797. },
  798. },
  799. beforeDestroy() {
  800. window.removeEventListener('resize', this.selfAdaption); //取消echarts自适应
  801. this.clear();
  802. }
  803. };
  804. </script>
  805. <style scoped>
  806. .back{
  807. background-image: url('assets/image/shuju.jpg');
  808. background-position: center center;
  809. background-size: cover;
  810. background-repeat: no-repeat;
  811. }
  812. .da{
  813. font-size: 20px;
  814. font-weight: 700;
  815. }
  816. .index2 img{
  817. width: 1.4rem !important;
  818. height: 1.4rem !important;
  819. }
  820. .data-all{
  821. text-align: center;
  822. }
  823. html,body{
  824. height: 100%;
  825. }
  826. .barg {
  827. position: absolute;
  828. }
  829. .barg div {
  830. width: 1.4rem;
  831. height: 2.8rem;
  832. background-color: #1d2242;
  833. margin: 0 1rem;
  834. top: ;
  835. }
  836. .boxTitle {
  837. padding: 0.6rem 1.4rem;
  838. color: #fff;
  839. font-size: 22px;
  840. position: relative;
  841. background-color: #16215F;
  842. display: inline-block;
  843. border-radius: 25px;
  844. margin-left: 16px;
  845. padding-left: 50px;
  846. margin-top: 30px;
  847. box-shadow: 2px 0px 2px #ccc;
  848. }
  849. .boxTitle::before {
  850. content: ' ';
  851. position: absolute;
  852. height: 18px;
  853. width: 18px;
  854. background-color: #F8E908;
  855. border-radius: 25px;
  856. top: 16px;
  857. left: 20px;
  858. }
  859. .boxTitle::after {
  860. content: ' ';
  861. position: absolute;
  862. height: 3px;
  863. width: 150px;
  864. background-color: #03F4FD;
  865. top: -20px;
  866. left: 0px;
  867. border-radius: 2px;
  868. }
  869. .boxTitle2 {
  870. padding:0.4rem 0.8rem;
  871. color: #fff;
  872. font-size: 14px;
  873. position: relative;
  874. background-color: #16215F;
  875. display: inline-block;
  876. border-radius: 25px;
  877. margin-left: 10px;
  878. padding-left: 30px;
  879. margin-top: 20px;
  880. box-shadow: 2px 0px 2px #ccc;
  881. }
  882. .boxTitle2::before {
  883. content: ' ';
  884. position: absolute;
  885. height: 12px;
  886. width: 12px;
  887. background-color: #F8E908;
  888. border-radius: 25px;
  889. top: 10px;
  890. left: 10px;
  891. }
  892. .boxTitle2::after {
  893. content: ' ';
  894. position: absolute;
  895. height: 3px;
  896. width: 120px;
  897. background-color: #03F4FD;
  898. top: -14px;
  899. left: 0px;
  900. border-radius: 2px;
  901. }
  902. .chart {
  903. height: 480px;
  904. }
  905. .main-right {
  906. margin-left: 5px;
  907. }
  908. .main-right .name {
  909. font-size: 18px;
  910. color: #0DD3DB;
  911. }
  912. .main-right .context {
  913. overflow: hidden;
  914. text-overflow: ellipsis;
  915. display: -webkit-box;
  916. -webkit-line-clamp: 2;
  917. -webkit-box-orient: vertical;
  918. font-size: 20px;
  919. height: 50px;
  920. margin-bottom: 6px;
  921. }
  922. .main-right2 .date {
  923. color: #909399;
  924. }
  925. .main-right2 {
  926. margin-left: 5px;
  927. }
  928. .main-right2 .name {
  929. font-size: 14px;
  930. color: #0DD3DB;
  931. }
  932. .main-right2 .context {
  933. overflow: hidden;
  934. text-overflow: ellipsis;
  935. display: -webkit-box;
  936. -webkit-line-clamp: 2;
  937. -webkit-box-orient: vertical;
  938. height: 40px;
  939. font-size: 16px;
  940. margin-bottom: 5px;
  941. }
  942. .main-right .date {
  943. color: #909399;
  944. }
  945. .numBox .flex-1 {
  946. height: 13rem;
  947. text-align: center;
  948. color: #fff;
  949. padding: 0.8rem;
  950. }
  951. .seamless-warp {
  952. /* padding: 10px; */
  953. overflow: hidden;
  954. }
  955. .num {
  956. font-size: 24px;
  957. font-weight: 700;
  958. color: #9ecef8;
  959. }
  960. .ranking {
  961. /* height: 100%; */
  962. }
  963. .rankingItem {
  964. color: #fff;
  965. border-radius: 8px;
  966. padding: 10px;
  967. }
  968. .rankingItem img {
  969. width: 30px;
  970. height: 30px;
  971. }
  972. .el-icon-help {
  973. font-size: 26px;
  974. margin-left: 10px;
  975. }
  976. .logo {
  977. width: 2.1rem;
  978. height: 2.1rem;
  979. margin-right: 10px;
  980. border-radius: 3px;
  981. }
  982. .box {
  983. background-color: rgba(23, 30, 72, 0.6);
  984. border-radius: 8px;
  985. height: 100%;
  986. }
  987. .screenBox {
  988. width: 100%;
  989. height: 100%;
  990. min-width: 1000px;
  991. }
  992. .zhuColor {
  993. background-color: #021D3B;
  994. box-shadow: 0px 2px 2px #01EEFE;
  995. position: relative;
  996. color: #fff;
  997. }
  998. .title span {
  999. color: #fff;
  1000. font-size: 1.8rem;
  1001. font-weight: 550;
  1002. position: relative;
  1003. top: -1.8rem;
  1004. }
  1005. .title::after {
  1006. content: ' ';
  1007. position: absolute;
  1008. top: 0px;
  1009. right: -15px;
  1010. border-width: 20px 15px;
  1011. border-style: solid;
  1012. border-color: transparent transparent #021D3B transparent;
  1013. transform: rotate(180deg);
  1014. }
  1015. .title::before {
  1016. content: ' ';
  1017. position: absolute;
  1018. top: 0px;
  1019. left: -15px;
  1020. border-width: 20px 15px;
  1021. border-style: solid;
  1022. transform: rotate(180deg);
  1023. border-color: transparent transparent #021D3B transparent;
  1024. }
  1025. .title2 span {
  1026. color: #fff;
  1027. font-size: 2rem;
  1028. font-weight: 550;
  1029. position: relative;
  1030. top: -2.1rem;
  1031. }
  1032. .title2::after {
  1033. content: ' ';
  1034. position: absolute;
  1035. top: 0px;
  1036. right: -7px;
  1037. border-width: 14px 7px;
  1038. border-style: solid;
  1039. border-color: transparent transparent #021D3B transparent;
  1040. transform: rotate(180deg);
  1041. }
  1042. .title2::before {
  1043. content: ' ';
  1044. position: absolute;
  1045. top: 0px;
  1046. left: -7px;
  1047. border-width: 14px 7px;
  1048. border-style: solid;
  1049. transform: rotate(180deg);
  1050. border-color: transparent transparent #021D3B transparent;
  1051. }
  1052. </style>