timeTable.vue 7.5 KB

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