Commit 7cd06d25 authored by 罗超's avatar 罗超

新增需求单

parent 5d7930b8
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
"mapbox-gl": "^2.15.0", "mapbox-gl": "^2.15.0",
"moment": "^2.24.0", "moment": "^2.24.0",
"os-browserify": "^0.3.0", "os-browserify": "^0.3.0",
"pako": "^2.1.0",
"particleground-light": "^1.0.6", "particleground-light": "^1.0.6",
"pdfjs-dist": "^2.16.105", "pdfjs-dist": "^2.16.105",
"pinyin": "^2.8.3", "pinyin": "^2.8.3",
......
...@@ -160,7 +160,8 @@ ...@@ -160,7 +160,8 @@
document.URL.indexOf("clientProtocol") == -1 && document.URL.indexOf("clientProtocol") == -1 &&
document.URL.indexOf("clientDisclaimerProtocol") == -1 && document.URL.indexOf("clientDisclaimerProtocol") == -1 &&
document.URL.indexOf("TravelContractConfirm") == -1 && document.URL.indexOf("TravelContractConfirm") == -1 &&
document.URL.indexOf("ViittoContractConfirm") == -1 document.URL.indexOf("ViittoContractConfirm") == -1 &&
document.URL.indexOf("/itinerary/detail") == -1
) { ) {
this.$router.push({ this.$router.push({
path: "/login" path: "/login"
...@@ -171,7 +172,8 @@ ...@@ -171,7 +172,8 @@
document.URL.indexOf("clientProtocol") != -1 || document.URL.indexOf("clientProtocol") != -1 ||
document.URL.indexOf("clientDisclaimerProtocol") != -1 || document.URL.indexOf("clientDisclaimerProtocol") != -1 ||
document.URL.indexOf("TravelContractConfirm") != -1 || document.URL.indexOf("TravelContractConfirm") != -1 ||
document.URL.indexOf("ViittoContractConfirm") != -1 document.URL.indexOf("ViittoContractConfirm") != -1 ||
document.URL.indexOf("/itinerary/detail") != -1
) { ) {
// 车系统改变 单页面方式 // 车系统改变 单页面方式
if(this.typeSystem==1) { if(this.typeSystem==1) {
...@@ -276,7 +278,9 @@ ...@@ -276,7 +278,9 @@
justify-content: center; justify-content: center;
z-index: 999999999999999; z-index: 999999999999999;
} }
.wide-autocomplete-popper {
width: unset !important;
}
.red-theme { .red-theme {
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto,
Helvetica Neue, Arial, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Helvetica Neue, Arial, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol,
......
<template>
<div v-if="visible" class="dify-session-wrapper">
<div v-if="isInitializing" class="init-loading">
<p>正在初始化会话,请稍等...</p>
</div>
<div v-else class="dify-session-dialog">
<el-button class="external-close-btn" icon="el-icon-close" circle @click="handleClose" />
<div v-loading="iframeLoading" class="iframe-wrapper">
<iframe v-if="showDifyIframe && difyUrl" :src="difyUrl"
:style="{ width: '100%', height: '100%' }" frameborder="0" allow="microphone"
@load="handleIframeLoad">
</iframe>
</div>
</div>
</div>
</template>
<script>
import { compressToBase64 } from '@/utils/compression';
import { API_CONFIG } from '@/config/api';
import { requirementService } from '@/services/requirement';
export default {
name: 'DifySession',
props: {
visible: {
type: Boolean,
default: false
},
userInfo: {
type: Object,
default: () => ({})
}
},
data() {
return {
isInitializing: false,
iframeLoading: true,
showDifyIframe: false,
difyBaseUrl: API_CONFIG.DIFY.BASE_URL,
conversationId: '',
difyUserId: '',
difyUrl: '',
iframeHeight: 600
};
},
watch: {
visible(val) {
if (val) {
this.initializeConversation();
} else {
this.resetSession();
}
}
},
mounted() {
if (this.visible) this.initializeConversation();
},
methods: {
async initSession(conversation_id) {
// 每次都是新会话
this.isInitializing = true;
this.iframeLoading = true;
this.showDifyIframe = false;
this.difyUserId = `${this.userInfo.EmployeeId || ''}-${this.userInfo.emName || ''}`;
this.conversationId = '';
try {
const compressedUserId = await compressToBase64(this.difyUserId);
const compressedConversationId = await compressToBase64(conversation_id);
this.difyUrl = `${this.difyBaseUrl}?sys.user_id=${encodeURIComponent(compressedUserId)}&sys.conversation_id=${encodeURIComponent(compressedConversationId)}&t=${Date.now()}`;
this.showDifyIframe = true;
} catch (e) {
this.$message.error('Dify会话初始化失败');
this.handleClose();
} finally {
this.isInitializing = false;
}
},
async initializeConversation() {
this.difyUserId = `${this.userInfo.EmployeeId}-${this.userInfo.emName}`;
this.isInitializing = true;
try {
const params = {
query: `你好`,
inputs: {},
response_mode: 'blocking',
user: this.difyUserId,
conversation_id: '',
auto_generate_name: true
};
const response = await requirementService.initializeConversation(params);
this.initSession(response.conversation_id)
} catch (error) {
this.$message.error(error.response?.data?.message || '初始化会话失败');
} finally {
}
},
handleIframeLoad() {
this.iframeLoading = false;
},
handleClose() {
this.$emit('close');
},
resetSession() {
this.showDifyIframe = false;
this.difyUrl = '';
this.iframeLoading = true;
this.isInitializing = false;
}
}
};
</script>
<style scoped>
.dify-session-wrapper {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background: rgba(0,0,0,0.4);
z-index: 3000;
display: flex;
align-items: center;
justify-content: center;
}
.dify-session-dialog {
background: #fff;
border-radius: 12px;
width: 900px;
height: 700px;
position: relative;
overflow: hidden;
display: flex;
flex-direction: column;
}
.external-close-btn {
position: absolute;
top: 16px;
right: 16px;
z-index: 10;
background: #f5f5f5;
border: none;
border-radius: 50%;
width: 32px;
height: 32px;
cursor: pointer;
padding: 9px;
}
.iframe-wrapper {
flex: 1;
min-height: 500px;
border-radius: 12px;
overflow: hidden;
}
.init-loading {
background: rgba(255, 255, 255, 0.9);
border-radius: 12px;
padding: 32px;
text-align: center;
box-shadow: 0 4px 24px rgba(0, 0, 0, 0.1);
}
</style>
export const API_CONFIG = {
DIFY: {
BASE_URL: 'http://dify.oytour.com/chatbot/VfHx89JgXTsz3kh1',
TIMEOUT: 600000 // 10分钟
}
};
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
<template>
<div class="info-card" :class="{ 'full-width': isFullWidth }">
<div class="card-title">{{ title }}</div>
<div v-for="(item, index) in items" :key="index" class="info-item">
<span class="label">{{ item.label }}</span>
<span class="value">{{ item.value || '-' }}</span>
</div>
</div>
</template>
<script>
export default {
name: 'InfoCard',
props: {
title: {
type: String,
required: true
},
items: {
type: Array,
required: true
},
isFullWidth: {
type: Boolean,
default: false
}
}
}
</script>
<style scoped>
.info-card {
background: #f8f9fa;
border-radius: 8px;
padding: 20px;
}
.info-card.full-width {
grid-column: span 2;
}
.card-title {
font-size: 16px;
font-weight: 500;
color: #1a1a1a;
margin-bottom: 16px;
padding-bottom: 12px;
border-bottom: 1px solid #eee;
}
.info-item {
display: flex;
align-items: flex-start;
margin-bottom: 12px;
}
.info-item:last-child {
margin-bottom: 0;
}
.info-item .label {
width: 80px;
color: #666;
font-size: 14px;
}
.info-item .value {
flex: 1;
color: #1a1a1a;
font-size: 14px;
word-break: break-all;
}
</style>
This diff is collapsed.
<template>
<el-dialog
:title="form.id ? '修改商机' : '新增商机'"
:visible.sync="visible"
width="900px"
:close-on-click-modal="false"
@close="handleClose">
<el-form ref="form" class="requirement-form" :model="form" :rules="rules" label-width="100px" size="small">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="客户信息" prop="customerInfo">
<el-input v-model="form.customerInfo" placeholder="请输入客户信息" :readonly="isReadonly"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="出发地" prop="departure">
<el-input v-model="form.departure" placeholder="请输入出发地" :readonly="isReadonly"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="目的地" prop="destination">
<el-input v-model="form.destination" placeholder="请输入目的地" :readonly="isReadonly"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="出发时间" prop="departureTime">
<el-input v-model="form.departureTime" placeholder="请填写出发时间" :readonly="isReadonly"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="出行人数" prop="travelers">
<el-input
v-model="form.travelers"
:min="1"
style="width: 100%;"
:disabled="isReadonly">
</el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="预算" prop="budget">
<el-input
v-model="form.budget"
:min="0"
:step="1000"
style="width: 100%;"
placeholder="请输入预算"
:disabled="isReadonly">
</el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="天数" prop="days">
<el-input
v-model="form.days"
:min="1"
style="width: 100%;"
:disabled="isReadonly">
</el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="主题" prop="theme">
<el-input v-model="form.theme" placeholder="请输入主题" :readonly="isReadonly"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="其他需求" prop="otherRequirements">
<el-input
type="textarea"
:rows="3"
v-model="form.otherRequirements"
placeholder="请输入其他需求"
:readonly="isReadonly">
</el-input>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="visible = false">{{ isReadonly ? '关 闭' : '取 消' }}</el-button>
<el-button type="primary" @click="handleSubmit" :loading="loading" v-if="!isReadonly">确 定</el-button>
</div>
</el-dialog>
</template>
<script>
import { requirementService } from '@/services/requirement'
export default {
name: 'RequirementForm',
props: {
value: {
type: Boolean,
default: false
},
states: {
type: Array,
default: () => []
},
editData: {
type: Object,
default: () => ({})
}
},
data() {
return {
visible: false,
loading: false,
departureTimeDate: '',
form: this.getInitialFormState(),
rules: {
customerInfo: [{ required: true, message: '请输入客户信息', trigger: 'blur' }],
departure: [{ required: true, message: '请输入出发地', trigger: 'blur' }],
destination: [{ required: true, message: '请输入目的地', trigger: 'blur' }],
departureTime: [{ required: true, message: '请选择出发时间', trigger: 'change' }],
travelers: [{ required: true, message: '请输入出行人数', trigger: 'blur' }],
budget: [{ required: true, message: '请输入预算', trigger: 'blur' }],
days: [{ required: true, message: '请输入天数', trigger: 'blur' }]
}
}
},
watch: {
value(val) {
this.visible = val;
},
visible(val) {
this.$emit('input', val);
},
editData: {
handler(val) {
if (val && val.id) {
this.form = JSON.parse(JSON.stringify(val));
this.departureTimeDate = this.form.departureTime;
} else {
this.resetForm();
}
},
immediate: true
}
},
computed: {
isReadonly() {
return this.editData.readonly === true;
}
},
methods: {
getInitialFormState() {
return {
customerInfo: '',
departure: '',
destination: '',
departureTime: '',
travelers: '1',
budget: '',
days: '1',
state: 0,
theme: '',
summary: '',
otherRequirements: '',
conversationId: '00000000-0000-0000-0000-000000000000'
};
},
resetForm() {
this.departureTimeDate = '';
this.form = this.getInitialFormState();
},
handleClose() {
this.$refs.form.resetFields();
this.resetForm();
this.visible = false;
this.$emit('close');
},
handleDateChange(val) {
this.form.departureTime = val || '';
},
generateSummary() {
const parts = [
this.form.customerInfo && `客户信息:${this.form.customerInfo}`,
this.form.theme && `主题:${this.form.theme}`,
`行程:${this.form.departure || '-'}${this.form.destination || '-'}`,
`出发时间:${this.form.departureTime || '-'}`,
`出行人数:${this.form.travelers || '-'}人`,
`天数:${this.form.days || '-'}天`,
`预算:${this.form.budget || '-'}元`,
this.form.otherRequirements && `其他需求:${this.form.otherRequirements}`
].filter(Boolean);
return parts.join('\n');
},
async handleSubmit() {
try {
const valid = await this.$refs.form.validate();
if (!valid) return;
this.loading = true;
this.form.summary = this.generateSummary();
if (this.form.id) {
await requirementService.updateRequirement(this.form);
this.$message.success('修改成功');
} else {
await requirementService.createRequirement(this.form);
this.$message.success('新增成功');
}
this.visible = false;
this.$emit('success');
} catch (error) {
console.error('提交需求失败:', error);
this.$message.error(error.response?.data?.message || '操作失败');
} finally {
this.loading = false;
}
}
}
}
</script>
<style scoped>
.requirement-form ::v-deep .el-input .el-input__inner {
height: 32px !important;
}
.requirement-form .el-form-item {
margin-bottom: 18px;
}
.dialog-footer {
text-align: right;
}
</style>
This diff is collapsed.
...@@ -126,7 +126,7 @@ export default { ...@@ -126,7 +126,7 @@ export default {
// domainUrl = "http://192.168.5.46:8501"; // domainUrl = "http://192.168.5.46:8501";
// domainUrl = "http://192.168.5.46"; // domainUrl = "http://192.168.5.46";
// domainUrl = "http://reborn.oytour.com"; // domainUrl = "http://reborn.oytour.com";
domainUrl = "http://192.168.5.214"; domainUrl = "http://reborn.oytour.com";
let crmLocalFileStreamDownLoadUrl = ""; let crmLocalFileStreamDownLoadUrl = "";
crmLocalFileStreamDownLoadUrl = locationName.indexOf('oytour') !== -1 ? "http://crm.oytour.com" : "http://testcrm.oytour.com"; crmLocalFileStreamDownLoadUrl = locationName.indexOf('oytour') !== -1 ? "http://crm.oytour.com" : "http://testcrm.oytour.com";
let javaUrldo = ""; let javaUrldo = "";
...@@ -192,9 +192,9 @@ export default { ...@@ -192,9 +192,9 @@ export default {
//google地图图片地址 //google地图图片地址
GoogleMapImageUrl: "http://imgfile.oytour.com", GoogleMapImageUrl: "http://imgfile.oytour.com",
//上传站点 //上传站点
UploadUrl: locationName.indexOf('oytour') !== -1 || locationName.indexOf('viitto') !== -1 ? "http://upload.oytour.com" : "http://192.168.5.46:8120", UploadUrl: locationName.indexOf('oytour') !== -1 || locationName.indexOf('viitto') !== -1 ? "http://upload.oytour.com" : "http://upload.oytour.com",
//文件站点 //文件站点
ViittoFileUrl: locationName.indexOf('oytour') !== -1 || locationName.indexOf('viitto') !== -1 ? "http://imgfile.oytour.com" : 'http://192.168.5.46:8130', ViittoFileUrl: locationName.indexOf('oytour') !== -1 || locationName.indexOf('viitto') !== -1 ? "http://imgfile.oytour.com" : 'http://imgfile.oytour.com',
javaUrl: locationName.indexOf('oytour') !== -1 || locationName.indexOf('viitto') !== -1 ? (locationName.indexOf('oytour') !== -1 ? "http://efficient.oytour.com" : "http://47.96.12.235:9001") : "http://192.168.10.123:9000", javaUrl: locationName.indexOf('oytour') !== -1 || locationName.indexOf('viitto') !== -1 ? (locationName.indexOf('oytour') !== -1 ? "http://efficient.oytour.com" : "http://47.96.12.235:9001") : "http://192.168.10.123:9000",
javaUrlNew: locationName.indexOf('oytour') !== -1 || locationName.indexOf('viitto') !== -1 ? (locationName.indexOf('oytour') !== -1 ? "http://property.oytour.com" : "http://47.96.12.235:9001") : "http://192.168.10.123:9000", javaUrlNew: locationName.indexOf('oytour') !== -1 || locationName.indexOf('viitto') !== -1 ? (locationName.indexOf('oytour') !== -1 ? "http://property.oytour.com" : "http://47.96.12.235:9001") : "http://192.168.10.123:9000",
//Java接口本站文件流下载地址 //Java接口本站文件流下载地址
...@@ -297,7 +297,8 @@ export default { ...@@ -297,7 +297,8 @@ export default {
this.$route.name.indexOf('confirmationOrderDownLoadNew') === -1 && this.$route.name.indexOf('PrintPage') === -1 && this.$route.name.indexOf('confirmationOrderDownLoadNew') === -1 && this.$route.name.indexOf('PrintPage') === -1 &&
this.$route.name.indexOf('TravelContractConfirm') === -1 && this.$route.name.indexOf('ViittoContractConfirm') === -1 && this.$route.name.indexOf('TravelContractConfirm') === -1 && this.$route.name.indexOf('ViittoContractConfirm') === -1 &&
this.$route.name.indexOf('OrderProfitLossList') === -1 && this.$route.name.indexOf('clientProtocol') === -1 && this.$route.name.indexOf('OrderProfitLossList') === -1 && this.$route.name.indexOf('clientProtocol') === -1 &&
this.$route.name.indexOf('clientDisclaimerProtocol') === -1 && this.$route.name.indexOf('guestLogin') === -1 this.$route.name.indexOf('clientDisclaimerProtocol') === -1 && this.$route.name.indexOf('guestLogin') === -1 &&
this.$route.name.indexOf('itineraryDetail') === -1
) { ) {
let previousPathInfo = { let previousPathInfo = {
path: this.$route.name, path: this.$route.name,
...@@ -320,6 +321,12 @@ export default { ...@@ -320,6 +321,12 @@ export default {
path: '/signature' path: '/signature'
}) })
} }
console.log(this.$route.path.toLowerCase())
if (this.$route.path.toLowerCase().includes('/itinerary/detail')) {
this.$router.push({
path: '/itinerary/detail/' + this.$route.params.id
})
}
if (this.$route.path.toLowerCase() == "/signname") { if (this.$route.path.toLowerCase() == "/signname") {
this.$router.push({ this.$router.push({
path: '/signname' path: '/signname'
......
// utils/request.js
import axios from 'axios';
// 创建 axios 实例
const service = axios.create({
baseURL: process.env.NODE_ENV === 'production'?'http://rw.oytour.com/api/app':'http://rw.oytour.com/api/app',//'http://localhost:19001/api/app', // 通用前缀
timeout: 10000
});
// 请求拦截器:自动加 token
service.interceptors.request.use(
config => {
const userInfoStr = localStorage.getItem('userInfo');
if (userInfoStr) {
const userInfo = JSON.parse(userInfoStr);
//userInfo.token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE3NDk0MzQzNDAuMCwiZXhwIjoxNzQ5NjkzNTQwLjAsInVzZXJJbmZvIjp7InVpZCI6IjE2MjMiLCJncm91cElkIjoyLCJyZXF1ZXN0RnJvbSI6MSwiZXhwaXJlVGltZSI6bnVsbCwidXNlck5hbWUiOiLnvZfotoUifX0.fXPjR4mp8aoMj-mlwYNAypAi7ktzGfxwphK1FJZAttg';
config.headers['Authorization'] = `Bearer ${userInfo.token}`;
}
config.headers['Accept'] = 'application/json';
return config;
},
error => {
return Promise.reject(error);
}
);
// 响应拦截器(可选)
service.interceptors.response.use(
response => response.data,
error => {
console.error('请求出错:', error);
return Promise.reject(error);
}
);
// 封装方法
const request = {
get(url, params = {}, config = {}) {
return service.get(url, { params, ...config });
},
post(url, data = {}, config = {}) {
return service.post(url, data, config);
},
put(url, data = {}, config = {}) {
return service.put(url, data, config);
},
delete(url, config = {}) {
return service.delete(url, config);
}
};
export default request;
...@@ -219,7 +219,7 @@ export default { ...@@ -219,7 +219,7 @@ export default {
}, },
}, },
{ {
path: '/scmAccountManagement', //供应商账号管理 path: '/scmAccountManagement', //供应商账号管理
name: 'scmAccountManagement', name: 'scmAccountManagement',
...@@ -1561,7 +1561,7 @@ export default { ...@@ -1561,7 +1561,7 @@ export default {
meta: { meta: {
title: '餐厅套餐查询' title: '餐厅套餐查询'
}, },
}, },
{ {
path: '/HotelRankingDetails', //酒店排行详情 path: '/HotelRankingDetails', //酒店排行详情
name: 'HotelRankingDetails', name: 'HotelRankingDetails',
...@@ -2200,14 +2200,14 @@ export default { ...@@ -2200,14 +2200,14 @@ export default {
title: '日本车行预订统计表' title: '日本车行预订统计表'
}, },
}, },
{ // {
path: '/HPTripPlan', //和平用车 // path: '/HPTripPlan', //和平用车
name: 'HPTripPlan', // name: 'HPTripPlan',
component: resolve => require(['@/components/busManagement/HPTripPlan'], resolve), // component: resolve => require(['@/components/busManagement/HPTripPlan'], resolve),
meta: { // meta: {
title: '日本车行预订统计表' // title: '日本车行预订统计表'
}, // },
}, // },
{ {
path: '/JapanBusMonthFStatistics', //用車單統計(財務單據) path: '/JapanBusMonthFStatistics', //用車單統計(財務單據)
name: 'JapanBusMonthFStatistics', name: 'JapanBusMonthFStatistics',
...@@ -3221,7 +3221,7 @@ export default { ...@@ -3221,7 +3221,7 @@ export default {
title: '报价单' title: '报价单'
}, },
}, },
{ // 销售 任务管理 { // 销售 任务管理
path: '/saleTaskManagement', path: '/saleTaskManagement',
name: 'saleTaskManagement', name: 'saleTaskManagement',
...@@ -6405,13 +6405,22 @@ export default { ...@@ -6405,13 +6405,22 @@ export default {
}, },
}, },
{ {
path: '/data_count', //维护教育视频 path: '/data_count',
name: 'data_count', name: 'data_count',
component: resolve => require(['@/components/rank/dataCount'], resolve), component: resolve => require(['@/components/rank/dataCount'], resolve),
meta: { meta: {
title: '客户运营数据统计' title: '客户运营数据统计'
}, },
}, },
{
path: '/requirements',
name: 'requirements',
component: resolve => require(['@/pages/requirements/index'], resolve),
meta: {
title: '商机管理'
},
},
] ]
}, },
{ {
...@@ -6703,7 +6712,22 @@ export default { ...@@ -6703,7 +6712,22 @@ export default {
meta: { meta: {
title: '财务批量打印页面' title: '财务批量打印页面'
}, },
} },
{
path: '/itinerary/detail/:id',
name: 'itineraryDetail',
component: resolve => require(['@/pages/itinerary/ItineraryDetail'], resolve),
meta: {
title: '商机管理'
},
},
{
path: '/itinerary/edit/:id?',
name: 'itineraryEdit',
component: resolve => require(['@/pages/itinerary/ItineraryEdit'], resolve),
meta: {
title: '编辑行程'
}
},
] ]
} }
import rwRequest from '@/plug/rwRequest';
export const itineraryService = {
/**
* 获取行程详情
* @param {string} id - 行程ID
* @returns {Promise} - API 响应
*/
getItineraryDetail: (id) => {
return rwRequest.get(`/itinerary/${id}`);
},
/**
* 创建行程
* @param {Object} data - 行程数据
* @returns {Promise} - API 响应
*/
createItinerary: (data) => {
return rwRequest.post('/travel', data);
},
/**
* 删除行程
* @param {string} id - 行程ID
* @returns {Promise} - API 响应
*/
deleteItinerary: (id) => {
return rwRequest.delete('/travel/'+id);
},
/**
* 更新行程
* @param {Object} data - 行程数据
* @returns {Promise} - API 响应
*/
updateItinerary: (data) => {
return rwRequest.put('/travel', data);
},
/**
* 获取行程列表
* @param {Object} params - 查询参数
* @returns {Promise} - API 响应
*/
getItineraryList: (params) => {
return rwRequest.get('/itinerary/list', { params });
},
/**
* 获取行程详情
* @param {string} id - 行程ID
* @returns {Promise} - API 响应
*/
getItineraryDetail: (id) => {
return rwRequest.get('/travel/'+id);
}
};
import rwRequest from '@/plug/rwRequest';
import { API_CONFIG } from '@/config/api';
export const requirementService = {
/**
* 初始化对话
* @param {Object} params - 请求参数
* @returns {Promise} - API 响应
*/
initializeConversation: (params) => {
return rwRequest.post('/dify/travelAI/chat-message', params, {
timeout: API_CONFIG.DIFY.TIMEOUT
});
},
/**
* 更新需求信息
* @param {Object} data - 需求数据
* @returns {Promise} - API 响应
*/
updateRequirement: (data) => {
return rwRequest.put('/requirement/requirements', data);
},
/**
* 创建新需求
* @param {Object} data - 需求数据
* @returns {Promise} - API 响应
*/
createRequirement: (data) => {
return rwRequest.post('/requirement/create-requirement', data);
},
/**
* 获取需求详情
* @param {string} id - 需求ID
* @returns {Promise} - API 响应
*/
getRequirementDetail: (id) => {
return rwRequest.get(`/requirement-query/${id}`);
},
/**
* 更新需求状态
* @param {Object} data - 包含id和state的对象
* @returns {Promise} - API 响应
*/
updateRequirementState: (data) => {
return rwRequest.put('/requirement/require-state', data);
},
/**
* 获取需求状态列表
* @returns {Promise} - API 响应
*/
getRequirementStates: () => {
return rwRequest.get('/requirement/requirement-states');
},
/**
* 获取分页需求列表
* @param {Object} params - 查询参数
* @returns {Promise} - API 响应
*/
getPagedRequirements: (params) => {
const queryParams = { ...params };
if (queryParams.state === -9) {
queryParams.state = null;
}
return rwRequest.get('/requirement/paged', queryParams);
}
};
import pako from 'pako';
/**
* 使用 gzip 压缩字符串并转换为 base64 格式
* @param {string} str - 要压缩的字符串
* @returns {string} - 压缩后的 base64 字符串
*/
export const compressToBase64 = (str) => {
const binaryData = pako.gzip(str);
return btoa(String.fromCharCode(...binaryData));
};
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