framework.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507
  1. <template>
  2. <div class="all-box">
  3. <!-- 头部提示 -->
  4. <!-- <div class="diy-tip" style="margin-bottom: 10px;">
  5. <div>
  6. 当前组织架构成员通过钉钉通讯录同步,员工开启积分管理后才能正式启用并进入“功道云积分制”,如果您的钉钉通讯录有变动,点击
  7. <span class="blue" style="margin-left: 10px;cursor: pointer;" @click="tb()" v-loading="tbLoading">
  8. <i class="el-icon-refresh"></i>
  9. 立即同步
  10. </span>
  11. </div>
  12. </div> -->
  13. <el-alert class="diy-tip" title="温馨提示:" @close="tips_close" v-show="tips_show" type="success" description show-icon>
  14. 当前组织架构成员通过微信通讯录同步,员工开启积分管理后才能正式启用并进入“功道云积分制”,如果您的微信通讯录有变动,点击立即同步
  15. <!-- <p>第一步:添加部门</p>
  16. <p>第二步:新增员工(员工可以批量导入,每次最多可以导入500个员工)</p>
  17. <p>备注:(导入员工的数量不能大于购买的员工数量)</p> -->
  18. </el-alert>
  19. <div class="all">
  20. <div class="flex-box">
  21. <div class="terr-left">
  22. <div class="rule_class_box" v-loading="ruleDeprt">
  23. <div class="company_name">
  24. <img src="static/images/two.png" />
  25. <span>组织架构</span>
  26. </div>
  27. <el-tree
  28. :data="bmList"
  29. class="cate-tree"
  30. :highlight-current="true"
  31. :props="{ children: '_child', label: 'name' }"
  32. @node-click="handleNodeClick"
  33. :accordion="true"
  34. empty-text="您暂无部门数据,请同步钉钉通讯录"
  35. >
  36. <div
  37. content="tree"
  38. v-show="treedata.length != 0"
  39. class="flex-box flex-v-ce"
  40. slot-scope="{ node, data }"
  41. style="font-size: 14px;color: #606266; width:100%; text-align: left;"
  42. >
  43. <img src="static/images/one.png" style="width: 20px;margin-right: 5px;" />
  44. <span class="name">{{ data.name }}</span>
  45. </div>
  46. </el-tree>
  47. </div>
  48. </div>
  49. <div class="terr-right border-right flex-1">
  50. <div class="margin-bottom">
  51. <el-button @click="participation()" :loading="enable_loading" size="medium" type="primary" style="margin-right: 10px;">批量启用积分管理</el-button>
  52. <el-input placeholder="输入同事姓名" size="medium" style="width: 230px;" v-model="keywords" clearable @input="searchUser()">
  53. <!-- <el-button slot="append" icon="el-icon-search" @click="getEmployee()"></el-button> -->
  54. </el-input>
  55. </div>
  56. <el-table :data="userList" @selection-change="handleSelectionChange" v-loading="tableToading">
  57. <el-table-column type="selection" width="50"></el-table-column>
  58. <el-table-column label="姓名">
  59. <template slot-scope="scope">
  60. <div class="flex-box flex-v-ce">
  61. <userImage :user_name="scope.row.name" :img_url="scope.row.img_url" width="44px" height="44px"></userImage>
  62. <div style="margin-left: 10px;">{{ scope.row.name }}</div>
  63. </div>
  64. </template>
  65. </el-table-column>
  66. <el-table-column label="部门">
  67. <template slot-scope="scope">
  68. <div class="flex-box flex-v-ce bms">
  69. <div v-for="(item, index) in scope.row.employee_detail.dept_list" :key="index">{{ item.dept_name }}</div>
  70. </div>
  71. </template>
  72. </el-table-column>
  73. <el-table-column prop="accedence_time" label="入职时间"></el-table-column>
  74. <el-table-column prop="accedence_time" label="是否参与排名" align="center">
  75. <template slot-scope="scope">
  76. <span class="participateRank" :style="scope.row.is_ranking==1?'color:#409eff':'color:rgb(255 83 70)'" @click="rankingtakePartIn(scope.row.id,scope.row.is_ranking)">{{ scope.row.is_ranking==1?'参与':'不参与' }}</span>
  77. <!-- <span>不参与</span> -->
  78. </template>
  79. </el-table-column>
  80. <el-table-column label="启用积分管理">
  81. <template slot="header" slot-scope="scope">
  82. <el-popover
  83. placement="top-start"
  84. width="300"
  85. trigger="manual"
  86. v-model="visible">
  87. <div class="el-popover2">
  88. <div class="title">提示 <i class="el-icon-info" style="margin-left: 5px;"></i></div>
  89. <div style="margin-bottom: 10px;">在这里启用积分管理,即可进入系统</div>
  90. <div class="flex-box">
  91. <div class="flex-1"></div>
  92. <el-button size="small" @click="visible_close()">我知道了</el-button>
  93. </div>
  94. </div>
  95. <div slot="reference" class="popover" @click="visible=!visible">启用积分管理</div>
  96. </el-popover>
  97. </template>
  98. <template slot-scope="scope">
  99. <div :class="[scope.row.is_official==1? 'switch-box':'']" @click="changeIs(scope.row.is_official, scope.row.id)">
  100. <div class="switch"></div>
  101. </div>
  102. <!-- <el-switch @change="changeIs($event, scope.row.id)" v-model="scope.row.is_official" :active-value="is" :inactive-value="no"></el-switch> -->
  103. </template>
  104. </el-table-column>
  105. <template slot="empty">
  106. <noData></noData>
  107. </template>
  108. </el-table>
  109. <div class="pagination">
  110. <el-pagination
  111. @size-change="handleSizeChange"
  112. @current-change="handleCurrentChange"
  113. :current-page="page"
  114. :page-sizes="[10, 20, 50, 100]"
  115. :page-size="perPage"
  116. layout="total,sizes, prev, pager, next"
  117. :total="total"
  118. ></el-pagination>
  119. </div>
  120. </div>
  121. </div>
  122. </div>
  123. <el-dialog
  124. title="设置是否参与排名"
  125. :visible.sync="dialogVisible"
  126. :modal-append-to-body="false"
  127. top="30vh"
  128. width="520px"
  129. :before-close="handleClose">
  130. <div style="margin-left:20px;">
  131. <el-radio v-for="(item,index) in radioLi" :key="index" v-model="radio" :label="item.id">
  132. <span style="font-size:17px;">{{item.name}}</span>
  133. <p style="font-size:14px;margin:8px 0 0 24px;">{{item.kam}}</p>
  134. </el-radio>
  135. </div>
  136. <span slot="footer" class="dialog-footer">
  137. <el-button @click="dialogVisible = false">取 消</el-button>
  138. <el-button type="primary" @click="setRanking" :disabled="rangLoad">确 定</el-button>
  139. </span>
  140. </el-dialog>
  141. </div>
  142. </template>
  143. <script>
  144. import noData from '@/components/noData';
  145. export default {
  146. data() {
  147. return {
  148. is: 1,
  149. no: 0,
  150. page: 1,
  151. perPage: 10,
  152. total: 0,
  153. info: {}, //公司信息
  154. tips_show: true,
  155. bmList: [],
  156. userList: [],
  157. class_type: '',
  158. treedata: [1],
  159. tableData: [],
  160. keywords: '',
  161. dept_id: 0,
  162. tableToading: false,
  163. tbLoading: false,
  164. selectIds: [],
  165. enable_loading:false,
  166. visible:false,
  167. ruleDeprt:false,
  168. dialogVisible:false,
  169. rankingtakePartInId:'',
  170. radio: '1',
  171. rangLoad:false,
  172. radioLi:[
  173. {id:'1',name:'参与排名',kam:'在排名中展示此人'},
  174. {id:'0',name:'不参与排名',kam:'排名不展示此人(自定义排名除外)'},
  175. ],
  176. };
  177. },
  178. components: {
  179. noData
  180. },
  181. watch: {
  182. dept_id(val) {
  183. this.getEmployee();
  184. }
  185. },
  186. created() {
  187. this.getInfo();
  188. // this.getDepartment();
  189. this.getEmployee();
  190. },
  191. mounted() {
  192. this.$nextTick(function() {
  193. if (localStorage.getItem('rule')) {
  194. this.tips_show = false;
  195. } else {
  196. this.tips_show = true;
  197. }
  198. });
  199. },
  200. methods: {
  201. setRanking(){
  202. this.rangLoad = true
  203. let data = {
  204. employee_id:this.rankingtakePartInId,
  205. switch:Number(this.radio)
  206. }
  207. this.$http('post','/api/employee/ranking_switch',data).then((res)=>{
  208. if(res.data.code == 1){
  209. this.$message.success({ message: res.data.msg });
  210. this.getEmployee()
  211. }
  212. }).finally(()=>{
  213. this.dialogVisible = false
  214. setTimeout(()=>{
  215. this.rangLoad = false
  216. },200)
  217. })
  218. },
  219. rankingtakePartIn(id,is_ranking){
  220. this.radio = is_ranking.toString()
  221. this.rankingtakePartInId = id
  222. this.dialogVisible = true
  223. },
  224. handleClose(done){
  225. done()
  226. },
  227. //同步信息
  228. tb() {
  229. this.$confirm('下次同步时间需在10分钟之后,是否同步?', '提示', {
  230. confirmButtonText: '确定',
  231. cancelButtonText: '取消',
  232. type: 'warning'
  233. }).then(() => {
  234. this.tbLoading = true;
  235. this.$http('post','/api/ding/department_sync').then(res => {
  236. this.$message.success({ message: '同步成功' });
  237. this.dept_id=0;
  238. this.getInfo();
  239. this.getEmployee();
  240. }).finally(()=>{
  241. this.tbLoading = false;
  242. });
  243. });
  244. },
  245. //搜索
  246. searchUser(){
  247. this.page = 1;
  248. this.getEmployee();
  249. },
  250. //是否开通
  251. changeIs(e, id) {
  252. var url = e == 1 ? '/api/employee/disable' : '/api/employee/enable';
  253. this.$http('post',url, { employee_id: [id] }).then(res => {
  254. if (res) {
  255. if(e==0){
  256. this.$message.success({ message: '开启成功,可在"角色权限设置对应管理范围"' });
  257. }else{
  258. this.$message.success({ message: res.data.msg });
  259. }
  260. this.getEmployee();
  261. }
  262. });
  263. },
  264. //批量开通权限
  265. participation() {
  266. if(this.selectIds.length==0){
  267. this.$message.error({ message: '请选择参与的人员!' });
  268. return
  269. }
  270. this.enable_loading=true;
  271. this.$http('post','/api/employee/enable', { employee_id: this.selectIds }).then(res => {
  272. if (res) {
  273. this.$message.success({ message: '开启成功,可在"角色权限设置对应管理范围"' });
  274. this.getEmployee();
  275. }
  276. }).finally(err=>{
  277. this.enable_loading=false;
  278. });
  279. },
  280. //获取公司信息
  281. getInfo(is) {
  282. this.ruleDeprt = true
  283. // api/test?employee_id=155
  284. this.$http('get','/api/site/info').then(res => {
  285. this.info = res.data.data;
  286. this.getDepartment(is);
  287. });
  288. },
  289. //选择员工
  290. handleSelectionChange(e) {
  291. var arr = [];
  292. for (var item in e) {
  293. arr.push(e[item].id);
  294. }
  295. this.selectIds = arr;
  296. },
  297. //点击部门
  298. handleNodeClick(e) {
  299. this.page = 1;
  300. this.dept_id = e.id;
  301. },
  302. //获取部门
  303. getDepartment() {
  304. this.ruleDeprt = true
  305. this.$http('get','/api/department/tree').then(res => {
  306. var list=[{
  307. id:0,
  308. name:this.info.name,
  309. _child:res.data.data.list
  310. }]
  311. this.bmList = list;
  312. }).finally(()=>{
  313. this.ruleDeprt = false
  314. });
  315. },
  316. //获取员工
  317. getEmployee() {
  318. this.tableToading = true;
  319. this.$http('get','/api/employee/index', {dept_id: this.dept_id, keywords: this.keywords, page: this.page, page_size: this.perPage }).then(res => {
  320. this.total = res.data.data.pageInfo.count;
  321. this.userList = res.data.data.list;
  322. var visible=localStorage.getItem('visible');
  323. if(!visible){
  324. this.visible=true;
  325. }
  326. }).finally(err=>{
  327. this.tableToading=false;
  328. });
  329. },
  330. visible_close(){
  331. localStorage.setItem('visible', 'true');
  332. this.visible = false;
  333. },
  334. //关闭提示
  335. tips_close() {
  336. localStorage.setItem('rule', 'true');
  337. this.tips_show = false;
  338. },
  339. handleSizeChange: function(val) {
  340. this.perPage = val;
  341. this.page = 1;
  342. this.getEmployee();
  343. },
  344. //页码变更
  345. handleCurrentChange: function(val) {
  346. this.page = val;
  347. this.getEmployee();
  348. }
  349. }
  350. };
  351. </script>
  352. <style lang="scss" scoped="scoped">
  353. .title{
  354. font-size: 16px;
  355. color: #909399;
  356. margin-bottom: 10px;
  357. }
  358. .popover{
  359. border: none;
  360. // color: #909399;
  361. font-weight: 600;
  362. cursor: pointer;
  363. }
  364. .popover:hover{
  365. background-color: #fff;
  366. border-color: #fff;
  367. }
  368. .switch{
  369. margin: 0;
  370. display: inline-block;
  371. position: relative;
  372. width: 40px;
  373. height: 20px;
  374. border: 1px solid #dcdfe6;
  375. outline: none;
  376. border-radius: 10px;
  377. box-sizing: border-box;
  378. background: #dcdfe6;
  379. cursor: pointer;
  380. transition: border-color .3s,background-color .3s;
  381. vertical-align: middle;
  382. }
  383. .switch:after {
  384. content: "";
  385. position: absolute;
  386. top: 1px;
  387. left: 1px;
  388. border-radius: 100%;
  389. transition: all .3s;
  390. width: 16px;
  391. height: 16px;
  392. background-color: #fff;
  393. }
  394. .switch-box .switch {
  395. border-color: #409eff;
  396. background-color: #409eff;
  397. }
  398. .switch-box .switch:after {
  399. left: 100%;
  400. margin-left: -17px;
  401. }
  402. .name {
  403. overflow: hidden;
  404. text-overflow: ellipsis;
  405. white-space: nowrap;
  406. width: 80%;
  407. }
  408. .bms div {
  409. margin-right: 10px;
  410. }
  411. .top-msg div:nth-child(1) {
  412. margin-bottom: 10px;
  413. }
  414. .company_name {
  415. position: relative;
  416. display: block;
  417. font-family: 'Microsoft YaHei';
  418. text-align: left;
  419. padding: 15px 25px;
  420. cursor: pointer;
  421. overflow: hidden;
  422. white-space: nowrap;
  423. text-overflow: ellipsis;
  424. border-bottom: 1px #f8f8f8 solid;
  425. }
  426. .company_name img {
  427. position: relative;
  428. display: inline-block;
  429. top: 2px;
  430. width: 18px;
  431. height: 18px;
  432. margin-right: 4px;
  433. }
  434. .terr-right {
  435. .custom-tree-node {
  436. margin-left: -4px;
  437. }
  438. .custom-tree-node * {
  439. vertical-align: middle;
  440. }
  441. .custom-tree-node:hover {
  442. .treeIcon {
  443. display: inline-block;
  444. width: 55%;
  445. }
  446. }
  447. }
  448. .el-popover2{
  449. // background-color: #409eff !important;
  450. color: #409eff;
  451. }
  452. .rule_class_box {
  453. /deep/ .el-tree-node {
  454. border-bottom: 1px #f8f8f8 solid;
  455. }
  456. /deep/ .el-tree-node__content {
  457. padding: 10px 0;
  458. // border-bottom: 1px #f8f8f8 solid;
  459. }
  460. /deep/ .el-tree-node__content:hover {
  461. background: #ecf5ff;
  462. border-radius: 4px;
  463. }
  464. /deep/ .el-tree--highlight-current .el-tree-node.is-current>.el-tree-node__content .name{
  465. color: #409eff !important;
  466. font-weight: normal;
  467. transition: 0.35s ease-in-out;
  468. }
  469. // ::v-deep .is-current .el-tree-node__content .el-icon-caret-right {
  470. // color: #409eff !important;
  471. // }
  472. // ::v-deep .is-current .el-tree-node__content .el-tree-node__label {
  473. // color: #409eff !important;
  474. // }
  475. // ::v-deep .is-current .el-tree-node__children .el-icon-caret-right {
  476. // color: #c0c4cc !important;
  477. // }
  478. // ::v-deep .is-current .el-tree-node__children .el-tree-node__label {
  479. // color: #606266 !important;
  480. // }
  481. // ::v-deep .is-current .name {
  482. // color: #409eff !important;
  483. // font-weight: normal;
  484. // transition: 0.35s ease-in-out;
  485. // }
  486. }
  487. .participateRank{
  488. cursor:pointer;
  489. }
  490. .all{
  491. background-color: #fff;
  492. border-radius: 5px;
  493. min-height:calc(100vh - 184px);
  494. min-width: 800px;
  495. position: relative;
  496. }
  497. </style>