httprule.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471
  1. <template>
  2. <div class="app-container">
  3. <el-header style="height:auto;!improtant">
  4. <div class="filter-container" style="padding-bottom: 20px;!improtant">
  5. <el-input v-model="listQuery.whenScript" disabled placeholder="any" style="width: 200px;" class="filter-item" @keyup.enter.native="handleFilter" />
  6. <el-input v-model="listQuery.execSort" placeholder="优先级" style="width: 200px;" class="filter-item" @keyup.enter.native="handleFilter" />
  7. <!-- <el-input-number v-model="listQuery.execSort" label="优先级" :min="1" :max="100" /> -->
  8. <el-select v-model="listQuery.status" class="filter-item" filterable clearable placeholder="状态">
  9. <el-option v-for="item in ruleStatus" :key="item.key" :label="item.display_name" :value="item.key" />
  10. </el-select>
  11. <!-- <el-input v-model="listQuery.interfaceName" placeholder="接口类" style="width: 200px;" class="filter-item" @keyup.enter.native="handleFilter" /> -->
  12. <el-button v-waves class="filter-item" type="primary" icon="el-icon-search" @click="handleFilter">
  13. 搜索
  14. </el-button>
  15. <el-button class="filter-item" style="margin-left: 10px;" type="primary" icon="el-icon-edit" @click="handleCreate">
  16. 新增
  17. </el-button>
  18. <el-checkbox v-model="showReviewer" class="filter-item" style="margin-left:15px;" @change="tableKey=tableKey+1">
  19. 显示返回值
  20. </el-checkbox>
  21. <el-button style="float: right;" type="primary" @click="prev">
  22. 返回
  23. </el-button>
  24. </div>
  25. </el-header>
  26. <el-table
  27. :key="tableKey"
  28. v-loading="listLoading"
  29. :data="list"
  30. fit
  31. highlight-current-row
  32. style="width: 100%;"
  33. :header-cell-style="styleObj"
  34. @sort-change="sortChange"
  35. >
  36. <el-table-column label="规则id" prop="id" sortable="custom" align="center" min-width="80px">
  37. <template slot-scope="scope">
  38. <span>{{ scope.row.id }}</span>
  39. </template>
  40. </el-table-column>
  41. <el-table-column label="接口id" min-width="150px" align="center">
  42. <!-- <template slot-scope="scope"> -->
  43. <span>{{ this.$route.query.methodName }}</span>
  44. <!-- </template> -->
  45. </el-table-column>
  46. <el-table-column label="mock结果" min-width="110px" align="center">
  47. <template slot-scope="scope">
  48. <span>{{ scope.row.execSort }}</span>
  49. </template>
  50. </el-table-column>
  51. <!-- <el-table-column label="方法ID" min-width="220px" align="center">
  52. <span>{{ this.$route.path.split('/')[3] }}</span>
  53. </el-table-column> -->
  54. <el-table-column label="规则" min-min-width="60px">
  55. <template slot-scope="{row}">
  56. <span>{{ row.whenScript }}</span>
  57. <!-- <el-tag>{{ row.type | typeFilter }}</el-tag> -->
  58. </template>
  59. </el-table-column>
  60. <el-table-column label="优先级" min-width="110px" align="center">
  61. <template slot-scope="scope">
  62. <span>{{ scope.row.execSort }}</span>
  63. </template>
  64. </el-table-column>
  65. <el-table-column label="状态" class-name="status-col" min-width="100">
  66. <template slot-scope="{row}">
  67. <el-tag :type="row.status | statusFilter">
  68. {{ statusMappings.get(row.status) }}
  69. </el-tag>
  70. </template>
  71. </el-table-column>
  72. <el-table-column label="备注" min-width="110px" align="center">
  73. <template slot-scope="scope">
  74. <span>{{ scope.row.execSort }}</span>
  75. </template>
  76. </el-table-column>
  77. <!-- <el-table-column label="更新时间" min-width="170px" align="center">
  78. <template slot-scope="scope">
  79. <span>{{ scope.row.updateTimeStr }}</span>
  80. </template>
  81. </el-table-column> -->
  82. <el-table-column v-if="showReviewer" label="返回值" min-width="110px" align="center">
  83. <template slot-scope="scope">
  84. <span style="color:red;">{{ scope.row.returnMessage }}</span>
  85. </template>
  86. </el-table-column>
  87. <el-table-column label="操作" align="center" min-width="370" class-name="small-padding fixed-width" fixed="right">
  88. <template slot-scope="{row}">
  89. <el-button type="primary" size="mini" @click="handleCheck(row)">
  90. 查看
  91. </el-button>
  92. <el-button type="primary" size="mini" @click="handleUpdate(row)">
  93. 编辑
  94. </el-button>
  95. <el-button type="primary" size="mini" @click="handleCopy(row)">
  96. 复制
  97. </el-button>
  98. <el-button type="primary" size="mini">
  99. 测试
  100. </el-button>
  101. <el-button v-if="row.status!=1" size="mini" type="success" @click="handleModifyStatus(row, 1)">
  102. 开启
  103. </el-button>
  104. <el-button v-if="row.status!=0" size="mini" type="danger" @click="handleModifyStatus(row, 0)">
  105. 关闭
  106. </el-button>
  107. </template>
  108. </el-table-column>
  109. </el-table>
  110. <pagination v-show="total>0" :total="total" :page.sync="listQuery.curIndex" :limit.sync="listQuery.pageSize" @pagination="getList" />
  111. <el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible" width="65%">
  112. <el-form ref="ruleDataForm" :rules="roleDataRules" :model="ruleData" label-position="left" label-width="120px" style="width: 500px; margin-left:80px;">
  113. <el-form-item label="规则" prop="whenScript">
  114. <el-input v-model="ruleData.whenScript" placeholder="any" disabled />
  115. </el-form-item>
  116. <el-form-item label="优先级" prop="execSort">
  117. <el-input-number v-model="ruleData.execSort" label="优先级" :min="1" :max="100" title="值越大,优先级越高" />
  118. </el-form-item>
  119. <el-form-item label="返回值" prop="returnMessage">
  120. <el-input v-model="ruleData.returnMessage" :autosize="{ minRows: 3, maxRows: 10}" type="textarea" placeholder="{ 'code': 200, 'data': { 'crowdComposition': 'U_866', 'campaignId': 789, 'id': 4606, 'class': 'com.didi.prado.config.api.dto.CampaignCrowdDTO'}}" @blur="getFormatJsonStrFromStringRule(ruleData.returnMessage)" />
  121. </el-form-item>
  122. </el-form>
  123. <div slot="footer" class="dialog-footer">
  124. <el-button @click="dialogFormVisible = false">
  125. 取消
  126. </el-button>
  127. <el-button v-if="showSubmit" type="primary" @click="dialogStatus==='create'?createData():updateData()">
  128. 确定
  129. </el-button>
  130. </div>
  131. </el-dialog>
  132. <el-dialog :visible.sync="dialogPvVisible" title="Reading statistics">
  133. <el-table :data="pvData" border fit highlight-current-row style="width: 100%">
  134. <el-table-column prop="key" label="Channel" />
  135. <el-table-column prop="pv" label="Pv" />
  136. </el-table>
  137. <span slot="footer" class="dialog-footer">
  138. <el-button type="primary" @click="dialogPvVisible = false">Confirm</el-button>
  139. </span>
  140. </el-dialog>
  141. </div>
  142. </template>
  143. <script>
  144. import { fetchEnvInfo, fetchRuleById, createRule, updateRule, changeStatus } from '@/api/httpmock'
  145. import waves from '@/directive/waves' // waves directive
  146. import { parseTime } from '@/utils'
  147. import Pagination from '@/components/Pagination' // secondary package based on el-pagination
  148. // var envSelections = []
  149. const ruleStatus = [
  150. { key: 1, display_name: '已开启' },
  151. { key: 0, display_name: '未开启' },
  152. { key: '', display_name: '全部显示' }
  153. ]
  154. export default {
  155. name: 'Httpmock',
  156. components: { Pagination },
  157. directives: { waves },
  158. filters: {
  159. statusFilter(status) {
  160. const statusMap = {
  161. 1: 'success',
  162. draft: 'info',
  163. 0: 'danger'
  164. }
  165. return statusMap[status]
  166. }
  167. },
  168. data() {
  169. return {
  170. styleObj: {
  171. 'color': 'rgba(0, 0, 0, 0.726)'
  172. },
  173. tableKey: 0,
  174. list: null,
  175. total: 0,
  176. listLoading: true,
  177. statusMappings: new Map([[1, '已开启'], [0, '未开启']]),
  178. ruleStatus,
  179. listQuery: {
  180. curIndex: 1,
  181. pageSize: 20,
  182. whenScript: 'any',
  183. methodId: 0,
  184. execSort: null,
  185. status: null,
  186. methodProtocol: ''
  187. },
  188. showSubmit: true,
  189. sortOptions: [{ label: 'ID Ascending', key: '+id' }, { label: 'ID Descending', key: '-id' }],
  190. statusOptions: ['published', 'draft', 'deleted'],
  191. showReviewer: false,
  192. ruleData: {
  193. methodId: 0,
  194. creator: '',
  195. updator: '',
  196. execSort: 1,
  197. whenScript: '',
  198. returnMessage: '',
  199. curIndex: 1,
  200. pageSize: 20
  201. },
  202. dialogFormVisible: false,
  203. dialogStatus: '',
  204. textMap: {
  205. update: '编辑',
  206. create: '新增规则'
  207. },
  208. dialogPvVisible: false,
  209. pvData: [],
  210. roleDataRules: {
  211. whenScript: [{ required: true, message: '规则不能为空', trigger: 'change' }],
  212. execSort: [{ required: true, message: '优先级1-100', trigger: 'change' }],
  213. returnMessage: [{ required: true, message: '不能为空', trigger: 'change' }]
  214. },
  215. downloadLoading: false
  216. }
  217. },
  218. created() {
  219. this.getList()
  220. },
  221. methods: {
  222. prev() {
  223. this.$router.go(-1)
  224. },
  225. getList() {
  226. this.listLoading = false
  227. this.ruleData.methodId = parseInt(this.$route.path.split('/')[3])
  228. // console.log(this.listQuery.methodId)
  229. console.log(this.ruleData)
  230. updateRule(this.ruleData).then(response => {
  231. this.list = response.data.mockRuleList
  232. this.total = response.data.total
  233. // Just to simulate the time of the request
  234. this.listLoading = false
  235. })
  236. },
  237. getFormatJsonStrFromStringRule: function(jsonStr) {
  238. console.log(jsonStr)
  239. var res = ''
  240. for (var i = 0, j = 0, k = 0, ii, ele; i < jsonStr.length; i++) { // k:缩进,j:""个数
  241. ele = jsonStr.charAt(i)
  242. if (j % 2 === 0 && ele === '}') {
  243. k--
  244. for (ii = 0; ii < k; ii++) ele = ' ' + ele
  245. ele = '\n' + ele
  246. } else if (j % 2 === 0 && ele === '{') {
  247. ele += '\n'
  248. k++
  249. for (ii = 0; ii < k; ii++) ele += ' '
  250. } else if (j % 2 === 0 && ele === ',') {
  251. ele += '\n'
  252. for (ii = 0; ii < k; ii++) ele += ' '
  253. } else if (ele === '"') j++
  254. res += ele
  255. }
  256. // eslint-disable-next-line no-return-assign
  257. return this.ruleData.returnMessage = res
  258. },
  259. updateEnvChannel(v) {
  260. console.log(v)
  261. this.ruleData.envChannel = v
  262. this.envSelections = []
  263. fetchEnvInfo(v).then(response => {
  264. for (var sel of response.data) {
  265. var envSel = {}
  266. envSel.key = sel.envId
  267. envSel.display_name = sel.envName
  268. this.envSelections.push(envSel)
  269. }
  270. })
  271. },
  272. handleFilter() {
  273. // this.listQuery.page = 1
  274. this.listQuery.methodStatus = this.listQuery.value
  275. this.getList()
  276. },
  277. sortChange(data) {
  278. const { prop, order } = data
  279. if (prop === 'id') {
  280. this.sortByID(order)
  281. }
  282. },
  283. sortByID(order) {
  284. if (order === 'ascending') {
  285. this.listQuery.sort = '+id'
  286. } else {
  287. this.listQuery.sort = '-id'
  288. }
  289. this.handleFilter()
  290. },
  291. resetServiceData() {
  292. this.ruleData = {
  293. methodId: 0,
  294. creator: '',
  295. updator: '',
  296. execSort: 1,
  297. whenScript: '',
  298. returnMessage: '',
  299. curIndex: 1,
  300. pageSize: 20
  301. }
  302. },
  303. handleCreate() {
  304. this.resetServiceData()
  305. this.dialogStatus = 'create'
  306. this.dialogFormVisible = true
  307. this.showSubmit = true
  308. this.$nextTick(() => {
  309. this.$refs['ruleDataForm'].clearValidate()
  310. })
  311. },
  312. createData() {
  313. const shouldJson = this.ruleData.returnMessage
  314. if (this.ruleData.whenScript === '') { this.ruleData.whenScript = 'any' }
  315. if (typeof shouldJson === 'string') {
  316. this.$refs['ruleDataForm'].validate((valid) => {
  317. if (valid) {
  318. delete this.ruleData.id
  319. this.ruleData.methodId = parseInt(this.$route.path.split('/')[3])
  320. createRule(this.ruleData).then(response => {
  321. // this.list.unshift(this.serviceData)
  322. if (response.code === 200) {
  323. this.dialogFormVisible = false
  324. this.getList()
  325. this.$notify({
  326. title: 'Success',
  327. message: 'Created Successfully',
  328. type: 'success',
  329. duration: 2000
  330. })
  331. } else {
  332. this.$notify({
  333. title: 'Failed',
  334. message: 'Created Failed',
  335. type: 'error',
  336. duration: 2000
  337. })
  338. }
  339. })
  340. }
  341. })
  342. }
  343. },
  344. handleUpdate(row) {
  345. var queryData = { id: row.id }
  346. fetchRuleById(queryData).then(response => {
  347. console.log(response)
  348. var row_data = response.data.mockRuleList
  349. // this.ruleData.timestamp = new Date(this.temp.timestamp)
  350. // console.log(this.ruleData)
  351. // console.log(row_data)
  352. this.ruleData = Object.assign({}, row_data[0])
  353. // console.log(this.ruleData)
  354. this.ruleData.timestamp = new Date(this.ruleData.timestamp)
  355. this.dialogStatus = 'update'
  356. this.dialogFormVisible = true
  357. this.showSubmit = true
  358. this.$nextTick(() => {
  359. this.$refs['ruleDataForm'].clearValidate()
  360. })
  361. })
  362. },
  363. handleModifyStatus(row, status) {
  364. var statusData = {
  365. id: row.id,
  366. status: status
  367. }
  368. // console.log(statusData)
  369. changeStatus(statusData).then(response => {
  370. // console.log(response)
  371. if (response.code === 200) {
  372. row.status = status
  373. this.$message({
  374. message: row.id.toString() + ' 操作成功!',
  375. type: 'success'
  376. })
  377. } else {
  378. this.$message({
  379. message: row.id.toString() + ' 操作失败!',
  380. type: 'danger'
  381. })
  382. }
  383. })
  384. },
  385. handleCopy(row) {
  386. this.ruleData = Object.assign({}, row) // copy obj
  387. this.ruleData.timestamp = new Date(this.ruleData.timestamp)
  388. this.dialogStatus = 'create'
  389. this.dialogFormVisible = true
  390. this.showSubmit = true
  391. this.$nextTick(() => {
  392. this.$refs['ruleDataForm'].clearValidate()
  393. })
  394. },
  395. updateData() {
  396. this.$refs['ruleDataForm'].validate((valid) => {
  397. if (valid) {
  398. // const tempData = Object.assign({}, this.ruleData)
  399. const tempData = {
  400. id: this.ruleData.id,
  401. methodId: parseInt(this.$route.path.split('/')[3]),
  402. creator: '',
  403. updator: '',
  404. execSort: this.ruleData.execSort,
  405. whenScript: this.ruleData.whenScript,
  406. returnMessage: this.ruleData.returnMessage,
  407. methodName: this.$route.query.methodName
  408. }
  409. updateRule(tempData).then(() => {
  410. this.getList()
  411. // for (const v of this.list) {
  412. // if (v.id === this.ruleData.id) {
  413. // const index = this.list.indexOf(v)
  414. // this.list.splice(index, 1, this.ruleData)
  415. // break
  416. // }
  417. // }
  418. this.dialogFormVisible = false
  419. this.$notify({
  420. title: 'Success',
  421. message: 'Update Successfully',
  422. type: 'success',
  423. duration: 2000
  424. })
  425. })
  426. }
  427. })
  428. },
  429. formatJson(filterVal, jsonData) {
  430. return jsonData.map(v => filterVal.map(j => {
  431. if (j === 'timestamp') {
  432. return parseTime(v[j])
  433. } else {
  434. return v[j]
  435. }
  436. }))
  437. },
  438. handleCheck(row) {
  439. var queryData = { id: row.id }
  440. fetchRuleById(queryData).then(response => {
  441. console.log(response)
  442. var row_data = response.data.mockRuleList
  443. // this.ruleData.timestamp = new Date(this.temp.timestamp)
  444. // console.log(this.ruleData)
  445. // console.log(row_data)
  446. this.ruleData = Object.assign({}, row_data[0])
  447. // console.log(this.ruleData)
  448. this.ruleData.timestamp = new Date(this.ruleData.timestamp)
  449. this.dialogStatus = 'update'
  450. this.dialogFormVisible = true
  451. this.showSubmit = false
  452. this.$nextTick(() => {
  453. this.$refs['ruleDataForm'].clearValidate()
  454. })
  455. })
  456. }
  457. }
  458. }
  459. </script>
  460. <style>
  461. .el-notification.right{
  462. position: fixed;
  463. right: 38.5%;
  464. }
  465. </style>