framework.vue 29 KB

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