custom_rank.vue 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228
  1. <template>
  2. <div class="all-box">
  3. <div class="all flex-box">
  4. <div class="terr-left" v-loading="item_loading">
  5. <div style="text-align: center; padding: 10px 0;"><el-button type="primary" @click="addGroup" :disabled="table_loading" v-if="employeeOrdept">新建分组</el-button></div>
  6. <el-menu v-if="groups_list.length > 0" default-active="0" class="el-menu-vertical-demo elMenuCustomRule_Z">
  7. <el-menu-item v-for="(item, index) in groups_list" :key="index" :index="index.toString()" @click="getGroupsInfo(item)">
  8. <i class="el-icon-document-copy"></i>
  9. <span slot="title">{{ item.name }}</span>
  10. </el-menu-item>
  11. </el-menu>
  12. <div v-else style="text-align: center;margin-top: 10%;" class="fontColorC">
  13. <img src="@/assets/image/nodata.png" style="width: 180px;height: 120px;margin: 30px auto;" />
  14. <div>还没有自定义分组</div>
  15. </div>
  16. </div>
  17. <div class="listData flex-1" v-loading="table_loading">
  18. <div style="margin-bottom: 10px;" v-if="groups_list.length != 0">
  19. <div class="groups_name">
  20. <div class="flex-box flex-v-ce margin-bottom">
  21. <div class="groupsName">
  22. {{ groups_info.name }}
  23. <span class="blue" v-if="total > 0">({{ total }}人)</span>
  24. </div>
  25. <el-button @click="editGroup" v-if="employeeOrdept" size="medium" style="margin-left:15px;">编辑</el-button>
  26. </div>
  27. </div>
  28. </div>
  29. <FormBox style="min-width: 800px !important;width:800px !important;">
  30. <div class="form-item" v-if="newGroupForm.date_interval == 1">
  31. <div class="form-label">月份</div>
  32. <div class="form-search">
  33. <el-date-picker size="medium" v-model="time.month" type="month" :clearable="false" placeholder="请选择月份" value-format="yyyy-MM"></el-date-picker>
  34. </div>
  35. </div>
  36. <div class="form-item" v-if="newGroupForm.date_interval == 2">
  37. <div class="form-label">季度</div>
  38. <div class="form-search">
  39. <Season ref="Seasons" :defaultHint="true" :isActive="true" class="date-picker-width" @confirm="export_quarter_confirm"></Season>
  40. </div>
  41. </div>
  42. <div class="form-item" v-if="newGroupForm.date_interval == 3">
  43. <div class="form-label">年份</div>
  44. <div class="form-search">
  45. <el-date-picker size="medium" v-model="time.year" type="year" :clearable="false" placeholder="请选择年份" value-format="yyyy"></el-date-picker>
  46. </div>
  47. </div>
  48. <div class="form-item">
  49. <el-checkbox style="margin-right: 10px;" v-model="sort" size="medium" label="由低到高" border></el-checkbox>
  50. <el-button type="primary" @click="exportExcel" v-if="table_list.length > 0" size="medium">导 出</el-button>
  51. </div>
  52. </FormBox>
  53. <div style="height: 10px;"></div>
  54. <el-alert
  55. v-if="lastUpdateTime != undefined || lastUpdateTime"
  56. :title="
  57. '温馨提醒:排名会在积分产生后自动更新,最近更新时间:' +
  58. (lastUpdateTime != undefined ? (lastUpdateTime == '' ? '正在更新,请稍候' : lastUpdateTime) : '正在更新,请稍候')
  59. "
  60. type="success"
  61. :closable="false"
  62. show-icon
  63. ></el-alert>
  64. <el-table :data="table_list" @row-click="open_detail">
  65. <el-table-column label="名次" width="80" align="center" >
  66. <template slot-scope="scope">
  67. <img v-if="scope.row.rank === 1" src="@/assets/image/statistics_NO1.png" alt="" />
  68. <img v-if="scope.row.rank === 2" src="@/assets/image/statistics_NO2.png" alt="" />
  69. <img v-if="scope.row.rank === 3" src="@/assets/image/statistics_NO3.png" alt="" />
  70. <span v-if="scope.row.rank > 3">{{ scope.row.rank }}</span>
  71. </template>
  72. </el-table-column>
  73. <el-table-column label="姓名" align="left">
  74. <template slot-scope="scope">
  75. <div class="flex-box">
  76. <userImage :user_name="scope.row.name" :img_url="scope.row.img_url" width="50px" height="50px"></userImage>
  77. <span style="line-height: 50px; padding-left: 10px;">{{ scope.row.name }}</span>
  78. </div>
  79. </template>
  80. </el-table-column>
  81. <el-table-column show-overflow-tooltip label="部门" align="left" prop="deptName"></el-table-column>
  82. <el-table-column label="B分" align="left" prop="point"></el-table-column>
  83. <el-table-column>
  84. <template slot-scope="scope">
  85. <span class="blue" style="cursor: pointer;">查看详情</span>
  86. </template>
  87. </el-table-column>
  88. <template slot="empty">
  89. <div class="nopoint_box">
  90. <div class="noimg noperson"></div>
  91. <span class="title">没有对应的数据</span>
  92. </div>
  93. </template>
  94. </el-table>
  95. <center style="padding: 20px 0;">
  96. <el-pagination
  97. background
  98. @size-change="handleSizeChange"
  99. @current-change="handleCurrentChange"
  100. :page-sizes="[10, 20, 50, 100]"
  101. layout="total, sizes, prev, pager, next"
  102. :page-size="params.page_size"
  103. :current-page="params.page"
  104. :total="total"
  105. ></el-pagination>
  106. </center>
  107. </div>
  108. </div>
  109. <!-- 新增分组 -->
  110. <el-dialog :title="popupType ? '新增分组' : '编辑分组'" width="500px" :visible.sync="groupShow" :close-on-click-modal="false">
  111. <div style="width: 400px;margin: 0 auto;">
  112. <el-form ref="newGroupForm" v-loading="loading" :model="newGroupForm" :rules="rules" label-width="85px" @submit.native.prevent>
  113. <el-form-item label="分组名称" prop="group_name">
  114. <el-input v-model="newGroupForm.group_name" placeholder="请输入分组名称" auto-complete="off"></el-input>
  115. </el-form-item>
  116. <el-form-item label="分组成员" :required="true">
  117. <el-input auto-complete="off" v-model="employees" placeholder="请选择分组成员"></el-input>
  118. <div @click="isEmployeeShow = true" style=" position: absolute; top: 0; right: 0; left: 0; bottom: 0; z-index: 9;"></div>
  119. <el-dialog title="选择人员" width="700px" :visible.sync="isEmployeeShow" append-to-body :before-close="handleClose">
  120. <EmployeeSelector
  121. v-if="isEmployeeShow"
  122. ref="Employee"
  123. :user_no_select="false"
  124. :selected="employees_selected"
  125. :close_clear_data="true"
  126. @confirm="move_employee_confirm"
  127. />
  128. <span slot="footer" class="dialog-footer">
  129. <el-button @click="isEmployeeShow = false">取 消</el-button>
  130. <el-button type="primary" @click="submitEmployee()">确 定</el-button>
  131. </span>
  132. </el-dialog>
  133. </el-form-item>
  134. <el-form-item label="积分规则" :required="true">
  135. <el-input auto-complete="off" v-model="newGroupFormRules" placeholder="全部规则分类"></el-input>
  136. <div @click="ruleDialogTableVisibles" style="height:36px; position: absolute; top: 0; right: 0; left: 0; bottom: 0; z-index: 9;cursor:pointer"></div>
  137. <div style="margin-bottom:12px;">
  138. <span style="font-size:13px;color:#8a8a8a;position: absolute; top: 30px; left: 0;">{{ ruleHint }}</span>
  139. </div>
  140. </el-form-item>
  141. <el-form-item label="统计周期" label-width="85px" :required="true" :show-message="false">
  142. <el-select v-model="options_time_value" placeholder="月度" @change="options_times">
  143. <el-option v-for="item in options_time" :key="item.value" :label="item.label" :value="item.value"></el-option>
  144. </el-select>
  145. </el-form-item>
  146. </el-form>
  147. </div>
  148. <div slot="footer" class="dialog-footer flex-v-ce flex-box">
  149. <el-button type="danger" v-if="!popupType" :loading="delLoad" @click="delItem">删除</el-button>
  150. <div class="flex-1"></div>
  151. <el-button @click="resetForm('newGroupForm')">取 消</el-button>
  152. <el-button type="primary" :loading="saveLoad" @click="subGroupForm('newGroupForm')">确 定</el-button>
  153. </div>
  154. </el-dialog>
  155. <!-- 选择规则 -->
  156. <el-dialog title="选择规则" width="952px" :visible.sync="ruleDialogTableVisible" @close="closeNone" append-to-body :before-close="handleClose">
  157. <div style="display:flex;position: relative;width:100%;height:40px">
  158. <span style="position: absolute;line-height:40px;left:20px">已选:{{ valuesOrLength.length }}条</span>
  159. <el-input type="text" class="search" style="position: absolute;right:20px;width:20%" placeholder="输入关键字搜索" v-model.trim="keyword" />
  160. </div>
  161. <el-row class="architecture">
  162. <el-col :span="8" class="RuleLeft" style="height:500px">
  163. <div ref="ruletree" class="department_box">
  164. <el-tree
  165. ref="menum"
  166. node-key="id"
  167. :accordion="true"
  168. :highlight-current="true"
  169. @node-expand="treeOpen"
  170. :data="treedata"
  171. :default-expand-all="defaultExpand"
  172. :props="defaultProps"
  173. @node-click="handleNodeClick"
  174. @check="handleCheckChange"
  175. >
  176. <div
  177. content="tree"
  178. v-if="!data.dis"
  179. v-show="treedata.length != 0"
  180. class="custom-tree-node"
  181. slot-scope="{ node, data }"
  182. style="font-size: 14px;color: #606266; width:100%; text-align: left;"
  183. >
  184. <span class="name">{{ data.name }}</span>
  185. </div>
  186. </el-tree>
  187. </div>
  188. </el-col>
  189. <el-col :span="16" class="RuleRight" v-loading="tableLoadingRule" style="height:500px;overflow-y:auto">
  190. <el-table
  191. ref="multipleTable"
  192. :data="tableData_rule"
  193. tooltip-effect="dark"
  194. style="width: 100%;cursor:pointer"
  195. @select="onTableSelect"
  196. @select-all="selectAll"
  197. @cell-click="clicktable"
  198. @selection-change="handleSelectionChange"
  199. >
  200. <el-table-column type="selection" width="55"></el-table-column>
  201. <el-table-column prop="remark" :label="'全选'" show-overflow-tooltip></el-table-column>
  202. </el-table>
  203. </el-col>
  204. </el-row>
  205. <span slot="footer" class="dialog-footer">
  206. <el-button @click="ruleDialogTableVisible = false">取 消</el-button>
  207. <el-button type="primary" @click="ruleDialogTableVisibleQD">确 定</el-button>
  208. </span>
  209. </el-dialog>
  210. </div>
  211. </template>
  212. <script>
  213. import EmployeeSelector from '@/components/EmployeeSelector.vue';
  214. import moment from 'moment';
  215. import Season from '@/components/season';
  216. // let valuesLengths = []
  217. var selecteds = [];
  218. let selectionID = [];
  219. //节流
  220. const delay = (function() {
  221. let timer = 0;
  222. return function(callback, ms) {
  223. clearTimeout(timer);
  224. timer = setTimeout(callback.ms);
  225. };
  226. })();
  227. export default {
  228. name:'custom_rank',
  229. data() {
  230. return {
  231. isEmployeeShow: false,
  232. ruleHint: '',
  233. employeeOrdept: !this.$authoritys('employee') && !this.$authoritys('dept_manager'),
  234. lastUpdateTime: '',
  235. tableLoadingRule: false, //规则细则加载
  236. keyword: '',
  237. values_no: [],
  238. backups: [], //备份
  239. valuesLength: [],
  240. multipleSelection: [],
  241. valuesOrLength: [],
  242. itemList: {},
  243. ruleTrees: [], //所有规则列表
  244. tableData_rule: [],
  245. defaultExpand: false,
  246. defaultProps: {
  247. children: 'child',
  248. label: 'name'
  249. },
  250. treedata: [],
  251. ruleDialogTableVisible: false, //编辑-规则-弹出框
  252. loading: false,
  253. options_time: [
  254. {
  255. value: '1',
  256. label: '月度'
  257. },
  258. {
  259. value: '2',
  260. label: '季度'
  261. },
  262. {
  263. value: '3',
  264. label: '年度'
  265. }
  266. ],
  267. options_time_value: '',
  268. popupType: false,
  269. item_loading: false,
  270. table_loading: false,
  271. groups_info_loading: false,
  272. groups_info: {
  273. name: '',
  274. employees: []
  275. },
  276. groups_list: [], //左边分组
  277. table_list: [],
  278. total: null,
  279. time: {
  280. year: moment().format('YYYY'), //年
  281. quarter: moment().format('YYYYQ'), //季度
  282. month: moment().format('YYYY-MM') //月
  283. },
  284. params: {
  285. page: 1,
  286. page_size: 10,
  287. group_id: '',
  288. sort: 'asc',
  289. rule: '',
  290. pt_id: 3
  291. },
  292. rule_trees: [],
  293. clickItem: null,
  294. groupShow: false,
  295. rules: {
  296. group_name: [{ required: true, message: '请输入分组名称', trigger: 'blur' }, { min: 3, max: 10, message: '长度在 3 到 10 个字符', trigger: 'blur' }]
  297. },
  298. newGroupForm: {
  299. group_name: '',
  300. employees: [],
  301. items: [],
  302. date_interval: '1'
  303. },
  304. newGroupFormRules: '',
  305. saveLoad: false,
  306. delLoad: false,
  307. show_employee_selector: false,
  308. employee_not_select: [],
  309. employees_selected: { employee: [], dept: [] },
  310. employees: '',
  311. props: { value: 'id', label: 'name', children: 'child', multiple: true, checkStrictly: true }, //
  312. sort: false
  313. };
  314. },
  315. watch: {
  316. 'time.month'(val, old_val) {
  317. this.time.month = val;
  318. this.params.page = 1;
  319. this.open_right(this.clickItem);
  320. },
  321. 'time.year'(val, old_val) {
  322. this.time.year = val;
  323. this.params.page = 1;
  324. this.open_right(this.clickItem);
  325. },
  326. // "time.quarter"(val, old_val) {
  327. // this.params.quarter = val
  328. // // this.params.page = 1;
  329. // // this.open_right(this.clickItem);
  330. // },
  331. sort(val) {
  332. this.params.page = 1;
  333. val ? (this.params.sort = 'desc') : (this.params.sort = 'asc');
  334. this.open_right(this.clickItem);
  335. },
  336. keyword() {
  337. //函数节流
  338. if (this.timer) {
  339. clearTimeout(this.timer);
  340. }
  341. //清空 全部
  342. if (!this.keyword) {
  343. this.tableData_rule = this.tableData_rule2;
  344. this.ifPitchOnChild(this.tableData_rule, selecteds);
  345. return;
  346. }
  347. this.timer = setTimeout(() => {
  348. const result = [];
  349. this.tableData_rule2.forEach(val => {
  350. if (val.remark.indexOf(this.keyword) > -1) {
  351. result.push(val);
  352. }
  353. });
  354. this.tableData_rule = result;
  355. this.ifPitchOnChild(this.tableData_rule, selecteds);
  356. }, 100);
  357. }
  358. },
  359. components: { EmployeeSelector, Season },
  360. methods: {
  361. open_detail(item) {
  362. let data={
  363. userInfo:JSON.stringify(item),
  364. type:3,
  365. items:this.clickItem.items,
  366. dateType:this.newGroupForm.date_interval,
  367. }
  368. if(this.newGroupForm.date_interval=='1'){
  369. data.date=this.time.month
  370. this.$router.push({path: '/JfDetail',query:data})
  371. }
  372. if(this.newGroupForm.date_interval=='2'){
  373. let date={type:2,year:this.time.quarter.slice(0,4),season:this.time.quarter.slice(4)}
  374. this.getDate((res)=>{
  375. data.start_date = this.$moment(Number(res.data.start+'000')).format('YYYY-MM-DD')
  376. data.end_date = this.$moment(Number(res.data.end+'000')).format('YYYY-MM-DD')
  377. this.$router.push({path: '/JfDetail',query:data})
  378. },date)
  379. }
  380. if(this.newGroupForm.date_interval=='3'){
  381. data.date=this.time.year
  382. this.$router.push({path: '/JfDetail',query:data})
  383. }
  384. },
  385. getDate(func,date) {
  386. this.$axios('post', '/api/timestamp', date).then(res => {
  387. func(res.data)
  388. });
  389. },
  390. exportExcel() {
  391. let months;
  392. if (this.newGroupForm.date_interval == '1') {
  393. months = this.time.month.replace('-', '');
  394. }
  395. let data={
  396. group_id:this.clickItem.id,
  397. date:'',
  398. sort:this.sort?'desc':'asc',
  399. employee_id:this.$getUserData().id,
  400. };
  401. data.date =this.newGroupForm.date_interval == '1'? months: this.newGroupForm.date_interval == '2'
  402. ? this.time.quarter
  403. : this.newGroupForm.date_interval == '3'
  404. ? this.time.year
  405. : '';
  406. let str='&group_id='+data.group_id+'&date='+data.date+'&sort='+data.sort;
  407. window.open(process.env.VUE_APP_BASE_API + 'api/download/groups_export/v2?employee_id='+this.$getUserData().id+str, '_blank');
  408. },
  409. submitEmployee() {
  410. this.$refs.Employee.confirm(); //调用组件的confirm();
  411. },
  412. //点击某行
  413. clicktable(row, column, cell, event) {
  414. let selectedsif = false;
  415. for (let i in selecteds) {
  416. if (row.id == selecteds[i]) {
  417. selectedsif = true;
  418. selecteds.splice(i, 1);
  419. this.toggleSelection([row], false);
  420. }
  421. }
  422. if (selectedsif == false) {
  423. selecteds.push(row.id);
  424. this.ifPitchOnChild(this.tableData_rule, selecteds);
  425. }
  426. },
  427. //全选
  428. selectAll(selection) {
  429. for (let i in selection) {
  430. selectionID.push(selection[i].id);
  431. }
  432. let tableData_rules = []; //当前分页id
  433. for (let i in this.tableData_rule) {
  434. tableData_rules.push(this.tableData_rule[i].id);
  435. }
  436. selectionID = [...new Set(selectionID)];
  437. if (selection.length == 0) {
  438. //全不选
  439. //判断差值
  440. var diff = [];
  441. var tmp = tableData_rules;
  442. selectionID.forEach(function(val1, i) {
  443. if (tableData_rules.indexOf(val1) < 0) {
  444. diff.push(val1);
  445. } else {
  446. tmp.splice(tmp.indexOf(val1), 1);
  447. }
  448. });
  449. selectionID = diff.concat(tmp);
  450. } else {
  451. //全选
  452. }
  453. selecteds = [...new Set(selectionID)];
  454. this.valuesOrLength = selecteds;
  455. },
  456. // 递归判断列表,把最后的children设为undefined
  457. getTreeData(data) {
  458. for (var i = 0; i < data.length; i++) {
  459. if (data[i].child.length < 1) {
  460. // children若为空数组,则将children设为undefined
  461. data[i].child = undefined;
  462. } else {
  463. // children若不为空数组,则继续 递归调用 本方法
  464. this.getTreeData(data[i].child);
  465. }
  466. }
  467. return data;
  468. },
  469. //获取规则
  470. get_rule_trees() {
  471. this.$axios('get', '/api/integral/rule/trees', { cycle_type: 1 }).then(res => {
  472. this.treedata = this.getTreeData(res.data.data.rule_tree || []);
  473. this.itemList = res.data.data.item_list; //规则
  474. });
  475. },
  476. //点击规则弹出窗口
  477. ruleDialogTableVisibles() {
  478. this.tableLoadingRule = true;
  479. selecteds = this.valuesOrLength;
  480. //点击弹出窗口并展示所有数据
  481. let tableData_r = [];
  482. for (let i in this.itemList) {
  483. for (let a in this.itemList[i]) {
  484. tableData_r.push(this.itemList[i][a]);
  485. }
  486. }
  487. this.tableData_rule2 = tableData_r; //赋予筛选数据
  488. this.tableData_rule = tableData_r;
  489. this.ruleDialogTableVisible = true;
  490. this.ifPitchOnChild(this.tableData_rule, selecteds);
  491. },
  492. recursion(data, arr) {
  493. for (let i in data.child) {
  494. if (data.child.length != 0) {
  495. arr.push(data.id);
  496. } else {
  497. arr.push(data.id);
  498. }
  499. }
  500. return [...new Set(arr)];
  501. },
  502. //此方法:拿到当前点击规则分类的所有子节点ID,(为了包含子分类 规则)
  503. menuIdInit(menus) {
  504. var _this = this;
  505. var _menu = menus;
  506. var menuId = [];
  507. var len = _menu.length;
  508. for (var i = 0; i < len; i++) {
  509. var item = _menu[i];
  510. if (item.child && item.child.length != 0) {
  511. var child = item.child;
  512. for (var j = 0; j < child.length; j++) {
  513. _menu[len + j] = child[j];
  514. }
  515. len = _menu.length;
  516. }
  517. menuId.push(item.id);
  518. }
  519. return menuId;
  520. },
  521. //点击规则分类
  522. handleNodeClick(data) {
  523. let dataArr = this.menuIdInit([data]); //调用方法
  524. this.tableLoadingRule = true;
  525. this.keyword = ''; //切换规则重置搜索框
  526. let tableData_r = [];
  527. for (let i in this.itemList) {
  528. for (let a in this.itemList[i]) {
  529. for (let x in dataArr) {
  530. if (dataArr[x] == this.itemList[i][a].rule_id) {
  531. tableData_r.push(this.itemList[i][a]);
  532. }
  533. }
  534. }
  535. }
  536. this.tableData_rule2 = tableData_r; //赋予筛选数据
  537. this.tableData_rule = tableData_r;
  538. this.ifPitchOnChild(this.tableData_rule, selecteds);
  539. },
  540. ifPitchOnChild(item, indexID) {
  541. let pitchOnChild = [];
  542. for (let i in item) {
  543. for (let a in indexID) {
  544. //判断外层的值相不相等
  545. if (indexID[a] == item[i].id) {
  546. pitchOnChild.push(item[i]);
  547. }
  548. }
  549. }
  550. this.toggleSelection(pitchOnChild, true);
  551. },
  552. //默认选中
  553. toggleSelection(rows, selected) {
  554. if (rows) {
  555. this.$nextTick(() => {
  556. rows.forEach(row => {
  557. this.$refs.multipleTable.toggleRowSelection(row, selected);
  558. });
  559. });
  560. } else {
  561. this.$refs.multipleTable.clearSelection();
  562. }
  563. setTimeout(() => {
  564. //给遮到层,让默认选中的有缓冲时间
  565. this.tableLoadingRule = false;
  566. }, 300);
  567. },
  568. onTableSelect(rows, row) {
  569. let selected = rows.length && rows.indexOf(row) !== -1;
  570. if (selected) {
  571. selecteds.push(row.id);
  572. } else {
  573. for (let i in selecteds) {
  574. if (row.id == selecteds[i]) {
  575. selecteds.splice(i, 1);
  576. }
  577. }
  578. }
  579. },
  580. //规则弹窗选中时
  581. handleSelectionChange(val) {},
  582. //关闭回调
  583. closeNone() {
  584. selecteds = [];
  585. },
  586. //规则弹窗确定
  587. ruleDialogTableVisibleQD() {
  588. let valuesLengths = [];
  589. for (let i in selecteds) {
  590. valuesLengths.push(selecteds[i]);
  591. }
  592. // valuesLengths = selecteds
  593. this.valuesOrLength = valuesLengths;
  594. this.newGroupForm.items = this.valuesOrLength;
  595. if (this.valuesOrLength.length >= 1) {
  596. this.newGroupFormRules = this.valuesOrLength.length + '条规则';
  597. this.ruleHint = '统计已选规则的积分(只选分类不指定规则的积分除外)';
  598. } else {
  599. this.newGroupFormRules = '';
  600. this.ruleHint = '统计所有积分(基础分和工龄分除外)';
  601. }
  602. this.ruleDialogTableVisible = false;
  603. },
  604. //关闭
  605. handleClose(done) {
  606. done();
  607. },
  608. // 选择时间-季度
  609. export_quarter_confirm(val) {
  610. this.time.quarter = val;
  611. this.params.page = 1;
  612. this.open_right(this.clickItem);
  613. },
  614. // 树型菜单点击筛选
  615. handleCheckChange(check, param) {},
  616. getRuletableData_rule(data) {
  617. let tableData_ruleP = [];
  618. for (let i in data) {
  619. }
  620. return data;
  621. },
  622. getRuleTreeDatas(data) {
  623. let dates = [];
  624. for (let i in data) {
  625. if (data[i].child == undefined) {
  626. dates.push(data[i]);
  627. } else {
  628. this.getRuleTreeData(data[i].child);
  629. }
  630. }
  631. return dates;
  632. },
  633. treeOpen() {},
  634. //点击编辑
  635. editGroup() {
  636. this.groupShow = true;
  637. this.popupType = false;
  638. this.getGroupsInfo(this.clickItem, true);
  639. },
  640. // 获取分类信息
  641. getGroupsInfo(item, ifs) {
  642. let self = this;
  643. if (!item) {
  644. return false;
  645. }
  646. if (!ifs) {
  647. self.table_loading = true;
  648. this.params.page = 1;
  649. }
  650. this.loading = true;
  651. self.$axios('get', '/api/integral/statistics/groups/info', { group_id: item.id })
  652. .then(res => {
  653. if (res.data.code == 1) {
  654. // 规则ID
  655. let itemsBjRule_ID = [];
  656. for (let i in res.data.data.items) {
  657. itemsBjRule_ID.push(res.data.data.items[i].id);
  658. }
  659. this.valuesOrLength = itemsBjRule_ID;
  660. if (this.valuesOrLength.length >= 1) {
  661. this.newGroupFormRules = this.valuesOrLength.length + '条规则';
  662. this.ruleHint = '统计已选规则的积分(只选分类不指定规则的积分除外)';
  663. } else {
  664. this.newGroupFormRules = '';
  665. this.ruleHint = '统计所有积分(基础分和工龄分除外)';
  666. }
  667. this.newGroupForm.date_interval = res.data.data.date_interval;
  668. this.options_time_value =
  669. res.data.data.date_interval == 1 ? '月度' : res.data.data.date_interval == 2 ? '季度' : res.data.data.date_interval == 3 ? '年度' : '';
  670. self.groups_info = res.data.data;
  671. self.newGroupForm.employees = [];
  672. self.employees = '';
  673. self.employees_selected.employee = res.data.data.employees;
  674. res.data.data.employees.forEach(element => {
  675. self.newGroupForm.employees.push(element.id);
  676. self.employees += element.name + ',';
  677. });
  678. self.newGroupForm.group_name = res.data.data.name;
  679. this.loading = false;
  680. if (!ifs) {
  681. this.open_right(item, true);
  682. }
  683. } else {
  684. self.$message.error(res.data.data.msg);
  685. this.loading = false;
  686. }
  687. })
  688. .catch(() => {
  689. if (!ifs) {
  690. self.table_loading = false;
  691. }
  692. })
  693. .finally(() => {
  694. this.loading = false;
  695. });
  696. },
  697. //编辑时间选中
  698. options_times(val) {
  699. this.newGroupForm.date_interval = val;
  700. },
  701. // 规则分类改变之后请求数据
  702. rule_null(val) {
  703. let ruleNullId = [];
  704. for (let i in val) {
  705. for (let a in val[i]) {
  706. ruleNullId.push(val[i][a]);
  707. }
  708. }
  709. },
  710. // 选人组件提交
  711. move_employee_confirm(data) {
  712. this.newGroupForm.employees = [];
  713. this.employees = '';
  714. this.employees_selected = data;
  715. if (data.employee !== null && data.employee.length != 0) {
  716. data.employee.forEach(element => {
  717. this.newGroupForm.employees.push(element.id);
  718. this.employees += element.name + ',';
  719. });
  720. }
  721. this.isEmployeeShow = false;
  722. },
  723. // 删除分组
  724. delItem() {
  725. let self = this;
  726. this.$confirm('确定要删除当前分组吗?, 是否继续?', '删除分组', {
  727. confirmButtonText: '确定',
  728. cancelButtonText: '取消',
  729. type: 'warning'
  730. }).then(() => {
  731. let data = { group_id: self.clickItem.id };
  732. self.delLoad = true;
  733. self.$axios('post', '/api/integral/statistics/groups/drop', data)
  734. .then(res => {
  735. if (res.data.code == 1) {
  736. self.$message.success(res.data.msg);
  737. self.groupShow = false;
  738. self.getGroupsList();
  739. } else {
  740. self.$message.error(res.data.msg);
  741. }
  742. })
  743. .finally(() => {
  744. self.delLoad = false;
  745. });
  746. });
  747. },
  748. // 提交表单
  749. subGroupForm(formName) {
  750. this.$refs[formName].validate(valid => {
  751. if (valid) {
  752. this.saveFun();
  753. }
  754. });
  755. },
  756. saveFun() {
  757. let self = this;
  758. let data = JSON.parse(JSON.stringify(self.newGroupForm));
  759. if (!self.popupType) {
  760. data.group_id = self.clickItem.id;
  761. }
  762. if(data.items.length==0){
  763. data.items=this.valuesOrLength
  764. }
  765. if(data.employees.length==0){
  766. this.$message.error("分组人员不能为空");
  767. return false
  768. }
  769. self.saveLoad = true;
  770. self.$axios('POST', this.popupType ? '/api/integral/statistics/groups/create' : '/api/integral/statistics/groups', data)
  771. .then(res => {
  772. if (res.data.code == 1) {
  773. if (self.popupType) {
  774. self.popupType = false;
  775. this.getGroupsList();
  776. } else {
  777. self.getGroupsList(self.clickItem.id); //传入当前ID.为了修改后页面不切换
  778. }
  779. self.$message.success(res.data.msg);
  780. const resData = res.data.data;
  781. self.groups_list.push({
  782. id: resData.id,
  783. employees: resData.employees,
  784. name: name
  785. }); //左边分组
  786. self.groupShow = false;
  787. this.employees = '';
  788. this.employee_not_select = [];
  789. this.employees_selected = { employee: [], dept: [] };
  790. } else {
  791. self.$message.error(res.data.msg);
  792. }
  793. })
  794. .finally(() => {
  795. setTimeout(() => {
  796. self.saveLoad = false;
  797. }, 500);
  798. });
  799. },
  800. // 重置表单
  801. resetForm(formName) {
  802. this.$refs[formName].resetFields();
  803. this.newGroupForm.employees = [];
  804. this.employees = '';
  805. this.employee_not_select = [];
  806. this.employees_selected = { employee: [], dept: [] };
  807. this.groupShow = false;
  808. },
  809. // 新增分组
  810. addGroup() {
  811. //规则
  812. (this.newGroupFormRules = ''), (this.valuesOrLength = []), (this.options_time_value = '');
  813. this.groupShow = true;
  814. this.popupType = true;
  815. this.employees = '';
  816. this.employee_not_select = [];
  817. this.employees_selected = { employee: [], dept: [] };
  818. this.newGroupForm = {
  819. group_name: '',
  820. employees: [],
  821. rules: [],
  822. items: [],
  823. date_interval: '1'
  824. };
  825. this.ruleHint = '统计所有积分(基础分和工龄分除外)';
  826. },
  827. // 页码变更
  828. handleCurrentChange(val) {
  829. this.params.page = val;
  830. this.open_right(this.clickItem);
  831. },
  832. handleSizeChange(val) {
  833. this.params.page_size = val;
  834. this.open_right(this.clickItem);
  835. },
  836. open_right(item, tim) {
  837. if (tim) {
  838. this.time = {
  839. year: moment().format('YYYY'), //年
  840. quarter: moment().format('YYYYQ'), //季度
  841. month: moment().format('YYYY-MM') //月
  842. };
  843. if (this.$refs.Seasons) {
  844. if (this.newGroupForm.date_interval == 2) {
  845. this.$refs.Seasons.choseQuarter = '';
  846. }
  847. }
  848. }
  849. this.valuesOrLength = [];
  850. let self = this;
  851. self.table_loading = true;
  852. self.clickItem = item;
  853. if (!item) {
  854. self.table_loading = false;
  855. return false;
  856. }
  857. let data = JSON.parse(JSON.stringify(self.params));
  858. data.rule ? '' : delete data.rule;
  859. // data.date ? "" : delete data.month;
  860. data.group_id = item.id;
  861. let months;
  862. if (this.newGroupForm.date_interval == '1') {
  863. months = this.time.month.replace('-', '');
  864. }
  865. data.date =
  866. this.newGroupForm.date_interval == '1'
  867. ? months
  868. : this.newGroupForm.date_interval == '2'
  869. ? this.time.quarter
  870. : this.newGroupForm.date_interval == '3'
  871. ? this.time.year
  872. : '';
  873. self.$axios('get', '/api/integral/statistics/groups/rank', data,'v2')
  874. .then(res => {
  875. if (res.data.code == 1) {
  876. this.table_list =this.$returnDeptName(res.data.data.list);
  877. self.total = res.data.data.total;
  878. self.lastUpdateTime = res.data.data.update_time;
  879. } else {
  880. self.$message.error(res.data.data.msg);
  881. }
  882. })
  883. .finally(() => {
  884. self.table_loading = false;
  885. });
  886. },
  887. // 获取分类列表
  888. getGroupsList(atPresent, isload) {
  889. let self = this;
  890. self.item_loading = true;
  891. self.$axios('get', '/api/integral/statistics/groups')
  892. .then(res => {
  893. if (res.data.code == 1) {
  894. // self.groups_list = res.data.data.list;//获取所有
  895. let lists = res.data.data.list;
  896. if (this.$authoritys('employee')) {
  897. //员工权限只能查看包含自己的
  898. let user = this.$getUserData().id;
  899. let data = [];
  900. lists.forEach(item => {
  901. if (item.employees.length == 0) {
  902. data.push(item);
  903. } else {
  904. item.employees.forEach(id=>{
  905. if(id==user){
  906. data.push(item);
  907. }
  908. })
  909. // if (item.employees.indexOf(user.toString()) != -1) {
  910. // data.push(item);
  911. // }
  912. }
  913. });
  914. this.$nextTick(()=>{
  915. this.groups_list = data;
  916. })
  917. } else {
  918. this.$nextTick(()=>{
  919. this.groups_list = lists;
  920. })
  921. }
  922. self.$nextTick(() => {
  923. if (atPresent) {
  924. for (let i in self.groups_list) {
  925. if (atPresent == self.groups_list[i].id) {
  926. self.getGroupsInfo(self.groups_list[i]);
  927. }
  928. }
  929. } else {
  930. if (!isload) {
  931. self.open_right(self.groups_list[0]);
  932. }
  933. self.getGroupsInfo(self.groups_list[0]);
  934. }
  935. });
  936. } else {
  937. self.$message.error(res.data.data.msg);
  938. }
  939. })
  940. .finally(() => {
  941. self.item_loading = false;
  942. });
  943. }
  944. },
  945. mounted() {
  946. this.get_rule_trees();
  947. this.getGroupsList(false, true); //避免首次进入调用两次open_right()方法,加上true判断
  948. }
  949. };
  950. </script>
  951. <style scoped lang="scss">
  952. .el-checkbox.is-bordered.el-checkbox--medium {
  953. padding: 9px 20px 7px 10px;
  954. }
  955. ::v-deep .itemClass .el-cascader-menu .el-cascader-menu__wrap li.el-cascader-node {
  956. height: auto;
  957. max-width: 500px;
  958. .el-cascader-node__label {
  959. white-space: initial;
  960. overflow: initial;
  961. text-overflow: initial;
  962. }
  963. }
  964. .listData {
  965. position: relative;
  966. display: table-cell;
  967. margin: 0 !important;
  968. padding: 20px;
  969. min-width: 600px;
  970. &::after {
  971. content: ' ';
  972. position: absolute;
  973. top: 0;
  974. left: 0;
  975. bottom: 0;
  976. width: 1px;
  977. background: #ebeef5;
  978. }
  979. & .groups_name {
  980. display: block;
  981. font-size: 20px;
  982. color: rgb(48, 49, 51);
  983. vertical-align: middle;
  984. }
  985. }
  986. ::v-deep .el-menu-item {
  987. overflow: hidden;
  988. white-space: nowrap;
  989. text-overflow: ellipsis;
  990. &.is-active {
  991. background-color: #ecf5ff;
  992. }
  993. }
  994. .architecture {
  995. display: flex;
  996. text-align: center;
  997. // margin-top:20px;
  998. padding-left: 0px;
  999. background-color: #fff;
  1000. width: 100%;
  1001. overflow: hidden;
  1002. cursor: default;
  1003. min-height: calc(60vh - 160px);
  1004. }
  1005. .architecture .RuleLine {
  1006. display: table-cell;
  1007. width: 1px;
  1008. min-height: 600px;
  1009. background: hsl(0, 2%, 76%);
  1010. }
  1011. .architecture .RuleLeft {
  1012. display: block;
  1013. text-align: center;
  1014. padding: 20px 10px;
  1015. border-right: none;
  1016. overflow-y: auto;
  1017. overflow-x: none;
  1018. }
  1019. /*滚动条的宽度*/
  1020. .architecture .RuleLeft::-webkit-scrollbar {
  1021. width: 9px;
  1022. height: 9px;
  1023. }
  1024. .architecture .RuleRight::-webkit-scrollbar {
  1025. width: 9px;
  1026. height: 9px;
  1027. }
  1028. /*外层轨道。可以用display:none让其不显示,也可以添加背景图片,颜色改变显示效果*/
  1029. .architecture .RuleLeft::-webkit-scrollbar-track {
  1030. width: 6px;
  1031. background-color: #fff0;
  1032. -webkit-border-radius: 2em;
  1033. -moz-border-radius: 2em;
  1034. border-radius: 2em;
  1035. }
  1036. .architecture .RuleRight::-webkit-scrollbar-track {
  1037. width: 6px;
  1038. background-color: #fff0;
  1039. -webkit-border-radius: 2em;
  1040. -moz-border-radius: 2em;
  1041. border-radius: 2em;
  1042. }
  1043. /*滚动条的设置*/
  1044. .architecture .RuleLeft::-webkit-scrollbar-thumb {
  1045. background-color: #fff0;
  1046. background-clip: padding-box;
  1047. min-height: 28px;
  1048. -webkit-border-radius: 2em;
  1049. -moz-border-radius: 2em;
  1050. border-radius: 2em;
  1051. }
  1052. .architecture .RuleRight::-webkit-scrollbar-thumb {
  1053. background-color: #fff0;
  1054. background-clip: padding-box;
  1055. min-height: 28px;
  1056. -webkit-border-radius: 2em;
  1057. -moz-border-radius: 2em;
  1058. border-radius: 2em;
  1059. }
  1060. /*滚动条移上去的背景*/
  1061. .architecture .RuleLeft:hover::-webkit-scrollbar-thumb {
  1062. overflow-x: none;
  1063. background-color: rgba(144, 147, 153, 0.3);
  1064. }
  1065. .architecture .RuleRight:hover::-webkit-scrollbar-thumb {
  1066. background-color: rgba(115, 118, 124, 0.3);
  1067. }
  1068. .architecture .RuleLeft .company_name {
  1069. position: relative;
  1070. display: block;
  1071. font-family: 'Microsoft YaHei';
  1072. text-align: left;
  1073. padding: 15px 28px 17px;
  1074. cursor: pointer;
  1075. overflow: hidden;
  1076. white-space: nowrap;
  1077. text-overflow: ellipsis;
  1078. border-bottom: 1px #f8f8f8 solid;
  1079. }
  1080. .architecture .RuleLeft .company_name img {
  1081. position: relative;
  1082. display: inline-block;
  1083. top: 2px;
  1084. width: 18px;
  1085. height: 18px;
  1086. margin-right: 4px;
  1087. }
  1088. .architecture .RuleLeft ::v-deep .el-button {
  1089. margin-bottom: 16px !important;
  1090. }
  1091. .architecture .RuleRight {
  1092. position: relative;
  1093. display: table-cell;
  1094. text-align: left;
  1095. padding: 20px;
  1096. }
  1097. .architecture .RuleRight .title span .sapn {
  1098. display: inline-block;
  1099. vertical-align: middle;
  1100. max-width: 600px;
  1101. overflow: hidden;
  1102. white-space: nowrap;
  1103. text-overflow: ellipsis;
  1104. }
  1105. .architecture .RuleRight:after {
  1106. content: ' ';
  1107. position: absolute;
  1108. top: 0;
  1109. left: 0;
  1110. bottom: 0;
  1111. width: 1px;
  1112. background: #ebeef5;
  1113. }
  1114. .architecture .RuleRight .list_box {
  1115. width: 100%;
  1116. background: #fff;
  1117. }
  1118. .architecture .RuleRight .list_box ::v-deep table {
  1119. font-family: 'Microsoft YaHei';
  1120. width: 100% !important;
  1121. /*max-width:1920px; */
  1122. }
  1123. .architecture .department_box {
  1124. }
  1125. .architecture .department_box ::v-deep .el-tree-node {
  1126. display: block;
  1127. text-align: center;
  1128. }
  1129. .architecture .department_box ::v-deep .el-tree-node__content {
  1130. // padding-left:24px !important;
  1131. height: auto !important;
  1132. }
  1133. .architecture .department_box ::v-deep .el-tree-node .el-icon-caret-right {
  1134. display: inline-block;
  1135. color: #909399;
  1136. font-size: 16px;
  1137. padding: 6px 8px;
  1138. }
  1139. .architecture .department_box ::v-deep .el-tree-node .el-icon-caret-right.is-leaf {
  1140. color: transparent;
  1141. cursor: default;
  1142. }
  1143. .architecture .department_box ::v-deep .el-tree-node .custom-tree-node img {
  1144. margin-top: 0px;
  1145. width: 20px;
  1146. }
  1147. .architecture .department_box ::v-deep .el-tree-node .custom-tree-node span {
  1148. }
  1149. .architecture .department_box ::v-deep .el-tree-node__content {
  1150. padding: 12px 0;
  1151. border-bottom: 1px #f8f8f8 solid;
  1152. }
  1153. .architecture .department_box ::v-deep .el-tree-node__content:hover {
  1154. background: #ecf5ff;
  1155. border-radius: 4px;
  1156. }
  1157. .architecture .department_box ::v-deep .is-focusable .is-current {
  1158. border-radius: 4px;
  1159. }
  1160. .architecture .department_box ::v-deep .is-focusable .is-current .name {
  1161. color: #409eff;
  1162. font-weight: normal;
  1163. transition: 0.35s ease-in-out;
  1164. }
  1165. .elMenuCustomRule_Z {
  1166. overflow-y: auto;
  1167. border: none;
  1168. // height: 980px;
  1169. }
  1170. // 滚动条样式
  1171. .elMenuCustomRule_Z::-webkit-scrollbar {
  1172. width: 9px;
  1173. height: 9px;
  1174. }
  1175. .elMenuCustomRule_Z::-webkit-scrollbar-track {
  1176. width: 6px;
  1177. background-color: #fff0;
  1178. -webkit-border-radius: 2em;
  1179. -moz-border-radius: 2em;
  1180. border-radius: 2em;
  1181. }
  1182. /*滚动条的设置*/
  1183. .elMenuCustomRule_Z::-webkit-scrollbar-thumb {
  1184. background-color: #fff0;
  1185. background-clip: padding-box;
  1186. min-height: 28px;
  1187. -webkit-border-radius: 2em;
  1188. -moz-border-radius: 2em;
  1189. border-radius: 2em;
  1190. }
  1191. /*滚动条移上去的背景*/
  1192. .elMenuCustomRule_Z:hover::-webkit-scrollbar-thumb {
  1193. background-color: rgba(144, 147, 153, 0.3);
  1194. }
  1195. ::v-deep .el-table .cell {
  1196. //让规则不隐藏
  1197. overflow: inherit;
  1198. white-space: normal;
  1199. }
  1200. .terr-left button {
  1201. margin: 0 auto;
  1202. display: block;
  1203. margin-bottom: 20px;
  1204. }
  1205. </style>