You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

467 lines
15 KiB

4 weeks ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
4 weeks ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
4 weeks ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
  1. <template>
  2. <div class="mod-config">
  3. <!-- 查询表单 - rqrq -->
  4. <el-form :inline="true" label-position="top" style="margin-top: 1px; margin-left: 0px;">
  5. <el-form-item label="接口名称">
  6. <el-input v-model="queryData.interfaceName" style="width: 120px" placeholder="接口名称" clearable></el-input>
  7. </el-form-item>
  8. <el-form-item label="方法名称">
  9. <el-input v-model="queryData.methodName" style="width: 120px" placeholder="方法名称" clearable></el-input>
  10. </el-form-item>
  11. <el-form-item label="业务主键">
  12. <el-input v-model="queryData.businessKey" style="width: 120px" placeholder="业务主键" clearable></el-input>
  13. </el-form-item>
  14. <el-form-item label="调用状态">
  15. <el-select v-model="queryData.status" placeholder="请选择" style="width: 120px" clearable>
  16. <el-option label="全部" value=""></el-option>
  17. <el-option
  18. v-for="item in statusOptions"
  19. :key="item.value"
  20. :label="item.label"
  21. :value="item.value">
  22. </el-option>
  23. </el-select>
  24. </el-form-item>
  25. <el-form-item label="创建时间从">
  26. <el-date-picker
  27. v-model="queryData.startDate"
  28. type="date"
  29. style="width: 120px"
  30. placeholder="开始日期"
  31. value-format="yyyy-MM-dd"
  32. clearable>
  33. </el-date-picker>
  34. </el-form-item>
  35. <el-form-item label="创建时间至">
  36. <el-date-picker
  37. v-model="queryData.endDate"
  38. type="date"
  39. style="width: 120px"
  40. placeholder="结束日期"
  41. value-format="yyyy-MM-dd"
  42. clearable>
  43. </el-date-picker>
  44. </el-form-item>
  45. <el-form-item label=" ">
  46. <el-button type="primary" @click="getDataList()">{{ $t('warehouse.common.search') }}</el-button>
  47. <el-button @click="resetQuery()">{{ $t('warehouse.common.reset') }}</el-button>
  48. <!-- 导出按钮 - rqrq -->
  49. <download-excel
  50. :fields="fields()"
  51. :data="exportData"
  52. type="xls"
  53. :name="exportName"
  54. :header="exportHeader"
  55. :footer="exportFooter"
  56. :fetch="createExportData"
  57. :before-generate="startDownload"
  58. :before-finish="finishDownload"
  59. :worksheet="$t('warehouse.common.exportWorksheet')"
  60. class="el-button el-button--primary el-button--medium">
  61. {{ $t('warehouse.common.download') }}
  62. </download-excel>
  63. </el-form-item>
  64. </el-form>
  65. <!-- 数据表格 - rqrq -->
  66. <el-table
  67. :data="dataList"
  68. :height="height"
  69. border
  70. highlight-current-row
  71. v-loading="dataListLoading"
  72. style="width: 100%;">
  73. <el-table-column
  74. v-for="(item,index) in columnList" :key="index"
  75. :sortable="item.columnSortable"
  76. :prop="item.columnProp"
  77. :header-align="item.headerAlign"
  78. :show-overflow-tooltip="item.showOverflowTooltip"
  79. :align="item.align"
  80. :fixed="item.fixed==''?false:item.fixed"
  81. :min-width="item.columnWidth"
  82. :label="item.columnLabel">
  83. <template slot-scope="scope">
  84. <span v-if="item.columnProp === 'status'">
  85. <el-tag
  86. :type="getStatusType(scope.row.status)"
  87. size="small">
  88. {{ getStatusLabel(scope.row.status) }}
  89. </el-tag>
  90. </span>
  91. <span v-else-if="item.columnProp === 'executionTime'">
  92. <span :style="{color: scope.row.executionTime > 3000 ? '#F56C6C' : '#67C23A'}">
  93. {{ scope.row.executionTime }} ms
  94. </span>
  95. </span>
  96. <span v-else>{{ scope.row[item.columnProp] }}</span>
  97. </template>
  98. </el-table-column>
  99. <!-- 操作列 - rqrq -->
  100. <el-table-column
  101. header-align="center"
  102. align="center"
  103. fixed="right"
  104. width="150"
  105. label="操作">
  106. <template slot-scope="scope">
  107. <a type="text" @click="viewDetail(scope.row)">查看详情</a>
  108. </template>
  109. </el-table-column>
  110. </el-table>
  111. <!-- 分页 - rqrq -->
  112. <el-pagination
  113. @size-change="sizeChangeHandle"
  114. @current-change="currentChangeHandle"
  115. :current-page="pageIndex"
  116. :page-sizes="[20, 50, 100, 1000]"
  117. :page-size="pageSize"
  118. :total="totalPage"
  119. layout="total, sizes, prev, pager, next, jumper">
  120. </el-pagination>
  121. <!-- 详情弹窗 - rqrq -->
  122. <el-dialog
  123. title="接口调用详情"
  124. :visible.sync="detailVisible"
  125. :close-on-click-modal="false"
  126. v-drag
  127. width="80%">
  128. <el-row :gutter="20">
  129. <el-col :span="12">
  130. <el-card class="box-card fixed-height-card">
  131. <div slot="header" class="clearfix">
  132. <span>基本信息</span>
  133. </div>
  134. <el-form label-width="120px" class="detail-form">
  135. <el-form-item label="接口名称:">
  136. <span>{{ detailData.interfaceName }}</span>
  137. </el-form-item>
  138. <el-form-item label="方法名称:">
  139. <span>{{ detailData.methodName }}</span>
  140. </el-form-item>
  141. <el-form-item label="工厂编码:">
  142. <span>{{ detailData.site }}</span>
  143. </el-form-item>
  144. <el-form-item label="业务主键:">
  145. <span>{{ detailData.businessKey }}</span>
  146. </el-form-item>
  147. <el-form-item label="调用状态:">
  148. <el-tag
  149. :type="getStatusType(detailData.status)"
  150. size="small">
  151. {{ getStatusLabel(detailData.status) }}
  152. </el-tag>
  153. </el-form-item>
  154. <el-form-item label="执行时间:">
  155. <span :style="{color: detailData.executionTime > 3000 ? '#F56C6C' : '#67C23A'}">
  156. {{ detailData.executionTime }} ms
  157. </span>
  158. </el-form-item>
  159. <el-form-item label="创建时间:">
  160. <span>{{ detailData.createdTime }}</span>
  161. </el-form-item>
  162. <el-form-item label="创建人:">
  163. <span>{{ detailData.createdBy }}</span>
  164. </el-form-item>
  165. </el-form>
  166. </el-card>
  167. </el-col>
  168. <el-col :span="12">
  169. <el-card class="box-card fixed-height-card">
  170. <div slot="header" class="clearfix">
  171. <span>返回信息</span>
  172. </div>
  173. <div class="detail-content-area">
  174. <el-input
  175. type="textarea"
  176. :rows="13"
  177. :value="detailData.errorMessage || '无错误'"
  178. :readonly="true">
  179. </el-input>
  180. </div>
  181. </el-card>
  182. </el-col>
  183. </el-row>
  184. <el-row :gutter="20" style="margin-top: 20px;">
  185. <el-col :span="12">
  186. <el-card class="box-card fixed-height-card">
  187. <div slot="header" class="clearfix">
  188. <span>请求数据</span>
  189. <el-button style="float: right; padding: 3px 0" type="text" @click="copyToClipboard(detailData.requestData)">复制</el-button>
  190. </div>
  191. <div class="detail-content-area">
  192. <pre class="json-pre">{{ formatJson(detailData.requestData) }}</pre>
  193. </div>
  194. </el-card>
  195. </el-col>
  196. <el-col :span="12">
  197. <el-card class="box-card fixed-height-card">
  198. <div slot="header" class="clearfix">
  199. <span>响应数据</span>
  200. <el-button style="float: right; padding: 3px 0" type="text" @click="copyToClipboard(detailData.responseData)">复制</el-button>
  201. </div>
  202. <div class="detail-content-area">
  203. <pre class="json-pre">{{ formatJson(detailData.responseData) }}</pre>
  204. </div>
  205. </el-card>
  206. </el-col>
  207. </el-row>
  208. <div slot="footer" class="dialog-footer">
  209. <el-button @click="detailVisible = false">{{ $t('warehouse.common.close') }}</el-button>
  210. </div>
  211. </el-dialog>
  212. </div>
  213. </template>
  214. <script>
  215. import {
  216. haiAnGetInterfaceCallLogList,
  217. haiAnGetStatusOptions
  218. } from '@/api/haianWarehouse/interfaceCallLog.js'
  219. export default {
  220. name: 'interfaceCallLog54',
  221. data() {
  222. // 默认携带登录工厂编码,保证日志查询上下文与海安工厂一致 - rqrq
  223. const defaultSite = this.$store.state.user.site
  224. return {
  225. // 查询条件 - rqrq
  226. queryData: {
  227. site: defaultSite,
  228. interfaceName: '',
  229. methodName: '',
  230. businessKey: '',
  231. status: '',
  232. startDate: '',
  233. endDate: '',
  234. page: 1,
  235. limit: 20
  236. },
  237. // 表格高度 - rqrq
  238. height: 450,
  239. // 状态选项 - rqrq
  240. statusOptions: [],
  241. // 表格列配置 - rqrq
  242. columnList: [
  243. { columnProp: 'interfaceName', headerAlign: 'center', align: 'center', columnLabel: '接口名称', columnWidth: 150, columnSortable: false, showOverflowTooltip: true, fixed: '' },
  244. { columnProp: 'methodName', headerAlign: 'center', align: 'center', columnLabel: '方法名称', columnWidth: 150, columnSortable: false, showOverflowTooltip: true, fixed: '' },
  245. { columnProp: 'businessKey', headerAlign: 'center', align: 'center', columnLabel: '业务主键', columnWidth: 150, columnSortable: false, showOverflowTooltip: true, fixed: '' },
  246. { columnProp: 'status', headerAlign: 'center', align: 'center', columnLabel: '调用状态', columnWidth: 100, columnSortable: false, showOverflowTooltip: true, fixed: '' },
  247. { columnProp: 'executionTime', headerAlign: 'center', align: 'center', columnLabel: '执行时间', columnWidth: 120, columnSortable: false, showOverflowTooltip: true, fixed: '' },
  248. { columnProp: 'site', headerAlign: 'center', align: 'center', columnLabel: '工厂编码', columnWidth: 80, columnSortable: false, showOverflowTooltip: true, fixed: '' },
  249. { columnProp: 'createdTime', headerAlign: 'center', align: 'center', columnLabel: '创建时间', columnWidth: 150, columnSortable: false, showOverflowTooltip: true, fixed: '' },
  250. { columnProp: 'createdBy', headerAlign: 'center', align: 'center', columnLabel: '创建人', columnWidth: 100, columnSortable: false, showOverflowTooltip: true, fixed: '' },
  251. { columnProp: 'remark', headerAlign: 'center', align: 'left', columnLabel: '备注', columnWidth: 200, columnSortable: false, showOverflowTooltip: true, fixed: '' }
  252. ],
  253. dataList: [],
  254. pageIndex: 1,
  255. pageSize: 20,
  256. totalPage: 0,
  257. dataListLoading: false,
  258. detailVisible: false,
  259. detailData: {},
  260. // 导出相关 - rqrq
  261. exportData: [],
  262. exportName: '海安接口调用日志' + this.dayjs().format('YYYYMMDDHHmmss'),
  263. exportHeader: ['海安接口调用日志'],
  264. exportFooter: []
  265. }
  266. },
  267. mounted() {
  268. this.$nextTick(() => {
  269. this.height = window.innerHeight - 220
  270. })
  271. },
  272. activated() {
  273. this.getDataList()
  274. this.getStatusOptions()
  275. },
  276. methods: {
  277. // 查询日志列表 - rqrq
  278. getDataList() {
  279. this.dataListLoading = true
  280. this.queryData.page = this.pageIndex
  281. this.queryData.limit = this.pageSize
  282. haiAnGetInterfaceCallLogList(this.queryData).then(({ data }) => {
  283. this.dataListLoading = false
  284. if (data && data.code === 0) {
  285. this.dataList = data.page.list || []
  286. this.totalPage = data.page.totalCount || 0
  287. } else {
  288. this.dataList = []
  289. this.totalPage = 0
  290. this.$alert(data.msg || this.$t('warehouse.message.queryFailed'), this.$t('warehouse.common.error'), { confirmButtonText: this.$t('warehouse.common.confirm') })
  291. }
  292. }).catch(() => {
  293. this.dataListLoading = false
  294. this.$alert(this.$t('warehouse.message.queryFailed'), this.$t('warehouse.common.error'), { confirmButtonText: this.$t('warehouse.common.confirm') })
  295. })
  296. },
  297. // 查询状态下拉选项 - rqrq
  298. getStatusOptions() {
  299. haiAnGetStatusOptions().then(({ data }) => {
  300. if (data && data.code === 0) {
  301. this.statusOptions = data.options || []
  302. }
  303. })
  304. },
  305. // 重置查询条件 - rqrq
  306. resetQuery() {
  307. this.queryData = {
  308. // 重置时保留site,避免空site触发后端必填校验失败 - rqrq
  309. site: this.$store.state.user.site,
  310. interfaceName: '',
  311. methodName: '',
  312. businessKey: '',
  313. status: '',
  314. startDate: '',
  315. endDate: '',
  316. page: 1,
  317. limit: 20
  318. }
  319. this.pageIndex = 1
  320. this.getDataList()
  321. },
  322. sizeChangeHandle(val) {
  323. this.pageSize = val
  324. this.pageIndex = 1
  325. this.getDataList()
  326. },
  327. currentChangeHandle(val) {
  328. this.pageIndex = val
  329. this.getDataList()
  330. },
  331. // 状态标签色 - rqrq
  332. getStatusType(status) {
  333. const statusMap = { PROCESSING: 'warning', SUCCESS: 'success', ERROR: 'danger', TIMEOUT: 'info' }
  334. return statusMap[status] || 'info'
  335. },
  336. // 状态文案 - rqrq
  337. getStatusLabel(status) {
  338. const statusMap = { PROCESSING: '处理中', SUCCESS: '成功', ERROR: '失败', TIMEOUT: '超时' }
  339. return statusMap[status] || '未知'
  340. },
  341. // 查看详情 - rqrq
  342. viewDetail(row) {
  343. this.detailData = row
  344. this.detailVisible = true
  345. },
  346. // 格式化JSON展示 - rqrq
  347. formatJson(jsonStr) {
  348. if (!jsonStr) {
  349. return '无数据'
  350. }
  351. try {
  352. return JSON.stringify(JSON.parse(jsonStr), null, 2)
  353. } catch (e) {
  354. return jsonStr
  355. }
  356. },
  357. // 复制文本 - rqrq
  358. copyToClipboard(text) {
  359. if (!text) {
  360. this.$message.warning('无内容可复制')
  361. return
  362. }
  363. const textarea = document.createElement('textarea')
  364. textarea.value = text
  365. document.body.appendChild(textarea)
  366. textarea.select()
  367. try {
  368. document.execCommand('copy')
  369. this.$message.success('复制成功')
  370. } catch (e) {
  371. this.$alert('复制失败', this.$t('warehouse.common.error'), { confirmButtonText: this.$t('warehouse.common.confirm') })
  372. }
  373. document.body.removeChild(textarea)
  374. },
  375. // 导出相关方法 - rqrq
  376. async createExportData() {
  377. const queryParams = { ...this.queryData, page: 1, limit: 999999 }
  378. const { data } = await haiAnGetInterfaceCallLogList(queryParams)
  379. if (data && data.code === 0) {
  380. return (data.page.list || []).map(item => ({ ...item, status: this.getStatusLabel(item.status) }))
  381. }
  382. return []
  383. },
  384. startDownload() {},
  385. finishDownload() {},
  386. fields() {
  387. let json = '{'
  388. this.columnList.forEach((item, index) => {
  389. if (index === this.columnList.length - 1) {
  390. json += '"' + item.columnLabel + '":"' + item.columnProp + '"'
  391. } else {
  392. json += '"' + item.columnLabel + '":"' + item.columnProp + '",'
  393. }
  394. })
  395. json += '}'
  396. return eval('(' + json + ')')
  397. }
  398. }
  399. }
  400. </script>
  401. <style scoped>
  402. .mod-config {
  403. padding: 10px;
  404. }
  405. .box-card {
  406. margin-bottom: 20px;
  407. }
  408. .fixed-height-card {
  409. height: 380px;
  410. }
  411. .detail-form {
  412. height: 320px;
  413. overflow-y: auto;
  414. }
  415. .detail-content-area {
  416. height: 320px;
  417. overflow-y: auto;
  418. }
  419. .json-pre {
  420. margin: 0;
  421. white-space: pre-wrap;
  422. word-wrap: break-word;
  423. font-size: 12px;
  424. line-height: 1.5;
  425. }
  426. .clearfix:before,
  427. .clearfix:after {
  428. display: table;
  429. content: '';
  430. }
  431. .clearfix:after {
  432. clear: both;
  433. }
  434. </style>