framework.vue 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986
  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. <div class="all">
  14. <div class="flex-box">
  15. <div class="terr-left">
  16. <div class="rule_class_box" v-loading="ruleDeprt">
  17. <div class="company_name">
  18. <img src="@/assets/image/two.png" />
  19. <span>组织架构</span>
  20. </div>
  21. <el-tree
  22. :data="bmList"
  23. class="cate-tree"
  24. :highlight-current="true"
  25. :props="{ children: '_child', label: 'name' }"
  26. @node-click="handleNodeClick"
  27. :accordion="true"
  28. empty-text="您暂无部门数据,请同步钉钉通讯录"
  29. >
  30. <div
  31. content="tree"
  32. v-show="treedata.length != 0"
  33. class="flex-box flex-v-ce"
  34. slot-scope="{ node, data }"
  35. style="font-size: 14px;color: #606266; width:100%; text-align: left;"
  36. >
  37. <img src="@/assets/image/one.png" style="width: 20px;margin-right: 5px;" />
  38. <span class="name">{{ data.name }}</span>
  39. </div>
  40. </el-tree>
  41. </div>
  42. </div>
  43. <div class="terr-right border-right flex-1">
  44. <div class="margin-bottom">
  45. <el-button @click="participation()" :loading="enable_loading" size="medium" type="primary">批量启用</el-button>
  46. <el-button @click="forbidden()" :loading="enable_loading" size="medium" type="danger" style="margin-right: 10px;">批量禁用</el-button>
  47. <el-select v-model="status" size="medium" style="margin-right: 10px;width: 150px;">
  48. <el-option
  49. v-for="item in options"
  50. :key="item.value"
  51. :label="item.label"
  52. :value="item.value">
  53. </el-option>
  54. </el-select>
  55. <el-input placeholder="输入同事姓名" size="medium" style="width: 230px;" v-model="keywords" clearable></el-input>
  56. </div>
  57. <div>
  58. <el-button size="small" type="success" @click="import_rules_show = true" plain>导入人员</el-button>
  59. <el-button size="small" type="primary" @click="derivedRule" plain>导出人员</el-button>
  60. </div>
  61. <el-table :data="userList" @selection-change="handleSelectionChange" v-loading="tableToading">
  62. <el-table-column type="selection" width="50" :selectable="selectable"></el-table-column>
  63. <el-table-column label="姓名">
  64. <template slot-scope="scope">
  65. <div class="flex-box flex-v-ce">
  66. <userImage :user_name="scope.row.name" :img_url="scope.row.img_url" width="44px" height="44px"></userImage>
  67. <div style="margin-left: 10px;">{{ scope.row.name }}</div>
  68. <div style="margin-left: 10px;" v-if="scope.row.is_creator" class="green">(创始人)</div>
  69. <div style="margin-left: 10px;" v-if="scope.row.id == userInfo.id" class="green">(我)</div>
  70. </div>
  71. </template>
  72. </el-table-column>
  73. <el-table-column label="部门">
  74. <template slot-scope="scope">
  75. <div class="flex-box flex-v-ce bms">
  76. <div v-for="(item, index) in scope.row.employee_detail.dept_list" :key="index">{{ item.dept_name }}</div>
  77. </div>
  78. </template>
  79. </el-table-column>
  80. <el-table-column prop="accedence_time" label="入职时间"></el-table-column>
  81. <!-- <el-table-column prop="id" label="员工标识" width="80">
  82. <template slot-scope="scope">
  83. <el-button size="mini" type="primary" @click="copyId(scope.row.id)">复制</el-button>
  84. </template>
  85. </el-table-column> -->
  86. <!-- <el-table-column label="是否参与排名" align="center">
  87. <template slot-scope="scope">
  88. <template v-if="scope.row.is_creator != 1">
  89. <span
  90. class="participateRank"
  91. :style="scope.row.is_ranking == 1 ? 'color:#409eff' : 'color:#F56C6C'"
  92. @click="rankingtakePartIn(scope.row.id, scope.row.is_ranking)"
  93. >
  94. {{ scope.row.is_ranking == 1 ? '参与' : '不参与' }}
  95. </span>
  96. </template>
  97. <span v-else class="fontColorB">不参与</span>
  98. </template>
  99. </el-table-column> -->
  100. <el-table-column label="启用积分管理">
  101. <template slot="header" slot-scope="scope">
  102. <el-popover placement="top-start" width="300" trigger="manual" v-model="visible">
  103. <div class="el-popover2">
  104. <div class="title">
  105. 提示
  106. <i class="el-icon-info" style="margin-left: 5px;"></i>
  107. </div>
  108. <div style="margin-bottom: 10px;">在这里启用积分管理,即可进入系统</div>
  109. <div class="flex-box">
  110. <div class="flex-1"></div>
  111. <el-button size="small" @click="visible_close()">我知道了</el-button>
  112. </div>
  113. </div>
  114. <div slot="reference" class="popover" @click="visible = !visible">
  115. 启用积分管理
  116. <i class="el-icon-info" style="margin-left: 5px;"></i>
  117. </div>
  118. </el-popover>
  119. </template>
  120. <template slot-scope="scope">
  121. <div :class="[scope.row.is_official == 1 ? 'switch-box' : '']" @click="changeIs(scope.row.is_official, scope.row.id)">
  122. <div class="switch"></div>
  123. </div>
  124. </template>
  125. </el-table-column>
  126. <!-- <el-table-column label="管理上级" align="center" width="80">
  127. <template slot-scope="scope">
  128. <span v-if="scope.row.is_creator != 1 && scope.row.is_official != 0" class="participateRank" style="color:#409eff;" @click="setSuperior(scope.row)">设置</span>
  129. </template>
  130. </el-table-column> -->
  131. <el-table-column prop="id" label="操作" >
  132. <template slot-scope="scope">
  133. <el-link type="primary" @click="moreMessage(scope.row.id)" :underline="false">更多信息</el-link>
  134. </template>
  135. </el-table-column>
  136. <template slot="empty">
  137. <noData></noData>
  138. </template>
  139. </el-table>
  140. <div class="pagination">
  141. <el-pagination
  142. @size-change="handleSizeChange"
  143. @current-change="handleCurrentChange"
  144. :current-page="page"
  145. :page-sizes="[10, 20, 50, 100]"
  146. :page-size="perPage"
  147. layout="total,sizes, prev, pager, next"
  148. :total="total"
  149. ></el-pagination>
  150. </div>
  151. </div>
  152. </div>
  153. <!-- 隐藏文本,用于复制ID -->
  154. <input v-model="copyIds" id="biao" style="opacity:0"/>
  155. </div>
  156. <el-dialog :close-on-click-modal="false" ref="EditInformation_list" title="员工详情" width="500px" :before-close="detailFormreturn" :visible.sync="diaTableVisible">
  157. <div style="padding-right:50px;">
  158. <el-form ref="detailForm" :model="messageMore" @submit.native.prevent v-loading="show_loading">
  159. <el-form-item label="员工标识" prop="id" :label-width="'100px'">
  160. <el-input v-model="copyIds" disabled auto-complete="off"></el-input>
  161. <span style="position:absolute;top:1px;right:7px;font-size:12px;color:#61aeff;cursor:pointer;" @click="copyToClipboard()">点击复制</span>
  162. </el-form-item>
  163. <el-form-item label="姓名" prop="name" :label-width="'100px'">
  164. <el-input v-model="messageMore.name" disabled ref="inputName" auto-complete="off"></el-input>
  165. </el-form-item>
  166. <el-form-item label="入职时间" prop="accedence_time" :label-width="'100px'">
  167. <el-date-picker
  168. style="width:100%;"
  169. v-model="messageMore.accedence_time"
  170. type="date"
  171. value-format="yyyy-MM-dd"
  172. placeholder="选择日期"
  173. disabled
  174. ></el-date-picker>
  175. </el-form-item>
  176. <el-form-item label="部门" prop="name" :label-width="'100px'">
  177. <el-input v-model="deptList" disabled ref="inputName" placeholder="暂无部门" auto-complete="off"></el-input>
  178. </el-form-item>
  179. <el-form-item label="是否参与排名" prop="name" :label-width="'100px'">
  180. <span v-if="messageMore.is_creator != 1" class="participateRank"
  181. :style="messageMore.is_ranking == 1 ? 'color:#409eff' : 'color:#F56C6C'"
  182. @click="rankingtakePartIn(messageMore.id, messageMore.is_ranking)">
  183. {{ messageMore.is_ranking == 1 ? '参与' : '不参与' }}
  184. </span>
  185. <span v-else class="fontColorB">不参与</span>
  186. </el-form-item>
  187. <el-form-item label="管理上级" prop="name" :label-width="'100px'">
  188. <el-input auto-complete="off" v-model="propList" :disabled="messageMore.is_creator == 1 || messageMore.is_official == 0" placeholder="暂无管理上级"></el-input>
  189. <div
  190. @click="setSuperior(messageMore)"
  191. v-if="messageMore.is_creator != 1 && messageMore.is_official != 0"
  192. style=" position: absolute; top: 0; right: 0; left: 0; bottom: 0; z-index: 9;"
  193. ></div>
  194. </el-form-item>
  195. <el-form-item label="直属上级" prop="name" :label-width="'100px'">
  196. <el-input auto-complete="off" v-model="dirSupervisor.name" :disabled="messageMore.is_creator == 1 || messageMore.is_official == 0" placeholder="暂无直属上级"></el-input>
  197. <div
  198. @click="dirSuperior(messageMore)"
  199. v-if="messageMore.is_creator != 1 && messageMore.is_official != 0"
  200. style=" position: absolute; top: 0; right: 0; left: 0; bottom: 0; z-index: 9;"
  201. ></div>
  202. </el-form-item>
  203. </el-form>
  204. </div>
  205. </el-dialog>
  206. <el-dialog title="设置是否参与排名" :visible.sync="dialogVisible" top="30vh" width="520px" :before-close="handleClose">
  207. <div style="margin-left:20px;">
  208. <el-radio v-for="(item, index) in radioLi" :key="index" v-model="radio" :label="item.id">
  209. <span style="font-size:17px;">{{ item.name }}</span>
  210. <p style="font-size:14px;margin:8px 0 0 24px;">{{ item.kam }}</p>
  211. </el-radio>
  212. </div>
  213. <span slot="footer" class="dialog-footer">
  214. <el-button @click="dialogVisible = false">取 消</el-button>
  215. <el-button type="primary" @click="setRanking" :disabled="rangLoad">确 定</el-button>
  216. </span>
  217. </el-dialog>
  218. <!-- 导入规则 -->
  219. <el-dialog title="导入人员" :visible.sync="import_rules_show" width="500px" @before-close="close_import">
  220. <div class="text-center flex-box-v flex-center-center">
  221. <p><img src="@/assets/image/rules_mould1.png" alt="" /></p>
  222. <p>仅支持xls、xlsx格式文件</p>
  223. <el-upload
  224. class="upload-demo"
  225. :headers="ATOKEN"
  226. ref="upload"
  227. :limit="1"
  228. :action="action"
  229. :on-remove="handleRemove"
  230. :on-success="handleSuccess"
  231. :before-upload="beforeFilesUpload"
  232. :file-list="fileList"
  233. >
  234. <el-button slot="trigger" type="primary">选取文件</el-button>
  235. </el-upload>
  236. </div>
  237. </el-dialog>
  238. <el-dialog title="设置管理上级" :visible.sync="manageScope_show" :before-close="publicClose2" top="5vh" width="700px">
  239. <EmployeeSelector
  240. v-if="manageScope_show"
  241. ref="Employee2"
  242. :employee_list="employeeList"
  243. :user_no_select="false"
  244. :close_clear_data="false"
  245. isCreatorSelect
  246. createDimness
  247. :selected="selected_manage"
  248. @confirm="manage_confirm"
  249. ></EmployeeSelector>
  250. <span slot="footer">
  251. <el-button @click="publicClose2()">取消</el-button>
  252. <el-button type="primary" :loading="scope_loading" :disabled="scope_loading" @click="sub_manageScope">完成</el-button>
  253. </span>
  254. </el-dialog>
  255. <el-dialog title="设置直属上级" :visible.sync="dirSupScope_show" :before-close="publicClose3" top="5vh" width="700px">
  256. <EmployeeSelector
  257. v-if="dirSupScope_show"
  258. :max="1"
  259. ref="Employee3"
  260. :multi="false"
  261. :close_clear_data="false"
  262. :employee_list="dirSupList"
  263. isCreatorSelect
  264. :selected="selected_dirSup"
  265. @confirm="dirSup_confirm"
  266. ></EmployeeSelector>
  267. <span slot="footer">
  268. <el-button @click="publicClose3()">取消</el-button>
  269. <el-button type="primary" :loading="scope_loading" :disabled="scope_loading" @click="dir_SupScope">完成</el-button>
  270. </span>
  271. </el-dialog>
  272. </div>
  273. </template>
  274. <script>
  275. import noData from '@/components/noData';
  276. import EmployeeSelector from '@/components/EmployeeSelector.vue';
  277. import {_debounce} from '@/api/auth';
  278. export default {
  279. data() {
  280. return {
  281. manageData: [],//管理员列表
  282. employeeList: [],
  283. manageScope_show: false,
  284. scope_loading: false,
  285. clickone: false,
  286. mangeId: 0,
  287. selected_manage: { employee: [], dept: [] },
  288. is: 1,
  289. no: 0,
  290. page: 1,
  291. perPage: 10,
  292. total: 0,
  293. info: {}, //公司信息
  294. tips_show: true,
  295. bmList: [],
  296. userList: [],
  297. class_type: '',
  298. treedata: [1],
  299. tableData: [],
  300. keywords: '',
  301. dept_id: 0,
  302. tableToading: false,
  303. tbLoading: false,
  304. selectIds: [],
  305. enable_loading: false,
  306. visible: false,
  307. ruleDeprt: false,
  308. dialogVisible: false,
  309. rankingtakePartInId: '',
  310. radio: '1',
  311. rangLoad: false,
  312. radioLi: [{ id: '1', name: '参与排名', kam: '在排名中展示此人' }, { id: '0', name: '不参与排名', kam: '排名不展示此人(自定义排名除外)' }],
  313. userInfo: this.$getUserData(),
  314. copyIds:'',
  315. options: [{
  316. value: '-1',
  317. label: '全部'
  318. }, {
  319. value: '1',
  320. label: '已开启'
  321. }, {
  322. value: '0',
  323. label: '已禁用'
  324. }],
  325. status: '-1',
  326. //导入规则
  327. import_rules_show: false,
  328. save_loading: false,
  329. import_btn_show: false,
  330. fileList: [],
  331. file: null,
  332. action: process.env.VUE_APP_BASE_API + 'api/employee/enable_import',
  333. ATOKEN: { 'A-TOKEN': this.$getToken()},
  334. diaTableVisible: false,
  335. messageMore: {},
  336. deptList: '',
  337. propList: '',
  338. dirSupervisor: {},
  339. dirSupScope_show: false,
  340. show_loading: false,
  341. newId: 0,
  342. dirSupList: [],
  343. selected_dirSup: { employee: [], dept: [] },
  344. };
  345. },
  346. components: {
  347. noData,
  348. EmployeeSelector
  349. },
  350. watch: {
  351. keywords: {
  352. deep: true,
  353. handler: _debounce(function(val) {
  354. this.page = 1;
  355. this.getEmployee();
  356. })
  357. },
  358. dept_id(val) {
  359. this.page = 1;
  360. this.getEmployee();
  361. },
  362. status(){
  363. this.page = 1;
  364. this.getEmployee();
  365. }
  366. },
  367. created() {
  368. this.getInfo();
  369. this.getEmployee();
  370. this.manageList();
  371. },
  372. mounted() {
  373. this.$nextTick(function() {
  374. if (localStorage.getItem('rule')) {
  375. this.tips_show = false;
  376. } else {
  377. this.tips_show = true;
  378. }
  379. });
  380. },
  381. methods: {
  382. manage_confirm(date) {
  383. let manageId = [];
  384. date.employee.forEach(item => manageId.push(item.id))
  385. let data = {
  386. employee_id: this.mangeId,
  387. manage_id: manageId
  388. }
  389. this.$axios('post', '/api/employee/superior', data).then(res =>{
  390. if(res.data.code == 1){
  391. this.manageScope_show = false
  392. this.$message.success('设置成功');
  393. this.moreMessage();
  394. }
  395. }).finally(_=>{
  396. this.scope_loading = false
  397. })
  398. },
  399. dirSup_confirm(date){
  400. let data = {
  401. employee_ids: [this.newId],
  402. superior_id: date.employee.length > 0 ? date.employee[0].id : null
  403. }
  404. this.$axios('post','/api/employee/directly_superior',data).then(res =>{
  405. if(res.data.code == 1){
  406. this.dirSupScope_show = false
  407. this.$message.success('设置成功');
  408. this.moreMessage();
  409. }
  410. }).finally(_=>{
  411. this.scope_loading = false
  412. })
  413. },
  414. sub_manageScope(){
  415. this.scope_loading = true
  416. this.$refs.Employee2.confirm();
  417. },
  418. dir_SupScope(){
  419. this.scope_loading = true
  420. this.$refs.Employee3.confirm();
  421. },
  422. detailFormreturn() {
  423. this.diaTableVisible = false
  424. },
  425. nameStrList(list,Str){
  426. let deptarr = ''
  427. list.forEach((x, y) =>{
  428. deptarr += x[Str] + ' ';
  429. })
  430. return deptarr
  431. },
  432. moreMessage(id) {
  433. let isId = 0;
  434. if(id){
  435. this.newId = id
  436. isId = id
  437. }else{
  438. isId = this.newId
  439. }
  440. this.diaTableVisible = true
  441. this.show_loading = true
  442. let http1 = this.$axios('get', '/api/employee/info', { id: isId })
  443. let http2 = this.$axios('get', '/api/employee/code', { employee_id: isId })
  444. Promise.all([http1, http2]).then(res =>{
  445. if(res[0]){
  446. if (res[0].data.code == 1) {
  447. let data = res[0].data.data
  448. if(data.employee_detail.dept_list){
  449. this.deptList = this.nameStrList(data.employee_detail.dept_list, 'dept_name');
  450. }
  451. if(data.employee_detail.superior_list){
  452. let employeeD = data.employee_detail
  453. if(employeeD.superior_id != 0){
  454. this.dirSupervisor = employeeD.superior_list.filter(x => x.id == employeeD.superior_id)[0]
  455. }else{
  456. this.dirSupervisor = {}
  457. }
  458. this.propList = this.nameStrList(employeeD.superior_list, 'name');
  459. }
  460. this.messageMore = data
  461. }
  462. }
  463. if(res[1]){
  464. if (res[1].data.code == 1) {
  465. this.copyIds = res[1].data.data.encrypt_code;
  466. }
  467. }
  468. }).finally(() =>{
  469. this.show_loading = false
  470. })
  471. // this.$axios('get', '/api/employee/info', { id: isId })
  472. // .then(res => {
  473. // if (res.data.code == 1) {
  474. // let data = res.data.data
  475. // if(data.employee_detail.dept_list){
  476. // this.deptList = this.nameStrList(data.employee_detail.dept_list, 'dept_name');
  477. // }
  478. // if(data.employee_detail.superior_list){
  479. // let employeeD = data.employee_detail
  480. // if(employeeD.superior_id != 0){
  481. // this.dirSupervisor = employeeD.superior_list.filter(x => x.id == employeeD.superior_id)[0]
  482. // console.log(this.dirSupervisor)
  483. // }
  484. // this.propList = this.nameStrList(employeeD.superior_list, 'name');
  485. // }
  486. // this.messageMore = data
  487. // }
  488. // }).finally(()=>{
  489. // this.show_loading = false
  490. // })
  491. },
  492. setSuperior(row){
  493. this.mangeId = row.id
  494. let createData = {}
  495. createData = this.manageData.filter(x => x.is_creator == 1)
  496. let list = this.manageData.filter(x => x.id != row.id && x.is_creator != 1)
  497. this.employeeList = list
  498. let supList = row.employee_detail.superior_list
  499. if(createData[0]){
  500. supList.forEach(item =>{
  501. createData.some(arr =>{
  502. if(item.id == arr.id){
  503. item.is_creator = true
  504. return true
  505. }
  506. })
  507. })
  508. }
  509. this.selected_manage.employee = supList
  510. this.manageScope_show = true
  511. },
  512. dirSuperior(row){
  513. this.dirSupList = row.employee_detail.superior_list
  514. if(this.dirSupervisor.name){
  515. let arr = []
  516. arr.push(this.dirSupervisor)
  517. this.selected_dirSup.employee = arr
  518. }else{
  519. this.selected_dirSup.employee = []
  520. }
  521. this.dirSupScope_show = true
  522. },
  523. publicClose2() {
  524. this.$refs.Employee2.close();
  525. this.manageScope_show = false;
  526. },
  527. publicClose3() {
  528. this.$refs.Employee3.close();
  529. this.dirSupScope_show = false
  530. },
  531. //管理列表
  532. manageList(){
  533. let params = {
  534. roles: ['creator', 'admin', 'point_manager', 'dept_manager']
  535. }
  536. this.$axios('get', '/api/employee/role_employee', params).then(res =>{
  537. if(res.data.code == 1){
  538. this.manageData = res.data.data.list
  539. }
  540. })
  541. },
  542. handleSuccess(response) {
  543. if (response.code == 1) {
  544. if (response.data.list.length > 0) {
  545. var htmls = response.data.list;
  546. var str = "<div class='red'></div>";
  547. htmls.forEach(item => {
  548. str += `<div>${item.姓名}:${item.line_err}</div>`;
  549. });
  550. this.$notify.error({
  551. title: '导入错误',
  552. dangerouslyUseHTMLString: true,
  553. message: str,
  554. duration: 0,
  555. offset: 50,
  556. customClass: 'notifyBox'
  557. });
  558. this.close_import();
  559. } else {
  560. this.file = response.data.list;
  561. this.$message.success({ message: response.msg });
  562. this.getEmployee();
  563. this.close_import();
  564. }
  565. }else{
  566. this.$message.error({ message: response.msg });
  567. }
  568. },
  569. handleRemove(file, fileList) {
  570. if (fileList !== null && fileList.length != 0) {
  571. this.import_btn_show = true;
  572. } else {
  573. this.import_btn_show = false;
  574. }
  575. },
  576. beforeFilesUpload(file) {
  577. const $ext_list = ['xlsx', 'xls'];
  578. let len = file.name.split('.').length - 1;
  579. const $ext_name = file.name.split('.')[len];
  580. if ($ext_list.indexOf($ext_name) != -1) {
  581. this.import_btn_show = true;
  582. } else {
  583. this.$message.warning('文件格式上传错误,仅支持上传xlsx,xls)');
  584. return false;
  585. }
  586. },
  587. //导出规则按钮
  588. derivedRule(){
  589. let status=this.status=='-1'? '':this.statu
  590. if(status){
  591. var str='&is_official='+status+'&dept_id='+this.dept_id+'&keywords='+this.keywords;
  592. }else{
  593. var str='&dept_id='+this.dept_id+'&keywords='+this.keywords;
  594. }
  595. let userData=this.$getUserData();
  596. window.open(process.env.VUE_APP_BASE_API+'/api/download/employee_status_export?employee_id='+userData.id+str)
  597. },
  598. // 导入相关
  599. close_import() {
  600. this.import_rules_show = false;
  601. this.import_btn_show = false;
  602. this.$refs.upload.clearFiles();
  603. },
  604. // 复制ID
  605. copyId(id) {
  606. this.$axios('get', '/api/employee/code', { employee_id: id })
  607. .then(res => {
  608. if (res.data.code == 1) {
  609. this.copyIds = res.data.data.encrypt_code;
  610. this.$nextTick(()=>{
  611. this.copyToClipboard();
  612. })
  613. }
  614. })
  615. },
  616. copyToClipboard() {
  617. var Url2=document.getElementById("biao");
  618. Url2.select(); // 选择对象
  619. document.execCommand("Copy"); // 执行浏览器复制命令
  620. this.$message.success('已复制');
  621. },
  622. forbidden() {
  623. if (this.selectIds.length == 0) {
  624. this.$message.error({ message: '请选择禁用的人员!' });
  625. return;
  626. }
  627. this.$confirm('确定禁用选择的人员?', '提示', {
  628. confirmButtonText: '确定',
  629. cancelButtonText: '取消',
  630. type: 'warning'
  631. }).then(() => {
  632. this.enable_loading = true;
  633. this.$axios('post', '/api/employee/disable', { employee_id: this.selectIds })
  634. .then(res => {
  635. if (res) {
  636. this.$message.success('已禁用');
  637. this.page=1;
  638. this.getEmployee();
  639. }
  640. })
  641. .finally(err => {
  642. this.enable_loading = false;
  643. });
  644. });
  645. },
  646. selectable(row) {
  647. if (row.is_creator) {
  648. return false;
  649. } else if (this.userInfo.id == row.id) {
  650. return false;
  651. } else {
  652. return true;
  653. }
  654. },
  655. setRanking() {
  656. this.rangLoad = true;
  657. let data = {
  658. employee_id: this.rankingtakePartInId,
  659. switch: Number(this.radio)
  660. };
  661. this.$axios('post', '/api/employee/ranking_switch', data)
  662. .then(res => {
  663. if (res.data.code == 1) {
  664. this.$message.success({ message: res.data.msg });
  665. this.moreMessage();
  666. }
  667. })
  668. .finally(() => {
  669. this.dialogVisible = false;
  670. setTimeout(() => {
  671. this.rangLoad = false;
  672. }, 200);
  673. });
  674. },
  675. rankingtakePartIn(id, is_ranking) {
  676. this.radio = is_ranking.toString();
  677. this.rankingtakePartInId = id;
  678. this.dialogVisible = true;
  679. },
  680. handleClose(done) {
  681. done();
  682. },
  683. //同步信息
  684. tb() {
  685. this.$confirm('下次同步时间需在10分钟之后,是否同步?', '提示', {
  686. confirmButtonText: '确定',
  687. cancelButtonText: '取消',
  688. type: 'warning'
  689. }).then(() => {
  690. this.tbLoading = true;
  691. this.$axios('post', '/api/ding/department_sync')
  692. .then(res => {
  693. this.$message.success({ message: '同步成功' });
  694. this.dept_id = 0;
  695. this.getInfo();
  696. this.page=1;
  697. this.getEmployee();
  698. })
  699. .finally(() => {
  700. this.tbLoading = false;
  701. });
  702. });
  703. },
  704. //搜索
  705. searchUser() {
  706. this.page = 1;
  707. this.getEmployee();
  708. },
  709. //是否开通
  710. changeIs(e, id) {
  711. var url = e == 1 ? '/api/employee/disable' : '/api/employee/enable';
  712. this.$axios('post', url, { employee_id: [id] }).then(res => {
  713. if (res) {
  714. if (e == 0) {
  715. this.$message.success({ message: '开启成功,可在"角色权限设置对应管理范围"' });
  716. } else {
  717. this.$message.success({ message: res.data.msg });
  718. }
  719. // this.page=1;
  720. this.getEmployee();
  721. }
  722. });
  723. },
  724. //批量开通权限
  725. participation() {
  726. if (this.selectIds.length == 0) {
  727. this.$message.error({ message: '请选择参与的人员!' });
  728. return;
  729. }
  730. this.enable_loading = true;
  731. this.$axios('post', '/api/employee/enable', { employee_id: this.selectIds })
  732. .then(res => {
  733. if (res) {
  734. this.$message.success({ message: '开启成功,可在"角色权限设置对应管理范围"' });
  735. this.page=1;
  736. this.getEmployee();
  737. }
  738. })
  739. .finally(err => {
  740. this.enable_loading = false;
  741. });
  742. },
  743. //获取公司信息
  744. getInfo(is) {
  745. this.ruleDeprt = true;
  746. this.$axios('get', '/api/site/info').then(res => {
  747. this.info = res.data.data;
  748. this.getDepartment(is);
  749. });
  750. },
  751. //选择员工
  752. handleSelectionChange(e) {
  753. var arr = [];
  754. for (var item in e) {
  755. arr.push(e[item].id);
  756. }
  757. this.selectIds = arr;
  758. },
  759. //点击部门
  760. handleNodeClick(e) {
  761. this.page = 1;
  762. this.dept_id = e.id;
  763. },
  764. //获取部门
  765. getDepartment() {
  766. this.ruleDeprt = true;
  767. this.$axios('get', '/api/department/tree')
  768. .then(res => {
  769. var list = [
  770. {
  771. id: 0,
  772. name: this.info.name,
  773. _child: res.data.data.list
  774. }
  775. ];
  776. this.bmList = list;
  777. })
  778. .finally(() => {
  779. this.ruleDeprt = false;
  780. });
  781. },
  782. //获取员工
  783. getEmployee() {
  784. this.tableToading = true;
  785. let data={
  786. dept_id: this.dept_id,
  787. keywords: this.keywords,
  788. page: this.page,
  789. page_size:this.perPage,
  790. }
  791. let is_official=this.status=='-1'? '':this.status;
  792. if(is_official){
  793. data.is_official=is_official;
  794. }
  795. this.$axios('get', '/api/employee/index', data).then(res => {
  796. this.total = res.data.data.pageInfo.count;
  797. this.userList = res.data.data.list;
  798. var visible = localStorage.getItem('visible');
  799. if (!visible) {
  800. this.visible = true;
  801. }
  802. })
  803. .finally(err => {
  804. this.tableToading = false;
  805. });
  806. },
  807. visible_close() {
  808. localStorage.setItem('visible', 'true');
  809. this.visible = false;
  810. },
  811. //关闭提示
  812. tips_close() {
  813. localStorage.setItem('rule', 'true');
  814. this.tips_show = false;
  815. },
  816. handleSizeChange: function(val) {
  817. this.perPage = val;
  818. this.page = 1;
  819. this.getEmployee();
  820. },
  821. //页码变更
  822. handleCurrentChange: function(val) {
  823. this.page = val;
  824. this.getEmployee();
  825. }
  826. }
  827. };
  828. </script>
  829. <style lang="scss" scoped="scoped">
  830. .text-center {
  831. text-align: center;
  832. }
  833. .text-center p {
  834. padding: 10px 0;
  835. }
  836. .title {
  837. font-size: 16px;
  838. color: #909399;
  839. margin-bottom: 10px;
  840. }
  841. .popover {
  842. border: none;
  843. // color: #909399;
  844. font-weight: 600;
  845. cursor: pointer;
  846. }
  847. .popover:hover {
  848. background-color: #fff;
  849. border-color: #fff;
  850. }
  851. .switch {
  852. margin: 0;
  853. display: inline-block;
  854. position: relative;
  855. width: 40px;
  856. height: 20px;
  857. border: 1px solid #dcdfe6;
  858. outline: none;
  859. border-radius: 10px;
  860. box-sizing: border-box;
  861. background: #dcdfe6;
  862. cursor: pointer;
  863. transition: border-color 0.3s, background-color 0.3s;
  864. vertical-align: middle;
  865. }
  866. .switch:after {
  867. content: '';
  868. position: absolute;
  869. top: 1px;
  870. left: 1px;
  871. border-radius: 100%;
  872. transition: all 0.3s;
  873. width: 16px;
  874. height: 16px;
  875. background-color: #fff;
  876. }
  877. .switch-box .switch {
  878. border-color: #409eff;
  879. background-color: #409eff;
  880. }
  881. .switch-box .switch:after {
  882. left: 100%;
  883. margin-left: -17px;
  884. }
  885. .name {
  886. overflow: hidden;
  887. text-overflow: ellipsis;
  888. white-space: nowrap;
  889. width: 80%;
  890. }
  891. .bms div {
  892. margin-right: 10px;
  893. }
  894. .top-msg div:nth-child(1) {
  895. margin-bottom: 10px;
  896. }
  897. .company_name {
  898. position: relative;
  899. display: block;
  900. font-family: 'Microsoft YaHei';
  901. text-align: left;
  902. padding: 15px 25px;
  903. cursor: pointer;
  904. overflow: hidden;
  905. white-space: nowrap;
  906. text-overflow: ellipsis;
  907. border-bottom: 1px #f8f8f8 solid;
  908. }
  909. .company_name img {
  910. position: relative;
  911. display: inline-block;
  912. top: 2px;
  913. width: 18px;
  914. height: 18px;
  915. margin-right: 4px;
  916. }
  917. .terr-right {
  918. .custom-tree-node {
  919. margin-left: -4px;
  920. }
  921. .custom-tree-node * {
  922. vertical-align: middle;
  923. }
  924. .custom-tree-node:hover {
  925. .treeIcon {
  926. display: inline-block;
  927. width: 55%;
  928. }
  929. }
  930. }
  931. .el-popover2 {
  932. color: #409eff;
  933. }
  934. .rule_class_box {
  935. ::v-deep .el-tree-node {
  936. border-bottom: 1px #f8f8f8 solid;
  937. }
  938. ::v-deep .el-tree-node__content {
  939. padding: 10px 0;
  940. // border-bottom: 1px #f8f8f8 solid;
  941. }
  942. ::v-deep .el-tree-node__content:hover {
  943. background: #ecf5ff;
  944. border-radius: 4px;
  945. }
  946. ::v-deep .el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content .name {
  947. color: #409eff !important;
  948. font-weight: normal;
  949. transition: 0.35s ease-in-out;
  950. }
  951. }
  952. .participateRank {
  953. cursor: pointer;
  954. text-decoration: underline;
  955. }
  956. .tips {
  957. background: #dcdfe6;
  958. border-radius: 50%;
  959. width: 14px;
  960. height: 14px;
  961. color: #fff;
  962. display: inline-block;
  963. font-size: 12px;
  964. line-height: 14px;
  965. text-align: center;
  966. }
  967. .rankingcla{
  968. font-size: 13px;
  969. color: #959595;
  970. }
  971. </style>