timeTable.vue 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. <template>
  2. <el-form ref="form" :model="form" :rules="rules">
  3. <ele-pro-table
  4. ref="table"
  5. :needPage="false"
  6. :columns="columns"
  7. :datasource="form.datasource"
  8. cache-key="systemRoleTable"
  9. >
  10. <!-- 表头工具栏 -->
  11. <template v-slot:toolbar>
  12. <el-button
  13. size="small"
  14. type="primary"
  15. icon="el-icon-plus"
  16. class="ele-btn-icon"
  17. @click="handlAdd"
  18. >
  19. 新增
  20. </el-button>
  21. </template>
  22. <template v-slot:name="scope">
  23. <el-form-item
  24. style="margin-bottom: 20px"
  25. :prop="'datasource.' + scope.$index + '.name'"
  26. :rules="{
  27. required: true,
  28. message: '请输入',
  29. trigger: 'change'
  30. }"
  31. >
  32. <el-input v-model="scope.row.name" placeholder="请输入"></el-input>
  33. </el-form-item>
  34. </template>
  35. <template v-slot:startTime="scope">
  36. <el-form-item
  37. style="margin-bottom: 20px"
  38. :prop="'datasource.' + scope.$index + '.startTime'"
  39. :rules="{
  40. required: true,
  41. message: '请输入',
  42. trigger: 'change'
  43. }"
  44. >
  45. <el-time-picker
  46. style="width: 100%"
  47. placeholder="起始时间"
  48. v-model="scope.row.startTime"
  49. format="HH:mm"
  50. value-format="HH:mm:ss"
  51. @change="changeStartTime"
  52. >
  53. </el-time-picker>
  54. </el-form-item>
  55. </template>
  56. <template v-slot:endTime="scope">
  57. <el-form-item
  58. style="margin-bottom: 20px"
  59. :prop="'datasource.' + scope.$index + '.endTime'"
  60. :rules="{
  61. required: true,
  62. message: '请输入',
  63. trigger: 'change'
  64. }"
  65. >
  66. <el-time-picker
  67. style="width: 100%"
  68. format="HH:mm"
  69. value-format="HH:mm:ss"
  70. placeholder="结束时间"
  71. v-model="scope.row.endTime"
  72. :picker-options="{
  73. selectableRange: setEndTime(scope)
  74. }"
  75. @change="changeEndTime"
  76. >
  77. </el-time-picker>
  78. </el-form-item>
  79. </template>
  80. <template v-slot:isFirst="scope">
  81. {{ scope.row.isFirst ? '是' : '否' }}
  82. </template>
  83. <template v-slot:workHour="scope">
  84. {{ getHour(scope.row) }}
  85. </template>
  86. <!-- 操作列 -->
  87. <template v-slot:action="{ row }">
  88. <el-popconfirm
  89. class="ele-action"
  90. title="确定要删除此角色吗?"
  91. @confirm="remove(row)"
  92. >
  93. <template v-slot:reference>
  94. <el-link type="danger" :underline="false" icon="el-icon-delete">
  95. 删除
  96. </el-link>
  97. </template>
  98. </el-popconfirm>
  99. <el-link
  100. type="primary"
  101. :underline="false"
  102. v-if="!row.isLeader"
  103. @click="setFirst(row)"
  104. >
  105. 设为首班
  106. </el-link>
  107. </template>
  108. </ele-pro-table>
  109. <!-- <el-button @click="verification">ada</el-button> -->
  110. </el-form>
  111. </template>
  112. <script>
  113. export default {
  114. data() {
  115. const defaultForm = {
  116. key: null,
  117. endTime: '',
  118. isFirst: 0,
  119. name: '',
  120. startTime: '',
  121. workHour: ''
  122. };
  123. return {
  124. defaultForm,
  125. form: {
  126. datasource: []
  127. },
  128. rules: {},
  129. columns: [
  130. {
  131. width: 45,
  132. type: 'index',
  133. columnKey: 'index',
  134. align: 'center'
  135. },
  136. {
  137. prop: 'name',
  138. label: '时段名称',
  139. slot: 'name'
  140. },
  141. {
  142. prop: 'startTime',
  143. label: '上班时间',
  144. slot: 'startTime'
  145. },
  146. {
  147. prop: 'endTime',
  148. label: '下班时间',
  149. slot: 'endTime'
  150. },
  151. {
  152. prop: 'workHour',
  153. label: '工作时数',
  154. slot: 'workHour'
  155. },
  156. {
  157. prop: 'isFirst',
  158. label: '是否当日首班',
  159. slot: 'isFirst'
  160. },
  161. {
  162. columnKey: 'action',
  163. label: '操作',
  164. width: 220,
  165. align: 'center',
  166. resizable: false,
  167. slot: 'action',
  168. showOverflowTooltip: true
  169. }
  170. ]
  171. };
  172. },
  173. methods: {
  174. remove(row) {
  175. console.log(row);
  176. let index = this.form.datasource.findIndex((n) => n.key == row.key);
  177. if (index !== -1) {
  178. this.form.datasource.splice(index, 1);
  179. this.setSort();
  180. }
  181. },
  182. // 清空表格
  183. restTable() {
  184. this.form.datasource = [];
  185. },
  186. // 重新排序
  187. setSort() {
  188. this.form.datasource.forEach((n, index) => {
  189. n.key = index + 1;
  190. });
  191. },
  192. // 添加
  193. handlAdd() {
  194. let item = JSON.parse(JSON.stringify(this.defaultForm));
  195. item.key = this.form.datasource.length + 1;
  196. this.form.datasource.push(item);
  197. },
  198. // 设为首班
  199. setFirst(row) {
  200. this.form.datasource.forEach((n) => {
  201. n.isFirst = 0;
  202. });
  203. row.isFirst = 1;
  204. },
  205. setEndTime(scope) {
  206. if (scope.row.startTime) {
  207. return `${scope.row.startTime} - 23:59:59`;
  208. } else {
  209. return '00:00:00 - 23:59:59';
  210. }
  211. },
  212. // 计算小时
  213. getHour(row) {
  214. let s1 = row.startTime;
  215. let s2 = row.endTime;
  216. let result = 0;
  217. if (!s1 || !s2) {
  218. result = 0;
  219. }
  220. var reDate = /\d{4}-\d{1,2}-\d{1,2} /;
  221. s1 = new Date(
  222. (reDate.test(s1) ? s1 : '1970-01-01 ' + s1).replace(/-/g, '/')
  223. );
  224. s2 = new Date(
  225. (reDate.test(s2) ? s2 : '1970-01-01 ' + s2).replace(/-/g, '/')
  226. );
  227. var ms = s2.getTime() - s1.getTime();
  228. if (ms < 0) return 0;
  229. result = Math.floor(ms / 1000 / 60 / 60); //小时
  230. row.workHour = result;
  231. this.$emit('timeAll', this.gettimeAll());
  232. return result;
  233. },
  234. // 获取工作日时常
  235. gettimeAll() {
  236. let result = 0;
  237. this.form.datasource.forEach((n) => {
  238. result += n.workHour;
  239. });
  240. return result;
  241. },
  242. verification() {
  243. return new Promise((resolve, reject) => {
  244. this.$refs.form.validate((valid) => {
  245. if (!valid) {
  246. reject();
  247. return false;
  248. }
  249. if (this.isOverlap()) {
  250. reject();
  251. return false;
  252. }
  253. resolve();
  254. });
  255. });
  256. },
  257. // 判断时间段是否重叠
  258. isOverlap() {
  259. let timeRanges = JSON.parse(JSON.stringify(this.form.datasource));
  260. // 按开始时间排序
  261. timeRanges.sort(function (a, b) {
  262. return (
  263. new Date(`1970-01-01 ${a.startTime}`) -
  264. new Date(`1970-01-01 ${b.startTime}`)
  265. );
  266. });
  267. console.log(timeRanges);
  268. for (var i = 0; i < timeRanges.length - 1; i++) {
  269. let endTime = timeRanges[i].endTime;
  270. let NstartTime = timeRanges[i + 1].startTime;
  271. if (endTime > NstartTime) {
  272. // 出现重叠
  273. this.$message.error(
  274. `上班时间${NstartTime}与下班时间${endTime}存在重叠`
  275. );
  276. return true;
  277. }
  278. }
  279. return false;
  280. },
  281. changeStartTime(val) {
  282. this.isOverlap();
  283. },
  284. changeEndTime(val) {
  285. this.isOverlap();
  286. }
  287. }
  288. };
  289. </script>
  290. <style lang="scss" scoped>
  291. </style>