index.vue 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  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="orange" icon="el-icon-plus" @click="onAdd">新增</m-button>
  6. <el-upload class="el-button pa-0" action="#" :show-file-list="false" :http-request="onImport">
  7. <m-button type="orange" icon="el-icon-upload2" :loading="importLoading">上传</m-button>
  8. </el-upload>
  9. <m-button type="orange" icon="el-icon-download" @click="onExport" :loading="exportLoading">导出</m-button>
  10. <m-button type="orange" icon="el-icon-download" @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('确定删除该员工吗?', '提示').then(async () => {
  193. try {
  194. await deleteRoster({ personnelCode: item.personnelCode })
  195. this.init()
  196. this.$message.success('删除成功')
  197. } catch (error) {
  198. this.$message.error(error)
  199. }
  200. }).catch(() => {})
  201. },
  202. async onImport (response) {
  203. this.importLoading = true
  204. const formData = new FormData()
  205. formData.append('file', response.file)
  206. try {
  207. await uploadRoster(formData)
  208. this.$message.success('导入成功')
  209. this.init()
  210. } catch (error) {
  211. this.$message.error(error)
  212. } finally {
  213. this.importLoading = false
  214. }
  215. },
  216. async onExport () {
  217. this.exportLoading = true
  218. try {
  219. const { data, name } = await exportRoster()
  220. downloadFile(data, name)
  221. } catch (error) {
  222. this.$message.error(error)
  223. } finally {
  224. this.exportLoading = false
  225. }
  226. },
  227. async onDownload () {
  228. this.downloadLoading = true
  229. try {
  230. const { data, name } = await downloadRosterTemplate()
  231. downloadFile(data, name)
  232. } catch (error) {
  233. this.$message.error(error)
  234. } finally {
  235. this.downloadLoading = false
  236. }
  237. },
  238. pageChange (index) {
  239. this.pageInfo.current = index
  240. this.init()
  241. }
  242. }
  243. }
  244. </script>
  245. <style lang="scss" scoped>
  246. </style>