预约规则.
This commit is contained in:
parent
f4a2826bb8
commit
8529fd1575
|
|
@ -256,6 +256,48 @@
|
|||
</el-form>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="预约登记规则" name="booking_rules">
|
||||
<div class="booking-rules-container">
|
||||
<el-alert
|
||||
title="为每个预约表单页面配置登记规则,规则将显示在小程序预约页面顶部"
|
||||
type="info"
|
||||
:closable="false"
|
||||
style="margin-bottom: 20px;" />
|
||||
|
||||
<el-collapse v-model="activeBookingRules">
|
||||
<el-collapse-item
|
||||
v-for="item in serviceTypeOptions"
|
||||
:key="item.value"
|
||||
:name="item.value"
|
||||
:title="item.label">
|
||||
<el-form label-width="100px">
|
||||
<el-form-item label="规则说明">
|
||||
<el-input
|
||||
v-model="bookingRulesConfig[item.value]"
|
||||
type="textarea"
|
||||
:rows="6"
|
||||
:placeholder="`请输入${item.label}的预约登记规则`"
|
||||
maxlength="2000"
|
||||
show-word-limit />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" size="small" @click="saveBookingRule(item.value)" :loading="savingRule === item.value">
|
||||
保存此规则
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-collapse-item>
|
||||
</el-collapse>
|
||||
|
||||
<div style="margin-top: 20px;">
|
||||
<el-button type="primary" @click="saveAllBookingRules" :loading="saving">
|
||||
<el-icon><Check /></el-icon>
|
||||
保存全部规则
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
|
||||
</el-tabs>
|
||||
</el-card>
|
||||
|
||||
|
|
@ -281,6 +323,31 @@ const contactFormRef = ref(null)
|
|||
const agreementFormRef = ref(null)
|
||||
const inviteFormRef = ref(null)
|
||||
|
||||
// 预约登记规则相关
|
||||
const activeBookingRules = ref([])
|
||||
const savingRule = ref('')
|
||||
const bookingRulesConfig = ref({})
|
||||
|
||||
// 服务类型选项
|
||||
const serviceTypeOptions = [
|
||||
{ value: 'flight', label: '全球机票代理' },
|
||||
{ value: 'hotel', label: '全球酒店预定' },
|
||||
{ value: 'lounge', label: '全球机场贵宾室服务' },
|
||||
{ value: 'airport_transfer', label: '机场接/送机服务' },
|
||||
{ value: 'unaccompanied_minor', label: '无成人陪伴儿童代办' },
|
||||
{ value: 'train', label: '高铁票代订' },
|
||||
{ value: 'telemedicine', label: '远程医疗问诊代理服务' },
|
||||
{ value: 'special_passenger', label: '特殊(特护)旅客定制服务代办' },
|
||||
{ value: 'pet_transport', label: '宠物托运代理' },
|
||||
{ value: 'guide_translation', label: '西班牙语专业导游/翻译服务' },
|
||||
{ value: 'visa', label: '签证咨询' },
|
||||
{ value: 'exhibition', label: '墨西哥展会咨询与协办服务' },
|
||||
{ value: 'air_logistics', label: '跨境航空物流/快递一站式服务' },
|
||||
{ value: 'sea_freight', label: '海运/清关一站式服务' },
|
||||
{ value: 'travel_planning', label: '旅游线路规划/咨询' },
|
||||
{ value: 'insurance', label: '跨境出行意外保险/国际财产保险咨询' }
|
||||
]
|
||||
|
||||
// Original configs for reset
|
||||
const originalConfigs = reactive({
|
||||
appearance: {},
|
||||
|
|
@ -431,6 +498,9 @@ const loadConfigs = async () => {
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 加载预约规则(使用独立接口)
|
||||
await loadBookingRules()
|
||||
} catch (error) {
|
||||
console.error('Load configs error:', error)
|
||||
ElMessage.error('加载配置失败')
|
||||
|
|
@ -445,6 +515,21 @@ const refreshConfigs = async () => {
|
|||
ElMessage.success('配置已刷新')
|
||||
}
|
||||
|
||||
// 加载预约规则
|
||||
const loadBookingRules = async () => {
|
||||
try {
|
||||
const response = await api.get('/api/v1/admin/booking-rules')
|
||||
if (response.data.code === 0) {
|
||||
const rules = response.data.data || []
|
||||
rules.forEach(rule => {
|
||||
bookingRulesConfig.value[rule.serviceType] = rule.rules || ''
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Load booking rules error:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// Save appearance config
|
||||
const saveAppearanceConfig = async () => {
|
||||
if (!appearanceFormRef.value) return
|
||||
|
|
@ -629,6 +714,40 @@ const resetInviteConfig = () => {
|
|||
inviteFormRef.value?.clearValidate()
|
||||
}
|
||||
|
||||
// 保存单个预约规则
|
||||
const saveBookingRule = async (serviceType) => {
|
||||
savingRule.value = serviceType
|
||||
try {
|
||||
await api.put(`/api/v1/admin/booking-rules/${serviceType}`, {
|
||||
rules: bookingRulesConfig.value[serviceType] || ''
|
||||
})
|
||||
ElMessage.success('规则保存成功')
|
||||
} catch (error) {
|
||||
console.error('Save booking rule error:', error)
|
||||
ElMessage.error(error.response?.data?.message || '保存规则失败')
|
||||
} finally {
|
||||
savingRule.value = ''
|
||||
}
|
||||
}
|
||||
|
||||
// 保存全部预约规则
|
||||
const saveAllBookingRules = async () => {
|
||||
saving.value = true
|
||||
try {
|
||||
const rules = serviceTypeOptions.map(item => ({
|
||||
serviceType: item.value,
|
||||
rules: bookingRulesConfig.value[item.value] || ''
|
||||
}))
|
||||
await api.post('/api/v1/admin/booking-rules/batch', { rules })
|
||||
ElMessage.success('全部规则保存成功')
|
||||
} catch (error) {
|
||||
console.error('Save all booking rules error:', error)
|
||||
ElMessage.error(error.response?.data?.message || '保存规则失败')
|
||||
} finally {
|
||||
saving.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// Clear images
|
||||
const clearLogo = async () => {
|
||||
try {
|
||||
|
|
@ -741,6 +860,8 @@ const handleTabChange = (tabName) => {
|
|||
contactFormRef.value?.clearValidate()
|
||||
} else if (tabName === 'agreement') {
|
||||
agreementFormRef.value?.clearValidate()
|
||||
} else if (tabName === 'booking_rules') {
|
||||
// 预约登记规则tab不需要清除验证
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -176,33 +176,6 @@
|
|||
<el-input v-model="form.titlePt" placeholder="Por favor, insira o título em português" />
|
||||
</el-form-item>
|
||||
|
||||
<el-divider content-position="left">多语言描述</el-divider>
|
||||
|
||||
<el-form-item label="中文描述" prop="descriptionZh">
|
||||
<el-input
|
||||
v-model="form.descriptionZh"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="请输入中文描述"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="英文描述" prop="descriptionEn">
|
||||
<el-input
|
||||
v-model="form.descriptionEn"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="Please enter English description"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="葡语描述" prop="descriptionPt">
|
||||
<el-input
|
||||
v-model="form.descriptionPt"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="Por favor, insira a descrição em português"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-divider content-position="left">其他信息</el-divider>
|
||||
|
||||
<el-form-item label="服务图片" prop="image">
|
||||
|
|
@ -313,9 +286,6 @@ const defaultForm = {
|
|||
titleZh: '',
|
||||
titleEn: '',
|
||||
titlePt: '',
|
||||
descriptionZh: '',
|
||||
descriptionEn: '',
|
||||
descriptionPt: '',
|
||||
image: '',
|
||||
sortOrder: 0,
|
||||
status: 'active'
|
||||
|
|
@ -439,9 +409,6 @@ function handleEdit(row) {
|
|||
titleZh: row.titleZh,
|
||||
titleEn: row.titleEn,
|
||||
titlePt: row.titlePt,
|
||||
descriptionZh: row.descriptionZh || '',
|
||||
descriptionEn: row.descriptionEn || '',
|
||||
descriptionPt: row.descriptionPt || '',
|
||||
image: row.image || '',
|
||||
sortOrder: row.sortOrder || 0,
|
||||
status: row.status
|
||||
|
|
@ -491,9 +458,6 @@ async function handleSubmit() {
|
|||
try {
|
||||
const data = { ...form }
|
||||
// Convert empty strings to null for optional fields
|
||||
if (!data.descriptionZh) data.descriptionZh = null
|
||||
if (!data.descriptionEn) data.descriptionEn = null
|
||||
if (!data.descriptionPt) data.descriptionPt = null
|
||||
if (!data.image) data.image = null
|
||||
if (data.price === null || data.price === '') data.price = null
|
||||
|
||||
|
|
|
|||
|
|
@ -130,6 +130,9 @@ const createApp = () => {
|
|||
const homeRoutes = require('./routes/homeRoutes');
|
||||
app.use('/api/v1/home', homeRoutes);
|
||||
|
||||
const bookingRuleRoutes = require('./routes/bookingRuleRoutes');
|
||||
app.use('/api/v1/booking-rules', bookingRuleRoutes);
|
||||
|
||||
const adminConfigRoutes = require('./routes/adminConfigRoutes');
|
||||
app.use('/api/v1/admin/config', adminConfigRoutes);
|
||||
|
||||
|
|
@ -148,6 +151,9 @@ const createApp = () => {
|
|||
const adminCommissionRoutes = require('./routes/adminCommissionRoutes');
|
||||
app.use('/api/v1/admin/commissions', adminCommissionRoutes);
|
||||
|
||||
const adminBookingRuleRoutes = require('./routes/adminBookingRuleRoutes');
|
||||
app.use('/api/v1/admin/booking-rules', adminBookingRuleRoutes);
|
||||
|
||||
// 404 handler
|
||||
app.use(notFoundHandler);
|
||||
|
||||
|
|
|
|||
166
backend/src/controllers/adminBookingRuleController.js
Normal file
166
backend/src/controllers/adminBookingRuleController.js
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
const { BookingRule } = require('../models');
|
||||
|
||||
/**
|
||||
* 获取所有预约规则
|
||||
*/
|
||||
const getAllRules = async (req, res) => {
|
||||
try {
|
||||
const rules = await BookingRule.findAll({
|
||||
order: [['createdAt', 'ASC']]
|
||||
});
|
||||
|
||||
res.json({
|
||||
code: 0,
|
||||
message: 'success',
|
||||
data: rules
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Get all booking rules error:', error);
|
||||
res.status(500).json({
|
||||
code: 500,
|
||||
message: '获取预约规则失败',
|
||||
data: null
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 根据服务类型获取规则
|
||||
*/
|
||||
const getRuleByServiceType = async (req, res) => {
|
||||
try {
|
||||
const { serviceType } = req.params;
|
||||
|
||||
const rule = await BookingRule.findOne({
|
||||
where: { serviceType }
|
||||
});
|
||||
|
||||
res.json({
|
||||
code: 0,
|
||||
message: 'success',
|
||||
data: rule
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Get booking rule error:', error);
|
||||
res.status(500).json({
|
||||
code: 500,
|
||||
message: '获取预约规则失败',
|
||||
data: null
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 创建或更新预约规则
|
||||
*/
|
||||
const upsertRule = async (req, res) => {
|
||||
try {
|
||||
const { serviceType } = req.params;
|
||||
const { rules, status } = req.body;
|
||||
|
||||
const [rule, created] = await BookingRule.upsert({
|
||||
serviceType,
|
||||
rules: rules || '',
|
||||
status: status || 'active'
|
||||
}, {
|
||||
returning: true
|
||||
});
|
||||
|
||||
res.json({
|
||||
code: 0,
|
||||
message: created ? '创建成功' : '更新成功',
|
||||
data: rule
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Upsert booking rule error:', error);
|
||||
res.status(500).json({
|
||||
code: 500,
|
||||
message: '保存预约规则失败',
|
||||
data: null
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 批量更新预约规则
|
||||
*/
|
||||
const batchUpsertRules = async (req, res) => {
|
||||
try {
|
||||
const { rules } = req.body; // [{ serviceType, rules, status }]
|
||||
|
||||
if (!Array.isArray(rules)) {
|
||||
return res.status(400).json({
|
||||
code: 400,
|
||||
message: '参数格式错误',
|
||||
data: null
|
||||
});
|
||||
}
|
||||
|
||||
const results = [];
|
||||
for (const item of rules) {
|
||||
const [rule] = await BookingRule.upsert({
|
||||
serviceType: item.serviceType,
|
||||
rules: item.rules || '',
|
||||
status: item.status || 'active'
|
||||
}, {
|
||||
returning: true
|
||||
});
|
||||
results.push(rule);
|
||||
}
|
||||
|
||||
res.json({
|
||||
code: 0,
|
||||
message: '批量保存成功',
|
||||
data: results
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Batch upsert booking rules error:', error);
|
||||
res.status(500).json({
|
||||
code: 500,
|
||||
message: '批量保存预约规则失败',
|
||||
data: null
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除预约规则
|
||||
*/
|
||||
const deleteRule = async (req, res) => {
|
||||
try {
|
||||
const { serviceType } = req.params;
|
||||
|
||||
const deleted = await BookingRule.destroy({
|
||||
where: { serviceType }
|
||||
});
|
||||
|
||||
if (deleted) {
|
||||
res.json({
|
||||
code: 0,
|
||||
message: '删除成功',
|
||||
data: null
|
||||
});
|
||||
} else {
|
||||
res.status(404).json({
|
||||
code: 404,
|
||||
message: '规则不存在',
|
||||
data: null
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Delete booking rule error:', error);
|
||||
res.status(500).json({
|
||||
code: 500,
|
||||
message: '删除预约规则失败',
|
||||
data: null
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
getAllRules,
|
||||
getRuleByServiceType,
|
||||
upsertRule,
|
||||
batchUpsertRules,
|
||||
deleteRule
|
||||
};
|
||||
35
backend/src/controllers/bookingRuleController.js
Normal file
35
backend/src/controllers/bookingRuleController.js
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
const { BookingRule } = require('../models');
|
||||
|
||||
/**
|
||||
* 根据服务类型获取预约规则(公开接口)
|
||||
*/
|
||||
const getRuleByServiceType = async (req, res) => {
|
||||
try {
|
||||
const { serviceType } = req.params;
|
||||
|
||||
const rule = await BookingRule.findOne({
|
||||
where: {
|
||||
serviceType,
|
||||
status: 'active'
|
||||
},
|
||||
attributes: ['serviceType', 'rules']
|
||||
});
|
||||
|
||||
res.json({
|
||||
code: 0,
|
||||
message: 'success',
|
||||
data: rule ? { rules: rule.rules } : { rules: '' }
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Get booking rule error:', error);
|
||||
res.status(500).json({
|
||||
code: 500,
|
||||
message: '获取预约规则失败',
|
||||
data: null
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
getRuleByServiceType
|
||||
};
|
||||
42
backend/src/models/BookingRule.js
Normal file
42
backend/src/models/BookingRule.js
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
const { DataTypes } = require('sequelize');
|
||||
const { sequelize } = require('../config/database');
|
||||
|
||||
/**
|
||||
* BookingRule Model
|
||||
* 预约登记规则配置,每个服务类型单独配置
|
||||
*/
|
||||
const BookingRule = sequelize.define('BookingRule', {
|
||||
id: {
|
||||
type: DataTypes.UUID,
|
||||
defaultValue: DataTypes.UUIDV4,
|
||||
primaryKey: true,
|
||||
},
|
||||
serviceType: {
|
||||
type: DataTypes.STRING(50),
|
||||
allowNull: false,
|
||||
unique: true,
|
||||
field: 'service_type',
|
||||
comment: '服务类型标识',
|
||||
},
|
||||
rules: {
|
||||
type: DataTypes.TEXT,
|
||||
allowNull: true,
|
||||
comment: '预约登记规则内容',
|
||||
},
|
||||
status: {
|
||||
type: DataTypes.ENUM('active', 'inactive'),
|
||||
defaultValue: 'active',
|
||||
allowNull: false,
|
||||
comment: '状态',
|
||||
},
|
||||
}, {
|
||||
tableName: 'booking_rules',
|
||||
timestamps: true,
|
||||
underscored: true,
|
||||
indexes: [
|
||||
{ fields: ['service_type'], unique: true },
|
||||
{ fields: ['status'] },
|
||||
],
|
||||
});
|
||||
|
||||
module.exports = BookingRule;
|
||||
|
|
@ -13,6 +13,7 @@ const Config = require('./Config');
|
|||
const HotService = require('./HotService');
|
||||
const PaymentOrder = require('./PaymentOrder');
|
||||
const Commission = require('./Commission');
|
||||
const BookingRule = require('./BookingRule');
|
||||
|
||||
/**
|
||||
* Define model associations
|
||||
|
|
@ -102,5 +103,6 @@ module.exports = {
|
|||
HotService,
|
||||
PaymentOrder,
|
||||
Commission,
|
||||
BookingRule,
|
||||
syncDatabase,
|
||||
};
|
||||
|
|
|
|||
46
backend/src/routes/adminBookingRuleRoutes.js
Normal file
46
backend/src/routes/adminBookingRuleRoutes.js
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
const express = require('express');
|
||||
const adminBookingRuleController = require('../controllers/adminBookingRuleController');
|
||||
const { authenticateAdmin } = require('../middleware/auth');
|
||||
const { requireAdmin } = require('../middleware/rbac');
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
// Apply authentication middleware
|
||||
router.use(authenticateAdmin);
|
||||
|
||||
/**
|
||||
* @route GET /api/v1/admin/booking-rules
|
||||
* @desc 获取所有预约规则
|
||||
* @access Private (Admin)
|
||||
*/
|
||||
router.get('/', requireAdmin, adminBookingRuleController.getAllRules);
|
||||
|
||||
/**
|
||||
* @route GET /api/v1/admin/booking-rules/:serviceType
|
||||
* @desc 根据服务类型获取规则
|
||||
* @access Private (Admin)
|
||||
*/
|
||||
router.get('/:serviceType', requireAdmin, adminBookingRuleController.getRuleByServiceType);
|
||||
|
||||
/**
|
||||
* @route PUT /api/v1/admin/booking-rules/:serviceType
|
||||
* @desc 创建或更新预约规则
|
||||
* @access Private (Admin)
|
||||
*/
|
||||
router.put('/:serviceType', requireAdmin, adminBookingRuleController.upsertRule);
|
||||
|
||||
/**
|
||||
* @route POST /api/v1/admin/booking-rules/batch
|
||||
* @desc 批量更新预约规则
|
||||
* @access Private (Admin)
|
||||
*/
|
||||
router.post('/batch', requireAdmin, adminBookingRuleController.batchUpsertRules);
|
||||
|
||||
/**
|
||||
* @route DELETE /api/v1/admin/booking-rules/:serviceType
|
||||
* @desc 删除预约规则
|
||||
* @access Private (Admin)
|
||||
*/
|
||||
router.delete('/:serviceType', requireAdmin, adminBookingRuleController.deleteRule);
|
||||
|
||||
module.exports = router;
|
||||
13
backend/src/routes/bookingRuleRoutes.js
Normal file
13
backend/src/routes/bookingRuleRoutes.js
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
const express = require('express');
|
||||
const bookingRuleController = require('../controllers/bookingRuleController');
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
/**
|
||||
* @route GET /api/v1/booking-rules/:serviceType
|
||||
* @desc 根据服务类型获取预约规则(公开接口)
|
||||
* @access Public
|
||||
*/
|
||||
router.get('/:serviceType', bookingRuleController.getRuleByServiceType);
|
||||
|
||||
module.exports = router;
|
||||
31
miniprogram/src/mixins/bookingRulesMixin.js
Normal file
31
miniprogram/src/mixins/bookingRulesMixin.js
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
/**
|
||||
* 预约登记规则混入
|
||||
* 用于在预约表单页面加载和显示预约规则
|
||||
*/
|
||||
import { AppServer } from '@/modules/api/AppServer.js'
|
||||
|
||||
const appServer = new AppServer()
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
bookingRules: '' // 预约登记规则
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 加载预约登记规则
|
||||
* @param {String} serviceType - 服务类型
|
||||
*/
|
||||
async loadBookingRules(serviceType) {
|
||||
try {
|
||||
const result = await appServer.GetBookingRule(serviceType)
|
||||
if (result.code === 0 && result.data && result.data.rules) {
|
||||
this.bookingRules = result.data.rules
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载预约规则失败:', error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -66,6 +66,9 @@ serverConfig.apiUrl_Upload_Image = baseUrl + '/api/v1/upload/image' // 上传图
|
|||
// ==================== 小程序码相关接口 ====================
|
||||
serverConfig.apiUrl_QRCode_GetMiniProgram = baseUrl + '/api/v1/qrcode/miniprogram' // 获取小程序码
|
||||
|
||||
// ==================== 预约规则相关接口 ====================
|
||||
serverConfig.apiUrl_BookingRule_Get = baseUrl + '/api/v1/booking-rules' // 获取预约规则
|
||||
|
||||
|
||||
/**
|
||||
* 获取完整的application/x-www-form-urlencoded请求参数
|
||||
|
|
@ -610,6 +613,17 @@ AppServer.prototype.GetMiniProgramQRCode = async function(params = {}) {
|
|||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取预约登记规则
|
||||
* @param {String} serviceType - 服务类型
|
||||
*/
|
||||
AppServer.prototype.GetBookingRule = async function(serviceType) {
|
||||
var url = serverConfig.apiUrl_BookingRule_Get + '/' + serviceType
|
||||
return this.getData(url).then((data) => {
|
||||
return data;
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传图片
|
||||
* @param {String} filePath - 本地文件路径
|
||||
|
|
|
|||
|
|
@ -12,7 +12,12 @@
|
|||
<!-- 可滚动内容区域 -->
|
||||
<view class="scroll-content">
|
||||
<view class="content">
|
||||
<view class=""
|
||||
<!-- 预约登记规则区域 -->
|
||||
<view class="booking-rules-box" v-if="bookingRules">
|
||||
<view class="rules-title">预约登记规则</view>
|
||||
<view class="rules-content">{{ bookingRules }}</view>
|
||||
</view>
|
||||
<view v-else class=""
|
||||
style="width: 680rpx; height: 396rpx; background-image: linear-gradient(-45deg, #60D7FF, #68BBD7); margin-top: 32rpx; border-radius: 20rpx; box-shadow: 0 0 10rpx 10rpx rgba(0, 0, 0, 0.1);">
|
||||
</view>
|
||||
|
||||
|
|
@ -238,9 +243,11 @@
|
|||
|
||||
<script>
|
||||
import { AppServer } from '@/modules/api/AppServer.js'
|
||||
import bookingRulesMixin from '@/mixins/bookingRulesMixin.js'
|
||||
const appServer = new AppServer()
|
||||
|
||||
export default {
|
||||
mixins: [bookingRulesMixin],
|
||||
data() {
|
||||
return {
|
||||
serviceId: "", // 服务ID(来自分类页)
|
||||
|
|
@ -326,6 +333,8 @@
|
|||
if (options.title) {
|
||||
this.serviceTitle = decodeURIComponent(options.title)
|
||||
}
|
||||
// 加载预约规则
|
||||
this.loadBookingRules('flight')
|
||||
},
|
||||
methods: {
|
||||
initDateRange() {
|
||||
|
|
@ -707,4 +716,29 @@
|
|||
min-width: 80rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* 预约登记规则样式 */
|
||||
.booking-rules-box {
|
||||
width: 680rpx;
|
||||
margin-top: 32rpx;
|
||||
padding: 30rpx;
|
||||
background-image: linear-gradient(-45deg, #60D7FF, #68BBD7);
|
||||
border-radius: 20rpx;
|
||||
box-shadow: 0 0 10rpx 10rpx rgba(0, 0, 0, 0.1);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.rules-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.rules-content {
|
||||
font-size: 26rpx;
|
||||
color: #fff;
|
||||
line-height: 1.6;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -12,7 +12,12 @@
|
|||
<!-- 可滚动内容区域 -->
|
||||
<view class="scroll-content">
|
||||
<view class="content">
|
||||
<view class=""
|
||||
<!-- 预约登记规则区域 -->
|
||||
<view class="booking-rules-box" v-if="bookingRules">
|
||||
<view class="rules-title">预约登记规则</view>
|
||||
<view class="rules-content">{{ bookingRules }}</view>
|
||||
</view>
|
||||
<view v-else class=""
|
||||
style="width: 680rpx; height: 396rpx; background-image: linear-gradient(-45deg, #60D7FF, #68BBD7); margin-top: 32rpx; border-radius: 20rpx; box-shadow: 0 0 10rpx 10rpx rgba(0, 0, 0, 0.1);">
|
||||
</view>
|
||||
|
||||
|
|
@ -209,9 +214,11 @@
|
|||
|
||||
<script>
|
||||
import { AppServer } from '@/modules/api/AppServer.js'
|
||||
import bookingRulesMixin from '@/mixins/bookingRulesMixin.js'
|
||||
const appServer = new AppServer()
|
||||
|
||||
export default {
|
||||
mixins: [bookingRulesMixin],
|
||||
data() {
|
||||
return {
|
||||
serviceId: "",
|
||||
|
|
@ -320,6 +327,8 @@
|
|||
if (options.title) {
|
||||
this.serviceTitle = decodeURIComponent(options.title)
|
||||
}
|
||||
// 加载预约规则
|
||||
this.loadBookingRules('hotel')
|
||||
},
|
||||
methods: {
|
||||
initDateRange() {
|
||||
|
|
@ -686,4 +695,29 @@
|
|||
min-width: 80rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* 预约登记规则样式 */
|
||||
.booking-rules-box {
|
||||
width: 680rpx;
|
||||
margin-top: 32rpx;
|
||||
padding: 30rpx;
|
||||
background-image: linear-gradient(-45deg, #60D7FF, #68BBD7);
|
||||
border-radius: 20rpx;
|
||||
box-shadow: 0 0 10rpx 10rpx rgba(0, 0, 0, 0.1);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.rules-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.rules-content {
|
||||
font-size: 26rpx;
|
||||
color: #fff;
|
||||
line-height: 1.6;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user