index.vue 43 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118
  1. <template>
  2. <div style="width: 100%;padding-top: 1%;display: flex;" :style="{'height':heightAll+'px'}">
  3. <div style="width: 98%;margin-left: 1%;">
  4. <div style="display: flex;width: 100%;align-items: center;margin-left: 0%;">
  5. <div>
  6. 组名称
  7. </div>
  8. <el-input size="mini" v-model="groupName" style="width: 10%;margin-left: 1%;" placeholder="" />
  9. <div style="margin-left: 2%;">
  10. 任务名称
  11. </div>
  12. <el-input size="mini" v-model="jobName" style="width: 10%;margin-left: 1%;" placeholder="" />
  13. <div style="margin-left: 2%;">
  14. 执行器名称
  15. </div>
  16. <el-input size="mini" v-model="executorInfo" style="width: 10%;margin-left: 1%;" placeholder="" />
  17. <div style="margin-left: 2%;">
  18. 状态
  19. </div>
  20. <el-select
  21. v-model="jobStatus"
  22. class="noBorSel"
  23. placeholder=""
  24. style="width: 10%;margin-left: 1%;"
  25. >
  26. <el-option label="启用" :value="0" />
  27. <el-option label="禁用" :value="1" />
  28. </el-select>
  29. <!-- <el-button type="" @click="" size="mini" style="margin-left:auto;" :icon="RefreshRight">重置 </el-button> -->
  30. <el-button type="primary" @click="getTable" size="mini" style="margin-left:auto;" :icon="Search">搜索 </el-button>
  31. </div>
  32. <!-- <el-divider/> -->
  33. <div style="width: 99%;margin-left: 1%;margin-top: 1%;">
  34. <div style="display: flex;justify-content: space-between;width: 100%;align-items: center;">
  35. <div style="font-weight: bold;">
  36. 定时任务列表
  37. </div>
  38. <div style="display: flex;width: 50%;">
  39. <el-button plain type="primary" @click="showAdd" size="mini" style="margin-left:auto;" :icon="Plus">新增 </el-button>
  40. <el-button type="danger" @click="delAll" plain size="mini" style="margin-left:1%;" :icon="Delete">删除</el-button>
  41. <!-- <el-dropdown trigger="click" v-model="dropdownVisible" @visible-change="handleVisibleChange" style="margin-left:1%;">
  42. <el-button type="primary" plain size="mini" style="margin-left:1%;" :icon="Setting">列设置</el-button>
  43. <template #dropdown>
  44. <el-dropdown-menu style="width: 150px;">
  45. <el-dropdown-item style="display: flex;text-align: center;" @click="add1Level" @click.stop="handleCheckboxClick">
  46. <el-checkbox v-model="showTablepane.rw" label="任务名称" size="small" @click.stop.native/>
  47. </el-dropdown-item>
  48. <el-dropdown-item style="display: flex;text-align: center;" @click="add1Level" @click.stop="handleCheckboxClick">
  49. <el-checkbox v-model="showTablepane.zm" label="组名称" size="small" @click.stop.native/>
  50. </el-dropdown-item>
  51. <el-dropdown-item style="display: flex;text-align: center;" @click="add1Level" @click.stop="handleCheckboxClick">
  52. <el-checkbox v-model="showTablepane.zx" label="执行器名称" size="small" @click.stop.native/>
  53. </el-dropdown-item>
  54. <el-dropdown-item style="display: flex;text-align: center;" @click="add1Level" @click.stop="handleCheckboxClick">
  55. <el-checkbox v-model="showTablepane.fz" label="负责人" size="small" @click.stop.native/>
  56. </el-dropdown-item>
  57. <el-dropdown-item style="display: flex;text-align: center;" @click="add1Level" @click.stop="handleCheckboxClick">
  58. <el-checkbox v-model="showTablepane.bq" label="标签" size="small" @click.stop.native/>
  59. </el-dropdown-item>
  60. <el-dropdown-item style="display: flex;text-align: center;" @click="add1Level" @click.stop="handleCheckboxClick">
  61. <el-checkbox v-model="showTablepane.cf" label="触发时间" size="small" @click.stop.native/>
  62. </el-dropdown-item>
  63. <el-dropdown-item style="display: flex;text-align: center;" @click="add1Level" @click.stop="handleCheckboxClick">
  64. <el-checkbox v-model="showTablepane.zt" label="状态" size="small" @click.stop.native/>
  65. </el-dropdown-item>
  66. <el-dropdown-item style="display: flex;text-align: center;" @click="add1Level" @click.stop="handleCheckboxClick">
  67. <el-checkbox v-model="showTablepane.rwl" label="任务类型" size="small" @click.stop.native/>
  68. </el-dropdown-item>
  69. <el-dropdown-item style="display: flex;text-align: center;" @click="add1Level" @click.stop="handleCheckboxClick">
  70. <el-checkbox v-model="showTablepane.cfl" label="触发类型" size="small" @click.stop.native/>
  71. </el-dropdown-item>
  72. <el-dropdown-item style="display: flex;text-align: center;" @click="add1Level" @click.stop="handleCheckboxClick">
  73. <el-checkbox v-model="showTablepane.jg" label="间隔时长" size="small" @click.stop.native/>
  74. </el-dropdown-item>
  75. <el-dropdown-item style="display: flex;text-align: center;" @click="add1Level" @click.stop="handleCheckboxClick">
  76. <el-checkbox v-model="showTablepane.zs" label="阻塞策略" size="small" @click.stop.native/>
  77. </el-dropdown-item>
  78. <el-dropdown-item style="display: flex;text-align: center;" @click="add1Level" @click.stop="handleCheckboxClick">
  79. <el-checkbox v-model="showTablepane.cs" label="超时时间(秒)" size="small" @click.stop.native/>
  80. </el-dropdown-item>
  81. <el-dropdown-item style="display: flex;text-align: center;" @click="add1Level" @click.stop="handleCheckboxClick">
  82. <el-checkbox v-model="showTablepane.gx" label="更新时间" size="small" @click.stop.native/>
  83. </el-dropdown-item>
  84. </el-dropdown-menu>
  85. </template>
  86. </el-dropdown> -->
  87. </div>
  88. </div>
  89. </div>
  90. <el-table
  91. :data="tableData"
  92. style="width: 100%;margin-left: 0%;margin-top:1%;"
  93. :cell-style="{ paddingTop:'3px',paddingBottom:'3px' }"
  94. :header-cell-style="{height: heightAll*0.01+'px',}"
  95. @selection-change="handleSelectionChange"
  96. :row-style="{ fontSize: '16px',textAlign:'center'}"
  97. border
  98. :height="tableheight">
  99. <el-table-column type="selection" width="55" />
  100. <el-table-column type="index" label="序号" width="80"></el-table-column>
  101. <el-table-column prop="jobName" label="任务名称" width="160" v-if="showTablepane.rw">
  102. <template #default="scope">
  103. <el-button type="primary" @click="showDe(scope.row)" size="mini" text style="margin-left: 1%;">{{scope.row.jobName}}</el-button>
  104. </template>
  105. </el-table-column>
  106. <el-table-column prop="groupName" label="组名称" width="160" v-if="showTablepane.zm"/>
  107. <el-table-column prop="executorInfo" label="执行器名称" width="160" v-if="showTablepane.zx"/>
  108. <el-table-column prop="ownerName" label="负责人" width="160" v-if="showTablepane.fz"/>
  109. <el-table-column prop="nextTriggerAt" label="触发时间" width="180" v-if="showTablepane.cf">
  110. </el-table-column>
  111. <el-table-column prop="jobStatus" label="状态" width="170" v-if="showTablepane.zt">
  112. <template #default="scope">
  113. <el-switch @change="changejobStatus(scope.row)" v-model="scope.row.jobStatus"/>
  114. </template>
  115. </el-table-column>
  116. <el-table-column prop="taskType" label="任务类型" width="170" v-if="showTablepane.rwl">
  117. <template #default="scope">
  118. <el-tag v-if="scope.row.taskType==1" type="success">集群</el-tag>
  119. <el-tag v-if="scope.row.taskType==2" type="info">广播</el-tag>
  120. <el-tag v-if="scope.row.taskType==3" type="warning">Sharding</el-tag>
  121. <el-tag v-if="scope.row.taskType==4" type="danger">Map</el-tag>
  122. <el-tag v-if="scope.row.taskType==5">MapReduce</el-tag>
  123. </template>
  124. </el-table-column>
  125. <el-table-column prop="triggerType" label="触发类型" width="170" v-if="showTablepane.cfl">
  126. <template #default="scope">
  127. <el-tag v-if="scope.row.triggerType==2">固定时间</el-tag>
  128. <el-tag v-if="scope.row.triggerType==3">CRON 表达式</el-tag>
  129. <el-tag v-if="scope.row.triggerType==99">工作流</el-tag>
  130. </template>
  131. </el-table-column>
  132. <el-table-column prop="retryInterval" label="间隔时长" width="170" v-if="showTablepane.jg"/>
  133. <el-table-column prop="blockStrategy" label="阻塞策略" width="170" v-if="showTablepane.zs">
  134. <template #default="scope">
  135. <el-tag v-if="scope.row.blockStrategy==1">丢弃</el-tag>
  136. <el-tag v-if="scope.row.blockStrategy==2">覆盖</el-tag>
  137. <el-tag v-if="scope.row.blockStrategy==3">并行</el-tag>
  138. </template>
  139. </el-table-column>
  140. <el-table-column prop="executorTimeout" label="超时时间(秒)" width="170" v-if="showTablepane.cs"/>
  141. <el-table-column prop="updateDt" label="更新时间" width="170" v-if="showTablepane.gx"/>
  142. <el-table-column prop="address" label="操作" width="222" fixed="right">
  143. <template #default="scope">
  144. <div style="display: flex;justify-content: space-between;width: 100%;">
  145. <el-button type="primary" @click="showEdit(scope.row)" size="mini" text style="margin-left: 1%;">编辑</el-button>
  146. <el-button @click="snaliTrigger(scope.row)" type="primary" text size="mini" style="margin-left: 1%;">执行</el-button>
  147. <el-button @click="delRow(scope.row)" type="danger" text size="mini" style="margin-left: 1%;">删除</el-button>
  148. </div>
  149. </template>
  150. </el-table-column>
  151. </el-table>
  152. <!-- <div style="float: right;margin-top: 1%;margin-right: 1%;">
  153. <el-pagination
  154. small
  155. v-model='currentPage'
  156. @current-change="changePage"
  157. background
  158. layout="prev, pager, next"
  159. :total="total"
  160. class="mt-4"
  161. />
  162. </div> -->
  163. </div>
  164. </div>
  165. <el-dialog :title="title" @close="clearForm" v-model="dialogVisible" title="" width="60%" destroy-on-close :key="tableKey">
  166. <el-form size="mini" style="margin-top: 0%;width: 98%;" :model="formJi" label-position="right" ref="formRefJi" label-width="120px" :rules="rulesJi">
  167. <el-row :gutter="24">
  168. <el-col :span="8">
  169. <el-form-item label="任务名称:" prop="jobName" style="">
  170. <div style="display: flex;width: 100%;justify-content: space-between;">
  171. <el-input v-model="formJi.jobName" style="width: 100%;"/>
  172. </div>
  173. </el-form-item>
  174. </el-col>
  175. <el-col :span="8">
  176. <el-form-item label="组名称:" prop="groupName" style="">
  177. <div style="display: flex;width: 100%;justify-content: space-between;">
  178. <el-input :disabled="!isAddTa" v-model="formJi.groupName" style="width: 100%;"/>
  179. </div>
  180. </el-form-item>
  181. </el-col>
  182. <el-col :span="8">
  183. <el-form-item label="负责人:" prop="" style="">
  184. <div style="display: flex;width: 100%;justify-content: space-between;">
  185. <el-input v-model="formJi.ownerName" style="width: 100%;"/>
  186. </div>
  187. </el-form-item>
  188. </el-col>
  189. </el-row>
  190. <el-row :gutter="48">
  191. <el-col :span="15">
  192. <!-- <el-form-item label="标签:" prop="" style="">
  193. <div
  194. v-if="parTag.length==0"
  195. @click='addTag'
  196. style="
  197. cursor: pointer;
  198. display: flex;
  199. justify-content: center;
  200. align-items: center;
  201. width: 200px;
  202. height: 30px;
  203. border: 0.5px dashed #c8c9cc;
  204. border-radius: 8px;
  205. position: relative;
  206. "
  207. >
  208. + &nbsp;添加
  209. </div>
  210. <div v-if="parTag.length!=0" v-for="(item,index) in parTag">
  211. <div style="display: flex;align-items: center;margin-top: 3%;" :class="{ 'no-margin-top': index === 0 }">
  212. <el-input v-model="item.key" style="width: 50%;" resize="none" placeholder="key"/>
  213. <div style="margin-left: 1%;">:</div>
  214. <el-input v-model="item.value" style="width: 50%;margin-left: 1%;" resize="none" placeholder="value"/>
  215. <el-icon @click="delTag(index)" style="margin-left: 3%;color: red;cursor: pointer;"><Minus /></el-icon>
  216. <el-icon @click="addTag" style="margin-left: 3%;color: #337ecc;cursor: pointer;"><Plus /></el-icon>
  217. </div>
  218. </div>
  219. </el-form-item> -->
  220. </el-col>
  221. </el-row>
  222. <el-row :gutter="48">
  223. <el-col :span="8">
  224. <el-form-item label="状态:" prop="jobStatus">
  225. <el-radio-group :disabled="!isAddTa" v-model="formJi.jobStatus" class="custom-radio-group" style="width: 100%;margin-top: -1%;">
  226. <el-radio :label=1 size="large">启用</el-radio>
  227. <el-radio :label=0 size="large">禁用</el-radio>
  228. </el-radio-group>
  229. </el-form-item>
  230. </el-col>
  231. </el-row>
  232. <el-row :gutter="48">
  233. <el-col :span="8">
  234. <el-form-item label="任务类型:" prop="taskType">
  235. <el-select
  236. v-model="formJi.taskType"
  237. class="noBorSel"
  238. placeholder=""
  239. style="width: 100%;margin-left: 0%;"
  240. >
  241. <el-option
  242. v-for="item in optionsTaskType"
  243. :key="item.value"
  244. :label="item.label"
  245. :value="item.value"
  246. />
  247. </el-select>
  248. </el-form-item>
  249. </el-col>
  250. </el-row>
  251. <el-form-item label="执行器名称:" prop="executorInfo">
  252. <div style="display: flex;width: 100%;align-items: center;">
  253. <el-input v-model="formJi.executorInfo" style="width: 75%;" placeholder=""/>
  254. </div>
  255. </el-form-item>
  256. <div style="margin-top: 0%;">
  257. <el-form-item label="方法参数:" >
  258. <el-input v-model="formJi.argsStr" style="width: 75%;" placeholder="" type="textarea" :row="2" resize="none"/>
  259. </el-form-item>
  260. <el-row :gutter="48">
  261. <el-col :span="8">
  262. <el-form-item label="路由策略:" prop="routeKey">
  263. <el-select
  264. v-model="formJi.routeKey"
  265. class="noBorSel"
  266. placeholder=""
  267. style="width: 100%;margin-left: 0%;"
  268. >
  269. <el-option label="Hash" :value="1" />
  270. <el-option label="随机" :value="2" />
  271. <el-option label="LRU" :value="3" />
  272. <el-option label="轮询" :value="4" />
  273. <el-option label="匹配第一个" :value="5" />
  274. <el-option label="匹配最后一个" :value="6" />
  275. </el-select>
  276. </el-form-item>
  277. </el-col>
  278. <el-col :span="8">
  279. <el-form-item label="阻塞策略:" prop="blockStrategy">
  280. <el-select
  281. v-model="formJi.blockStrategy"
  282. class="noBorSel"
  283. placeholder=""
  284. style="width: 100%;margin-left: 0%;"
  285. >
  286. <el-option label="丢弃" :value="1" />
  287. <el-option label="覆盖" :value="2" />
  288. <el-option label="并行" :value="3" />
  289. </el-select>
  290. </el-form-item>
  291. </el-col>
  292. </el-row>
  293. <el-row :gutter="48">
  294. <el-col :span="8">
  295. <el-form-item label="触发类型:" prop="triggerType">
  296. <el-select
  297. v-model="formJi.triggerType"
  298. class="noBorSel"
  299. placeholder=""
  300. style="width: 100%;margin-left: 0%;"
  301. >
  302. <el-option label="固定时间" :value="2" />
  303. <el-option label="CRON 表达式" :value="3" />
  304. <el-option label="工作流" :value="99" />
  305. </el-select>
  306. </el-form-item>
  307. </el-col>
  308. <el-col :span="8">
  309. <el-form-item label="间隔时长:" prop="triggerInterval">
  310. <el-input-number
  311. v-model="formJi.triggerInterval"
  312. style="width: 100%;"
  313. class="mx-4"
  314. :min="1"
  315. :max="10"
  316. controls-position="right"
  317. @CHANGE="handleChange"
  318. />
  319. </el-form-item>
  320. </el-col>
  321. </el-row>
  322. <el-row :gutter="48">
  323. <el-col :span="8">
  324. <el-form-item label="超时时间(秒):" prop="executorTimeout">
  325. <el-input-number
  326. v-model="formJi.executorTimeout"
  327. style="width: 100%;"
  328. class="mx-4"
  329. :min="1"
  330. :max="10"
  331. controls-position="right"
  332. @change="handleChange"
  333. />
  334. </el-form-item>
  335. </el-col>
  336. <el-col :span="8">
  337. <el-form-item label="最大重试次数:" prop="maxRetryTimes">
  338. <el-input-number
  339. v-model="formJi.maxRetryTimes"
  340. style="width: 100%;"
  341. class="mx-4"
  342. :min="1"
  343. :max="10"
  344. controls-position="right"
  345. @change="handleChange"
  346. />
  347. </el-form-item>
  348. </el-col>
  349. </el-row>
  350. <el-row :gutter="48">
  351. <el-col :span="8">
  352. <el-form-item label="重试间隔:" prop="retryInterval">
  353. <el-input-number
  354. v-model="formJi.retryInterval"
  355. style="width: 100%;"
  356. class="mx-4"
  357. :min="1"
  358. :max="10"
  359. controls-position="right"
  360. @change="handleChange"
  361. />
  362. </el-form-item>
  363. </el-col>
  364. </el-row>
  365. <el-form-item label="描述:" >
  366. <el-input v-model="formJi.description" style="width: 75%;" placeholder="" type="textarea" :row="2" resize="none"/>
  367. </el-form-item>
  368. </div>
  369. <!-- <div v-if="formJi.executorInfoTy=='内置执行器'" style="margin-top: 4%;">
  370. <el-form-item label="请求参数:" >
  371. <el-input
  372. style="width: 75%"
  373. v-model="input3"
  374. placeholder="Please input"
  375. class="input-with-select"
  376. >
  377. <template #prepend>
  378. <el-select v-model="select" placeholder="Select" style="width: 115px">
  379. <el-option label="POST" value="1" />
  380. <el-option label="GET" value="2" />
  381. <el-option label="PUT" value="3" />
  382. <el-option label="DELETE" value="3" />
  383. </el-select>
  384. </template>
  385. </el-input>
  386. </el-form-item>
  387. <el-row :gutter="48">
  388. <el-col :span="24">
  389. <el-form-item label="Media Type:">
  390. <el-input v-model="formZu.dcNote" style="width: 75%;" placeholder="" resize="none"/>
  391. </el-form-item>
  392. </el-col>
  393. </el-row>
  394. <el-form-item label="Header 参数:" style="width: 50%;">
  395. <div
  396. v-if="parTag.length==0"
  397. @click='addTag'
  398. style="
  399. cursor: pointer;
  400. display: flex;
  401. justify-content: center;
  402. align-items: center;
  403. width: 200px;
  404. height: 30px;
  405. border: 0.5px dashed #c8c9cc;
  406. border-radius: 8px;
  407. position: relative;
  408. "
  409. >
  410. + &nbsp;添加
  411. </div>
  412. <div v-if="parTag.length!=0" v-for="(item,index) in parTag">
  413. <div style="display: flex;align-items: center;margin-top: 3%;" :class="{ 'no-margin-top': index === 0 }">
  414. <el-input v-model="item.key" style="width: 50%;" resize="none" placeholder="key"/>
  415. <div style="margin-left: 1%;">:</div>
  416. <el-input v-model="item.value" style="width: 50%;margin-left: 1%;" resize="none" placeholder="value"/>
  417. <el-icon @click="delTag(index)" style="margin-left: 3%;color: red;cursor: pointer;"><Minus /></el-icon>
  418. <el-icon @click="addTag" style="margin-left: 3%;color: #337ecc;cursor: pointer;"><Plus /></el-icon>
  419. </div>
  420. </div>
  421. </el-form-item>
  422. <el-form-item label="Body 参数">
  423. <el-input v-model="formZu.dcNote" style="width: 75%;" placeholder="" type="textarea" :row='2' resize="none"/>
  424. </el-form-item>
  425. <el-form-item label="接口超时时间">
  426. <el-input-number
  427. v-model="formJi.retryInterval"
  428. style="width: 75%;"
  429. class="mx-4"
  430. :min="1"
  431. :max="10"
  432. controls-position="right"
  433. @change="handleChange"
  434. />
  435. </el-form-item>
  436. <el-row :gutter="48">
  437. <el-col :span="8">
  438. <el-form-item label="路由策略:">
  439. <el-select
  440. v-model="serzu"
  441. class="noBorSel"
  442. placeholder=""
  443. style="width: 100%;margin-left: 0%;"
  444. >
  445. <el-option
  446. v-for="item in optionsShuLei"
  447. :key="item.value"
  448. :label="item.label"
  449. :value="item.value"
  450. />
  451. </el-select>
  452. </el-form-item>
  453. </el-col>
  454. <el-col :span="8">
  455. <el-form-item label="阻塞策略:">
  456. <el-select
  457. v-model="serzu"
  458. class="noBorSel"
  459. placeholder=""
  460. style="width: 100%;margin-left: 0%;"
  461. >
  462. <el-option
  463. v-for="item in optionsShuLei"
  464. :key="item.value"
  465. :label="item.label"
  466. :value="item.value"
  467. />
  468. </el-select>
  469. </el-form-item>
  470. </el-col>
  471. </el-row>
  472. <el-row :gutter="48">
  473. <el-col :span="8">
  474. <el-form-item label="触发类型:">
  475. <el-select
  476. v-model="serzu"
  477. class="noBorSel"
  478. placeholder=""
  479. style="width: 100%;margin-left: 0%;"
  480. >
  481. <el-option
  482. v-for="item in optionsShuLei"
  483. :key="item.value"
  484. :label="item.label"
  485. :value="item.value"
  486. />
  487. </el-select>
  488. </el-form-item>
  489. </el-col>
  490. <el-col :span="8">
  491. <el-form-item label="间隔时长:">
  492. <el-input-number
  493. v-model="formJi.retryInterval"
  494. style="width: 100%;"
  495. class="mx-4"
  496. :min="1"
  497. :max="10"
  498. controls-position="right"
  499. @change="handleChange"
  500. />
  501. </el-form-item>
  502. </el-col>
  503. </el-row>
  504. <el-row :gutter="48">
  505. <el-col :span="8">
  506. <el-form-item label="超时时间(秒):">
  507. <el-input-number
  508. v-model="formJi.retryInterval"
  509. style="width: 100%;"
  510. class="mx-4"
  511. :min="1"
  512. :max="10"
  513. controls-position="right"
  514. @change="handleChange"
  515. />
  516. </el-form-item>
  517. </el-col>
  518. <el-col :span="8">
  519. <el-form-item label="最大重试次数:">
  520. <el-input-number
  521. v-model="formJi.retryInterval"
  522. style="width: 100%;"
  523. class="mx-4"
  524. :min="1"
  525. :max="10"
  526. controls-position="right"
  527. @change="handleChange"
  528. />
  529. </el-form-item>
  530. </el-col>
  531. </el-row>
  532. <el-row :gutter="48">
  533. <el-col :span="8">
  534. <el-form-item label="重试间隔:">
  535. <el-input-number
  536. v-model="formJi.retryInterval"
  537. style="width: 100%;"
  538. class="mx-4"
  539. :min="1"
  540. :max="10"
  541. controls-position="right"
  542. @change="handleChange"
  543. />
  544. </el-form-item>
  545. </el-col>
  546. <el-col :span="8">
  547. <el-form-item label="告警通知:">
  548. <el-select
  549. v-model="serzu"
  550. class="noBorSel"
  551. placeholder=""
  552. style="width: 100%;margin-left: 0%;"
  553. >
  554. <el-option
  555. v-for="item in optionsShuLei"
  556. :key="item.value"
  557. :label="item.label"
  558. :value="item.value"
  559. />
  560. </el-select>
  561. </el-form-item>
  562. </el-col>
  563. </el-row>
  564. <el-form-item label="描述:" >
  565. <el-input v-model="formZu.dcNote" style="width: 75%;" placeholder="" type="textarea" :row="2" resize="none"/>
  566. </el-form-item>
  567. </div> -->
  568. </el-form>
  569. <template #footer>
  570. <span class="dialog-footer">
  571. <el-button size="mini" @click="dialogVisible = false">取消</el-button>
  572. <el-button v-if="isAddTa" type="primary" @click="addTa" size="mini">
  573. 提交
  574. </el-button>
  575. <el-button v-if="!isAddTa" type="primary" @click="saveEditTa" size="mini">
  576. 提交
  577. </el-button>
  578. </span>
  579. </template>
  580. </el-dialog>
  581. <el-dialog @close="clearFromTree" v-model="dialogVisibleTree" title="" width="55%" destroy-on-close :key="tableKey">
  582. <el-descriptions
  583. class="margin-top"
  584. :title="titleDe"
  585. style="padding-top: 2%;"
  586. :column="3"
  587. :size="size"
  588. border
  589. >
  590. <el-descriptions-item>
  591. <template #label>
  592. <div class="cell-item">
  593. 任务名称
  594. </div>
  595. </template>
  596. {{formJi.jobName}}
  597. </el-descriptions-item>
  598. <el-descriptions-item>
  599. <template #label>
  600. <div class="cell-item">
  601. 组名称
  602. </div>
  603. </template>
  604. {{formJi.groupName}}
  605. </el-descriptions-item>
  606. <el-descriptions-item>
  607. <template #label>
  608. <div class="cell-item">
  609. 负责人
  610. </div>
  611. </template>
  612. {{formJi.ownerName}}
  613. </el-descriptions-item>
  614. <el-descriptions-item>
  615. <template #label>
  616. <div class="cell-item">
  617. 状态
  618. </div>
  619. </template>
  620. <el-tag size="small">{{formJi.jobStatus}}</el-tag>
  621. </el-descriptions-item>
  622. <el-descriptions-item>
  623. <template #label>
  624. <div class="cell-item">
  625. 任务类型
  626. </div>
  627. </template>
  628. {{formJi.taskType}}
  629. </el-descriptions-item>
  630. <el-descriptions-item>
  631. <template #label>
  632. <div class="cell-item">
  633. 执行器名称
  634. </div>
  635. </template>
  636. {{formJi.executorInfo}}
  637. </el-descriptions-item>
  638. <el-descriptions-item>
  639. <template #label>
  640. <div class="cell-item">
  641. 方法参数
  642. </div>
  643. </template>
  644. {{formJi.argsStr}}
  645. </el-descriptions-item>
  646. <el-descriptions-item>
  647. <template #label>
  648. <div class="cell-item">
  649. 路由策略
  650. </div>
  651. </template>
  652. {{formJi.routeKey}}
  653. </el-descriptions-item>
  654. <el-descriptions-item>
  655. <template #label>
  656. <div class="cell-item">
  657. 阻塞策略
  658. </div>
  659. </template>
  660. {{formJi.blockStrategy}}
  661. </el-descriptions-item>
  662. <el-descriptions-item>
  663. <template #label>
  664. <div class="cell-item">
  665. 触发类型
  666. </div>
  667. </template>
  668. {{formJi.triggerType}}
  669. </el-descriptions-item>
  670. <el-descriptions-item>
  671. <template #label>
  672. <div class="cell-item">
  673. 间隔时长
  674. </div>
  675. </template>
  676. {{formJi.triggerInterval}}
  677. </el-descriptions-item>
  678. <el-descriptions-item>
  679. <template #label>
  680. <div class="cell-item">
  681. 超时时间(秒)
  682. </div>
  683. </template>
  684. {{formJi.executorTimeout}}
  685. </el-descriptions-item>
  686. <el-descriptions-item>
  687. <template #label>
  688. <div class="cell-item">
  689. 最大重试次数
  690. </div>
  691. </template>
  692. {{formJi.maxRetryTimes}}
  693. </el-descriptions-item>
  694. <el-descriptions-item>
  695. <template #label>
  696. <div class="cell-item">
  697. 重试间隔
  698. </div>
  699. </template>
  700. {{formJi.retryInterval}}
  701. </el-descriptions-item>
  702. <el-descriptions-item>
  703. <template #label>
  704. <div class="cell-item">
  705. 描述:
  706. </div>
  707. </template>
  708. {{formJi.description}}
  709. </el-descriptions-item>
  710. </el-descriptions>
  711. <template #footer>
  712. <span class="dialog-footer">
  713. <el-button size="mini" type="primary" @click="dialogVisibleTree = false">确定</el-button>
  714. </span>
  715. </template>
  716. </el-dialog>
  717. </template>
  718. <script setup>
  719. import { Search,RefreshRight,Plus,Download,Upload,Delete,Setting,Minus} from '@element-plus/icons-vue'
  720. import { reactive } from 'vue'
  721. import Codemirror from 'codemirror-editor-vue3';
  722. import { snailList,addSnail,snailDe,snailEdit,delSnamil,snailSta,snailTri } from "@/api/service/timing";
  723. import { ref, onMounted, onUnmounted, nextTick } from 'vue';
  724. const groupName= ref('')
  725. const jobName= ref('')
  726. const jobStatus= ref('')
  727. const executorInfo= ref('')
  728. const { proxy } = getCurrentInstance();
  729. const data = ref([])
  730. const title = ref([])
  731. const titleTree = ref([])
  732. const code = ref(null)
  733. const currentPage = ref(1)
  734. const total = ref(1)
  735. const tableData = ref([])
  736. const tableheight = window.innerHeight*0.7
  737. const heightAll = window.innerHeight
  738. const dialogVisible = ref(false)
  739. const dialogVisibleTree = ref(false)
  740. const isAdd = ref(false)
  741. const isAddTa = ref(false)
  742. const treeId = ref('');
  743. const titleDe = ref('')
  744. const parTag = ref([])
  745. const optionsTaskType = ref([
  746. {
  747. label:'集群',
  748. value:1
  749. },
  750. {
  751. label:'广播',
  752. value:2
  753. },
  754. {
  755. label:'Sharding',
  756. value:3
  757. },
  758. {
  759. label:'Map',
  760. value:4
  761. },
  762. {
  763. label:'MapReduce',
  764. value:5
  765. },
  766. ])
  767. const cmOptions = {
  768. mode: 'x-sql',
  769. hintOptions: {
  770. completeSingle: false,
  771. tables: {
  772. users: ['id', 'name', 'email'], // 自定义表字段提示
  773. products: ['id', 'price', 'stock']
  774. }
  775. }
  776. };
  777. const cmRef = ref(null)
  778. const showTablepane = ref({
  779. rw:true,
  780. zm:true,
  781. zx:true,
  782. fz:true,
  783. bq:true,
  784. cf:true,
  785. zt:true,
  786. rwl:true,
  787. cfl:true,
  788. jg:true,
  789. zs:true,
  790. cs:true,
  791. gx:true,
  792. })
  793. const formJi = ref({
  794. jobName:'',
  795. groupName:'',
  796. jobStatus:'',
  797. taskType:'',
  798. executorInfo:'',
  799. executorInfoTy:'',
  800. type:'',
  801. mdContact:'',
  802. mdUnit:'',
  803. devUnit:'',
  804. devContact:'',
  805. deployDir:'',
  806. deployIp:'',
  807. deployPort:'',
  808. mirrorImageUrl:'',
  809. mdRunCmd:'',
  810. envOs:'',
  811. envDisk:'',
  812. envGpuMem:'11',
  813. evnArmX86:'',
  814. envCpuNum:'',
  815. envGpuType:'',
  816. envGpuNum:'2',
  817. envMem:'',
  818. mdInNote:'',
  819. mdOutNote:''
  820. });
  821. const selectedRows = ref([])
  822. const activeTabKey = ref(0)
  823. const rulesJi = reactive({
  824. jobName: [{ required: true, message: '必填', trigger: 'blur' }],
  825. groupName: [{ required: true, message: '必填', trigger: 'blur' }],
  826. taskType: [{ required: true, message: '必填', trigger: 'blur' }],
  827. jobStatus: [{ required: true, message: '必填', trigger: 'blur' }],
  828. executorInfo: [{ required: true, message: '必填', trigger: 'blur' }],
  829. routeKey: [{ required: true, message: '可选', trigger: 'blur' }],
  830. blockStrategy: [{ required: true, message: '必填', trigger: 'blur' }],
  831. triggerInterval: [{ required: true, message: '必填', trigger: 'blur' }],
  832. executorTimeout: [{ required: true, message: '必填', trigger: 'blur' }],
  833. maxRetryTimes: [{ required: true, message: '必填', trigger: 'blur' }],
  834. retryInterval: [{ required: true, message: '必填', trigger: 'blur' }],
  835. triggerType: [{ required: true, message: '必填', trigger: 'blur' }],
  836. });
  837. const formRefJi = ref();
  838. const formZu = ref({
  839. itemName:'',
  840. itemTp:'',
  841. itemEn:'',
  842. itemTp:'',
  843. itemDataTp:'',
  844. itemDefaultVal:'',
  845. itemUnit:'',
  846. itemNotes:'',
  847. });
  848. const rulesZu = reactive({
  849. itemName: [{ required: true, message: '必填', trigger: 'blur' }],
  850. itemEn: [{ required: true, message: '必填', trigger: 'blur' }],
  851. itemTp: [{ required: true, message: '必填', trigger: 'blur' }],
  852. itemDataTp: [{ required: true, message: '必填', trigger: 'blur' }],
  853. itemDefaultVal: [{ required: true, message: '必填', trigger: 'blur' }],
  854. });
  855. const formRefZu = ref();
  856. const formTree = ref({
  857. itemName:'',
  858. catePid:'',
  859. itemNo:'',
  860. itemNotes:''
  861. });
  862. const rulesTree = reactive({
  863. itemNo: [{ required: true, message: '必填', trigger: 'blur' }],
  864. catePid: [{ required: true, message: '必填', trigger: 'blur' }],
  865. itemName: [{ required: true, message: '必填', trigger: 'blur' }],
  866. });
  867. const formRefTree = ref();
  868. const dropdownVisible = ref(false);
  869. const handleSelectionChange = (selection) => {
  870. selectedRows.value = selection;
  871. };
  872. function snaliTrigger(row){
  873. var par = {
  874. jobId:row.id,
  875. taskType:row.taskType
  876. }
  877. snailTri(par).then(res=>{
  878. if(res.code===200){
  879. proxy.$modal.msgSuccess(res.msg);
  880. }
  881. })
  882. }
  883. function showCode(){
  884. Object.keys(rulesJi).forEach(key => {
  885. delete rulesJi[key];
  886. });
  887. if(formJi.value.executorInfoTy==='自定义执行器'){
  888. Object.assign(rulesJi, {
  889. jobName: [{ required: true, message: '必填', trigger: 'blur' }],
  890. groupName: [{ required: true, message: '必填', trigger: 'blur' }],
  891. taskType: [{ required: true, message: '必填', trigger: 'blur' }],
  892. jobStatus: [{ required: true, message: '必填', trigger: 'blur' }],
  893. executorInfo: [{ required: true, message: '必填', trigger: 'blur' }],
  894. routeKey: [{ required: true, message: '可选', trigger: 'blur' }],
  895. blockStrategy: [{ required: true, message: '必填', trigger: 'blur' }],
  896. triggerInterval: [{ required: true, message: '必填', trigger: 'blur' }],
  897. executorTimeout: [{ required: true, message: '必填', trigger: 'blur' }],
  898. maxRetryTimes: [{ required: true, message: '必填', trigger: 'blur' }],
  899. retryInterval: [{ required: true, message: '必填', trigger: 'blur' }],
  900. triggerType: [{ required: true, message: '必填', trigger: 'blur' }],
  901. });
  902. }
  903. if(formJi.value.executorInfoTy==='内置执行器'){
  904. Object.assign(rulesJi, {
  905. jobName: [{ required: true, message: '必填', trigger: 'blur' }],
  906. groupName: [{ required: true, message: '必填', trigger: 'blur' }],
  907. taskType: [{ required: true, message: '必填', trigger: 'blur' }],
  908. jobStatus: [{ required: true, message: '必填', trigger: 'blur' }],
  909. executorInfo: [{ required: true, message: '必填', trigger: 'blur' }],
  910. routeKey: [{ required: true, message: '可选', trigger: 'blur' }],
  911. blockStrategy: [{ required: true, message: '必填', trigger: 'blur' }],
  912. triggerInterval: [{ required: true, message: '必填', trigger: 'blur' }],
  913. executorTimeout: [{ required: true, message: '必填', trigger: 'blur' }],
  914. maxRetryTimes: [{ required: true, message: '必填', trigger: 'blur' }],
  915. retryInterval: [{ required: true, message: '必填', trigger: 'blur' }],
  916. triggerType: [{ required: true, message: '必填', trigger: 'blur' }],
  917. });
  918. }
  919. }
  920. function delAll(){
  921. var parDel = ''
  922. selectedRows.value.forEach(item=>{
  923. parDel = parDel + item.id + ','
  924. })
  925. parDel = parDel.slice(0, -1)
  926. proxy.$modal.confirm('是否确认删除?').then(function () {
  927. var par = {
  928. jobIds:parDel
  929. }
  930. return delSnamil(par);
  931. }).then(() => {
  932. getTable();
  933. proxy.$modal.msgSuccess("删除成功");
  934. }).catch(() => {});
  935. }
  936. function showDe(row){
  937. dialogVisibleTree.value = true
  938. var par = {
  939. jobId:row.id
  940. }
  941. snailDe(par).then(res=>{
  942. formJi.value = res.data
  943. if(formJi.value.jobStatus===0){
  944. formJi.value.jobStatus = '启用'
  945. }
  946. if(formJi.value.jobStatus===1){
  947. formJi.value.jobStatus = '关闭'
  948. }
  949. })
  950. }
  951. async function changejobStatus(row){
  952. var par = {
  953. jobId:row.id,
  954. status:row.jobStatus===true?1:0
  955. }
  956. await snailSta(par).then(res=>{
  957. formJi.value = res
  958. if(res.code===200){
  959. proxy.$modal.msgSuccess("修改成功");
  960. }
  961. })
  962. }
  963. const handleCheckboxClick = () => {
  964. // 1. 执行 checkbox 的切换逻辑(v-model 自动处理)
  965. // 2. 手动保持下拉菜单展开
  966. dropdownVisible.value = true;
  967. };
  968. function addTag(){
  969. parTag.value.push({value:'',key:''})
  970. }
  971. function delTag(index){
  972. parTag.value.splice(index,1)
  973. }
  974. function clearForm(){
  975. formJi.value = {
  976. }
  977. }
  978. function formatTimestamp(ms) {
  979. const date = new Date(ms);
  980. const year = date.getFullYear();
  981. const month = String(date.getMonth() + 1).padStart(2, '0'); // 补零
  982. const day = String(date.getDate()).padStart(2, '0'); // 补零
  983. return `${year}年${month}月${day}日`;
  984. }
  985. function getTable(){
  986. var par = {
  987. groupName:groupName.value,
  988. executorInfo:executorInfo.value,
  989. jobName:jobName.value,
  990. jobStatus:jobStatus.value
  991. }
  992. snailList(par).then(res=>{
  993. tableData.value = res.rows
  994. tableData.value.forEach(item=>{
  995. if(item.jobStatus===0){
  996. item.jobStatus = false
  997. }
  998. if(item.jobStatus===1){
  999. item.jobStatus = true
  1000. }
  1001. item.nextTriggerAt = formatTimestamp(item.nextTriggerAt)
  1002. })
  1003. total.value = res.total
  1004. })
  1005. }
  1006. function showAdd(){
  1007. isAddTa.value = true
  1008. title.value = '新增'
  1009. dialogVisible.value = true
  1010. }
  1011. function showEdit(row){
  1012. isAddTa.value = false
  1013. title.value = '编辑'
  1014. dialogVisible.value = true
  1015. var par = {
  1016. jobId:row.id
  1017. }
  1018. snailDe(par).then(res=>{
  1019. formJi.value = res.data
  1020. })
  1021. }
  1022. function clearFromTree(){
  1023. formTree.value = {
  1024. itemName:'',
  1025. catePid:'',
  1026. itemNo:'',
  1027. itemNotes:''
  1028. }
  1029. }
  1030. function addTa(){
  1031. formRefJi.value.validate(async (valid) => {
  1032. if(valid){
  1033. if(formJi.value.argsStr){
  1034. formJi.value.argsStr = JSON.parse(formJi.value.argsStr)
  1035. }
  1036. await addSnail(formJi.value).then(res=>{
  1037. if(res.code===200){
  1038. proxy.$modal.msgSuccess("新增成功");
  1039. getTable()
  1040. dialogVisible.value = false
  1041. }
  1042. })
  1043. }
  1044. });
  1045. }
  1046. function saveEditTa(){
  1047. if(formJi.value.argsStr){
  1048. formJi.value.argsStr = JSON.parse(formJi.value.argsStr)
  1049. }
  1050. snailEdit(formJi.value).then(res=>{
  1051. if(res.code===200){
  1052. proxy.$modal.msgSuccess("修改成功");
  1053. dialogVisible.value = false
  1054. getTable()
  1055. }
  1056. })
  1057. }
  1058. function delRow(row) {
  1059. proxy.$modal.confirm('是否确认删除?').then(function () {
  1060. var par = {
  1061. jobIds:row.id
  1062. }
  1063. return delSnamil(par);
  1064. }).then(() => {
  1065. getTable();
  1066. proxy.$modal.msgSuccess("删除成功");
  1067. }).catch(() => {});
  1068. };
  1069. onMounted(() => {
  1070. getTable()
  1071. });
  1072. </script>
  1073. <style scoped>
  1074. .no-margin-top {
  1075. margin-top: 0 !important;
  1076. }
  1077. .drag-handle {
  1078. cursor: move;
  1079. }
  1080. .ghost {
  1081. opacity: 0.5;
  1082. background: #c8ebfb;
  1083. }
  1084. /* 防止文字选中 */
  1085. :deep(.el-table__row) {
  1086. user-select: none;
  1087. -webkit-user-select: none;
  1088. }
  1089. </style>
  1090. <style scoped lang="scss">
  1091. .el-table .el-table__row td {
  1092. height: 60px !important; /* 行高 */
  1093. }
  1094. .custom-tree-node {
  1095. display: flex; /* 启用 Flex 布局 */
  1096. align-items: center; /* 垂直居中 */
  1097. gap: 8px; /* 图标与文字间距 */
  1098. }
  1099. .custom-tree-node {
  1100. flex: 1;
  1101. display: flex;
  1102. align-items: center;
  1103. justify-content: space-between;
  1104. font-size: 14px;
  1105. padding-right: 8px;
  1106. }
  1107. </style>