atten-info.vue 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. <template>
  2. <basic-container>
  3. <avue-crud
  4. v-bind="bindVal"
  5. v-on="onEvent"
  6. v-model="form"
  7. :page.sync="page"
  8. :before-open="handleBeforeOpen"
  9. :permission="permissionList"
  10. :header-cell-style="headerCellStyle"
  11. >
  12. <template slot="menuLeft">
  13. <el-button
  14. type="danger"
  15. size="small"
  16. icon="el-icon-delete"
  17. plain
  18. @click="handleDelete"
  19. >
  20. 清除考勤数据
  21. </el-button>
  22. <el-button
  23. type="success"
  24. size="small"
  25. plain
  26. icon="el-icon-upload2"
  27. @click="handleImport"
  28. >
  29. 导入
  30. </el-button>
  31. <el-button
  32. type="warning"
  33. size="small"
  34. plain
  35. icon="el-icon-download"
  36. @click="handleExport"
  37. >
  38. 导出
  39. </el-button>
  40. <print-table-btn @click="printTable" />
  41. <div style="display: flex; align-items: center;">
  42. <year-month-select v-model="params.yearAndMonth" :showAllYear="false"></year-month-select>
  43. </div>
  44. </template>
  45. <!-- <template slot="technicianId" slot-scope="{ row }">
  46. <span>{{ row.name }}</span>
  47. </template>
  48. <template slot="gsTotalSearch">
  49. <div style="display: flex; align-items: center;">
  50. <avue-input-number v-model="params.gsTotalStart" :min="0"></avue-input-number>
  51. <span style="width: 70px; text-align: center;">至</span>
  52. <avue-input-number v-model="params.gsTotalEnd" :min="0"></avue-input-number>
  53. </div>
  54. </template> -->
  55. </avue-crud>
  56. <upload-excel-dialog ref="uploadExcelDialog" :uploadAfter="uploadAfter"/>
  57. <WideTablePrinter
  58. ref="printWideTable"
  59. :columns="wideTableColumns"
  60. :data="data"
  61. :print-title="printTitle"
  62. :rows-per-page="30"
  63. :default-landscape="true"
  64. />
  65. </basic-container>
  66. </template>
  67. <script>
  68. import YearMonthSelect from "@/components/year-month-select";
  69. import UploadExcelDialog from "@/components/upload-excel-dialog";
  70. import {exportBlob} from "@/api/common";
  71. import {getToken} from "@/util/auth";
  72. import {downloadXls} from "@/util/util";
  73. import { deepClone, getMonthDatesWithMarkers } from "@/util/util";
  74. import moment from "moment";
  75. import ChineseHoliday from "@chnlib/chinese-holiday";
  76. export default window.$crudCommon({
  77. components: {
  78. YearMonthSelect,
  79. UploadExcelDialog,
  80. },
  81. data() {
  82. return {
  83. params: {
  84. yearAndMonth: moment(new Date()).format('YYYYMM'),
  85. },
  86. defaultColumns: [],
  87. wideTableColumns: [],
  88. printTitle: "",
  89. };
  90. },
  91. watch: {
  92. 'params.yearAndMonth'(newVal) {
  93. this.refreshTableCol(newVal);
  94. this.page.currentPage = 1;
  95. this.getList(this.page);
  96. }
  97. },
  98. async created() {
  99. this.defaultColumns = deepClone(this.option.column);
  100. this.refreshTableCol(this.params.yearAndMonth);
  101. },
  102. beforeDestroy() {
  103. this.option.column = deepClone(this.defaultColumns);
  104. },
  105. methods: {
  106. // handleBeforeOpen(done, type) {
  107. // this.option.column.forEach(item => {
  108. // if (item.prop == "technicianId") {
  109. // item.dicUrl = '/api/kd-scientific/technician/page';
  110. // item.dicQuery.yearAndMonth = this.params.yearAndMonth;
  111. // }
  112. // });
  113. // done();
  114. // },
  115. refreshTableCol(yearAndMonth) {
  116. let yearMonth = moment(yearAndMonth).format("YYYY-MM").split("-");
  117. const monthDays = getMonthDatesWithMarkers(Number(yearMonth[0]), Number(yearMonth[1]));
  118. let newColumns = deepClone(this.defaultColumns);
  119. monthDays.forEach((item) => {
  120. let col = {
  121. prop: moment(item.dateString).format('yyyyMMDD'),
  122. label: item.dayName + "" + item.day.toString(),
  123. type: 'number',
  124. precision: 1,
  125. min: 0,
  126. width: 45,
  127. align: 'center',
  128. isWorkDay: ChineseHoliday.isWorkday(item.dateString),
  129. showOverflowTooltip: true,
  130. }
  131. if (!ChineseHoliday.isWorkday(item.dateString)) {
  132. col.labelClassName = 'red';
  133. col.labelClassName = 'red';
  134. }
  135. newColumns.push(col);
  136. });
  137. newColumns.push({
  138. prop: "monthlyHours",
  139. label: "本月出勤/小时",
  140. type: 'number',
  141. precision: 1,
  142. min: 0,
  143. width: 70,
  144. align: 'center',
  145. showOverflowTooltip: true,
  146. display: false,
  147. }, {
  148. prop: "monthlyDays",
  149. label: "本月出勤/天",
  150. type: 'number',
  151. precision: 1,
  152. min: 0,
  153. width: 70,
  154. align: 'center',
  155. showOverflowTooltip: true,
  156. display: false,
  157. });
  158. this.option.column = newColumns;
  159. },
  160. getFormData() {
  161. const newFormData = { ...this.form, yearAndMonth: this.params.yearAndMonth };
  162. let dailyAttendances = [];
  163. Object.keys(this.form).forEach(key => {
  164. if (key.indexOf(this.params.yearAndMonth) > -1) {
  165. if (this.form[key]) {
  166. dailyAttendances.push({
  167. workDate: key,
  168. workHours: this.form[key]
  169. });
  170. }
  171. delete newFormData[key];
  172. }
  173. });
  174. newFormData.dailyAttendances = dailyAttendances;
  175. return newFormData;
  176. },
  177. handleImport() {
  178. let excelParams = { yearAndMonth: this.params.yearAndMonth };
  179. this.$refs.uploadExcelDialog.open('/api/kd-scientific/attendance/import', excelParams);
  180. },
  181. uploadAfter() {
  182. this.page.currentPage = 1;
  183. this.getList(this.page);
  184. },
  185. handleExport() {
  186. exportBlob(`/api/kd-scientific/attendance/export?${this.website.tokenHeader}=${getToken()}`, this.params).then(res => {
  187. downloadXls(res.data, `考勤信息${this.params.yearAndMonth}.xlsx`);
  188. });
  189. },
  190. /**
  191. * 打印表格
  192. * @param isLandscape 是否横向打印
  193. */
  194. printTable(isLandscape) {
  195. this.wideTableColumns = this.$refs.crud.columnOption;
  196. this.printTitle = `考勤信息${this.params.yearAndMonth}`;
  197. this.$nextTick(() => {
  198. this.$refs.printWideTable.printTable(isLandscape);
  199. })
  200. },
  201. headerCellStyle ({ column }) {
  202. let color = column.labelClassName ? 'red' : 'rgba(0,0,0,.85)';
  203. return {
  204. color
  205. }
  206. }
  207. },
  208. }, {
  209. // 模块路径
  210. name: 'yfCostManage/basicDataSetting/attenInfo',
  211. res: ({ data }) => {
  212. let newList = [];
  213. data.records.forEach((item) => {
  214. let objData = { ...item, id: item.technicianId };
  215. item.dailyAttendances.forEach(hourItem => {
  216. objData[hourItem.workDate] = (hourItem.workHours || 0).toFixed(1);
  217. });
  218. newList.push(objData);
  219. });
  220. data.records = newList;
  221. return data;
  222. },
  223. });
  224. </script>