Commit c61dfa23 authored by 罗超's avatar 罗超

1

parent b7b69832
......@@ -46,11 +46,39 @@
<el-table-column prop="title" label="标题"></el-table-column>
<el-table-column prop="recommendReason" label="推荐理由" width="200"></el-table-column>
<el-table-column prop="creationTime" label="创建时间" width="180"></el-table-column>
<el-table-column label="操作" width="200">
<el-table-column label="TD行程" width="100">
<template slot-scope="scope">
<span
v-if="scope.row.tdId == 0"
style="color: #f56c6c;"
>未创建</span>
<span
v-else
class="td-created"
@click="previewTD(scope.row)"
style="cursor:pointer;"
>已创建</span>
</template>
</el-table-column>
<el-table-column label="操作" width="250">
<template slot-scope="scope">
<el-button type="text" size="small" @click="handleEdit(scope.row)">修改</el-button>
<el-button type="text" size="small" style="color:#f56c6c;margin-right: 10px;" @click="handleDelete(scope.row)">删除</el-button>
<el-button type="text" size="small" @click="openPublishDialog(scope.row)">发布行程</el-button>
<template v-if="scope.row.tdId == 0">
<el-button type="text" size="small" style="margin-left:8px;" @click="openTdDialog(scope.row)">创建TD</el-button>
</template>
<template v-else>
<el-dropdown style="margin-left:8px;" @command="cmd => handleTdDropdown(cmd, scope.row)">
<el-button type="text" size="small">TD操作<i class="el-icon-arrow-down el-icon--right"></i></el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="change">更换模版</el-dropdown-item>
<!-- <el-dropdown-item command="delete">删除行程</el-dropdown-item> -->
<el-dropdown-item command="edit">编辑行程</el-dropdown-item>
<el-dropdown-item command="view">查看行程</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
</template>
</el-table-column>
</el-table>
......@@ -116,6 +144,12 @@
</el-input>
<div style="height: 30px;"></div>
</el-dialog>
<TdTemplateDialog
:visible="tdDialogVisible"
:isEdit="tdDialogRow && tdDialogRow.tdId > 0"
@close="tdDialogVisible=false"
@confirm="onTdTemplateConfirm"
/>
</el-drawer>
</template>
......@@ -124,11 +158,13 @@ import { requirementService } from '@/services/requirement';
import { itineraryService } from '@/services/itinerary';
import InfoCard from './InfoCard.vue';
import QRCode from 'qrcode'
import TdTemplateDialog from './TdTemplateDialog.vue';
export default {
name: 'RequirementDetail',
components: {
InfoCard
InfoCard,
TdTemplateDialog
},
props: {
value: {
......@@ -158,7 +194,9 @@ export default {
],
currentPublishOption: 'wechatH5',
qrcodeUrl: '',
createQrcode: false
createQrcode: false,
tdDialogVisible: false,
tdDialogRow: null
}
},
computed: {
......@@ -393,6 +431,88 @@ export default {
'Closed': 'danger' // 已关闭
};
return typeMap[state] || 'info';
},
previewTD(row) {
// 先请求接口获取uid,再拼接PPT预览链接
if (row.tdId > 0) {
this.apipost && this.apipost(
"travel_temp_token", {},
res => {
if (res.data && res.data.resultCode == 1) {
let href = this.domainManager().PptUrl;
const pageUrl = `/play/${row.tdId}/0/2`
let url = `${href}/autoLogin?uid=${res.data.data}&model=1001&redict=${encodeURIComponent(pageUrl)}`;
window.open(url, '_blank');
} else {
this.$message.error('获取TD行程token失败');
}
},
err => {
this.$message.error('获取TD行程token失败');
}
);
}
},
editTD(row) {
// 先请求接口获取uid,再拼接PPT预览链接
if (row.tdId > 0) {
this.apipost && this.apipost(
"travel_temp_token", {},
res => {
if (res.data && res.data.resultCode == 1) {
let href = this.domainManager().PptUrl;
const pageUrl = `/editor/${row.tdId}/1/1/0/e/1/c/1`
let url = `${href}/autoLogin?uid=${res.data.data}&model=1001&redict=${encodeURIComponent(pageUrl)}`;
window.open(url, '_blank');
} else {
this.$message.error('获取TD行程token失败');
}
},
err => {
this.$message.error('获取TD行程token失败');
}
);
}
},
openTdDialog(row) {
this.tdDialogRow = row;
this.tdDialogVisible = true;
},
async onTdTemplateConfirm(tempId) {
if (!this.tdDialogRow) return;
const loading = this.$loading({
lock: true,
text: '正在为你创建TD行程,请稍等',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
});
try {
await itineraryService.setTravelTemplateAsync(this.tdDialogRow.id, tempId);
this.$message.success('TD行程创建成功');
this.tdDialogVisible = false;
this.getDetail && this.getDetail();
} catch (e) {
this.$message.error('TD行程创建失败');
} finally {
loading.close();
}
},
handleTdDropdown(cmd, row) {
if (cmd === 'change') {
this.$confirm('此操作将会解除现有的关联设计,重新创建新设计是否执行?', '提示', {
type: 'warning'
}).then(() => {
this.openTdDialog(row);
});
} else if (cmd === 'delete') {
// 空方法
} else if (cmd === 'edit') {
// 空方法
this.editTD(row)
} else if (cmd === 'view') {
// 空方法
this.previewTD(row)
}
}
},
activated() {
......@@ -480,4 +600,16 @@ export default {
color: #333;
font-weight: 500;
}
.td-created {
display: inline-block;
padding: 2px 10px;
border-radius: 8px;
background: #e6f7ff;
color: #409EFF;
font-weight: 500;
transition: background 0.2s;
}
.td-created:hover {
background: #bae7ff;
}
</style>
<template>
<div class="td-template-dialog-mask" v-if="visible">
<div class="td-template-dialog">
<div class="td-template-header">
<span>{{ isEdit ? '修改TD模版' : '创建TD模版' }}</span>
<span class="td-template-close" @click="$emit('close')">×</span>
</div>
<div class="td-template-filter">
<input v-model="filterTitle" placeholder="关键字" class="td-template-input" @input="onFilterChange" />
<select v-model="filterType" class="td-template-select" @change="onFilterChange">
<option value="0">全部版型</option>
<option value="1">横版</option>
<option value="2">竖版</option>
</select>
</div>
<!-- <div class="td-template-list-title">全部模版</div> -->
<div class="td-template-content">
<div class="td-template-masonry">
<div v-for="item in sortedTemplates" :key="item.TempId" class="td-template-card" :class="{'vertical': item.TempType==2, 'selected': selectedId===item.TempId}" @click="selectTemplate(item)">
<img :src="item.CoverImg" :alt="item.Title" loading="lazy" />
<!-- <div class="td-template-title">{{ item.Title }}</div> -->
<!-- <div class="td-template-type">{{ item.TempType==1 ? '横版' : '竖版' }}</div> -->
<div v-if="item.isAiRecommend" class="td-template-ai-tag">AI推荐</div>
</div>
</div>
</div>
<div class="td-template-footer">
<button class="td-template-btn" :disabled="!selectedId" @click="onCreate">创建</button>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'TdTemplateDialog',
props: {
visible: Boolean,
isEdit: Boolean
},
data() {
return {
filterTitle: '',
filterType: '0',
templates: [],
sources:[],
selectedId: null
}
},
computed: {
hasFilter() {
return this.filterTitle.trim() || this.filterType !== '0';
},
sortedTemplates() {
// AI推荐优先
return [...this.templates].sort((a, b) => (b.isAiRecommend ? 1 : 0) - (a.isAiRecommend ? 1 : 0));
}
},
watch: {
visible(val) {
if (val) {
this.loadTemplates();
}
}
},
mounted() {
this.loadTemplates()
},
methods: {
onFilterChange() {
let temps = JSON.parse(JSON.stringify(this.sources))
if(this.filterTitle && this.filterTitle!='')
temps = temps.filter(x=>x.Title.indexOf(this.filterTitle)!=-1)
if(this.filterType>0){
temps = temps.filter(x=>x.TempType==this.filterType)
}
this.templates = temps
},
loadTemplates() {
// API参数
const msg = {
pageIndex: 1,
pageSize: 1000,
LineId: 0,
Title: this.filterTitle,
TagJsonStr: '',
CountryList: [],
SeasonList: [],
ColorList: [],
pageCount: 1,
TempType: Number(this.filterType),
TemplateType: 1,
type: 0,
OrderByType: 1
};
if (this.apipost) {
this.apipost('triptemplate_GetTripTemplatePage', msg, res => {
console.log(res)
if (res.data.resultCode === 1) {
this.templates = res.data.data.pageData || [];
this.sources = res.data.data.pageData || [];
} else {
this.templates = [];
}
});
} else {
// mock
this.templates = [
{
TempId: 1427,
Title: '日本红叶狩',
CoverImg: 'https://im.oytour.com/pptist/desgin/250704145047901_tpl_00.jpg',
TempType: 1,
isAiRecommend: true
},
{
TempId: 1428,
Title: '北海道雪景',
CoverImg: 'https://im.oytour.com/pptist/desgin/250704145047901_tpl_01.jpg',
TempType: 2,
isAiRecommend: false
},
{
TempId: 1429,
Title: '东京樱花季',
CoverImg: 'https://im.oytour.com/pptist/desgin/250704145047901_tpl_02.jpg',
TempType: 1,
isAiRecommend: true
}
];
return;
}
},
selectTemplate(item) {
this.selectedId = item.TempId;
},
onCreate() {
if (this.selectedId) {
this.$emit('confirm', this.selectedId);
}
}
}
}
</script>
<style scoped>
.td-template-dialog-mask {
position: fixed;
z-index: 9999;
left: 0; top: 0; right: 0; bottom: 0;
background: rgba(0,0,0,0.35);
display: flex;
align-items: center;
justify-content: center;
}
.td-template-dialog {
background: #fff;
border-radius: 16px;
min-width: 700px;
max-width: 900px;
min-height: 480px;
box-shadow: 0 8px 32px rgba(0,0,0,0.18);
padding: 0 0 24px 0;
position: relative;
overflow: hidden;
}
.td-template-header {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 20px;
font-weight: bold;
padding: 20px 32px 10px 32px;
border-bottom: 1px solid #f0f0f0;
}
.td-template-close {
font-size: 28px;
cursor: pointer;
color: #888;
transition: color 0.2s;
}
.td-template-close:hover {
color: #f56c6c;
}
.td-template-filter {
display: flex;
gap: 16px;
padding: 18px 32px 0 32px;
align-items: center;
}
.td-template-input {
flex: 1;
padding: 8px 12px;
border: 1px solid #e0e0e0;
border-radius: 6px;
font-size: 15px;
}
.td-template-select {
padding: 8px 12px;
border: 1px solid #e0e0e0;
border-radius: 6px;
font-size: 15px;
}
.td-template-list-title {
font-size: 16px;
font-weight: 500;
margin: 18px 32px 8px 32px;
}
.td-template-content{
height: 70vh;
overflow: hidden;
overflow-y: auto;
margin-top: 18px;
}
.td-template-masonry {
column-count: 3;
column-gap: 18px;
margin: 0 32px;
min-height: 180px;
}
.td-template-card {
break-inside: avoid;
margin-bottom: 18px;
width: 100%;
background: #f7fafd;
border-radius: 10px;
box-shadow: 0 1px 4px rgba(64,158,255,0.06);
display: flex;
flex-direction: column;
align-items: center;
cursor: pointer;
transition: box-shadow 0.2s, background 0.2s, border 0.2s;
border: 2px solid transparent;
padding: 10px 8px 10px 8px;
position: relative;
}
.td-template-card.selected {
border: 2px solid #409EFF;
background: #e6f7ff;
}
.td-template-card.vertical {
min-height: 260px;
}
.td-template-card img {
width: 100%;
/* height: 110px; */
object-fit: cover;
border-radius: 6px;
/* margin-bottom: 8px; */
background: #eee;
}
.td-template-title {
font-size: 15px;
font-weight: 500;
margin-bottom: 4px;
text-align: center;
color: #333;
}
.td-template-type {
font-size: 13px;
color: #888;
text-align: center;
}
.td-template-ai-tag {
position: absolute;
top: 8px;
right: 8px;
background: linear-gradient(90deg, #1a1a1a 80%, #bfa14a 100%);
color: #FFD700;
font-size: 13px;
/* font-weight: bold; */
padding: 2px 10px;
border-radius: 10px 10px 10px 0;
box-shadow: 0 2px 8px rgba(0,0,0,0.08);
letter-spacing: 1px;
z-index: 2;
}
.td-template-footer {
padding: 20px 32px;
text-align: right;
}
.td-template-btn {
padding: 10px 20px;
background-color: #409EFF;
color: #fff;
border: none;
border-radius: 6px;
cursor: pointer;
transition: background-color 0.2s;
}
.td-template-btn:hover {
background-color: #66b1ff;
}
.td-template-btn:disabled {
background-color: #d3d3d3;
cursor: not-allowed;
}
</style>
......@@ -62,5 +62,13 @@ export const itineraryService = {
*/
getItineraryDetail: (id) => {
return rwRequest.get('/travel/'+id);
},
/**
* 获取所有的模版
* @returns
*/
setTravelTemplateAsync:(id,tempId)=>{
return rwRequest.post(`/travel/${id}/td-asnyc/${tempId}`);
}
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment