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.
567 lines
17 KiB
567 lines
17 KiB
<script setup> |
|
import {onBeforeMount, ref, reactive, computed} from 'vue'; |
|
import {ElMessage} from 'element-plus' |
|
import {get_ai_show_data, get_report_date, get_test_date_api, test_prompt, get_prompt_api} from "@/apis/ai_show.js"; |
|
|
|
// region 表格数据代码 |
|
const tableData = ref([]) |
|
const hallData = ref([]) |
|
const hallArray = ref([]) |
|
const test_date = ref() |
|
const test_date_option = ref([]) |
|
|
|
// 表格展示的数据 |
|
const showData = ref([]) |
|
const hallType = ref({}) |
|
const createTime = ref('') |
|
const prompt = ref('') |
|
const tokens = ref(0) |
|
const takeTimes = ref(0) |
|
const realSales = ref('') |
|
const aiSales = ref('') |
|
const aiCount = ref('') |
|
const compareCount = ref('') |
|
const aiTotal = ref('') |
|
const compareTotal = ref('') |
|
const showResult = ref('') |
|
const templateDate = ref('') |
|
const result = ref(false) |
|
const loading = ref(false) |
|
const think = ref('') |
|
const aiModel = ref('') |
|
|
|
// 日期控件参数 |
|
const calendarStart = ref('') |
|
const calendarEnd = ref('') |
|
|
|
// 对话框 |
|
const dialogFormVisible = ref(false) |
|
const formLabelWidth = '140px' |
|
const form = reactive({ |
|
cinema_code: '', |
|
show_date: '', |
|
prompt: '', |
|
}) |
|
const testLoading = ref(false) |
|
const promptLoading = ref(false) |
|
|
|
// 过滤条件数据 |
|
// 计算日期 |
|
const getDefaultDate = () => { |
|
const date = new Date() |
|
// date.setDate(date.getDate() + 1) |
|
const year = date.getFullYear().toString().padStart(4, "0") |
|
const month = (date.getMonth() + 1).toString().padStart(2, "0") |
|
const day = date.getDate().toString().padStart(2, "0") |
|
console.log(`${year}-${month}-${day}`) |
|
return `${year}-${month}-${day}` |
|
} |
|
const show_date = ref(`2026-06-12`) |
|
const show_date_old = ref(`2026-06-12`) |
|
show_date.value = getDefaultDate() |
|
const cinema_code = ref('11078801') |
|
const cinema_code_old = ref('11078801') |
|
const force = ref(true) |
|
const templateSwitch = ref(false) |
|
const compareSwitch = ref('new') // template target new |
|
|
|
|
|
const show_alter = () => { |
|
ElMessage.error('没有查询到有效的智能排片数据,请调整日期和影院后再试!') |
|
} |
|
|
|
async function get_calendar_date() { |
|
await get_report_date().then(res => { |
|
if (res.status === 'success') { |
|
calendarStart.value = res.start |
|
calendarEnd.value = res.end |
|
} |
|
}).catch(err => { |
|
console.log(err) |
|
}) |
|
} |
|
|
|
// 通过异步请求获取影院列表数据 |
|
async function get_data() { |
|
showData.value = [] |
|
loading.value = true |
|
prompt.value = '' |
|
tokens.value = 0 |
|
takeTimes.value = 0 |
|
realSales.value = '' |
|
aiSales.value = '' |
|
showResult.value = '' |
|
aiCount.value = '' |
|
aiTotal.value = '' |
|
compareCount.value = '' |
|
result.value = false |
|
createTime.value = '' |
|
think.value = '' |
|
aiModel.value = '' |
|
force.value = compareSwitch.value === 'new' |
|
if (compareSwitch.value !== 'new') { |
|
test_date.value = '' |
|
} |
|
if (show_date.value !== show_date_old.value) { |
|
test_date.value = '' |
|
} |
|
if (cinema_code.value !== cinema_code_old.value) { |
|
test_date.value = '' |
|
} |
|
test_date_option.value = [] |
|
await get_ai_show_data(cinema_code.value, show_date.value, force.value, test_date.value).then(res => { |
|
if (res.status === 'success') { |
|
console.log(res) |
|
result.value = false |
|
prompt.value = res.data.prompt |
|
tokens.value = res.data.take_tokens |
|
takeTimes.value = res.data.take_times |
|
realSales.value = res.data.real_sales |
|
aiSales.value = res.data.ai_sales |
|
showResult.value = res.data.result |
|
templateDate.value = res.data.template_date |
|
hallType.value = res.data.hall_type |
|
aiCount.value = res.data.ai_count |
|
aiTotal.value = res.data.ai_total |
|
createTime.value = res.data.create_time |
|
think.value = res.data.think |
|
aiModel.value = res.data.ai_model |
|
if (compareSwitch.value === 'template') { |
|
showData.value = res.data.template_obj |
|
compareCount.value = res.data.template_count |
|
compareTotal.value = res.data.template_total |
|
} else if (compareSwitch.value === 'new') { |
|
showData.value = res.data.real_obj |
|
compareCount.value = res.data.real_count |
|
compareTotal.value = res.data.real_total |
|
} else { |
|
showData.value = res.data.target_obj |
|
compareCount.value = res.data.target_count |
|
compareTotal.value = res.data.target_total |
|
} |
|
console.log(showData.value, prompt.value, tokens.value, takeTimes.value, realSales.value, aiSales.value, showResult.value) |
|
formatTableData() |
|
loading.value = false |
|
cinema_code_old.value = cinema_code.value |
|
show_date_old.value = show_date.value |
|
get_test_date() |
|
} else { |
|
result.value = true |
|
show_alter() |
|
loading.value = false |
|
} |
|
}).catch(err => { |
|
console.log(err) |
|
} |
|
) |
|
loading.value = false |
|
} |
|
|
|
// 处理表格数据 |
|
function formatTableData() { |
|
hallArray.value = [] |
|
hallData.value = [] |
|
tableData.value = [] |
|
let temp = 0; |
|
showData.value.forEach((item, index) => { |
|
tableData.value.push({ |
|
hall: item[0] + '\n\n支持制式:' + hallType.value[item[0]], |
|
ai_show: item[2], |
|
ai_language: item[4], |
|
ai_start: item[5], |
|
ai_end: item[6], |
|
ai_length: item[7], |
|
ai_duration: item[8], |
|
real_show: item[9], |
|
real_language: item[11], |
|
real_start: item[12], |
|
real_end: item[13], |
|
real_length: item[14], |
|
real_duration: item[15], |
|
}) |
|
if (hallArray.value.indexOf(item[0]) >= 0) { |
|
hallData.value[temp] += 1 |
|
hallData.value.push(0) |
|
} else { |
|
hallArray.value.push(item[0]) |
|
temp = index |
|
hallData.value.push(1) |
|
} |
|
}) |
|
console.log('hallArray.value', hallArray.value) |
|
console.log('hallData.value', hallData.value) |
|
} |
|
|
|
|
|
// 通过接口获取测试数据的下拉列表数据 |
|
const get_test_date = () => { |
|
get_test_date_api(cinema_code.value, show_date.value).then(res => { |
|
if (res.status === 'success') { |
|
res.date.forEach((item) => { |
|
test_date_option.value.push({'value': item, label: item}) |
|
}) |
|
} |
|
}) |
|
} |
|
|
|
// 提交测试提示词 |
|
async function requestTest() { |
|
testLoading.value = true |
|
dialogFormVisible.value = false |
|
await test_prompt(form.cinema_code, form.show_date, form.prompt).then(res => { |
|
if (res.status === 'success') { |
|
get_test_date_api(form.cinema_code, form.show_date).then(res => { |
|
if (res.status === 'success') { |
|
test_date_option.value = [] |
|
res.date.forEach((item) => { |
|
test_date_option.value.push({'value': item, label: item}) |
|
}) |
|
} |
|
}) |
|
console.log(res) |
|
} |
|
}).catch(err => { |
|
console.log(err) |
|
}) |
|
testLoading.value = false |
|
form.cinema_code = '' |
|
form.show_date = '' |
|
form.prompt = '' |
|
} |
|
|
|
async function generalPrompt() { |
|
promptLoading.value = true |
|
form.prompt = '' |
|
await get_prompt_api(form.cinema_code, form.show_date).then(res => { |
|
if (res.status === 'success') { |
|
form.prompt = res.data |
|
} |
|
promptLoading.value = false |
|
}).catch(err => { |
|
console.log(err) |
|
}) |
|
promptLoading.value = false |
|
} |
|
|
|
const testButton = computed(() => { |
|
if (testLoading.value === true) { |
|
return 'AI排片中' |
|
} else { |
|
return '测试提示词' |
|
} |
|
|
|
}) |
|
|
|
|
|
// 处理表格合并 |
|
const objectSpanMethod = ({row, column, rowIndex, columnIndex}) => { |
|
if (column.property === 'hall') { |
|
const rowSpan = hallData.value[rowIndex] |
|
if (hallData.value[rowIndex] === 0) { |
|
return { |
|
rowspan: rowSpan, |
|
colspan: 0, |
|
} |
|
} else { |
|
return { |
|
rowspan: rowSpan, |
|
colspan: 1, |
|
} |
|
} |
|
} else { |
|
return { |
|
rowspan: 1, |
|
colspan: 1, |
|
} |
|
} |
|
} |
|
|
|
|
|
// 日历禁用日期 |
|
const disabledDate = (time) => { |
|
const start = new Date(calendarStart.value) |
|
const end = new Date(calendarEnd.value) |
|
return time.getTime() < start || time.getTime() > end |
|
} |
|
|
|
// 日历禁用日期 |
|
const disabledFormDate = (time) => { |
|
const today = new Date() |
|
const start = new Date() |
|
const end = new Date().setDate(today.getDate() + 7) |
|
return time.getTime() < start || time.getTime() > end |
|
} |
|
|
|
const tableHeader = computed(() => { |
|
if (compareSwitch.value === 'new') { |
|
return '目标日期最新排片数据(实时更新)' |
|
} else if (compareSwitch.value === 'template') { |
|
return '模板日期排片数据' |
|
} else { |
|
return '目标日期历史排片数据' |
|
} |
|
}) |
|
|
|
const compareDesc = computed(() => { |
|
if (compareSwitch.value === 'new') { |
|
return '排片占比(AI/目标日期最新排片数据)' |
|
} else if (compareSwitch.value === 'template') { |
|
return '排片占比(AI/模板日期排片数据)' |
|
} else { |
|
return '排片占比(AI/目标日期历史排片数据)' |
|
} |
|
}) |
|
|
|
// 定义生命周期,在加载时获取一次表格数据 |
|
onBeforeMount( |
|
async () => { |
|
await get_data() |
|
await get_calendar_date() |
|
} |
|
) |
|
|
|
|
|
// endregion |
|
|
|
</script> |
|
|
|
<template> |
|
<el-row align="middle"> |
|
<el-col :span="2"> |
|
<el-text>排片目标日期</el-text> |
|
</el-col> |
|
<el-col :span="3"> |
|
<el-date-picker |
|
v-model="show_date" |
|
type="date" |
|
placeholder="选择排片日期" |
|
size="default" |
|
:disabled-date="disabledDate" |
|
value-format="YYYY-MM-DD" |
|
@change="get_data" |
|
style="width: 140px" |
|
/> |
|
</el-col> |
|
<el-col :span="12"> |
|
<el-radio-group v-model="cinema_code" @change="get_data"> |
|
<el-radio-button value="11078801" label="11078801">保利国际影城北京凯德大峡谷店</el-radio-button> |
|
<el-radio-button value="31073101" label="31073101">SFC上影(永华店)</el-radio-button> |
|
<el-radio-button value="33040301" label="33040301">宁波影都(东门口店)</el-radio-button> |
|
</el-radio-group> |
|
</el-col> |
|
<el-col :span="3"> |
|
<el-text>智能排片生成时间:</el-text> |
|
</el-col> |
|
<el-col :span="3"> |
|
<el-text>{{ createTime }}</el-text> |
|
</el-col> |
|
</el-row> |
|
<el-row style="margin: 10px 0 0 0" align="middle"> |
|
<el-col :span="2"> |
|
<el-tooltip |
|
class="box-item" |
|
effect="dark" |
|
content="最新排片数据:实时获取影院目标日期的排片数据;模板日期排片数据:AI生成排片时刻,参考的模板日期排片数据(历史数据不更新);目标日期排片数据:AI生成排片时刻,目标日期的排片数据(历史数据不更新)" |
|
placement="top" |
|
> |
|
<el-text>对比数据选择</el-text> |
|
</el-tooltip> |
|
</el-col> |
|
<el-col :span="9"> |
|
<el-radio-group v-model="compareSwitch" @change="get_data"> |
|
<el-radio value="new" label="new">最新排片数据</el-radio> |
|
<el-radio value="template" label="template">模板日期排片数据</el-radio> |
|
<el-radio value="target" label="target">目标日期排片数据</el-radio> |
|
</el-radio-group> |
|
</el-col> |
|
<el-col :span="4" v-if="compareSwitch==='template'"> |
|
<el-text>模板日期:{{ templateDate }}</el-text> |
|
</el-col> |
|
</el-row> |
|
<el-row style="margin: 10px 0 20px 0" align="middle"> |
|
<el-col :span="2"> |
|
<el-button type="primary" @click="dialogFormVisible = true" :disabled="testLoading" :loading="testLoading"> |
|
{{ testButton }} |
|
</el-button> |
|
</el-col> |
|
<el-col :span="3" v-if="compareSwitch==='new'" align="right"> |
|
<el-text>手动测试数据:</el-text> |
|
</el-col> |
|
<el-col :span="4" v-if="compareSwitch==='new'"> |
|
<el-select v-model="test_date" placeholder="请选择" v-if="compareSwitch==='new'" :clearable="true" |
|
@change="get_data" style="width: 240px"> |
|
<el-option |
|
v-for="item in test_date_option" |
|
:key="item.value" |
|
:label="item.label" |
|
:value="item.value" |
|
/> |
|
</el-select> |
|
</el-col> |
|
</el-row> |
|
<el-dialog v-model="dialogFormVisible" title="测试提示词" width="800" style="max-height: 800px"> |
|
<el-form :model="form"> |
|
<el-form-item label="目标日期" :label-width="formLabelWidth"> |
|
<el-date-picker |
|
v-model="form.show_date" |
|
type="date" |
|
placeholder="选择排片日期" |
|
size="default" |
|
:disabled-date="disabledFormDate" |
|
value-format="YYYY-MM-DD" |
|
style="width: 140px" |
|
/> |
|
</el-form-item> |
|
<el-form-item label="测试影院" :label-width="formLabelWidth"> |
|
<el-select v-model="form.cinema_code" placeholder="请选择" style="width: 260px"> |
|
<el-option label="保利国际影城北京凯德大峡谷店" value="11078801"/> |
|
<el-option label="SFC上影(永华店)" value="31073101"/> |
|
<el-option label="宁波影都(东门口店)" value="33040301"/> |
|
</el-select> |
|
</el-form-item> |
|
<el-form-item label="" :label-width="formLabelWidth"> |
|
<el-button type="primary" @click="generalPrompt" :loading="promptLoading" > |
|
生成提示词 |
|
</el-button> |
|
</el-form-item> |
|
<el-form-item label="提示词" :label-width="formLabelWidth"> |
|
<el-input |
|
v-model="form.prompt" |
|
style="width: 600px" |
|
placeholder="请输入提示词" |
|
type="textarea" |
|
:autosize="{ minRows: 6, maxRows: 15 }" |
|
clearable |
|
/> |
|
</el-form-item> |
|
</el-form> |
|
<template #footer> |
|
<div class="dialog-footer"> |
|
<el-button @click="dialogFormVisible = false">取消</el-button> |
|
<el-button type="primary" @click="requestTest"> |
|
提交 |
|
</el-button> |
|
</div> |
|
</template> |
|
</el-dialog> |
|
|
|
|
|
<el-table :data="tableData" style="width: 100%" v-loading="loading" :span-method="objectSpanMethod"> |
|
<el-table-column prop="hall" label="影厅别名" min-width="160"></el-table-column> |
|
<el-table-column label="智能排片" align="center"> |
|
<el-table-column prop="ai_show" label="影片别名" min-width="160"></el-table-column> |
|
<el-table-column prop="ai_language" label="语言" min-width="60"></el-table-column> |
|
<el-table-column prop="ai_start" label="开始时间" min-width="80"></el-table-column> |
|
<el-table-column prop="ai_end" label="结束时间" min-width="80"></el-table-column> |
|
<el-table-column prop="ai_length" label="片长" min-width="60"></el-table-column> |
|
<el-table-column prop="ai_duration" label="场间" min-width="60"></el-table-column> |
|
</el-table-column> |
|
<el-table-column :label="tableHeader" align="center"> |
|
<el-table-column prop="real_show" label="影片别名" min-width="160"></el-table-column> |
|
<el-table-column prop="real_language" label="语言" min-width="60"></el-table-column> |
|
<el-table-column prop="real_start" label="开始时间" min-width="80"></el-table-column> |
|
<el-table-column prop="real_end" label="结束时间" min-width="80"></el-table-column> |
|
<el-table-column prop="real_length" label="片长" min-width="60"></el-table-column> |
|
<el-table-column prop="real_duration" label="场间" min-width="60"></el-table-column> |
|
</el-table-column> |
|
</el-table> |
|
<el-row style="margin-top: 30px"> |
|
<el-text style="font-weight: bold" size="large">相关数据:</el-text> |
|
</el-row> |
|
<el-row> |
|
<el-col :span="3" align="right"> |
|
<el-text style="font-weight: bold">调用模型:</el-text> |
|
</el-col> |
|
<el-col :span="4" align="left"> |
|
<el-text>{{ aiModel }}</el-text> |
|
</el-col> |
|
</el-row> |
|
<el-row> |
|
<el-col :span="3" align="right"> |
|
<el-text style="font-weight: bold">智能排片预估销售额:</el-text> |
|
</el-col> |
|
<el-col :span="4" align="left"> |
|
<el-text>{{ aiSales }}元</el-text> |
|
</el-col> |
|
</el-row> |
|
<el-row> |
|
<el-col :span="3" align="right"> |
|
<el-text style="font-weight: bold">真实排片销售额:</el-text> |
|
</el-col> |
|
<el-col :span="4" align="left"> |
|
<el-text>{{ realSales }}元</el-text> |
|
</el-col> |
|
</el-row> |
|
<el-row> |
|
<el-col :span="3" align="right"> |
|
<el-text style="font-weight: bold">智能排片耗时:</el-text> |
|
</el-col> |
|
<el-col :span="4" align="left"> |
|
<el-text>{{ takeTimes }}s</el-text> |
|
</el-col> |
|
</el-row> |
|
<el-row> |
|
<el-col :span="3" align="right"> |
|
<el-text style="font-weight: bold">智能排片消耗Tokens:</el-text> |
|
</el-col> |
|
<el-col :span="4" align="left"> |
|
<el-text>{{ tokens }}</el-text> |
|
</el-col> |
|
</el-row> |
|
<el-row> |
|
<el-col :span="3" align="right"> |
|
<el-text style="font-weight: bold">{{ compareDesc }}</el-text> |
|
</el-col> |
|
<el-col :span="9" align="left"> |
|
<el-text>{{ aiCount }}</el-text> |
|
</el-col> |
|
<el-col :span="9" align="left"> |
|
<el-text>{{ compareCount }}</el-text> |
|
</el-col> |
|
</el-row> |
|
<el-row> |
|
<el-col :span="3" align="right"> |
|
</el-col> |
|
<el-col :span="9" align="left"> |
|
<el-text>{{ aiTotal }}</el-text> |
|
</el-col> |
|
<el-col :span="9" align="left"> |
|
<el-text>{{ compareTotal }}</el-text> |
|
</el-col> |
|
</el-row> |
|
<el-row> |
|
<el-col :span="3" align="right"> |
|
<el-text style="font-weight: bold">AI返回结果:</el-text> |
|
</el-col> |
|
<el-col :span="21" align="left"> |
|
<el-text>{{ showResult }}</el-text> |
|
</el-col> |
|
</el-row> |
|
<el-row> |
|
<el-col :span="3" align="right"> |
|
<el-text style="font-weight: bold">提示词:</el-text> |
|
</el-col> |
|
<el-col :span="21" align="left"> |
|
<el-text>{{ prompt }}</el-text> |
|
</el-col> |
|
</el-row> |
|
<el-row> |
|
<el-col :span="3" align="right"> |
|
<el-text style="font-weight: bold">AI思考过程:</el-text> |
|
</el-col> |
|
<el-col :span="21" align="left"> |
|
<el-text>{{ think }}</el-text> |
|
</el-col> |
|
</el-row> |
|
</template> |
|
|
|
|
|
<style> |
|
.el-text { |
|
white-space: pre-wrap; /* 或者使用 pre-line */ |
|
} |
|
|
|
.el-table .cell { |
|
white-space: pre-line; |
|
} |
|
</style>
|
|
|