Example.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506
  1. <template>
  2. <div class="table-container">
  3. <!-- 用例模块 -->
  4. <div class="deviceExamples">
  5. <!-- 用例 -->
  6. <div class="title-container">
  7. <div class="title-main">用例</div>
  8. <div class="title-right">
  9. <div class="check-resaults">
  10. 总数:
  11. <span class="total">
  12. {{ unitsData.total }}
  13. </span>
  14. </div>
  15. <div class="check-resaults">
  16. 成功数:
  17. <span class="success">
  18. {{ unitsData.successful }}
  19. </span>
  20. </div>
  21. <div class="check-resaults">
  22. 失败数:
  23. <span class="faild">
  24. {{ unitsData.failed }}
  25. </span>
  26. </div>
  27. <div class="check-resaults">
  28. <el-button
  29. icon="el-icon-refresh"
  30. class="light-button"
  31. size="mini"
  32. @click="refreshManual(true)"
  33. >刷新</el-button>
  34. </div>
  35. <div class="check-resaults">
  36. <el-button class="light-button" icon="el-icon-file" size="mini" @click="openFileTransfer()">文件传输</el-button>
  37. </div>
  38. <div class="check-resaults">
  39. <el-button
  40. icon="el-icon-document"
  41. class="light-button"
  42. size="mini"
  43. @click="checkReport()"
  44. >查看报文</el-button>
  45. </div>
  46. <div class="check-resaults">
  47. <el-button
  48. type="primary"
  49. icon="el-icon-plus"
  50. size="mini"
  51. :disabled="componentParames.isDisable"
  52. @click="editRow()"
  53. >添加</el-button>
  54. </div>
  55. </div>
  56. </div>
  57. <!-- 用例表格 -->
  58. <div class="table-data">
  59. <!-- {
  60. "id": "2300000037",
  61. "name": null,
  62. "suiteId": null,
  63. "planId": "3200000028",
  64. "ruleId": 102,
  65. "ruleName": "读开关量",
  66. "not": null,
  67. "value": null,
  68. "error": null,
  69. "params": {}
  70. } -->
  71. <el-table :key="tableIsUpdate" v-loading="vloading" :data="tableData" stripe>
  72. <el-table-column prop="id" label="序号" width="100px" />
  73. <el-table-column prop="name" label="用例名称" width="150px" />
  74. <el-table-column prop="state" label="测试状态" width="120px">
  75. <template slot-scope="scope">
  76. <span :style="{'color':scope.row.stateStyle}">{{ scope.row.state }}</span>
  77. </template>
  78. </el-table-column>
  79. <el-table-column v-if="false" prop="ruleName" label="测试规则" width="135px" />
  80. <el-table-column prop="duration" label="持续时间(ms)" width="135px" />
  81. <el-table-column prop="occur" label="执行时间(ms)" width="135px" />
  82. <!-- 鲜总说不要了 06.测试/20230704/设备检测用例相关改动.png
  83. <el-table-column prop="not" label="规则取反" width="75px" :formatter="formatBool" />
  84. <el-table-column prop="value" label="期望值" width="75px" />
  85. <el-table-column prop="error" label="误差范围" width="75px" /> -->
  86. <el-table-column prop="unit" label="循环次数" width="150px">
  87. <template slot-scope="scope">
  88. <!-- 总数/成功数/失败数 -->
  89. <ul v-if="scope.row.unit" class="unit">
  90. <li>
  91. <div class="unit-title">总数:</div>
  92. <div class="unit-value total">{{ scope.row.unit.total }}</div>
  93. </li>
  94. <li>
  95. <div class="unit-title">成功数:</div>
  96. <div class="unit-value successful">{{ scope.row.unit.successful }}</div>
  97. </li>
  98. <li>
  99. <div class="unit-title">失败数:</div>
  100. <div class="unit-value failed">{{ scope.row.unit.failed }}</div>
  101. </li>
  102. </ul>
  103. </template>
  104. </el-table-column>
  105. <el-table-column prop="params" label="参数设置">
  106. <template slot-scope="scope">
  107. <ul class="setting-json">
  108. <li
  109. v-for="(settingItem) in scope.row.params"
  110. :key="settingItem.id "
  111. >
  112. <div>{{ settingItem.id }}({{ settingItem.name }}):{{ settingItem.value || 0 }}</div>
  113. <!-- <span v-if="index < scope.row.params.length - 1">,</span> -->
  114. </li>
  115. </ul>
  116. </template>
  117. </el-table-column>
  118. <el-table-column fixed="right" label="操作" width="120px">
  119. <template slot-scope="scope">
  120. <el-button
  121. class="table-act"
  122. type="text"
  123. icon="el-icon-edit"
  124. size="small"
  125. @click="editRow(scope.$index)"
  126. >编辑</el-button>
  127. <el-button
  128. class="table-act"
  129. type="text"
  130. icon="el-icon-delete"
  131. size="small"
  132. @click="delRow(scope.$index)"
  133. >删除</el-button>
  134. </template>
  135. </el-table-column>
  136. <!-- 隐藏 列 这里不用显示,但是在编辑的时候需要获取此数据 -->
  137. <el-table-column
  138. v-if="false"
  139. prop="deviceCheckId"
  140. label="序号"
  141. />
  142. <!-- 隐藏 列 -->
  143. </el-table>
  144. </div>
  145. <!-- 用例分页 -->
  146. <div class="page-bar">
  147. <pagination
  148. background
  149. layout="pager"
  150. :limit="deviceExamples.pageLimit"
  151. :total="deviceExamples.paginationTotalElements"
  152. :current-page.sync="deviceExamples.paginationNumber"
  153. :page="deviceExamples.paginationNumber"
  154. :auto-scroll="false"
  155. @pagination="getDeviceExamples"
  156. />
  157. </div>
  158. </div>
  159. <!-- 查看报文 model -->
  160. <ModelReport
  161. v-if="showModelReport"
  162. :report-parames="{
  163. 'deviceName':componentParames.deviceName,
  164. 'curPlanId':componentParames.curPlanId
  165. }"
  166. @toggleModel="closeModel"
  167. />
  168. <!-- 添加/编辑用例 model -->
  169. <ModelFormExample
  170. v-if="showModelForm"
  171. :model-parames="{
  172. 'curPlanId':componentParames.curPlanId,
  173. 'deviceName':componentParames.deviceName,
  174. 'curSuiteId':componentParames.curSuiteId,
  175. 'modelFormData':modelFormData
  176. }"
  177. @toggleModel="closeModel"
  178. />
  179. <ModelFormFileTransferOpt104
  180. v-if="showFileTransferOpt104ModelForm"
  181. :model-parames="{
  182. 'curPlanId':componentParames.curPlanId,
  183. 'productId':componentParames.productId,
  184. 'deviceName':componentParames.deviceName,
  185. 'curSuiteId':componentParames.curSuiteId
  186. }"
  187. @toggleModel="closeModel"
  188. />
  189. </div>
  190. </template>
  191. <script>
  192. import {
  193. httpGet,
  194. delRecord,
  195. json2ArrayContext
  196. } from '@/api/common-action'
  197. // 分页
  198. import Pagination from '@/components/Pagination'
  199. // 查看报文
  200. import ModelReport from '../components/ModelReport'
  201. // 添加用例
  202. import ModelFormExample from '../components/ModelFormExample'
  203. import ModelFormFileTransferOpt104 from '../components/ModelFormFileTransferOpt104'
  204. // 导入总线
  205. import { EventBus } from '@/main.js'
  206. export default {
  207. name: 'Example',
  208. components: {
  209. Pagination,
  210. ModelReport,
  211. ModelFormExample,
  212. ModelFormFileTransferOpt104
  213. },
  214. props: {
  215. componentParames: {
  216. type: Object,
  217. default: function() {
  218. return {}
  219. }
  220. }
  221. },
  222. data() {
  223. return {
  224. showFileTransferOpt104ModelForm: false,
  225. vloading: true,
  226. tableData: [],
  227. tableIsUpdate: 0,
  228. unitsData: {},
  229. // 用例
  230. deviceExamples: {
  231. pageLimit: 5,
  232. paginationNumber: 1,
  233. paginationTotalElements: 1
  234. },
  235. // 是否显示 查看报文
  236. showModelReport: false,
  237. // 编辑用例数据
  238. modelFormData: {},
  239. // 是否显示 添加/编辑用例
  240. showModelForm: false
  241. }
  242. },
  243. // watch: {
  244. // componentParames: {
  245. // handler() {
  246. // // 监听传入的值 是否有变化 ,如有 刷新表格数据
  247. // // console.log('刷新表格数据 componentParames', this.componentParames)
  248. // // // 获取用例列表数据 ,不传分页信息,即采集默认分页获取第一页数据
  249. // // this.getDeviceExamples()
  250. // // // 刷新一次用例状态
  251. // this.refreshManual()
  252. // }
  253. // }
  254. // },
  255. created() {
  256. },
  257. mounted() {
  258. EventBus.$off('refreshManualFn')
  259. EventBus.$on('refreshManualFn', this.refreshManual)
  260. this.$nextTick(() => {
  261. // 网页加载完成后执行
  262. this.initFunctions()
  263. })
  264. },
  265. methods: {
  266. // 初始化
  267. async initFunctions() {
  268. // 所有需要加载时初始化的函数都放这里
  269. // console.log('Example initFunctions componentParames=', this.componentParames)
  270. // 获取用例列表数据 ,不传分页信息,即采集默认分页获取第一页数据
  271. this.getDeviceExamples()
  272. },
  273. // 文件传输
  274. openFileTransfer() {
  275. this.showFileTransferOpt104ModelForm = true
  276. },
  277. // 手动刷新状态 manual
  278. refreshManual(isHand) {
  279. // 接口 用例状态(高频刷新) /test/execute/:runner/results
  280. const getUrl = `/test/execute/${this.componentParames.curPlanId}/results`
  281. // const getUrl = `/test/execute/${this.componentParames.curPlanId}/models`
  282. // console.log('手动刷新 getUrl=', getUrl)
  283. httpGet(getUrl).then(res => {
  284. this.unitsData = res
  285. if (this.tableData.length > 0) {
  286. // this.tableData.filter(item)
  287. this.tableData.forEach(item => {
  288. res.units.forEach(uitem => {
  289. // console.log('item.id=', item.id)
  290. // console.log('uitem.id=', uitem.id)
  291. if (item.id === uitem.id) {
  292. // console.log('uitem.stateName=', uitem.stateName)
  293. item.state = uitem.stateName
  294. item.stateStyle = uitem.stateStyle
  295. item.unit = uitem
  296. }
  297. })
  298. })
  299. // 解决tableData无法刷新的问题
  300. this.tableIsUpdate = 'example' + new Date().getTime()
  301. }
  302. // console.log('this.tableData', this.tableData)
  303. if (isHand) {
  304. this.$message({
  305. message: '用例刷新成功',
  306. type: 'success',
  307. duration: 500,
  308. offset: window.screen.height / 3
  309. })
  310. }
  311. })
  312. },
  313. // 格式化bool值
  314. formatBool(val) {
  315. const rs = val.not.toString()
  316. return rs
  317. },
  318. // 获取用例
  319. getDeviceExamples(pageObj) {
  320. this.vloading = true
  321. // 翻页时pageObj对象才会有值,属性分别为page和limit
  322. if (pageObj == null) {
  323. pageObj = {
  324. page: 0,
  325. limit: this.deviceExamples.pageLimit
  326. }
  327. this.deviceExamples.paginationNumber = 0
  328. } else {
  329. this.deviceExamples.pageLimit = pageObj.limit
  330. }
  331. // 获取用例表格数据
  332. httpGet(`/test/plan/${this.componentParames.curPlanId}/units?page=${pageObj.page}&size=${pageObj.limit}`).then((response) => {
  333. this.vloading = false
  334. this.tableData = response.content
  335. // 格式化参数设置显示
  336. this.tableData.forEach(item => {
  337. item.params = json2ArrayContext(item.params)
  338. item.units = []
  339. })
  340. this.deviceExamples.paginationTotalElements = response.totalElements * 1
  341. this.deviceExamples.paginationNumber = response.number * 1 + 1
  342. // 刷新一次用例状态
  343. this.refreshManual(false)
  344. })
  345. },
  346. // 编辑
  347. editRow(index) {
  348. // console.log('this.tableData[index]=', this.tableData[index])
  349. // 如果是添加,则index为空,modelFormData也为空
  350. this.modelFormData = this.tableData[index]
  351. this.showModelForm = true
  352. },
  353. // 删除
  354. delRow(index) {
  355. this.$confirm(
  356. '此操作将永久删除该记录, 是否继续?',
  357. `删除`,
  358. {
  359. confirmButtonText: '确定',
  360. cancelButtonText: '取消',
  361. type: 'warning'
  362. }
  363. ).then(() => {
  364. // console.log('delRow index=', index)
  365. // 接口 删除用例 /test/unit/:unit
  366. // :unit 例:2300000036
  367. const delUrl = `/test/unit/${this.tableData[index].id}`
  368. // console.log('delRow delUrl=', delUrl)
  369. delRecord(delUrl).then(res => {
  370. this.$message({
  371. message: '删除成功',
  372. type: 'success',
  373. offset: window.screen.height / 3
  374. })
  375. // 后端成功执行后,前端再删除选中行
  376. this.tableData.splice(index, 1)
  377. })
  378. }).catch(() => {
  379. this.$message({
  380. type: 'info',
  381. message: '已取消删除',
  382. offset: window.screen.height / 3
  383. })
  384. })
  385. },
  386. // 查看报文
  387. checkReport() {
  388. // console.log('checkReport 查看报文 开始')
  389. this.showModelReport = true
  390. },
  391. // 关闭 model
  392. closeModel(modelName, modelShow) {
  393. // console.log('closeModel modelName=', modelName)
  394. // console.log('closeModel modelShow=', modelShow)
  395. switch (modelName) {
  396. // case 'ModelAddStep':
  397. // this.deviceDetail.showModelAddStep = modelShow
  398. // break
  399. case 'ModelReport':
  400. this.showModelReport = modelShow
  401. break
  402. case 'ModelFormExample':
  403. this.showModelForm = modelShow
  404. // 操作过用例模态框 刷新一次用例数据 保持页数不变
  405. this.getDeviceExamples({
  406. page: this.deviceExamples.paginationNumber - 1,
  407. limit: this.deviceExamples.pageLimit
  408. })
  409. break
  410. case 'ModelFormFileTransferOpt104':
  411. this.showFileTransferOpt104ModelForm = false
  412. break
  413. default:
  414. console.log('未获取到 modelName')
  415. break
  416. }
  417. }
  418. }
  419. }
  420. </script>
  421. <style lang="scss" scoped>
  422. .title-container {
  423. display: flex;
  424. justify-content: space-between;
  425. padding: 20px 0;
  426. .title-right {
  427. display: flex;
  428. align-items: center;
  429. .check-resaults {
  430. padding-right: 16px;
  431. .success {
  432. color: #00706b;
  433. }
  434. .faild {
  435. color: #f00;
  436. padding-right: 6px;
  437. }
  438. span {
  439. font-weight: bold;
  440. }
  441. }
  442. }
  443. }
  444. .title-main {
  445. color: #111;
  446. font-weight: bold;
  447. }
  448. // 用例表格样式
  449. .table-container {
  450. padding: 0;
  451. .el-table {
  452. font-size: 12px;
  453. }
  454. .unit {
  455. list-style: none;
  456. padding-left: 0;
  457. li {
  458. display: flex;
  459. // 总数使用默认颜色
  460. // .total {
  461. // // color: #00706b;
  462. // }
  463. .successful {
  464. color: #00706b;
  465. }
  466. .failed {
  467. color: #c51437;
  468. }
  469. }
  470. }
  471. .setting-json {
  472. padding: 0;
  473. margin: 0;
  474. list-style: none;
  475. li {
  476. display: inline;
  477. }
  478. }
  479. }
  480. // 底部按钮
  481. .bottom-button {
  482. display: flex;
  483. justify-content: center;
  484. padding-bottom: 20px;
  485. .cancel-plan {
  486. padding-right: 20px;
  487. }
  488. }
  489. // 按钮公用样式
  490. .dark-button {
  491. background-color: #00706B;
  492. border: 1px #00706B solid;
  493. color: #fff;
  494. }
  495. .light-button {
  496. color: #00706B;
  497. border: 1px #00706B solid;
  498. }
  499. </style>