Newer
Older
urbanLifeline_YanAn / src / components / patrolCrontab / index.vue
@zhangqy zhangqy on 3 Oct 8 KB first commit
  1. <template>
  2. <div>
  3. <el-tabs type="border-card">
  4. <el-tab-pane label="秒" v-if="shouldHide('second')">
  5. <CrontabSecond
  6. @update="updateCrontabValue"
  7. :check="checkNumber"
  8. :cron="crontabValueObj"
  9. ref="cronsecond"
  10. />
  11. </el-tab-pane>
  12.  
  13. <el-tab-pane label="分钟" v-if="shouldHide('min')">
  14. <CrontabMin
  15. @update="updateCrontabValue"
  16. :check="checkNumber"
  17. :cron="crontabValueObj"
  18. ref="cronmin"
  19. />
  20. </el-tab-pane>
  21.  
  22. <el-tab-pane label="小时" v-if="shouldHide('hour')">
  23. <CrontabHour
  24. @update="updateCrontabValue"
  25. :check="checkNumber"
  26. :cron="crontabValueObj"
  27. ref="cronhour"
  28. />
  29. </el-tab-pane>
  30.  
  31. <el-tab-pane label="日" v-if="shouldHide('day')">
  32. <CrontabDay
  33. @update="updateCrontabValue"
  34. :check="checkNumber"
  35. :cron="crontabValueObj"
  36. ref="cronday"
  37. />
  38. </el-tab-pane>
  39.  
  40. <el-tab-pane label="月" v-if="shouldHide('month')">
  41. <CrontabMonth
  42. @update="updateCrontabValue"
  43. :check="checkNumber"
  44. :cron="crontabValueObj"
  45. ref="cronmonth"
  46. />
  47. </el-tab-pane>
  48.  
  49. <el-tab-pane label="周" v-if="shouldHide('week')">
  50. <CrontabWeek
  51. @update="updateCrontabValue"
  52. :check="checkNumber"
  53. :cron="crontabValueObj"
  54. ref="cronweek"
  55. />
  56. </el-tab-pane>
  57.  
  58. <el-tab-pane label="年" v-if="shouldHide('year')">
  59. <CrontabYear
  60. @update="updateCrontabValue"
  61. :check="checkNumber"
  62. :cron="crontabValueObj"
  63. ref="cronyear"
  64. />
  65. </el-tab-pane>
  66. </el-tabs>
  67.  
  68. <div class="popup-main">
  69. <div class="popup-result">
  70. <p class="title">时间表达式</p>
  71. <table>
  72. <thead>
  73. <th v-for="item of tabTitles" :key="item">{{ item }}</th>
  74. <th>Cron 表达式</th>
  75. </thead>
  76. <tbody>
  77. <td>
  78. <span v-if="crontabValueObj.hour.length < 10">{{
  79. crontabValueObj.hour
  80. }}</span>
  81. <el-tooltip v-else :content="crontabValueObj.hour" placement="top"
  82. ><span>{{ crontabValueObj.hour }}</span></el-tooltip
  83. >
  84. </td>
  85. <td>
  86. <span v-if="crontabValueObj.day.length < 10">{{
  87. crontabValueObj.day
  88. }}</span>
  89. <el-tooltip v-else :content="crontabValueObj.day" placement="top"
  90. ><span>{{ crontabValueObj.day }}</span></el-tooltip
  91. >
  92. </td>
  93. <td>
  94. <span v-if="crontabValueObj.month.length < 10">{{
  95. crontabValueObj.month
  96. }}</span>
  97. <el-tooltip
  98. v-else
  99. :content="crontabValueObj.month"
  100. placement="top"
  101. ><span>{{ crontabValueObj.month }}</span></el-tooltip
  102. >
  103. </td>
  104. <td>
  105. <span v-if="crontabValueObj.week.length < 10">{{
  106. crontabValueObj.week
  107. }}</span>
  108. <el-tooltip v-else :content="crontabValueObj.week" placement="top"
  109. ><span>{{ crontabValueObj.week }}</span></el-tooltip
  110. >
  111. </td>
  112. <td>
  113. <span v-if="crontabValueObj.year.length < 10">{{
  114. crontabValueObj.year
  115. }}</span>
  116. <el-tooltip v-else :content="crontabValueObj.year" placement="top"
  117. ><span>{{ crontabValueObj.year }}</span></el-tooltip
  118. >
  119. </td>
  120. <td class="result">
  121. <span v-if="crontabValueString.length < 90">{{
  122. crontabValueString
  123. }}</span>
  124. <el-tooltip v-else :content="crontabValueString" placement="top"
  125. ><span>{{ crontabValueString }}</span></el-tooltip
  126. >
  127. </td>
  128. </tbody>
  129. </table>
  130. </div>
  131. <!-- <CrontabResult :ex="crontabValueString"></CrontabResult> -->
  132.  
  133. <div class="pop_btn">
  134. <el-button type="primary" @click="submitFill">确定</el-button>
  135. <el-button type="warning" @click="clearCron">重置</el-button>
  136. </div>
  137. </div>
  138. </div>
  139. </template>
  140.  
  141. <script setup>
  142. import CrontabSecond from "./second.vue";
  143. import CrontabMin from "./min.vue";
  144. import CrontabHour from "./hour.vue";
  145. import CrontabDay from "./day.vue";
  146. import CrontabMonth from "./month.vue";
  147. import CrontabWeek from "./week.vue";
  148. import CrontabYear from "./year.vue";
  149. import CrontabResult from "./result.vue";
  150. const { proxy } = getCurrentInstance();
  151. const emit = defineEmits(["hide", "fill"]);
  152. const props = defineProps({
  153. hideComponent: {
  154. type: Array,
  155. default: () => [],
  156. },
  157. expression: {
  158. type: String,
  159. default: "",
  160. },
  161. });
  162. // const tabTitles = ref(["秒", "分钟", "小时", "日", "月", "周", "年"]);
  163. const tabTitles = ref(["小时", "日", "月", "周", "年"]);
  164. const tabActive = ref(0);
  165. const hideComponent = ref([]);
  166. const expression = ref("");
  167. const crontabValueObj = ref({
  168. hour: "*",
  169. day: "*",
  170. month: "*",
  171. week: "?",
  172. year: "",
  173. });
  174. const crontabValueString = computed(() => {
  175. const obj = crontabValueObj.value;
  176. return (
  177. obj.hour +
  178. " " +
  179. obj.day +
  180. " " +
  181. obj.month +
  182. " " +
  183. obj.week +
  184. (obj.year === "" ? "" : " " + obj.year)
  185. );
  186. });
  187. watch(expression, () => resolveExp());
  188. function shouldHide(key) {
  189. return !(hideComponent.value && hideComponent.value.includes(key));
  190. }
  191. function resolveExp() {
  192. // 反解析 表达式
  193. if (expression.value) {
  194. const arr = expression.value.split(/\s+/);
  195. if (arr.length >= 4) {
  196. //4 位以上是合法表达式
  197. let obj = {
  198. hour: arr[0],
  199. day: arr[1],
  200. month: arr[2],
  201. week: arr[3],
  202. year: arr[4] ? arr[4] : "",
  203. };
  204. crontabValueObj.value = {
  205. ...obj,
  206. };
  207. }
  208. } else {
  209. // 没有传入的表达式 则还原
  210. clearCron();
  211. }
  212. }
  213. // tab切换值
  214. function tabCheck(index) {
  215. tabActive.value = index;
  216. }
  217. // 由子组件触发,更改表达式组成的字段值
  218. function updateCrontabValue(name, value, from) {
  219. crontabValueObj.value[name] = value;
  220. }
  221. // 表单选项的子组件校验数字格式(通过-props传递)
  222. function checkNumber(value, minLimit, maxLimit) {
  223. // 检查必须为整数
  224. value = Math.floor(value);
  225. if (value < minLimit) {
  226. value = minLimit;
  227. } else if (value > maxLimit) {
  228. value = maxLimit;
  229. }
  230. return value;
  231. }
  232.  
  233. // 填充表达式
  234. function submitFill() {
  235. emit("fill", crontabValueString.value);
  236. }
  237. function clearCron() {
  238. // 还原选择项
  239. crontabValueObj.value = {
  240. hour: "*",
  241. day: "*",
  242. month: "*",
  243. week: "?",
  244. year: "",
  245. };
  246. }
  247. onMounted(() => {
  248. expression.value = props.expression;
  249. hideComponent.value = props.hideComponent;
  250. console.log(props.hideComponent);
  251. });
  252. </script>
  253.  
  254. <style lang="scss" scoped>
  255. .pop_btn {
  256. text-align: center;
  257. margin-top: 20px;
  258. }
  259. .popup-main {
  260. position: relative;
  261. margin: 10px auto;
  262. background: #fff;
  263. border-radius: 5px;
  264. font-size: 12px;
  265. overflow: hidden;
  266. }
  267. .popup-title {
  268. overflow: hidden;
  269. line-height: 34px;
  270. padding-top: 6px;
  271. background: #f2f2f2;
  272. }
  273. .popup-result {
  274. box-sizing: border-box;
  275. line-height: 24px;
  276. margin: 25px auto;
  277. padding: 15px 10px 10px;
  278. border: 1px solid #ccc;
  279. position: relative;
  280. }
  281. .popup-result .title {
  282. position: absolute;
  283. top: -28px;
  284. left: 50%;
  285. width: 140px;
  286. font-size: 14px;
  287. margin-left: -70px;
  288. text-align: center;
  289. line-height: 30px;
  290. background: #fff;
  291. }
  292. .popup-result table {
  293. text-align: center;
  294. width: 100%;
  295. margin: 0 auto;
  296. }
  297. .popup-result table td:not(.result) {
  298. width: 3.5rem;
  299. min-width: 3.5rem;
  300. max-width: 3.5rem;
  301. }
  302. .popup-result table span {
  303. display: block;
  304. width: 100%;
  305. font-family: arial;
  306. line-height: 30px;
  307. height: 30px;
  308. white-space: nowrap;
  309. overflow: hidden;
  310. border: 1px solid #e8e8e8;
  311. }
  312. .popup-result-scroll {
  313. font-size: 12px;
  314. line-height: 24px;
  315. height: 10em;
  316. overflow-y: auto;
  317. }
  318. </style>