mirror of
https://github.com/ChuXunYu/warOfCoins.git
synced 2026-01-31 08:31:26 +00:00
Initial commit
This commit is contained in:
419
pages/strategy/strategy.js
Normal file
419
pages/strategy/strategy.js
Normal file
@@ -0,0 +1,419 @@
|
||||
// strategy.js
|
||||
const app = getApp()
|
||||
|
||||
Page({
|
||||
data: {
|
||||
event: null,
|
||||
strategies: {
|
||||
economic: [
|
||||
{
|
||||
id: 'economic_1',
|
||||
title: '调整边币兑换率',
|
||||
description: '通过合理调整边币与法币的兑换率,稳定币值',
|
||||
applicable: ['exchange', 'fakeCurrency'],
|
||||
historyCase: {
|
||||
title: '1943年陕甘宁边区调整币值案例',
|
||||
description: '1943年初,陕甘宁边区政府通过调整边币与法币兑换率,有效应对了币值波动'
|
||||
}
|
||||
},
|
||||
{
|
||||
id: 'economic_2',
|
||||
title: '紧缩货币发行',
|
||||
description: '减少边币发行量,提高现有边币价值',
|
||||
applicable: ['exchange', 'fakeCurrency', 'shortage'],
|
||||
historyCase: {
|
||||
title: '1944年某根据地紧缩货币政策',
|
||||
description: '1944年,某根据地实施紧缩货币政策,有效控制了通货膨胀'
|
||||
}
|
||||
},
|
||||
{
|
||||
id: 'economic_3',
|
||||
title: '建立物资储备',
|
||||
description: '组织经济战备,储备重要物资以稳定物价',
|
||||
applicable: ['shortage', 'exchange'],
|
||||
historyCase: {
|
||||
title: '1942年晋察冀边区物资储备计划',
|
||||
description: '1942年,晋察冀边区政府建立战略物资储备,有效应对了国民党经济封锁'
|
||||
}
|
||||
}
|
||||
],
|
||||
administrative: [
|
||||
{
|
||||
id: 'admin_1',
|
||||
title: '查抄伪币窝点',
|
||||
description: '派出工作组和武装力量,打击伪造边币的犯罪活动',
|
||||
applicable: ['fakeCurrency'],
|
||||
historyCase: {
|
||||
title: '1941年晋冀鲁豫边区打击伪币行动',
|
||||
description: '1941年,晋冀鲁豫边区政府开展了大规模打击伪币活动,摧毁多个伪币制造点'
|
||||
}
|
||||
},
|
||||
{
|
||||
id: 'admin_2',
|
||||
title: '实施物资配给',
|
||||
description: '对关键物资实行统一配给制度,确保公平分配',
|
||||
applicable: ['shortage'],
|
||||
historyCase: {
|
||||
title: '1945年山东解放区物资配给制度',
|
||||
description: '1945年,山东解放区实施关键物资配给制度,保障了军民基本生活需求'
|
||||
}
|
||||
},
|
||||
{
|
||||
id: 'admin_3',
|
||||
title: '设立边币管理委员会',
|
||||
description: '成立专门机构,统一协调货币政策和币值稳定措施',
|
||||
applicable: ['fakeCurrency', 'exchange', 'shortage'],
|
||||
historyCase: {
|
||||
title: '1940年陕甘宁边区货币管理委员会',
|
||||
description: '1940年,陕甘宁边区成立货币管理委员会,统一协调金融政策,保障了经济发展'
|
||||
}
|
||||
}
|
||||
],
|
||||
mobilization: [
|
||||
{
|
||||
id: 'mob_1',
|
||||
title: '开展拒用伪币宣传',
|
||||
description: '通过各种渠道向民众普及伪币识别知识,动员群众拒绝使用伪币',
|
||||
applicable: ['fakeCurrency'],
|
||||
historyCase: {
|
||||
title: '1943年冀中群众性反伪币运动',
|
||||
description: '1943年,冀中地区开展了声势浩大的反伪币宣传运动,有效减少了伪币流通'
|
||||
}
|
||||
},
|
||||
{
|
||||
id: 'mob_2',
|
||||
title: '组织互助合作',
|
||||
description: '发动群众组建互助组和合作社,共同应对物资短缺',
|
||||
applicable: ['shortage'],
|
||||
historyCase: {
|
||||
title: '1942年抗日民主根据地互助合作运动',
|
||||
description: '1942年,多个抗日根据地开展互助合作运动,有效缓解了物资短缺问题'
|
||||
}
|
||||
},
|
||||
{
|
||||
id: 'mob_3',
|
||||
title: '开展爱用边币运动',
|
||||
description: '动员群众积极使用边币,增强对根据地货币的信心',
|
||||
applicable: ['exchange', 'fakeCurrency'],
|
||||
historyCase: {
|
||||
title: '1944年晋冀鲁豫边区爱用边币运动',
|
||||
description: '1944年,晋冀鲁豫边区开展爱用边币运动,提高了边币的公信力和使用范围'
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
showModal: false,
|
||||
currentHistoryCase: null,
|
||||
currentRound: 0,
|
||||
maxRounds: 3,
|
||||
selectedStrategies: [],
|
||||
strategiesUsed: {},
|
||||
roundTitle: "第1轮 - 初期应对",
|
||||
isProcessing: false, // 处理状态防止重复点击
|
||||
isLoading: true, // 加载状态
|
||||
selectableCount: 0, // 当前可选择的策略数
|
||||
roundDescriptions: [
|
||||
"初期应对 - 选择最紧急的措施",
|
||||
"中期调整 - 加强应对效果",
|
||||
"后期加强 - 巩固已有成果"
|
||||
]
|
||||
},
|
||||
|
||||
onLoad: function() {
|
||||
wx.showLoading({
|
||||
title: '加载中...',
|
||||
mask: true
|
||||
});
|
||||
|
||||
try {
|
||||
// 从全局数据获取选中的事件
|
||||
const selectedEvent = app.globalData.selectedEvent;
|
||||
|
||||
if (selectedEvent) {
|
||||
// 重置全局状态
|
||||
app.globalData.selectedStrategies = [];
|
||||
app.globalData.currentRound = 0;
|
||||
|
||||
this.initData(selectedEvent);
|
||||
} else {
|
||||
// 如果没有选中事件,创建一个测试事件(用于调试)
|
||||
const testEvent = {
|
||||
id: 'fake_currency_1',
|
||||
type: 'fakeCurrency',
|
||||
title: '伪币冲击:初级',
|
||||
description: '敌方在根据地周边地区投放少量伪造边币,市场上开始出现伪币流通现象',
|
||||
level: 1,
|
||||
impact: '市场信心轻微下降,边币贬值风险较小'
|
||||
};
|
||||
|
||||
this.initData(testEvent);
|
||||
wx.showToast({
|
||||
title: '使用测试数据',
|
||||
icon: 'none',
|
||||
duration: 2000
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('初始化数据出错:', error);
|
||||
wx.hideLoading();
|
||||
wx.showToast({
|
||||
title: '加载失败,请重试',
|
||||
icon: 'none',
|
||||
duration: 2000
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
// 初始化数据和计算可选择的策略数量
|
||||
initData: function(eventData) {
|
||||
try {
|
||||
// 设置基本数据
|
||||
this.setData({
|
||||
event: eventData,
|
||||
currentRound: 0,
|
||||
selectedStrategies: [],
|
||||
strategiesUsed: {},
|
||||
roundTitle: "第1轮 - 初期应对",
|
||||
isProcessing: false
|
||||
});
|
||||
|
||||
// 计算可选择的策略数量
|
||||
let count = 0;
|
||||
const eventType = eventData.type;
|
||||
|
||||
// 遍历所有策略类别
|
||||
for (const category in this.data.strategies) {
|
||||
this.data.strategies[category].forEach(strategy => {
|
||||
if (strategy.applicable && strategy.applicable.indexOf(eventType) > -1) {
|
||||
count++;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this.setData({
|
||||
selectableCount: count,
|
||||
isLoading: false
|
||||
});
|
||||
|
||||
wx.hideLoading();
|
||||
} catch (error) {
|
||||
console.error('初始化数据出错:', error);
|
||||
wx.hideLoading();
|
||||
wx.showToast({
|
||||
title: '数据初始化失败',
|
||||
icon: 'none',
|
||||
duration: 2000
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
handleStrategySelect: function(e) {
|
||||
// 防止重复处理
|
||||
if (this.data.isProcessing || this.data.showModal) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const strategyType = e.currentTarget.dataset.type;
|
||||
const strategyId = e.currentTarget.dataset.id;
|
||||
const isApplicable = e.currentTarget.dataset.applicable;
|
||||
const isUsed = e.currentTarget.dataset.used;
|
||||
|
||||
// 如果不适用或已使用,不处理
|
||||
if (isApplicable === 'false' || isUsed === 'true') {
|
||||
wx.vibrateShort(); // 轻微震动提示无法选择
|
||||
return;
|
||||
}
|
||||
|
||||
// 找到选中的策略
|
||||
const selectedStrategy = this.data.strategies[strategyType].find(item => item.id === strategyId);
|
||||
|
||||
if (selectedStrategy) {
|
||||
// 设置处理中状态
|
||||
this.setData({
|
||||
isProcessing: true
|
||||
});
|
||||
|
||||
// 轻微振动反馈
|
||||
wx.vibrateShort({
|
||||
type: 'light'
|
||||
});
|
||||
|
||||
// 标记该策略已使用
|
||||
let newStrategiesUsed = {...this.data.strategiesUsed};
|
||||
newStrategiesUsed[selectedStrategy.id] = true;
|
||||
|
||||
// 添加到已选策略列表
|
||||
let newSelectedStrategies = [...this.data.selectedStrategies];
|
||||
newSelectedStrategies.push({
|
||||
round: this.data.currentRound + 1,
|
||||
strategy: selectedStrategy
|
||||
});
|
||||
|
||||
// 更新到全局数据
|
||||
app.globalData.selectedStrategies = newSelectedStrategies;
|
||||
|
||||
// 显示历史案例模态框
|
||||
this.setData({
|
||||
showModal: true,
|
||||
currentHistoryCase: selectedStrategy.historyCase,
|
||||
strategiesUsed: newStrategiesUsed,
|
||||
selectedStrategies: newSelectedStrategies
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('选择策略出错:', error);
|
||||
this.setData({
|
||||
isProcessing: false
|
||||
});
|
||||
wx.showToast({
|
||||
title: '操作失败,请重试',
|
||||
icon: 'none',
|
||||
duration: 2000
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
closeModal: function() {
|
||||
// 如果还在处理中,防止重复点击
|
||||
if (!this.data.showModal) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// 先关闭模态框
|
||||
this.setData({
|
||||
showModal: false,
|
||||
currentHistoryCase: null
|
||||
});
|
||||
|
||||
// 增加轮次
|
||||
const newRound = this.data.currentRound + 1;
|
||||
app.globalData.currentRound = newRound;
|
||||
|
||||
// 如果达到最大轮次,跳转到结果页面
|
||||
if (newRound >= this.data.maxRounds) {
|
||||
wx.showToast({
|
||||
title: '策略选择完成',
|
||||
icon: 'success',
|
||||
duration: 1000,
|
||||
mask: true
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
this.navigateToResults();
|
||||
}, 1000);
|
||||
} else {
|
||||
// 否则继续下一轮
|
||||
let roundTitle = "";
|
||||
if (newRound === 1) {
|
||||
roundTitle = "第2轮 - 中期调整";
|
||||
} else if (newRound === 2) {
|
||||
roundTitle = "第3轮 - 后期加强";
|
||||
}
|
||||
|
||||
// 更新当前轮次状态
|
||||
this.setData({
|
||||
currentRound: newRound,
|
||||
roundTitle: roundTitle,
|
||||
isProcessing: false // 重置处理状态
|
||||
});
|
||||
|
||||
wx.showToast({
|
||||
title: `进入${roundTitle}`,
|
||||
icon: 'none',
|
||||
duration: 1500
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('关闭模态框出错:', error);
|
||||
this.setData({
|
||||
isProcessing: false
|
||||
});
|
||||
wx.showToast({
|
||||
title: '操作失败,请重试',
|
||||
icon: 'none',
|
||||
duration: 2000
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
// 添加返回首页的函数
|
||||
navigateBack: function() {
|
||||
wx.showModal({
|
||||
title: '确认返回',
|
||||
content: '返回将丢失当前已选择的策略,确定返回吗?',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
wx.navigateBack();
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
preventBubble: function(e) {
|
||||
// 阻止冒泡,防止点击内容区域关闭模态框
|
||||
return;
|
||||
},
|
||||
|
||||
// 提前结束,直接查看结果
|
||||
finishEarly: function() {
|
||||
if (this.data.selectedStrategies.length > 0) {
|
||||
wx.showModal({
|
||||
title: '确认完成',
|
||||
content: '确定结束当前决策过程,直接查看结果吗?',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
this.navigateToResults();
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
wx.showToast({
|
||||
title: '请至少选择一个策略',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
// 跳转到结果页面的统一方法
|
||||
navigateToResults: function() {
|
||||
wx.navigateTo({
|
||||
url: '/pages/result/result',
|
||||
success: () => {
|
||||
console.log('跳转到结果页面');
|
||||
// 跳转成功后重置处理状态
|
||||
this.setData({
|
||||
isProcessing: false
|
||||
});
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error('跳转失败', err);
|
||||
wx.showToast({
|
||||
title: '跳转失败,请重试',
|
||||
icon: 'none'
|
||||
});
|
||||
this.setData({
|
||||
isProcessing: false
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 生命周期函数
|
||||
onShareAppMessage: function() {
|
||||
return {
|
||||
title: '边区危机应对策略小游戏',
|
||||
path: '/pages/index/index',
|
||||
imageUrl: '/images/share-img.jpg' // 需要提供分享图片
|
||||
};
|
||||
},
|
||||
|
||||
// 页面卸载时清理
|
||||
onUnload: function() {
|
||||
// 取消可能存在的定时器
|
||||
if (this.navigateTimer) {
|
||||
clearTimeout(this.navigateTimer);
|
||||
}
|
||||
}
|
||||
})
|
||||
6
pages/strategy/strategy.json
Normal file
6
pages/strategy/strategy.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"usingComponents": {
|
||||
"history-modal": "/components/HistoryModal/HistoryModal"
|
||||
},
|
||||
"navigationBarTitleText": "边币战争 - 策略选择"
|
||||
}
|
||||
133
pages/strategy/strategy.wxml
Normal file
133
pages/strategy/strategy.wxml
Normal file
@@ -0,0 +1,133 @@
|
||||
<!--strategy.wxml-->
|
||||
<view class="container vintage-bg page-transition">
|
||||
<view class="event-header card">
|
||||
<view class="event-title">{{event.title}}</view>
|
||||
<view class="event-desc">{{event.description}}</view>
|
||||
<view class="event-impact">影响:{{event.impact}}</view>
|
||||
<view class="level-indicator">
|
||||
<text>危机等级:</text>
|
||||
<view class="level-dots">
|
||||
<view class="level-dot {{event.level >= 1 ? 'active' : ''}}"></view>
|
||||
<view class="level-dot {{event.level >= 2 ? 'active' : ''}}"></view>
|
||||
<view class="level-dot {{event.level >= 3 ? 'active' : ''}}"></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 轮次指示器 -->
|
||||
<view class="round-indicator">
|
||||
<view class="round-dot {{currentRound >= 0 ? 'active' : ''}} {{currentRound > 0 ? 'completed' : ''}}"></view>
|
||||
<view class="round-dot {{currentRound >= 1 ? 'active' : ''}} {{currentRound > 1 ? 'completed' : ''}}"></view>
|
||||
<view class="round-dot {{currentRound >= 2 ? 'active' : ''}} {{currentRound > 2 ? 'completed' : ''}}"></view>
|
||||
</view>
|
||||
|
||||
<!-- 已选策略显示区域 -->
|
||||
<view class="selected-strategies" wx:if="{{selectedStrategies.length > 0}}">
|
||||
<view class="section-title">已选择的策略</view>
|
||||
<view class="strategies-list">
|
||||
<view wx:for="{{selectedStrategies}}" wx:key="index" class="selected-strategy-item">
|
||||
<view class="round-label">第{{item.round}}轮</view>
|
||||
<view class="strategy-name">{{item.strategy.title}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="strategy-section">
|
||||
<view class="section-title">{{roundTitle}}</view>
|
||||
|
||||
<view class="selection-help">选择一个适用于当前危机的策略,不可选择已使用过的策略</view>
|
||||
|
||||
<!-- 可选策略数量提示 -->
|
||||
<view class="tip-container" wx:if="{{selectableCount === 0}}">
|
||||
当前事件没有可用的应对策略,请返回选择其他事件。
|
||||
</view>
|
||||
|
||||
<!-- 加载状态显示 -->
|
||||
<view class="loading-container" wx:if="{{isLoading}}">
|
||||
<view class="loading-spinner"></view>
|
||||
</view>
|
||||
|
||||
<view class="strategy-category" wx:if="{{!isLoading}}">
|
||||
<view class="category-header">
|
||||
<view class="category-icon economic-icon"></view>
|
||||
<view class="category-title">经济手段</view>
|
||||
</view>
|
||||
<view class="strategy-list">
|
||||
<view wx:for="{{strategies.economic}}" wx:key="id"
|
||||
class="strategy-item card {{item.applicable.indexOf(event.type) > -1 ? '' : 'disabled'}} {{strategiesUsed[item.id] ? 'used' : ''}}"
|
||||
bindtap="handleStrategySelect"
|
||||
data-type="economic" data-id="{{item.id}}"
|
||||
data-applicable="{{item.applicable.indexOf(event.type) > -1}}"
|
||||
data-used="{{strategiesUsed[item.id]}}">
|
||||
<view class="strategy-title">{{item.title}}</view>
|
||||
<view class="strategy-desc">{{item.description}}</view>
|
||||
<view wx:if="{{item.applicable.indexOf(event.type) === -1}}" class="not-applicable">不适用于当前危机</view>
|
||||
<view wx:elif="{{strategiesUsed[item.id]}}" class="already-used">已经使用</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="strategy-category" wx:if="{{!isLoading}}">
|
||||
<view class="category-header">
|
||||
<view class="category-icon admin-icon"></view>
|
||||
<view class="category-title">行政手段</view>
|
||||
</view>
|
||||
<view class="strategy-list">
|
||||
<view wx:for="{{strategies.administrative}}" wx:key="id"
|
||||
class="strategy-item card {{item.applicable.indexOf(event.type) > -1 ? '' : 'disabled'}} {{strategiesUsed[item.id] ? 'used' : ''}}"
|
||||
bindtap="handleStrategySelect"
|
||||
data-type="administrative" data-id="{{item.id}}"
|
||||
data-applicable="{{item.applicable.indexOf(event.type) > -1}}"
|
||||
data-used="{{strategiesUsed[item.id]}}">
|
||||
<view class="strategy-title">{{item.title}}</view>
|
||||
<view class="strategy-desc">{{item.description}}</view>
|
||||
<view wx:if="{{item.applicable.indexOf(event.type) === -1}}" class="not-applicable">不适用于当前危机</view>
|
||||
<view wx:elif="{{strategiesUsed[item.id]}}" class="already-used">已经使用</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="strategy-category" wx:if="{{!isLoading}}">
|
||||
<view class="category-header">
|
||||
<view class="category-icon mob-icon"></view>
|
||||
<view class="category-title">群众动员</view>
|
||||
</view>
|
||||
<view class="strategy-list">
|
||||
<view wx:for="{{strategies.mobilization}}" wx:key="id"
|
||||
class="strategy-item card {{item.applicable.indexOf(event.type) > -1 ? '' : 'disabled'}} {{strategiesUsed[item.id] ? 'used' : ''}}"
|
||||
bindtap="handleStrategySelect"
|
||||
data-type="mobilization" data-id="{{item.id}}"
|
||||
data-applicable="{{item.applicable.indexOf(event.type) > -1}}"
|
||||
data-used="{{strategiesUsed[item.id]}}">
|
||||
<view class="strategy-title">{{item.title}}</view>
|
||||
<view class="strategy-desc">{{item.description}}</view>
|
||||
<view wx:if="{{item.applicable.indexOf(event.type) === -1}}" class="not-applicable">不适用于当前危机</view>
|
||||
<view wx:elif="{{strategiesUsed[item.id]}}" class="already-used">已经使用</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="action-buttons">
|
||||
<view class="back-btn" bindtap="navigateBack">返回事件选择</view>
|
||||
<view wx:if="{{selectedStrategies.length > 0}}" class="finish-btn" bindtap="finishEarly">查看最终结果</view>
|
||||
</view>
|
||||
|
||||
<!-- 历史案例模态框 -->
|
||||
<view class="modal-mask" wx:if="{{showModal}}" catchtap="preventBubble">
|
||||
<view class="modal-content">
|
||||
<view class="modal-header">
|
||||
<text class="modal-title">历史案例参考</text>
|
||||
<view class="modal-close" catchtap="closeModal">×</view>
|
||||
</view>
|
||||
<view class="modal-body">
|
||||
<view class="case-title">{{currentHistoryCase.title}}</view>
|
||||
<view class="case-image"></view>
|
||||
<view class="case-desc">{{currentHistoryCase.description}}</view>
|
||||
</view>
|
||||
<view class="modal-footer">
|
||||
<view class="btn" catchtap="closeModal">了解了,继续</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
625
pages/strategy/strategy.wxss
Normal file
625
pages/strategy/strategy.wxss
Normal file
@@ -0,0 +1,625 @@
|
||||
/**strategy.wxss**/
|
||||
.container {
|
||||
padding: 30rpx;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.vintage-bg {
|
||||
background-color: #f8f6f1;
|
||||
background-image: url('data:image/png;base64,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');
|
||||
position: relative;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
/* 添加页面切换动画 */
|
||||
.page-transition {
|
||||
animation: fadeIn 0.5s ease-in-out;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from { opacity: 0; }
|
||||
to { opacity: 1; }
|
||||
}
|
||||
|
||||
.event-header {
|
||||
margin-bottom: 30rpx;
|
||||
padding: 20rpx;
|
||||
border-radius: 10rpx;
|
||||
background-color: #fff;
|
||||
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
|
||||
animation: slideDown 0.5s ease-out;
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.event-header:active {
|
||||
transform: scale(0.98);
|
||||
}
|
||||
|
||||
@keyframes slideDown {
|
||||
from {
|
||||
transform: translateY(-30rpx);
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
transform: translateY(0);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.event-title {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
margin-bottom: 15rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.event-desc {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
margin-bottom: 15rpx;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.event-impact {
|
||||
font-size: 26rpx;
|
||||
color: #d9534f;
|
||||
margin-bottom: 15rpx;
|
||||
}
|
||||
|
||||
.level-indicator {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.level-dots {
|
||||
display: flex;
|
||||
margin-left: 10rpx;
|
||||
}
|
||||
|
||||
.level-dot {
|
||||
width: 20rpx;
|
||||
height: 20rpx;
|
||||
border-radius: 50%;
|
||||
background-color: #ddd;
|
||||
margin-right: 5rpx;
|
||||
transition: background-color 0.5s ease;
|
||||
}
|
||||
|
||||
.level-dot.active {
|
||||
background-color: #d9534f;
|
||||
animation: pulseDot 2s infinite;
|
||||
}
|
||||
|
||||
@keyframes pulseDot {
|
||||
0% { opacity: 1; }
|
||||
50% { opacity: 0.6; }
|
||||
100% { opacity: 1; }
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
margin: 20rpx 0;
|
||||
color: #333;
|
||||
position: relative;
|
||||
padding-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.section-title::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 60rpx;
|
||||
height: 4rpx;
|
||||
background-color: #5cb85c;
|
||||
transition: width 0.3s ease;
|
||||
}
|
||||
|
||||
.section-title:hover::after {
|
||||
width: 120rpx;
|
||||
}
|
||||
|
||||
.strategy-category {
|
||||
margin-bottom: 40rpx;
|
||||
animation: fadeInUp 0.6s ease-out;
|
||||
animation-fill-mode: both;
|
||||
}
|
||||
|
||||
.strategy-category:nth-child(2) {
|
||||
animation-delay: 0.2s;
|
||||
}
|
||||
|
||||
.strategy-category:nth-child(3) {
|
||||
animation-delay: 0.4s;
|
||||
}
|
||||
|
||||
@keyframes fadeInUp {
|
||||
from {
|
||||
transform: translateY(20rpx);
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
transform: translateY(0);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.category-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 15rpx;
|
||||
}
|
||||
|
||||
.category-icon {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
margin-right: 10rpx;
|
||||
border-radius: 50%;
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.category-header:hover .category-icon {
|
||||
transform: scale(1.2);
|
||||
}
|
||||
|
||||
.economic-icon {
|
||||
background-color: #5bc0de;
|
||||
}
|
||||
|
||||
.admin-icon {
|
||||
background-color: #f0ad4e;
|
||||
}
|
||||
|
||||
.mob-icon {
|
||||
background-color: #5cb85c;
|
||||
}
|
||||
|
||||
.category-title {
|
||||
font-size: 30rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.strategy-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.strategy-item {
|
||||
position: relative;
|
||||
padding: 20rpx;
|
||||
border-radius: 10rpx;
|
||||
background-color: #fff;
|
||||
transition: all 0.3s;
|
||||
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
|
||||
border-left: 8rpx solid transparent;
|
||||
transform-origin: center;
|
||||
}
|
||||
|
||||
.strategy-item.disabled {
|
||||
opacity: 0.6;
|
||||
background-color: #f5f5f5;
|
||||
cursor: not-allowed;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.strategy-item.used {
|
||||
opacity: 0.6;
|
||||
border-left-color: #999;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
/* 非禁用状态下的策略项高亮效果 */
|
||||
.strategy-item:not(.disabled):not(.used) {
|
||||
background-color: #fff;
|
||||
border-left-color: #5cb85c;
|
||||
color: #333;
|
||||
opacity: 1;
|
||||
animation: pulse 2s infinite;
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0% {
|
||||
box-shadow: 0 0 0 0 rgba(92, 184, 92, 0.4);
|
||||
}
|
||||
70% {
|
||||
box-shadow: 0 0 0 6rpx rgba(92, 184, 92, 0);
|
||||
}
|
||||
100% {
|
||||
box-shadow: 0 0 0 0 rgba(92, 184, 92, 0);
|
||||
}
|
||||
}
|
||||
|
||||
.strategy-item:not(.disabled):not(.used):active {
|
||||
transform: scale(0.98);
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
|
||||
.strategy-title {
|
||||
font-size: 30rpx;
|
||||
font-weight: bold;
|
||||
margin-bottom: 10rpx;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.strategy-desc {
|
||||
font-size: 26rpx;
|
||||
line-height: 1.5;
|
||||
color: inherit;
|
||||
margin-bottom: 15rpx;
|
||||
}
|
||||
|
||||
.not-applicable, .already-used {
|
||||
font-size: 24rpx;
|
||||
padding: 4rpx 10rpx;
|
||||
border-radius: 4rpx;
|
||||
display: inline-block;
|
||||
margin-top: 10rpx;
|
||||
}
|
||||
|
||||
.not-applicable {
|
||||
background-color: #f8d7da;
|
||||
color: #721c24;
|
||||
}
|
||||
|
||||
.already-used {
|
||||
background-color: #d1ecf1;
|
||||
color: #0c5460;
|
||||
}
|
||||
|
||||
.selected-strategies {
|
||||
margin-bottom: 30rpx;
|
||||
padding: 20rpx;
|
||||
border-radius: 10rpx;
|
||||
background-color: #fff;
|
||||
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
|
||||
animation: slideIn 0.5s ease-out;
|
||||
}
|
||||
|
||||
@keyframes slideIn {
|
||||
from {
|
||||
transform: translateX(-30rpx);
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
transform: translateX(0);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.strategies-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 15rpx;
|
||||
}
|
||||
|
||||
.selected-strategy-item {
|
||||
background-color: #f0f8ff;
|
||||
border-radius: 8rpx;
|
||||
padding: 15rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
min-width: 150rpx;
|
||||
transition: all 0.3s ease;
|
||||
animation: popIn 0.5s ease-out;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.selected-strategy-item:hover {
|
||||
transform: translateY(-5rpx);
|
||||
box-shadow: 0 5rpx 15rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
@keyframes popIn {
|
||||
0% {
|
||||
transform: scale(0.8);
|
||||
opacity: 0;
|
||||
}
|
||||
70% {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
100% {
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.round-label {
|
||||
font-size: 22rpx;
|
||||
color: #666;
|
||||
margin-bottom: 5rpx;
|
||||
background-color: #f5f5f5;
|
||||
padding: 2rpx 8rpx;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
|
||||
.strategy-name {
|
||||
font-size: 26rpx;
|
||||
color: #333;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-top: 40rpx;
|
||||
padding: 20rpx 0;
|
||||
animation: fadeInUp 0.5s ease-out;
|
||||
animation-delay: 0.8s;
|
||||
animation-fill-mode: both;
|
||||
}
|
||||
|
||||
.back-btn, .finish-btn {
|
||||
padding: 15rpx 30rpx;
|
||||
border-radius: 50rpx;
|
||||
font-size: 28rpx;
|
||||
text-align: center;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.back-btn {
|
||||
background-color: #f8f9fa;
|
||||
color: #6c757d;
|
||||
border: 1rpx solid #dee2e6;
|
||||
}
|
||||
|
||||
.back-btn:active {
|
||||
background-color: #e9ecef;
|
||||
transform: scale(0.98);
|
||||
}
|
||||
|
||||
.finish-btn {
|
||||
background-color: #5cb85c;
|
||||
color: white;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.finish-btn:active {
|
||||
background-color: #4cae4c;
|
||||
transform: scale(0.98);
|
||||
}
|
||||
|
||||
.finish-btn::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: 5rpx;
|
||||
height: 5rpx;
|
||||
background: rgba(255, 255, 255, 0.5);
|
||||
opacity: 0;
|
||||
border-radius: 100%;
|
||||
transform: scale(1, 1) translate(-50%);
|
||||
transform-origin: 50% 50%;
|
||||
}
|
||||
|
||||
.finish-btn:active::after {
|
||||
animation: ripple 1s ease-out;
|
||||
}
|
||||
|
||||
@keyframes ripple {
|
||||
0% {
|
||||
transform: scale(0, 0);
|
||||
opacity: 0.5;
|
||||
}
|
||||
100% {
|
||||
transform: scale(20, 20);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* 模态框样式 */
|
||||
.modal-mask {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
z-index: 999;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
animation: fadeIn 0.3s ease;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
width: 85%;
|
||||
background: #fff;
|
||||
border-radius: 10rpx;
|
||||
overflow: hidden;
|
||||
max-height: 90vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
animation: scaleIn 0.3s ease;
|
||||
transform-origin: center;
|
||||
}
|
||||
|
||||
@keyframes scaleIn {
|
||||
0% {
|
||||
transform: scale(0.9);
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.modal-header {
|
||||
padding: 20rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
border-bottom: 1rpx solid #eee;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
.modal-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.modal-close {
|
||||
font-size: 40rpx;
|
||||
color: #999;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
width: 50rpx;
|
||||
height: 50rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.modal-close:hover {
|
||||
background-color: #f5f5f5;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.modal-body {
|
||||
padding: 30rpx;
|
||||
max-height: 60vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.case-title {
|
||||
font-size: 30rpx;
|
||||
font-weight: bold;
|
||||
margin-bottom: 20rpx;
|
||||
color: #333;
|
||||
border-left: 4rpx solid #5cb85c;
|
||||
padding-left: 15rpx;
|
||||
}
|
||||
|
||||
.case-image {
|
||||
width: 100%;
|
||||
height: 300rpx;
|
||||
background-color: #f8f9fa;
|
||||
margin-bottom: 20rpx;
|
||||
border-radius: 8rpx;
|
||||
background-image: url('https://placeholder.pics/svg/400x150/DEDEDE/555555/历史案例');
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
transition: transform 0.5s ease;
|
||||
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.case-image:hover {
|
||||
transform: scale(1.02);
|
||||
}
|
||||
|
||||
.case-desc {
|
||||
font-size: 28rpx;
|
||||
line-height: 1.6;
|
||||
color: #666;
|
||||
text-indent: 2em;
|
||||
}
|
||||
|
||||
.modal-footer {
|
||||
padding: 20rpx;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
border-top: 1rpx solid #eee;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
.btn {
|
||||
padding: 15rpx 30rpx;
|
||||
border-radius: 50rpx;
|
||||
font-size: 28rpx;
|
||||
background-color: #5cb85c;
|
||||
color: white;
|
||||
text-align: center;
|
||||
transition: all 0.3s ease;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.btn:active {
|
||||
transform: scale(0.98);
|
||||
background-color: #4cae4c;
|
||||
}
|
||||
|
||||
/* 加载状态 */
|
||||
.loading-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100rpx;
|
||||
margin: 20rpx 0;
|
||||
}
|
||||
|
||||
.loading-spinner {
|
||||
width: 50rpx;
|
||||
height: 50rpx;
|
||||
border: 4rpx solid rgba(0, 0, 0, 0.1);
|
||||
border-left-color: #5cb85c;
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
/* 提示性样式 */
|
||||
.tip-container {
|
||||
margin: 20rpx 0;
|
||||
padding: 15rpx;
|
||||
background-color: #fff3cd;
|
||||
border-left: 4rpx solid #ffc107;
|
||||
border-radius: 4rpx;
|
||||
font-size: 26rpx;
|
||||
color: #856404;
|
||||
animation: fadeIn 0.5s ease-in-out;
|
||||
}
|
||||
|
||||
.round-indicator {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin: 20rpx 0;
|
||||
padding: 15rpx;
|
||||
background-color: rgba(255, 255, 255, 0.8);
|
||||
border-radius: 20rpx;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.round-dot {
|
||||
width: 20rpx;
|
||||
height: 20rpx;
|
||||
border-radius: 50%;
|
||||
background-color: #ddd;
|
||||
margin: 0 10rpx;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.round-dot.active {
|
||||
background-color: #5cb85c;
|
||||
transform: scale(1.2);
|
||||
box-shadow: 0 0 8rpx rgba(92, 184, 92, 0.5);
|
||||
}
|
||||
|
||||
.round-dot.completed {
|
||||
background-color: #28a745;
|
||||
}
|
||||
|
||||
/* 策略选择提示文字 */
|
||||
.selection-help {
|
||||
font-size: 24rpx;
|
||||
color: #6c757d;
|
||||
text-align: center;
|
||||
margin: 10rpx 0 30rpx;
|
||||
font-style: italic;
|
||||
animation: fadeIn 0.8s ease-in-out;
|
||||
background-color: rgba(255, 255, 255, 0.7);
|
||||
padding: 10rpx;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
Reference in New Issue
Block a user