index.vue 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. <template>
  2. <div class="white" :class="{ 'pa-3': !$attrs.panorama }">
  3. <m-search v-if="!$attrs.panorama" :items="searchItems" v-model="searchValues" class="mb-3" @search="onSearch">
  4. <template #button>
  5. <m-button type="primary" icon="el-icon-plus" plain @click="onAdd">新增</m-button>
  6. <el-upload class="el-button pa-0" action="#" :show-file-list="false" :http-request="onImport">
  7. <m-button type="primary" icon="el-icon-upload2" plain :loading="importLoading">上传</m-button>
  8. </el-upload>
  9. <m-button type="primary" icon="el-icon-download" plain @click="onExport" :loading="exportLoading">导出</m-button>
  10. <m-button type="primary" icon="el-icon-download" plain @click="onDownload" :loading="downloadLoading">下载模板</m-button>
  11. </template>
  12. </m-search>
  13. <m-table
  14. card-title="员工花名册"
  15. v-loading="loading"
  16. row-key="id"
  17. :items="items"
  18. :headers="headers"
  19. :page-size="pageInfo.size"
  20. :page-current="pageInfo.current"
  21. :total="total"
  22. :default-sort="{ prop: 'sort', order: 'ascending' }"
  23. @page-change="pageChange"
  24. >
  25. <template #actions="{ row }">
  26. <m-button text type="primary" @click="onEdit(row)">编辑</m-button>
  27. <m-button text type="danger" @click="onDelete(row)">删除</m-button>
  28. </template>
  29. </m-table>
  30. <rosterEdit ref="rosterEditRef" :title="title" @refresh="init"></rosterEdit>
  31. </div>
  32. </template>
  33. <script>
  34. import { downloadFile } from '@/utils'
  35. import rosterEdit from './rosterEdit.vue'
  36. import {
  37. getRosterList,
  38. deleteRoster,
  39. uploadRoster,
  40. exportRoster,
  41. downloadRosterTemplate
  42. } from '@/api/system'
  43. import { mapGetters } from 'vuex'
  44. export default {
  45. name: 'sys-roster',
  46. components: { rosterEdit },
  47. data () {
  48. return {
  49. importLoading: false,
  50. exportLoading: false,
  51. downloadLoading: false,
  52. title: '',
  53. loading: false,
  54. searchValues: {
  55. employeeName: null
  56. },
  57. headers: [
  58. // { text: '一级机构', align: 'start', value: 'secondLevelBranch' },
  59. { label: '上级机构', prop: 'parentOrganizationName' },
  60. { label: '部门', prop: 'deptName' },
  61. { label: '员工名称', prop: 'employeeName' },
  62. { label: '人员类别', prop: 'personnelCategory' },
  63. { label: '岗位名称', prop: 'postName' },
  64. { label: '岗位序列', prop: 'positionSequence' },
  65. { label: '岗位类别', prop: 'positionCategory' },
  66. { label: '职务层级', prop: 'jobLevel' },
  67. { label: '通行证号', prop: 'passes' },
  68. { label: '工行时间', prop: 'tradeUnionsTimeText' },
  69. { label: '薪酬档次', align: 'center', prop: 'salaryCategory' },
  70. { label: '薪酬级别', align: 'center', prop: 'salaryLevel' },
  71. { label: '操作', prop: 'actions' }
  72. ],
  73. itemData: {},
  74. items: [],
  75. orders: [],
  76. pageInfo: {
  77. size: 10,
  78. current: 1
  79. },
  80. total: 0
  81. }
  82. },
  83. computed: {
  84. ...mapGetters(['organizationTree']),
  85. searchItems () {
  86. return [
  87. {
  88. label: '员工名称',
  89. options: {
  90. placeholder: '请输入员工名称'
  91. },
  92. prop: 'employeeName',
  93. type: 'input'
  94. },
  95. {
  96. label: '部门名称',
  97. options: {
  98. clearable: true,
  99. placeholder: '请选择部门',
  100. options: this.organizationTree,
  101. showAllLevels: false,
  102. props: {
  103. emitPath: false,
  104. value: 'organizationNo',
  105. label: 'organizationName',
  106. children: 'child'
  107. }
  108. },
  109. prop: 'organizationNo',
  110. type: 'cascader'
  111. }
  112. ]
  113. }
  114. },
  115. created () {
  116. // 全景视图终止自动调用
  117. if (this.$attrs.panorama) {
  118. return
  119. }
  120. this.init()
  121. },
  122. methods: {
  123. // 执行全景初始化操作
  124. onInitPanorama (organizationNo, employeeNo) {
  125. this.panorama = { organizationNo, employeeNo }
  126. if (employeeNo) {
  127. this.searchValues = {
  128. personnelCode: employeeNo
  129. }
  130. } else {
  131. this.searchValues = {
  132. organizationNo: organizationNo
  133. }
  134. }
  135. this.init()
  136. },
  137. async init () {
  138. this.loading = true
  139. const query = {}
  140. if (this.$attrs.panorama) {
  141. if (this.searchValues.personnelCode) {
  142. query.entity = {
  143. personnelCode: this.searchValues.personnelCode
  144. }
  145. }
  146. if (this.searchValues.organizationNo) {
  147. Object.assign(query, {
  148. organizationNo: this.searchValues.organizationNo
  149. })
  150. }
  151. } else {
  152. Object.assign(query, {
  153. entity: this.searchValues
  154. })
  155. }
  156. try {
  157. const { data } = await getRosterList({
  158. page: { ...this.pageInfo, orders: this.orders },
  159. ...query
  160. })
  161. this.items = data.records.map(e => {
  162. const date = new Date(e.tradeUnionsTime)
  163. // 获取年、月、日
  164. const year = date.getFullYear()
  165. const month = String(date.getMonth() + 1).padStart(2, '0') // 月份从0开始,所以要加1
  166. const day = String(date.getDate()).padStart(2, '0')
  167. return {
  168. ...e,
  169. tradeUnionsTimeText: `${year}${month}${day}`
  170. }
  171. })
  172. this.total = data.total
  173. } catch (error) {
  174. this.$message.error(error)
  175. } finally {
  176. this.loading = false
  177. }
  178. },
  179. onSearch () {
  180. this.pageInfo.current = 1
  181. this.init()
  182. },
  183. onAdd () {
  184. this.title = '新增员工'
  185. this.$refs.rosterEditRef.open()
  186. },
  187. onEdit (item) {
  188. this.title = '编辑员工'
  189. this.$refs.rosterEditRef.open(item)
  190. },
  191. onDelete (item) {
  192. this.$confirm('确定删除该员工吗?', '提示', {
  193. confirmButtonText: '确定',
  194. cancelButtonText: '取消',
  195. type: 'warning'
  196. }).then(async () => {
  197. try {
  198. await deleteRoster({ personnelCode: item.personnelCode })
  199. this.init()
  200. this.$message.success('删除成功')
  201. } catch (error) {
  202. this.$message.error(error)
  203. }
  204. }).catch(() => {})
  205. },
  206. async onImport (response) {
  207. this.importLoading = true
  208. const formData = new FormData()
  209. formData.append('file', response.file)
  210. try {
  211. await uploadRoster(formData)
  212. this.$message.success('导入成功')
  213. this.init()
  214. } catch (error) {
  215. this.$message.error(error)
  216. } finally {
  217. this.importLoading = false
  218. }
  219. },
  220. async onExport () {
  221. this.exportLoading = true
  222. try {
  223. const { data, name } = await exportRoster()
  224. downloadFile(data, name)
  225. } catch (error) {
  226. this.$message.error(error)
  227. } finally {
  228. this.exportLoading = false
  229. }
  230. },
  231. async onDownload () {
  232. this.downloadLoading = true
  233. try {
  234. const { data, name } = await downloadRosterTemplate()
  235. downloadFile(data, name)
  236. } catch (error) {
  237. this.$message.error(error)
  238. } finally {
  239. this.downloadLoading = false
  240. }
  241. },
  242. pageChange (index) {
  243. this.pageInfo.current = index
  244. this.init()
  245. }
  246. }
  247. }
  248. </script>
  249. <style lang="scss" scoped>
  250. </style>