registerInfoDialog.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. <template>
  2. <div>
  3. <el-dialog
  4. title="签到信息"
  5. center
  6. :visible.sync="dialogVisible"
  7. width="70%"
  8. append-to-body
  9. top
  10. style="margin-top:100px"
  11. :close-on-click-modal="false"
  12. :show-close="true"
  13. :close-on-press-escape="false"
  14. >
  15. <div class="contain">
  16. <div class="selector">
  17. <div>
  18. 签到状态:
  19. <el-select v-model="selectItem" placeholder="请选择" @change="onSelectorChange">
  20. <el-option
  21. v-for="item in ['全部','已签到','未签到','已补签']"
  22. :key="item"
  23. :label="item"
  24. :value="item"
  25. />
  26. </el-select>
  27. </div>
  28. <div class="rate">
  29. <div>
  30. <el-popover
  31. placement="top-start"
  32. width="300"
  33. trigger="hover"
  34. :content="`应到:${calRate.mustPeople}人,应到人员中实际签到:${calRate.mustSignIn}人(总计签到人数:${calRate.signIn}人,其他签到人数:${calRate.signIn-calRate.mustSignIn}人)`"
  35. >
  36. <div slot="reference" style="cursor: pointer;">出勤率:{{ calRate.signInRate }}%</div>
  37. </el-popover>
  38. </div>
  39. <div>
  40. <el-popover
  41. placement="top-start"
  42. width="300"
  43. trigger="hover"
  44. :content="`应到:${calRate.mustPeople}人,未到:${calRate.noSignIn}人`"
  45. >
  46. <div slot="reference" style="cursor: pointer;">缺勤率:{{ calRate.noSignInRate }}%</div>
  47. </el-popover>
  48. </div>
  49. <div>
  50. <el-popover
  51. placement="top-start"
  52. width="300"
  53. trigger="hover"
  54. :content="`应到:${calRate.mustPeople}人,补签:${calRate.laterSignIn}人`"
  55. >
  56. <div slot="reference" style="cursor: pointer;">补签率:{{ calRate.laterSignInRate }}%</div>
  57. </el-popover>
  58. </div>
  59. </div>
  60. </div>
  61. <div class="table">
  62. <el-table :data="showPaperList" row-key="ren_yuan_id_">
  63. <el-table-column
  64. prop=""
  65. label="序号"
  66. type="index"
  67. width="100"
  68. :index="showIndex"
  69. />
  70. <el-table-column
  71. prop="ren_yuan_id_"
  72. label="应参训人员"
  73. width="150"
  74. >
  75. <template slot-scope="{row}">
  76. <ibps-user-selector
  77. type="user"
  78. :value="row.ren_yuan_id_"
  79. readonly-text="text"
  80. :disabled="true"
  81. :multiple="true"
  82. />
  83. </template>
  84. </el-table-column>
  85. <el-table-column
  86. prop="status"
  87. label="签到状态"
  88. width="150"
  89. >
  90. <template slot-scope="{row}">
  91. <el-tag :type="showType(row)">{{ row.status }}</el-tag>
  92. </template>
  93. </el-table-column>
  94. <el-table-column
  95. prop="qian_dao_shi_jian"
  96. label="签到时间"
  97. align="center"
  98. />
  99. </el-table>
  100. </div>
  101. <el-pagination
  102. style="margin-top: 5px; padding-bottom: 10px"
  103. :current-page="pagination.currentPage"
  104. :page-sizes="[10, 20,30, 50]"
  105. :page-size="pagination.pageSize"
  106. layout="prev,pager,next,jumper,sizes,->,total"
  107. :total="categoryList.length"
  108. @size-change="handleSizeChange"
  109. @current-change="handleCurrentChange"
  110. />
  111. </div>
  112. <span slot="footer" class="dialog-footer">
  113. <el-button @click="close">关 闭</el-button>
  114. </span>
  115. </el-dialog>
  116. </div>
  117. </template>
  118. <script>
  119. import ibpsUserSelector from '@/business/platform/org/selector'
  120. export default {
  121. components: {
  122. ibpsUserSelector
  123. },
  124. props: {
  125. visible: {
  126. type: Boolean,
  127. default: false
  128. },
  129. params: {
  130. type: Object,
  131. default: () => {
  132. return {}
  133. }
  134. }
  135. },
  136. data () {
  137. return {
  138. pagination: {
  139. pageSize: 10,
  140. currentPage: 1
  141. },
  142. dialogVisible: true,
  143. tableList: [],
  144. selectItem: '全部'
  145. }
  146. },
  147. computed: {
  148. // 计算各种统计率
  149. calRate () {
  150. const total = this.tableList.length
  151. let mustPeople = this.tableList.filter(i => i.flag).length
  152. let noSignIn = 0
  153. let signIn = 0
  154. let mustSignIn = 0 // 应参人数中签到的人数
  155. let laterSignIn = 0
  156. this.tableList.forEach(item => {
  157. if (item.status === '已签到') {
  158. signIn++
  159. if (item.flag) mustSignIn++
  160. }
  161. if (item.status === '未签到') noSignIn++
  162. if (item.status === '已补签') laterSignIn++
  163. })
  164. if (mustPeople === 0) { // 没有确定参会人员的情况
  165. mustPeople = total
  166. mustSignIn = signIn
  167. }
  168. const signInRate = mustPeople === 0 ? 0 : mustSignIn / mustPeople * 100
  169. const noSignInRate = mustPeople === 0 ? 0 : noSignIn / mustPeople * 100
  170. const laterSignInRate = mustPeople === 0 ? 0 : laterSignIn / mustPeople * 100
  171. return {
  172. mustSignIn,
  173. mustPeople,
  174. total,
  175. signIn,
  176. noSignIn,
  177. laterSignIn,
  178. signInRate: signInRate.toFixed(2),
  179. noSignInRate: noSignInRate.toFixed(2),
  180. laterSignInRate: laterSignInRate.toFixed(2)
  181. }
  182. },
  183. categoryList () {
  184. const list = { '已签到': 1, '已补签': 2, '未签到': 3 }
  185. const tempList = this.selectItem === '全部' ? this.tableList : this.tableList.filter(item => item.status === this.selectItem)
  186. // 默认排序显示
  187. tempList.sort((a, b) => {
  188. if (list[a.status] && list[b.status]) { return list[a.status] - list[b.status] }
  189. })
  190. return tempList
  191. },
  192. showPaperList () {
  193. const start = (this.pagination.currentPage - 1) * this.pagination.pageSize
  194. const end = start + this.pagination.pageSize
  195. return this.categoryList.slice(start, end)
  196. }
  197. },
  198. async mounted () {
  199. console.log(this.params)
  200. await this.getAllPeople()
  201. },
  202. methods: {
  203. // 选择器切换
  204. onSelectorChange () {
  205. this.pagination = {
  206. pageSize: 10,
  207. currentPage: 1
  208. }
  209. },
  210. // tag 类型
  211. showType (row) {
  212. let type = ''
  213. switch (row.status) {
  214. case '已签到':
  215. type = 'success'
  216. break
  217. case '未签到':
  218. type = 'danger'
  219. break
  220. case '已补签':
  221. type = 'warning'
  222. break
  223. default:
  224. break
  225. }
  226. return type
  227. },
  228. // 手动签到的
  229. addPeople () {
  230. if (!this.params.addPeople) return
  231. this.params.addPeople.split(',').forEach(person => {
  232. const p = this.tableList.find(item => item.ren_yuan_id_ === person)
  233. if (!p) {
  234. this.tableList.push({
  235. ren_yuan_id_: person,
  236. status: '已签到'
  237. })
  238. } else {
  239. p.status = '已签到'
  240. }
  241. })
  242. },
  243. // 获取全部培训人员 7.15通用性调整
  244. async getAllPeople () {
  245. const sql = `select * from ${this.params.tableName} where id_='${this.params.guan_lian_id_}'`
  246. const { variables: { data }} = await this.$common.request('sql', sql)
  247. if (data.length <= 0) {
  248. return this.$message.warning('数据异常!')
  249. }
  250. // console.log('全部人员', data)
  251. let peopleList = []
  252. switch (this.params.tableName) {
  253. case 't_fwxyhyqdb':
  254. peopleList = data[0].bian_zhi_can_hui_?.split(',')
  255. break
  256. case 't_rypxcjb':
  257. peopleList = data[0].pei_xun_ren_yuan_?.split(',')
  258. break
  259. default:
  260. break
  261. }
  262. peopleList.forEach(person => {
  263. if (person) {
  264. this.tableList.push({
  265. ren_yuan_id_: person,
  266. status: '未签到',
  267. qian_dao_shi_jian: '',
  268. flag: true // 原本应参人员的标记
  269. })
  270. }
  271. })
  272. await this.getRegisterPeople()
  273. if (this.params.tableName === 't_rypxcjb') {
  274. if (data[0].shi_fou_guo_shen_ === '进行中') {
  275. this.addPeople()
  276. }
  277. if (data[0].shi_fou_guo_shen_ === '已结束' && data[0].bu_qian_ren_yuan_) {
  278. data[0].bu_qian_ren_yuan_.split(',').forEach(person => {
  279. const p = this.tableList.find(item => item.ren_yuan_id_ === person)
  280. if (p) {
  281. p.status = '已补签'
  282. } else {
  283. this.tableList.push({
  284. ren_yuan_id_: person,
  285. status: '已补签',
  286. qian_dao_shi_jian: ''
  287. })
  288. }
  289. })
  290. }
  291. } else if (this.params.tableName === 't_fwxyhyqdb' || this.params.tableName === 't_nshyjyb' || this.params.tableName === 't_gshyjyb' || this.params.tableName === 't_jykzjbdjb') {
  292. if (data[0].shi_fou_guo_shen_ !== '已完成') {
  293. this.addPeople()
  294. }
  295. }
  296. },
  297. // 获取已签到人员
  298. async getRegisterPeople () {
  299. const sql = `select * from t_qdxxb where guan_lian_id_='${this.params.guan_lian_id_}'`
  300. const { variables: { data }} = await this.$common.request('sql', sql)
  301. // console.log('已签到', data)
  302. data.forEach(person => {
  303. const p = this.tableList.find(item => item.ren_yuan_id_ === person.ren_yuan_id_)
  304. if (!p) {
  305. this.tableList.push({
  306. ren_yuan_id_: person.ren_yuan_id_,
  307. status: '已签到',
  308. qian_dao_shi_jian: person.qian_dao_shi_jian
  309. })
  310. } else {
  311. p.status = '已签到'
  312. p.qian_dao_shi_jian = person.qian_dao_shi_jian
  313. }
  314. })
  315. },
  316. // 当前页码改变
  317. handleCurrentChange (val) {
  318. this.pagination.currentPage = val
  319. },
  320. // 页码选择器改变
  321. handleSizeChange (val) {
  322. this.pagination.pageSize = val
  323. this.pagination.currentPage = 1
  324. },
  325. // 分页连续序号
  326. showIndex (index) {
  327. return index + 1 + (this.pagination.currentPage - 1) * this.pagination.pageSize
  328. },
  329. close () {
  330. this.dialogVisible = false
  331. }
  332. }
  333. }
  334. </script>
  335. <style lang="scss" scoped>
  336. .contain{
  337. padding: 20px;
  338. .table{
  339. height:440px;
  340. overflow: auto;
  341. margin-top: 20px;
  342. }
  343. .selector{
  344. display: flex;
  345. justify-content: space-between;
  346. align-items: center;
  347. .rate{
  348. display: flex;
  349. div{
  350. margin: 0 8px;
  351. font-size: 16px;
  352. }
  353. }
  354. }
  355. }
  356. </style>