SalaryCount.vue 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. <script setup lang="ts">
  2. import { ref, reactive } from 'vue'
  3. import type { TableColumnCtx } from 'element-plus'
  4. import { Salary_List, Salary_Send, Salary_Excel } from '@/api/salary/index'
  5. import { ElMessage } from 'element-plus'
  6. let date = new Date()
  7. const year = date.getFullYear()
  8. const month = date.getMonth()
  9. const salaryFromData = reactive({
  10. year: year + '',
  11. month: (month < 10 ? '0' : '') + month,
  12. T_uuid: ''
  13. })
  14. const salarDateYearChange = (val: string) => {
  15. if (!val) return
  16. initParam.T_date = `${val}-${salaryFromData.month}`
  17. getSalary_List()
  18. }
  19. const salarDateMonthChange = (val: string) => {
  20. if (!val) return
  21. initParam.T_date = `${salaryFromData.year}-${val}`
  22. getSalary_List()
  23. }
  24. const tableTH = [
  25. { type: 'index', label: '序号', width: '60px', fixed: 'left' },
  26. { prop: 'T_user_name', label: '姓名', fixed: 'left', width: '80px' },
  27. { prop: 'T_user_dept', label: '部门', fixed: 'left', width: '80px' },
  28. { prop: 'T_user_post', label: '岗位', fixed: 'left', width: '100px' },
  29. { prop: 'T_base', label: '基本工资', sortable: true, width: '120px' },
  30. { prop: 'T_post', label: '岗位工资', sortable: true, width: '120px' },
  31. { prop: 'T_seniority', label: '工龄工资', sortable: true, width: '120px' },
  32. { prop: 'T_perf', label: '绩效金额', sortable: true, width: '120px' },
  33. { prop: 'T_perf_score', label: '绩效得分', sortable: true, width: '120px' },
  34. { prop: 'T_actual_Perf', label: '实发绩效', sortable: true, width: '120px' },
  35. { prop: 'T_back_payment', label: '其他补款', sortable: true, width: '120px' },
  36. { prop: 'T_attendance', label: '考勤扣款', sortable: true, width: '120px' },
  37. { prop: 'T_cut_payment', label: '其他扣款', sortable: true, width: '120px' },
  38. { prop: 'T_laballot', label: '应发合计', sortable: true, width: '120px' },
  39. { prop: 'T_pension_insurance', label: '养老保险', sortable: true, width: '120px' },
  40. { prop: 'T_unemployment_insurance', label: '失业保险', sortable: true, width: '120px' },
  41. { prop: 'T_medical_insurance', label: '基本医疗保险', sortable: true, width: '140px' },
  42. { prop: 'T_large_medical_insurance', label: '大额医疗保险', sortable: true, width: '140px' },
  43. { prop: 'T_housing_fund', label: '公积金', sortable: true, width: '100px' },
  44. { prop: 'T_tax', label: '个税扣款', sortable: true, width: '120px' },
  45. { prop: 'T_laborage', label: '扣款合计', sortable: true, width: '120px' },
  46. { prop: 'T_total', label: '实发合计', sortable: true, width: '120px' }
  47. ]
  48. interface User {
  49. Id: number
  50. T_user_name: string
  51. T_base: number
  52. T_post: number
  53. T_seniority: number
  54. T_Perf: number
  55. T_Perf_score: number
  56. T_back_payment: number
  57. T_tax: number
  58. T_attendance: number
  59. T_cut_payment: number
  60. T_pension_insurance: number
  61. T_unemployment_insurance: number
  62. T_medical_insurance: number
  63. T_Large_medical_insurance: number
  64. T_housing_fund: number
  65. }
  66. interface SpanMethodProps {
  67. row: User
  68. column: TableColumnCtx<User>
  69. rowIndex: number
  70. columnIndex: number
  71. }
  72. const arraySpanMethod = ({ rowIndex, columnIndex }: SpanMethodProps) => {
  73. if (rowIndex === tableData.value.length - 1) {
  74. if (columnIndex === 2) {
  75. return [1, 3]
  76. } else if (columnIndex === 3 || columnIndex === 4) {
  77. return [0, 0]
  78. }
  79. }
  80. }
  81. const initParam = reactive({
  82. T_date: `${salaryFromData.year}-${salaryFromData.month}`,
  83. page: 1,
  84. page_z: 999
  85. })
  86. const getSalary_List = async () => {
  87. const res: any = await Salary_List(initParam)
  88. tableData.value = res.Data.Data
  89. }
  90. getSalary_List()
  91. const exportSalaryExcel = async () => {
  92. const res: any = await Salary_Excel({ T_date: `${salaryFromData.year}-${salaryFromData.month}` })
  93. if (res.Code === 200) {
  94. window.open(res.Data)
  95. }
  96. }
  97. const publishSalary = async () => {
  98. // Salary_Send
  99. if (multipleSelection.value.length === 0 || multipleSelection.value[0]?.Id === 0) {
  100. ElMessage({
  101. message: '请选择用户!!!',
  102. type: 'warning'
  103. })
  104. return
  105. }
  106. multipleSelection.value.pop()
  107. for await (let item of multipleSelection.value) {
  108. Salary_Send({ T_id: item.Id })
  109. }
  110. }
  111. const multipleSelection = ref<User[]>([])
  112. const handleSelectionChange = (val: User[]) => {
  113. multipleSelection.value = val
  114. }
  115. const tableData = ref<User[]>([])
  116. const tableRowClassName = ({ rowIndex }: { row: User; rowIndex: number }) => {
  117. if (rowIndex % 2 === 0) {
  118. return 'warning-row'
  119. } else {
  120. return 'success-row'
  121. }
  122. }
  123. </script>
  124. <template>
  125. <div class="SalaryCount">
  126. <el-card class="m-b-3">
  127. <el-row :gutter="24">
  128. <el-col :span="12" class="d-flex">
  129. <span class="demonstration">年:</span>
  130. <el-date-picker
  131. v-model="salaryFromData.year"
  132. style="width: 100px"
  133. value-format="YYYY"
  134. type="year"
  135. placeholder="请选择年"
  136. @change="salarDateYearChange"
  137. />
  138. <span class="demonstration">月:</span>
  139. <el-date-picker
  140. v-model="salaryFromData.month"
  141. style="width: 100px"
  142. popper-class="picker-date"
  143. format="MM"
  144. value-format="MM"
  145. type="month"
  146. placeholder="请选择月"
  147. @change="salarDateMonthChange"
  148. />
  149. </el-col>
  150. <el-col :span="12" class="d-flex">
  151. <el-button type="primary" @click="exportSalaryExcel">导出表格</el-button>
  152. <el-button type="success" @click="publishSalary">发布</el-button>
  153. </el-col>
  154. </el-row>
  155. </el-card>
  156. <el-card class="table-card">
  157. <el-table
  158. :data="tableData"
  159. @selection-change="handleSelectionChange"
  160. :span-method="arraySpanMethod"
  161. border
  162. style="width: 100%"
  163. :row-class-name="tableRowClassName"
  164. >
  165. <el-table-column type="selection" width="55" />
  166. <template v-for="(item, index) in tableTH" :key="index">
  167. <el-table-column
  168. v-if="item.type === 'index' || item.fixed === 'left'"
  169. :type="item.type"
  170. align="center"
  171. v-bind="item"
  172. />
  173. <el-table-column
  174. v-else
  175. :prop="item.prop"
  176. :label="item.label"
  177. :width="item.width"
  178. align="center"
  179. label-class-name="label-table"
  180. :sortable="item.sortable"
  181. />
  182. </template>
  183. </el-table>
  184. <!-- <div class="pagination">
  185. <el-pagination background layout="total,prev, pager, next" :total="total" />
  186. </div> -->
  187. </el-card>
  188. </div>
  189. </template>
  190. <style scoped lang="scss">
  191. .SalaryCount {
  192. height: 100%;
  193. .table-card {
  194. height: calc(100% - 72px - 12px);
  195. :deep(.el-card__body) {
  196. height: 100%;
  197. }
  198. }
  199. }
  200. :deep(.el-table .warning-row) {
  201. background-color: var(--el-color-warning-light-9);
  202. }
  203. :deep(.el-table .success-row) {
  204. background-color: var(--el-color-success-light-9);
  205. }
  206. .label-table {
  207. white-space: nowrap;
  208. }
  209. .d-flex {
  210. display: flex;
  211. justify-content: start;
  212. align-items: center;
  213. flex-wrap: nowrap;
  214. }
  215. .pagination {
  216. display: flex;
  217. justify-content: end;
  218. margin-top: 2rem;
  219. }
  220. </style>