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.
618 lines
18 KiB
618 lines
18 KiB
<script setup> |
|
import {cinema_list} from '@/apis/update.js'; |
|
import { |
|
end_mock, |
|
get_overtime_show_info, |
|
get_response_json, |
|
set_error_code_config, |
|
set_overtime_config, |
|
start_mock |
|
} from "@/apis/mock.js"; |
|
import {onMounted, onBeforeUnmount} from "vue"; |
|
import {ref, computed} from "vue"; |
|
import {InfoFilled} from "@element-plus/icons-vue"; |
|
import JsonEditorVue from "json-editor-vue3"; |
|
import ApiBlock from "@/components/mock/ApiBlock.vue"; |
|
import {onBeforeRouteLeave} from "vue-router"; |
|
|
|
const mockConfigPost = ref() |
|
let cinema_items = ref([]); |
|
const selectIp = ref('') |
|
|
|
const checkAll = ref(false) |
|
const isIndeterminate = ref(false) |
|
const checkedMockConfig = ref([]) |
|
const mockConfigItems = ['download_film_info', 'get_cinema_info', 'get_screen_info', 'report_ticket', |
|
'report_film_schedule', 'upload_screen_seat_info', 'get_overtime_ticket_status', 'valid_error'] |
|
|
|
const tabs_dict = [ |
|
{label: '影片信息下载', name: 'download_film_info'}, |
|
{label: '影院信息下载', name: 'get_cinema_info'}, |
|
{label: '影厅信息下载', name: 'get_screen_info'}, |
|
{label: '票房数据上报', name: 'report_ticket'}, |
|
{label: '排片数据上报', name: 'report_film_schedule'}, |
|
{label: '座位信息上报', name: 'upload_screen_seat_info'}, |
|
{label: '超时票务查询', name: 'get_overtime_ticket_status'}, |
|
{label: '数据清洗查询', name: 'valid_error'}, |
|
] |
|
const tabs_array = computed(() => { |
|
const tabs = [] |
|
tabs_dict.forEach((tab_item, index) => { |
|
if (checkedMockConfig.value.indexOf(tab_item.name) >= 0) { |
|
tabs.push(tab_item) |
|
} |
|
}) |
|
console.log(selectIp.value) |
|
return tabs |
|
}) |
|
|
|
const activeName = ref(0) |
|
|
|
|
|
const handleClick = (tab, event) => { |
|
console.log(tab.paneName) |
|
if (tab.name === 1) { |
|
console.log('tab', tab.label) |
|
} |
|
} |
|
|
|
|
|
// const json_data = {"a": 1, "b": "c"} |
|
const mockConfig = |
|
[ |
|
{ |
|
label: '数据下载', |
|
items: [{key: 'download_film_info', name: '影片信息下载接口'}, |
|
{key: 'get_cinema_info', name: '影院信息下载接口'}, |
|
{key: 'get_screen_info', name: '影厅信息下载接口'}] |
|
}, { |
|
label: '数据上报', |
|
items: [{key: 'report_ticket', name: '票房数据上报接口'}, |
|
{key: 'report_film_schedule', name: '排片数据上报接口'}, |
|
{key: 'upload_screen_seat_info', name: '座位信息上报接口'}] |
|
}, { |
|
label: '超时票务审核', |
|
items: [{key: 'get_overtime_ticket_status', name: '超时票务查询接口'},] |
|
}, { |
|
label: '数据查询', |
|
items: [{key: 'valid_error', name: '数据清洗查询接口'},] |
|
} |
|
] |
|
|
|
const handleIpChange = () => { |
|
// 处理超时退票部分 |
|
getOvertimeShowInfo() |
|
handleOvertimeConfigChange() |
|
// 获取接口JSON数据 |
|
getResponseJson() |
|
// 处理接口勾选状态 |
|
checkedMockConfig.value = [] |
|
checkAll.value = false |
|
isIndeterminate.value = false |
|
activeName.value = 0 |
|
} |
|
|
|
const handleCheckAllChange = (val) => { |
|
if (selectIp.value === '') { |
|
alert('请先选择测试影院IP!') |
|
checkedMockConfig.value = [] |
|
checkAll.value = false |
|
isIndeterminate.value = false |
|
return |
|
} |
|
console.log(tabs_array.value.length) |
|
checkedMockConfig.value = val ? mockConfigItems : [] |
|
isIndeterminate.value = false |
|
activeName.value = 0 |
|
} |
|
const handleCheckedMockChange = (value) => { |
|
|
|
if (selectIp.value === '') { |
|
alert('请先选择测试影院IP!') |
|
checkedMockConfig.value = [] |
|
checkAll.value = false |
|
isIndeterminate.value = false |
|
return |
|
} |
|
console.log(tabs_array.value.length) |
|
console.log(tabs_array.value.length) |
|
const checkedCount = value.length |
|
checkAll.value = checkedCount === mockConfigItems.length |
|
isIndeterminate.value = checkedCount > 0 && checkedCount < mockConfigItems.length |
|
activeName.value = 0 |
|
} |
|
|
|
async function get_cinema_items() { |
|
cinema_items = [] |
|
await cinema_list().then(res => { |
|
if (Array.isArray(res)) { |
|
const ip_list = res.map((item, index) => { |
|
return {value: item.ip, label: item.ip} |
|
}) |
|
cinema_items.value = [...ip_list] |
|
console.log(cinema_items) |
|
} else { |
|
console.log('else') |
|
} |
|
}).catch(err => { |
|
console.log('err') |
|
console.log(err) |
|
}) |
|
} |
|
|
|
|
|
// 过场退票相关代码 |
|
// select组件绑定数据 |
|
const selectedOvertimeShowType = ref('') |
|
const selectedShowInfo = ref('') |
|
const selectedStatus = ref('') |
|
// Select组件展示数据 |
|
const showInfo = ref([]) |
|
const sellShowInfo = ref([]) |
|
const refundShowInfo = ref([]) |
|
const auditStatusInfo = ref({}) |
|
|
|
// 当设置了过场售退类型后更新场次列表 |
|
const handleOvertimeShowTypeChange = () => { |
|
console.log(selectedOvertimeShowType.value) |
|
if (selectedOvertimeShowType.value === 'sell') { |
|
showInfo.value = sellShowInfo.value |
|
} else { |
|
showInfo.value = refundShowInfo.value |
|
console.log(refundShowInfo.value) |
|
} |
|
selectedShowInfo.value = '' |
|
selectedStatus.value = '' |
|
} |
|
|
|
// 当ip更新后清除数据 |
|
const handleOvertimeConfigChange = () => { |
|
selectedOvertimeShowType.value = '' |
|
selectedShowInfo.value = '' |
|
selectedStatus.value = '' |
|
} |
|
|
|
// 处理选择完全部选项后通知后台存储设置 |
|
const handleOvertimeConfigSave = () => { |
|
if (selectedOvertimeShowType.value !== '' && selectedShowInfo.value !== '' && selectedStatus.value !== '') { |
|
const params = {ip: selectIp.value, show_id: selectedShowInfo.value, audit_status: selectedStatus.value} |
|
set_overtime_config(params).then(res => { |
|
console.log(res) |
|
}).catch(err => { |
|
console.log(err) |
|
}) |
|
getOvertimeResponseJson() |
|
} |
|
} |
|
|
|
// 获取过场售退场次和审核的结果数据用于填充select组件 |
|
async function getOvertimeShowInfo() { |
|
await get_overtime_show_info({ip: selectIp.value}).then( |
|
res => { |
|
sellShowInfo.value = [...res['sell']] |
|
refundShowInfo.value = [...res['refund']] |
|
auditStatusInfo.value = [...res['status']] |
|
} |
|
).catch( |
|
err => { |
|
console.log(err) |
|
} |
|
) |
|
} |
|
|
|
|
|
// 获取Json数据部分逻辑 |
|
// 定义存储Json的对象 |
|
const allJsonData = ref({}) |
|
|
|
// 获取Json的请求封装 |
|
function getResponseJson() { |
|
mockConfigItems.forEach( |
|
(api, index) => { |
|
const req = { |
|
ip: selectIp.value, |
|
api: api |
|
} |
|
if (api === 'download_film_info') { |
|
get_response_json(req).then(res => { |
|
allJsonData.value.download_film_info = res |
|
}).catch(err => { |
|
console.log(err) |
|
}) |
|
} |
|
if (api === 'get_cinema_info') { |
|
get_response_json(req).then(res => { |
|
allJsonData.value.get_cinema_info = res |
|
}).catch(err => { |
|
console.log(err) |
|
}) |
|
} |
|
if (api === 'get_screen_info') { |
|
get_response_json(req).then(res => { |
|
allJsonData.value.get_screen_info = res |
|
}).catch(err => { |
|
console.log(err) |
|
}) |
|
} |
|
if (api === 'report_ticket') { |
|
get_response_json(req).then(res => { |
|
allJsonData.value.report_ticket = res |
|
}).catch(err => { |
|
console.log(err) |
|
}) |
|
} |
|
if (api === 'report_film_schedule') { |
|
get_response_json(req).then(res => { |
|
allJsonData.value.report_film_schedule = res |
|
}).catch(err => { |
|
console.log(err) |
|
}) |
|
} |
|
if (api === 'upload_screen_seat_info') { |
|
get_response_json(req).then(res => { |
|
allJsonData.value.upload_screen_seat_info = res |
|
}).catch(err => { |
|
console.log(err) |
|
}) |
|
} |
|
if (api === 'valid_error') { |
|
get_response_json(req).then(res => { |
|
allJsonData.value.valid_error = res |
|
}).catch(err => { |
|
console.log(err) |
|
}) |
|
} |
|
} |
|
) |
|
} |
|
|
|
// 单独处理超时的json获取 |
|
const getOvertimeResponseJson = () => { |
|
const req = { |
|
ip: selectIp.value, |
|
api: 'get_overtime_ticket_status', |
|
show: selectedShowInfo.value, |
|
type: selectedOvertimeShowType.value === 'sell' ? '0' : '1', |
|
status: selectedStatus.value |
|
} |
|
get_response_json(req).then(res => { |
|
allJsonData.value.get_overtime_ticket_status = res |
|
}).catch(err => { |
|
console.log(err) |
|
}) |
|
} |
|
|
|
// 重新计算顺序 |
|
const checkedItemsOrdered = computed(() => { |
|
let temp = [] |
|
mockConfigItems.forEach( |
|
(item) => { |
|
if (checkedMockConfig.value.indexOf(item) >= 0) { |
|
temp.push(item) |
|
} |
|
} |
|
) |
|
return temp |
|
}) |
|
|
|
const handleRunningChange = () => { |
|
if (running.value === true) { |
|
alert('开始模拟后修改的接口不会被模拟,如果需要修改接口模拟参数,请停止后再修改!') |
|
} |
|
} |
|
|
|
// 计算属性: 用于切换标签时,回填对应的Json数据,支持读写的计算属性 |
|
const json_data = computed( |
|
{ |
|
get() { |
|
return allJsonData.value[checkedItemsOrdered.value[activeName.value]] |
|
}, |
|
set(newVal) { |
|
allJsonData.value[checkedItemsOrdered.value[activeName.value]] = newVal |
|
} |
|
} |
|
) |
|
|
|
// 处理开始和停止按键的逻辑 |
|
const running = ref(false) |
|
const disableAll = ref(false) |
|
const startBtn_disable = ref(false) |
|
const startBtn_loading = ref(false) |
|
|
|
const handleStart = () => { |
|
console.log(selectedOvertimeShowType.value) |
|
console.log(selectedShowInfo.value) |
|
console.log(selectedStatus.value) |
|
if (selectIp.value === '') { |
|
alert('请先选择影院IP!') |
|
return; |
|
} |
|
if (checkedMockConfig.value.length===0){ |
|
alert('请先选择要模拟的接口!') |
|
return; |
|
} |
|
if (checkedMockConfig.value.indexOf('get_overtime_ticket_status') >= 0) { |
|
if (selectedOvertimeShowType.value === '' || selectedShowInfo.value === '' || selectedStatus.value === '') { |
|
alert('请先设置‘超时票务查询’中的选项!') |
|
return |
|
} |
|
} |
|
running.value = true |
|
startBtn_disable.value = true |
|
startBtn_loading.value = true |
|
const params = {ip: selectIp.value} |
|
let mock_config = {} |
|
mockConfigItems.forEach((item) => { |
|
mock_config[item] = checkedMockConfig.value.indexOf(item) >= 0 |
|
}) |
|
console.log(mock_config) |
|
const data = JSON.stringify({mock_config: mock_config, json_data: allJsonData.value}) |
|
console.log(data) |
|
start_mock(params, data).then(res => { |
|
}).catch(err => { |
|
}) |
|
// 处理置灰逻辑 |
|
disableAll.value = true |
|
} |
|
|
|
const handleEnd = () => { |
|
if (selectIp.value === '') { |
|
alert('请先选择影院IP!') |
|
return |
|
} |
|
running.value = false |
|
startBtn_disable.value = false |
|
startBtn_loading.value = false |
|
disableAll.value = false |
|
const params = {ip: selectIp.value} |
|
end_mock(params).then(res => { |
|
}).catch(err => { |
|
}) |
|
} |
|
|
|
// 抽屉相关 |
|
const drawer = ref(false) |
|
|
|
// ValidError相关 |
|
const selectErrorCode = ref('0') |
|
const errorCode = [ |
|
{label: '验证通过', code: '0'}, |
|
{label: '数据报送方错误', code: '100'}, |
|
{label: '影院编码错误', code: '200'}, |
|
{label: '影厅编码错误', code: '201'}, |
|
{label: '网售商编码错误', code: '202'}, |
|
{label: '座位编码错误', code: '203'}, |
|
{label: '影片编码错误', code: '204'}, |
|
{label: '场次编码错误', code: '205'}, |
|
{label: '票价错误', code: '300'}, |
|
{label: '退票类型,查无此票', code: '400'}, |
|
{label: '超时退票', code: '500'}, |
|
{label: '超时售票', code: '600'}, |
|
{label: '超期退票', code: '700'}, |
|
{label: '影院停业上报受限', code: '800'}, |
|
{label: '影院营业上报受限', code: '801'}, |
|
{label: '影院注销上报错误', code: '802'}, |
|
{label: '影院停业上报错误', code: '803'} |
|
] |
|
const handleErrorCodeChange = () => { |
|
const params = { |
|
ip: selectIp.value, |
|
api: 'valid_error', |
|
error_code: selectErrorCode.value |
|
} |
|
set_error_code_config(params).then( |
|
(res) => { |
|
} |
|
).catch((err) => { |
|
}) |
|
} |
|
|
|
// Vue生命周期钩子函数 |
|
onMounted( |
|
async () => { |
|
await get_cinema_items(); |
|
} |
|
) |
|
onBeforeRouteLeave((from, to, next) => { |
|
console.log(selectIp.value) |
|
console.log(to.path) |
|
console.log(from.path) |
|
if (to.path === '/mock' && running.value === true) { |
|
alert('请先停止运行!') |
|
}else{ |
|
next() |
|
} |
|
|
|
}) |
|
|
|
|
|
</script> |
|
|
|
<template> |
|
<el-form |
|
ref="mockConfigPost" |
|
> |
|
<el-row justify="start"> |
|
<el-col :span="4"> |
|
<el-select v-model="selectIp" class="m-2" placeholder="选择要模拟的影院IP" @change="handleIpChange" |
|
:disabled="disableAll"> |
|
<el-option |
|
v-for="item in cinema_items.value" |
|
:key="item.value" |
|
:label="item.label" |
|
:value="item.value" |
|
/> |
|
</el-select> |
|
</el-col> |
|
</el-row> |
|
<div class="api_desc"> |
|
<p>接口设置 |
|
<el-popover |
|
placement="top-start" |
|
title="接口设置说明:" |
|
:width="400" |
|
trigger="hover" |
|
content="勾选需要测试的接口,点击‘开始’,启动对应单机的接口模拟,未勾选的接口会直接穿透到专资。需要指定接口的返回参数,可以在最下方编辑器中修改。" |
|
> |
|
<template #reference> |
|
<el-icon> |
|
<InfoFilled/> |
|
</el-icon> |
|
</template> |
|
</el-popover> |
|
</p> |
|
</div> |
|
<el-row justify="start"> |
|
<el-col :span="1"> |
|
<el-checkbox |
|
v-model="checkAll" |
|
:indeterminate="isIndeterminate" |
|
@change="handleCheckAllChange" |
|
:disabled="disableAll" |
|
> |
|
全选 |
|
</el-checkbox> |
|
</el-col> |
|
</el-row> |
|
<el-checkbox-group |
|
v-model="checkedMockConfig" |
|
@change="handleCheckedMockChange" |
|
:disabled="disableAll" |
|
> |
|
<template v-for="api_items in mockConfig"> |
|
<el-divider content-position="left"> |
|
<span class="api_label">{{ api_items.label }}</span> |
|
</el-divider> |
|
<el-row justify="start"> |
|
<el-col :span=5 v-for="api in api_items.items"> |
|
<el-checkbox |
|
:key="api.key" |
|
:label="api.key" |
|
> |
|
{{ api.name }} |
|
</el-checkbox> |
|
<el-popover |
|
v-if="api.key === 'get_overtime_ticket_status'" |
|
placement="top-start" |
|
title="超时票务查询接口说明:" |
|
:width="400" |
|
trigger="hover" |
|
content="此接口勾选后需要在下方接口返回值定义区域中指定要测试的场次和状态信息。" |
|
> |
|
<template #reference> |
|
<el-icon> |
|
<InfoFilled/> |
|
</el-icon> |
|
</template> |
|
</el-popover> |
|
<el-popover |
|
v-if="api.key === 'valid_error'" |
|
placement="top-start" |
|
title="数据清洗查询说明:" |
|
:width="400" |
|
trigger="hover" |
|
content="此接口勾选后需要在下方接口返回值定义区域中指定验证数据的返回状态,由于此接口为实时数据请求,选择状态后不会更新JSON编辑器中的返回值数据, 需要通过单机日志查看所选状态的返回值。" |
|
> |
|
<template #reference> |
|
<el-icon> |
|
<InfoFilled/> |
|
</el-icon> |
|
</template> |
|
</el-popover> |
|
</el-col> |
|
</el-row> |
|
</template> |
|
</el-checkbox-group> |
|
<br> |
|
<el-drawer v-model="drawer" :with-header="false" size="1000px" style="height: 100%"> |
|
<ApiBlock :tabs="tabs_dict"/> |
|
</el-drawer> |
|
<el-row justify="start"> |
|
<el-row :span="12"> |
|
<el-button @click="handleStart" :disabled="startBtn_disable" :loading="startBtn_loading">开始</el-button> |
|
<el-button @click="handleEnd">停止</el-button> |
|
<el-button type="primary" @click="drawer = true">接口文档</el-button> |
|
</el-row> |
|
</el-row> |
|
</el-form> |
|
<br> |
|
<div> |
|
<el-tabs v-model="activeName" class="api_tabs" @tab-click="handleClick"> |
|
<el-tab-pane v-for="(tab,index) in tabs_array" :label="tab.label" :name="index"> |
|
<div v-if="tabs_array[index].name==='get_overtime_ticket_status'"> |
|
<el-row> |
|
<el-col :span="4"> |
|
<label class="api-label">售/退</label>  |
|
<el-select style="width: 50%" v-model="selectedOvertimeShowType" placeholder="请选择" |
|
@change="handleOvertimeShowTypeChange" :disabled="disableAll"> |
|
<el-option key="sell" label="过场售票" value="sell"></el-option> |
|
<el-option key="refund" label="过场退票" value="refund"></el-option> |
|
</el-select> |
|
</el-col> |
|
<el-col :span="6"> |
|
<label class="api-label">场次</label>  |
|
<el-select style="width: 75%" v-model="selectedShowInfo" placeholder="请选择" |
|
@change="handleOvertimeConfigSave" :disabled="disableAll"> |
|
<el-option v-for="show in showInfo" :key="show.id" :label="show.show" :value="show.id"></el-option> |
|
</el-select> |
|
</el-col> |
|
<el-col :span="6"> |
|
<label class="api-label">审核结果</label>  |
|
<el-select style="width: 50%" v-model="selectedStatus" placeholder="请选择" |
|
@change="handleOvertimeConfigSave" :disabled="disableAll"> |
|
<el-option v-for="status in auditStatusInfo" :key="status.key" :label="status.status" |
|
:value="status.key"></el-option> |
|
</el-select> |
|
</el-col> |
|
</el-row> |
|
</div> |
|
<div v-if="tabs_array[index].name==='valid_error'"> |
|
<el-row justify="start"> |
|
<el-col span="6"> |
|
<label class="api-label">场次状态</label>  |
|
<el-select v-model="selectErrorCode" class="m-2" placeholder="请选择返回状态" |
|
@change="handleErrorCodeChange" |
|
:disabled="disableAll"> |
|
<el-option |
|
v-for="item in errorCode" |
|
:key="item.code" |
|
:label="item.code + '-' + item.label" |
|
:value="item.code" |
|
/> |
|
</el-select> |
|
</el-col> |
|
</el-row> |
|
</div> |
|
<JsonEditorVue class="editor" v-model="json_data" language="zh-CN" @change="handleRunningChange"/> |
|
</el-tab-pane> |
|
</el-tabs> |
|
</div> |
|
|
|
</template> |
|
|
|
<style scoped> |
|
span.api_label { |
|
font-size: 14px; |
|
} |
|
|
|
div.api_desc { |
|
text-align: left; |
|
} |
|
|
|
.el-divider--horizontal { |
|
line-height: 1; |
|
} |
|
|
|
.editor { |
|
width: 75%; |
|
margin-top: 10px; |
|
} |
|
|
|
.api-label { |
|
font-size: 14px; |
|
} |
|
|
|
.el-icon { |
|
font-size: 14px; |
|
} |
|
</style>
|
|
|