flManagement.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607
  1. <template>
  2. <div>
  3. <div class="all">
  4. <div class="flex-box-ce flex-d-wrap" style="margin-top: 16px;">
  5. <div class="flex-box" style="margin-bottom: 10px;">
  6. <el-button type="primary" size="medium" @click="openCz(1)" style="margin-left: 10px;" plain>发放功勋点</el-button>
  7. <el-button type="warning" size="medium" @click="openCz(2)" style="margin-left: 10px;" plain>回收功勋点</el-button>
  8. <el-button type="success" size="medium" @click="openCz(3)" style="margin-left: 10px;" plain>转换功勋点</el-button>
  9. </div>
  10. <div class="flex-box-end flex-v-ce" style="font-size: 16px;margin-left: 10px;margin-bottom: 10px;">
  11. <span>当前转换比例</span>
  12. <span class="blue" style="padding: 0 10px;font-weight: 600;">1 : 10</span>
  13. <i class="el-icon-edit" style="font-size: 16px;" @click="isZh = true"></i>
  14. </div>
  15. <div class="flex-1"></div>
  16. <div class="flex-box-ce" style="margin-bottom: 10px;">
  17. <div class="label">部门</div>
  18. <el-cascader
  19. size="medium"
  20. class="date-picker-width"
  21. v-model="dept_name"
  22. :options="dept_tree"
  23. :props="{ checkStrictly: true, value: 'id', label: 'name', children: '_child' }"
  24. ref="dept"
  25. clearable
  26. filterable
  27. placeholder="全公司"
  28. ></el-cascader>
  29. </div>
  30. <div class="flex-box-ce" style="margin-bottom: 10px;">
  31. <div class="label">人员</div>
  32. <el-select v-model="select_employee_id" size="medium" filterable placeholder="请输入或选择人员" clearable>
  33. <el-option v-for="item in employee_map" :key="item.id" :label="item.name" :value="item.id"></el-option>
  34. </el-select>
  35. </div>
  36. </div>
  37. <el-table :data="list" style="width: 100%" v-loading="loading" @selection-change="deleteEvents">
  38. <el-table-column label="姓名" align="center" prop="point">
  39. <template slot-scope="scope">
  40. <div class="flex-box">
  41. <userImage :user_name="scope.row.employee_name" :img_url="scope.row.employee_img_url" width="50px" height="50px"></userImage>
  42. <span style="line-height: 50px; padding-left: 10px;">{{ scope.row.employee_name }}</span>
  43. </div>
  44. </template>
  45. </el-table-column>
  46. <el-table-column label="部门" align="center" prop="point"></el-table-column>
  47. <el-table-column label="累计B分" align="center" prop="point"></el-table-column>
  48. <el-table-column label="当前可转B分" align="center" prop="point">
  49. <template slot="header" slot-scope="scope">
  50. <el-tooltip effect="dark" placement="top-start">
  51. <div slot="content">
  52. <div style="margin-bottom: 10px;">说明</div>
  53. <div style="padding-left: 20px;">
  54. 1、可转B分余额,来自员工在企业内所得的累计B分(包含基础分和工龄分) <br />
  55. 2、员工可以通过获得更多的累计B分,来增加可转B分余额的收入 <br />
  56. 3、回收功勋点不会增加可转B分余额 <br />
  57. 4、转换成功勋点后,余额将被扣除
  58. </div>
  59. </div>
  60. <span>
  61. <span>当前可转B分</span>
  62. <i class="el-icon-warning"></i>
  63. </span>
  64. </el-tooltip>
  65. </template>
  66. </el-table-column>
  67. <el-table-column label="转换后可得功勋点" align="center" prop="point"></el-table-column>
  68. <el-table-column label="现有功勋点" align="center" prop="point"></el-table-column>
  69. <el-table-column label="操作">
  70. <template slot-scope="scope">
  71. <el-link type="primary" @click="moreMessage(scope.row.id)" :underline="false" style="padding-right: 10px;">个人明显</el-link>
  72. <el-dropdown @command="handleCommand">
  73. <el-button size="mini">
  74. 管理
  75. <i class="el-icon-arrow-down el-icon--right"></i>
  76. </el-button>
  77. <el-dropdown-menu slot="dropdown">
  78. <el-dropdown-item :command="{id:scope.row.employee_id,name:'1'}">发放</el-dropdown-item>
  79. <el-dropdown-item :command="{id:scope.row.employee_id,name:'2'}">回收</el-dropdown-item>
  80. <el-dropdown-item :command="{id:scope.row.employee_id,name:'3'}">转换</el-dropdown-item>
  81. </el-dropdown-menu>
  82. </el-dropdown>
  83. </template>
  84. </el-table-column>
  85. <template slot="empty">
  86. <div class="nopoint_box">
  87. <div class="noimg noperson"></div>
  88. <span class="title">没有对应的数据</span>
  89. </div>
  90. </template>
  91. </el-table>
  92. <center style="padding: 20px 0;">
  93. <el-pagination
  94. background
  95. @size-change="handleSizeChange"
  96. @current-change="handleCurrentChange"
  97. :current-page="formData.page"
  98. :page-sizes="[10, 20, 50, 100]"
  99. layout="total, sizes, prev, pager, next"
  100. :page-size="pageLimit"
  101. :total="total"
  102. ></el-pagination>
  103. </center>
  104. </div>
  105. <!-- 转换设置 -->
  106. <el-dialog title="转换设置" :visible.sync="isZh" width="500px" top="10%">
  107. <div class="flex-box-ce" style="margin-bottom: 20px;">
  108. <span class="yellow flex-1">B分转换功勋点将按以下比列进行转换</span>
  109. <span style="cursor: pointer;" class="blue" @click="innerVisible = true">查看转换历史</span>
  110. </div>
  111. <div class="flex-box-ce flex-center-center" style="margin-bottom: 10px;font-size: 16px;">
  112. <span>转换比例 1:</span>
  113. <el-input type="text" class="width-250" v-model="zhNum" placeholder="请输入比例" @input="[zhNum=zhNum.replace(/[^\d]/g,'')]"/>
  114. </div>
  115. <div style="text-align: center;"><i class="el-icon-d-arrow-left fontColorT" style="font-size: 30px;transform: rotate(-90deg);"></i></div>
  116. <div style="text-align: center;font-size: 22px;margin: 10px 0 30px 0;">
  117. 1 B分 =
  118. <span class="blue">{{ zhNum }}</span>
  119. 功勋点
  120. </div>
  121. <span slot="footer" class="dialog-footer">
  122. <el-button @click="isZh = false" size="medium">取 消</el-button>
  123. <el-button type="primary" @click="exportExcel" size="medium">确 定</el-button>
  124. </span>
  125. <el-dialog width="500px" title="历史转换比例记录" :visible.sync="innerVisible" append-to-body>
  126. <div style="max-height: 400px;overflow-y: auto;" class="scroll-bar">
  127. <div v-for="(item, index) in innerList" :key="index" style="padding-bottom: 16px;">
  128. <span class="green">{{ item.name }}</span>
  129. 在{{ item.date }} 修改转换比列为
  130. <span class="blue">{{ item.num }}</span>
  131. </div>
  132. </div>
  133. <span slot="footer" class="dialog-footer"><el-button @click="innerVisible = false" size="medium">关 闭</el-button></span>
  134. </el-dialog>
  135. </el-dialog>
  136. <!-- 发放/回收/转换 -->
  137. <el-dialog :title="czText + '功勋点'" :visible.sync="isCz" width="500px" top="10%">
  138. <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="120px">
  139. <el-form-item :label="czText+'对象'" prop="employee_ids" v-if="isEmployee">
  140. <div class="border flex-box-ce">
  141. <div class="flex-1" v-if="Administrator.length == 0">请选择人员</div>
  142. <div v-else style="width: 180px;" class="font-flex-word">
  143. <span v-for="(item, index) in Administrator" :key="index">
  144. <i v-if="index != 0">,</i>
  145. {{ item.name }}
  146. </span>
  147. </div>
  148. <span v-if="Administrator.length > 0" class="blue">{{ Administrator.length }}人</span>
  149. <i class="el-icon-arrow-down icon-right" v-else></i>
  150. <div @click="openAdministrator()" class="inputDc"></div>
  151. </div>
  152. </el-form-item>
  153. <el-form-item :label="czText+'数值'" prop="zhNum">
  154. <el-input type="text" class="width-250" placeholder="请输入功勋点" v-model="ruleForm.zhNum" @input="[ruleForm.zhNum=ruleForm.zhNum.replace(/[^\d]/g,'')]"/>
  155. </el-form-item>
  156. <el-form-item label="备注原因:" prop="content">
  157. <el-input
  158. type="textarea"
  159. v-model="ruleForm.content"
  160. placeholder="请输入原因"
  161. class="width-250"
  162. :autosize="{ minRows: 3, maxRows: 6 }"
  163. show-word-limit
  164. maxlength="100"
  165. ></el-input>
  166. </el-form-item>
  167. </el-form>
  168. <span slot="footer" class="dialog-footer">
  169. <el-button @click="isCz = false" size="medium">取 消</el-button>
  170. <el-button type="primary" @click="submit('ruleForm')" size="medium">确 定</el-button>
  171. </span>
  172. </el-dialog>
  173. <el-dialog title="选择人员" width="640px" :visible.sync="isChecks" append-to-body>
  174. <EmployeeSelector ref="members" v-if="isChecks" :selected="selected" @confirm="employeeConfirm" />
  175. <span slot="footer" class="dialog-footer">
  176. <el-button @click="isChecks = false">取 消</el-button>
  177. <el-button type="primary" @click="$refs.members.confirm()">确 定</el-button>
  178. </span>
  179. </el-dialog>
  180. <!-- 个人明细 -->
  181. <el-dialog title="个人明细" width="700px" :visible.sync="isDetail" top="5%">
  182. <div class="flex-box-ce">
  183. <div class="titled" v-for="(item,index) in detailData" :key="index">
  184. <div class="num" :class="item.num>0? 'blue':'red'">{{item.num}}</div>
  185. <div class="fontColorF">{{item.name}}</div>
  186. </div>
  187. </div>
  188. <div class="flex-box-end " style="margin-bottom: 10px;">
  189. <el-button type="primary" plain size="small">导出个人明细</el-button>
  190. </div>
  191. <el-table :data="[]" style="width: 100%" border v-loading="loading">
  192. <el-table-column label="姓名" align="left" prop="point"></el-table-column>
  193. <el-table-column label="部门" align="center" prop="point"></el-table-column>
  194. <el-table-column label="功勋点" align="center" prop="point"></el-table-column>
  195. <el-table-column label="描述" align="center" prop="point"></el-table-column>
  196. <el-table-column label="时间" align="center" prop="point"></el-table-column>
  197. <template slot="empty">
  198. <noData></noData>
  199. </template>
  200. </el-table>
  201. <center style="padding-top: 20px;">
  202. <el-pagination
  203. background
  204. @current-change="handleCurrentChange2"
  205. layout="prev, pager, next"
  206. :total="total">
  207. </el-pagination>
  208. </center>
  209. <span slot="footer" class="dialog-footer">
  210. <el-button @click="isDetail = false">取 消</el-button>
  211. <el-button type="primary">确 定</el-button>
  212. </span>
  213. </el-dialog>
  214. </div>
  215. </template>
  216. <script>
  217. import EmployeeSelector from '@/components/EmployeeSelector';
  218. export default {
  219. name: 'flManagement',
  220. components: { EmployeeSelector },
  221. data() {
  222. return {
  223. activeName: '1',
  224. select_employee_id: '',
  225. employee_map: [],
  226. dept_name: [],
  227. dept_tree: [],
  228. loading: false,
  229. formData: {
  230. dept_id: '0',
  231. sort: 'DESC',
  232. page: 1,
  233. page_size: 10,
  234. pt_id: 3,
  235. type: 'all'
  236. },
  237. list: null,
  238. pageLimit: 10,
  239. total: null,
  240. isZh: false,
  241. zhNum:1,
  242. positions: [{ id: 0, age: 'all', name: '全部' }, { id: 1, age: 'manager', name: '管理者' }, { id: 2, age: 'employee', name: '员工' }],
  243. Dc_Data: {
  244. //导出数据
  245. value1: '', //时间
  246. DC_position: '全部', //人员
  247. dept_name: [] //部门
  248. },
  249. innerVisible: false,
  250. innerList: [
  251. { name: '阿松大阿松大', date: '2020-20-1', num: '1:30' },
  252. { name: '阿松大阿松大', date: '2020-20-1', num: '1:30' },
  253. { name: '阿松大阿松大', date: '2020-20-1', num: '1:30' },
  254. { name: '阿松大阿松大', date: '2020-20-1', num: '1:30' }
  255. ],
  256. // 发放/回收/转换
  257. Administrator: [],
  258. isChecks: false,
  259. selected: { dept: [], employee: [] },
  260. ruleForm: {
  261. content: '',
  262. zhNum: '',
  263. employee_ids: []
  264. },
  265. rules: {
  266. zhNum: [{ required: true, message: '请输入数值', trigger: 'blur' }],
  267. employee_ids: [{ required: true, message: '请选择被考核人员', trigger: 'change' }]
  268. },
  269. czText: '发放',
  270. isCz: false,
  271. isEmployee:true,
  272. // 个人明显
  273. isDetail:false,
  274. detailData:[
  275. {name:'现有功勋点',num:1000},
  276. {name:'管理员发放',num:254},
  277. {name:'B分转换',num:20},
  278. {name:'同事点赞',num:166},
  279. {name:'兑换奖品',num:-100},
  280. {name:'被回收',num:-25}
  281. ]
  282. };
  283. },
  284. watch: {
  285. isCz(val){
  286. if(!val){
  287. this.ruleForm={
  288. content: '',
  289. zhNum: '',
  290. employee_ids:[]
  291. };
  292. this.isEmployee=true;
  293. this.Administrator= [];
  294. this.selected={ dept: [], employee: [] };
  295. }
  296. },
  297. dept_name(val) {
  298. if (val.length !== 0) {
  299. this.formData.dept_id = val[val.length - 1];
  300. } else {
  301. this.formData.dept_id = '0';
  302. }
  303. this.formData.page = 1;
  304. this.$nextTick(() => {
  305. this.$refs.dept.dropDownVisible = false;
  306. this.get_list();
  307. });
  308. }
  309. },
  310. methods: {
  311. moreMessage(){
  312. this.isDetail=true;
  313. },
  314. handleCommand(e){
  315. this.ruleForm.employee_ids.push(e.id);
  316. this.isEmployee=false;
  317. this.openCz(Number(e.name))
  318. },
  319. submit(str){
  320. this.$refs[str].validate((valid) => {
  321. if (valid) {
  322. console.log(this.ruleForm)
  323. } else {
  324. console.log('error submit!!');
  325. return false;
  326. }
  327. });
  328. this.isCz=true;
  329. },
  330. keyupEvent(str){
  331. this.ruleForm.zhNum=this.ruleForm.zhNum.replace(/^(0+)|[^\d]+/g,'')
  332. },
  333. openCz(index) {
  334. switch (index) {
  335. case 1:
  336. this.czText = '发放';
  337. break;
  338. case 2:
  339. this.czText = '回收';
  340. break;
  341. case 3:
  342. this.czText = '转换';
  343. break;
  344. }
  345. this.isCz=true;
  346. },
  347. // 选择录入对象
  348. employeeConfirm(e) {
  349. this.ruleForm.employee_ids = e.employee.map(item=>{
  350. return item.id
  351. })
  352. this.selected.employee = e.employee.length > 0 ? e.employee : [];
  353. this.Administrator = e.employee.length > 0 ? e.employee : [];
  354. this.isChecks = false;
  355. },
  356. openAdministrator() {
  357. this.isChecks = true;
  358. },
  359. handleClick() {
  360. },
  361. deleteEvents(selection) {
  362. let listId = [];
  363. selection.forEach(item => {
  364. listId.push(item.id);
  365. });
  366. this.selectionID = listId;
  367. },
  368. exportExcel() {},
  369. handleCurrentChange2(val) {
  370. this.formData.page = val;
  371. this.get_list();
  372. },
  373. // 页面变更
  374. handleCurrentChange(val) {
  375. this.formData.page = val;
  376. this.get_list();
  377. },
  378. handleSizeChange(val) {
  379. this.pageLimit = val;
  380. this.formData.page_size = this.pageLimit;
  381. this.get_list();
  382. },
  383. //获取部门
  384. getDepartment() {
  385. this.$axios('get', '/api/department/tree').then(res => {
  386. this.dept_tree = this.getTreeData(res.data.data.list);
  387. });
  388. },
  389. get_list() {
  390. this.loading = true;
  391. this.$axios('get', '/api/integral/statistics/ranking', this.formData, 'v2')
  392. .then(res => {
  393. if (res.data.code == 1) {
  394. this.list = res.data.data.list;
  395. this.total = res.data.data.total;
  396. } else {
  397. this.$message.error(res.data.data.msg);
  398. }
  399. })
  400. .finally(() => {
  401. this.loading = false;
  402. });
  403. },
  404. // 递归判断列表,把最后的children设为undefined
  405. getTreeData(data) {
  406. for (var i = 0; i < data.length; i++) {
  407. if (data[i]._child.length < 1) {
  408. // children若为空数组,则将children设为undefined
  409. data[i]._child = undefined;
  410. } else {
  411. // children若不为空数组,则继续 递归调用 本方法
  412. this.getTreeData(data[i]._child);
  413. }
  414. }
  415. return data;
  416. }
  417. },
  418. created() {
  419. this.getDepartment();
  420. this.employee_map = JSON.parse(localStorage.getItem('userList'));
  421. },
  422. mounted() {
  423. this.tips_show = JSON.parse(localStorage.getItem('total_rank_tips')) ? false : true;
  424. this.get_list();
  425. }
  426. };
  427. </script>
  428. <style scoped lang="scss">
  429. .titled{
  430. width: 110px;
  431. text-align: left;
  432. margin-bottom: 20px;
  433. color: #606266;
  434. font-size: 14px;
  435. // border-right: 1px solid #f1f1f1;
  436. padding: 0 10px;
  437. }
  438. .titled .num{
  439. font-size: 16px;
  440. font-weight: 600;
  441. margin-bottom: 10px;
  442. }
  443. .border {
  444. -webkit-appearance: none;
  445. background-color: #fff;
  446. background-image: none;
  447. border-radius: 4px;
  448. border: 1px solid #dcdfe6;
  449. -webkit-box-sizing: border-box;
  450. box-sizing: border-box;
  451. color: #c0c4cf;
  452. font-size: inherit;
  453. height: auto;
  454. outline: 0;
  455. padding: 0 15px;
  456. width: 250px;
  457. position: relative;
  458. cursor: pointer;
  459. }
  460. .border .font-flex-word {
  461. color: #606266;
  462. }
  463. .el-icon-edit {
  464. position: relative;
  465. cursor: pointer;
  466. }
  467. .el-icon-edit::after {
  468. content: '';
  469. position: absolute;
  470. left: -5px;
  471. top: -5px;
  472. bottom: -5px;
  473. right: -5px;
  474. }
  475. .label {
  476. width: 40px;
  477. text-align: right;
  478. padding: 0 10px;
  479. }
  480. .search_box {
  481. ::v-deep button:active {
  482. background: #26a2ff;
  483. }
  484. ::v-deep button:active .el-icon-search {
  485. color: #fff;
  486. }
  487. }
  488. .date-picker-width {
  489. width: 100% !important;
  490. }
  491. .nopoint_box {
  492. display: inline-block;
  493. text-align: center;
  494. width: 100%;
  495. margin-bottom: 10px;
  496. }
  497. .noimg {
  498. display: inline-block;
  499. width: 110px;
  500. height: 110px;
  501. margin: 22px auto 16px;
  502. background-size: 99%;
  503. }
  504. .noperson {
  505. display: inline-block;
  506. width: 110px;
  507. height: 110px;
  508. line-height: none;
  509. margin: 22px auto 16px;
  510. background-size: 99%;
  511. }
  512. .title {
  513. display: block;
  514. text-align: center;
  515. font-size: 12px !important;
  516. line-height: 30px;
  517. color: #909399 !important;
  518. padding: 0;
  519. }
  520. .nopoint_box a {
  521. color: #26a2ff;
  522. }
  523. .chart_content {
  524. .chart-legend__wrap {
  525. text-align: right;
  526. padding: 20px;
  527. padding-right: 50px;
  528. & .chart-legend__pink {
  529. position: relative;
  530. padding-left: 12px;
  531. padding-right: 5px;
  532. &:after {
  533. content: '';
  534. position: absolute;
  535. margin-top: -2px;
  536. top: 35%;
  537. left: 0;
  538. width: 8px;
  539. height: 8px;
  540. background: #f56c6c;
  541. border-radius: 100%;
  542. }
  543. }
  544. & .chart-legend__green {
  545. position: relative;
  546. padding-left: 12px;
  547. &:after {
  548. content: '';
  549. position: absolute;
  550. margin-top: -2px;
  551. top: 35%;
  552. left: 0;
  553. width: 8px;
  554. height: 8px;
  555. background: #53b87f;
  556. border-radius: 100%;
  557. }
  558. }
  559. }
  560. }
  561. .drawer_title {
  562. font-size: 18px;
  563. padding: 20px;
  564. }
  565. .manager_statistics_box {
  566. background-color: #ffffff;
  567. padding: 20px;
  568. min-height: calc(100vh - 160px);
  569. ::v-deep .el-row .el-checkbox .el-checkbox__label {
  570. line-height: 20px;
  571. }
  572. }
  573. .diy_tip_bg {
  574. background: #f5f6f9;
  575. overflow: hidden;
  576. .diy-tip {
  577. margin-bottom: 15px;
  578. border: 1px solid #67c23a;
  579. padding: 20px 16px;
  580. p {
  581. color: #67c23a !important;
  582. font-size: 14px;
  583. margin: 0 !important;
  584. padding: 4px 0;
  585. }
  586. }
  587. }
  588. .width-250{
  589. width: 250px;
  590. }
  591. .inputDc {
  592. position: absolute;
  593. top: 0;
  594. right: 0;
  595. left: 0;
  596. bottom: 0;
  597. z-index: 9;
  598. cursor: pointer;
  599. }
  600. </style>