- 前端: 更新AI营养师、计算器、打卡、食物详情等页面 - 前端: 更新食物百科、知识详情、营养知识页面 - 前端: 更新社区首页 - 后端: 更新ToolKieAIServiceImpl服务 - API: 更新models-api.js和user.js
656 lines
18 KiB
Vue
656 lines
18 KiB
Vue
<template>
|
||
<view class="food-page">
|
||
<!-- 搜索框 -->
|
||
<view class="search-container">
|
||
<view class="search-box">
|
||
<text class="search-icon">🔍</text>
|
||
<input
|
||
class="search-input"
|
||
v-model="searchText"
|
||
placeholder="搜索食物名称..."
|
||
placeholder-style="color: #9fa5c0"
|
||
@input="handleSearch"
|
||
/>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 分类标签 -->
|
||
<scroll-view class="category-scroll" scroll-x>
|
||
<view class="category-list">
|
||
<view
|
||
class="category-item"
|
||
:class="{ active: currentCategory === 'all' }"
|
||
@click="selectCategory('all')"
|
||
>
|
||
<text>全部</text>
|
||
</view>
|
||
<view
|
||
class="category-item"
|
||
:class="{ active: currentCategory === 'grain' }"
|
||
@click="selectCategory('grain')"
|
||
>
|
||
<text class="category-icon">🌾</text>
|
||
<text>谷薯类</text>
|
||
</view>
|
||
<view
|
||
class="category-item"
|
||
:class="{ active: currentCategory === 'vegetable' }"
|
||
@click="selectCategory('vegetable')"
|
||
>
|
||
<text class="category-icon">🥬</text>
|
||
<text>蔬菜类</text>
|
||
</view>
|
||
<view
|
||
class="category-item"
|
||
:class="{ active: currentCategory === 'fruit' }"
|
||
@click="selectCategory('fruit')"
|
||
>
|
||
<text class="category-icon">🍎</text>
|
||
<text>水果类</text>
|
||
</view>
|
||
<view
|
||
class="category-item"
|
||
:class="{ active: currentCategory === 'meat' }"
|
||
@click="selectCategory('meat')"
|
||
>
|
||
<text class="category-icon">🍖</text>
|
||
<text>肉蛋类</text>
|
||
</view>
|
||
<view
|
||
class="category-item"
|
||
:class="{ active: currentCategory === 'seafood' }"
|
||
@click="selectCategory('seafood')"
|
||
>
|
||
<text class="category-icon">🐟</text>
|
||
<text>水产类</text>
|
||
</view>
|
||
<view
|
||
class="category-item"
|
||
:class="{ active: currentCategory === 'dairy' }"
|
||
@click="selectCategory('dairy')"
|
||
>
|
||
<text class="category-icon">🥛</text>
|
||
<text>奶类</text>
|
||
</view>
|
||
<view
|
||
class="category-item"
|
||
:class="{ active: currentCategory === 'bean' }"
|
||
@click="selectCategory('bean')"
|
||
>
|
||
<text class="category-icon">🫘</text>
|
||
<text>豆类</text>
|
||
</view>
|
||
<view
|
||
class="category-item"
|
||
:class="{ active: currentCategory === 'nut' }"
|
||
@click="selectCategory('nut')"
|
||
>
|
||
<text class="category-icon">🥜</text>
|
||
<text>坚果类</text>
|
||
</view>
|
||
</view>
|
||
</scroll-view>
|
||
|
||
<!-- 食物列表 -->
|
||
<scroll-view class="food-scroll" scroll-y>
|
||
<view class="food-list-container">
|
||
<view class="food-count">共 {{ filteredFoodList.length }} 种食物</view>
|
||
<view class="food-list">
|
||
<view
|
||
class="food-item"
|
||
v-for="(item, index) in filteredFoodList"
|
||
:key="item.id != null ? item.id : index"
|
||
@click="goToFoodDetail(item)"
|
||
>
|
||
<view class="food-image-wrapper">
|
||
<image
|
||
class="food-image"
|
||
:src="getFoodImage(item)"
|
||
mode="aspectFill"
|
||
@error="onFoodImageError(item)"
|
||
></image>
|
||
<view v-if="item.warning" class="warning-badge">⚠️</view>
|
||
</view>
|
||
<view class="food-info">
|
||
<view class="food-header">
|
||
<view class="food-name-wrapper">
|
||
<text class="food-name">{{ item.name }}</text>
|
||
<view class="safety-tag" :class="item.safetyClass || 'safe'">
|
||
<text>{{ item.safety || '—' }}</text>
|
||
</view>
|
||
</view>
|
||
<view v-if="item.category" class="category-badge">
|
||
<text>{{ item.category }}</text>
|
||
</view>
|
||
</view>
|
||
<view class="nutrition-list">
|
||
<view
|
||
class="nutrition-item"
|
||
v-for="(nut, idx) in getNutritionList(item)"
|
||
:key="idx"
|
||
>
|
||
<text class="nutrition-label">{{ nut.label || '—' }}</text>
|
||
<text class="nutrition-value" :class="nut.colorClass || 'green'">{{ nut.value != null ? nut.value : '—' }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</scroll-view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import { HTTP_REQUEST_URL } from '@/config/app.js';
|
||
|
||
export default {
|
||
data() {
|
||
// 无图时的占位图(灰色背景,与 .food-image-wrapper 背景一致)
|
||
const defaultPlaceholder = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTkyIiBoZWlnaHQ9IjE5MiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZTRlNWU3Ii8+PC9zdmc+';
|
||
return {
|
||
searchText: '',
|
||
currentCategory: 'all',
|
||
searchTimer: null,
|
||
defaultPlaceholder,
|
||
imageErrorIds: {}, // 图片加载失败时用占位图,key 为 item.id
|
||
foodList: [
|
||
{
|
||
name: '香蕉',
|
||
category: '水果类',
|
||
safety: '谨慎吃',
|
||
safetyClass: 'careful',
|
||
image: 'https://www.figma.com/api/mcp/asset/480782b7-5802-454c-9021-fad8cce6c195',
|
||
warning: true,
|
||
nutrition: [
|
||
{ label: '蛋白质', value: '1.4g', colorClass: 'green' },
|
||
{ label: '钾', value: '330mg', colorClass: 'red' },
|
||
{ label: '磷', value: '28mg', colorClass: 'orange' }
|
||
],
|
||
categoryType: 'fruit'
|
||
},
|
||
{
|
||
name: '玉米笋(罐头)',
|
||
category: '蔬菜类',
|
||
safety: '放心吃',
|
||
safetyClass: 'safe',
|
||
image: 'https://www.figma.com/api/mcp/asset/59db0f38-437e-4dfa-8fc6-d3eb6d2e9840',
|
||
warning: false,
|
||
nutrition: [
|
||
{ label: '钾', value: '36mg', colorClass: 'green' },
|
||
{ label: '钙', value: '6mg', colorClass: 'green' },
|
||
{ label: '磷', value: '4mg', colorClass: 'green' }
|
||
],
|
||
categoryType: 'vegetable'
|
||
},
|
||
{
|
||
name: '五谷香',
|
||
category: '谷薯类',
|
||
safety: '放心吃',
|
||
safetyClass: 'safe',
|
||
image: 'https://www.figma.com/api/mcp/asset/61347bd7-1ab4-485f-b8d0-09c7ede49fe6',
|
||
warning: false,
|
||
nutrition: [
|
||
{ label: '钾', value: '7mg', colorClass: 'green' },
|
||
{ label: '钙', value: '2mg', colorClass: 'green' },
|
||
{ label: '磷', value: '13mg', colorClass: 'green' }
|
||
],
|
||
categoryType: 'grain'
|
||
},
|
||
{
|
||
name: '糯米粥',
|
||
category: '谷薯类',
|
||
safety: '放心吃',
|
||
safetyClass: 'safe',
|
||
image: 'https://www.figma.com/api/mcp/asset/cf95c2ea-9fb0-4e40-b134-39873207f769',
|
||
warning: false,
|
||
nutrition: [
|
||
{ label: '钾', value: '13mg', colorClass: 'green' },
|
||
{ label: '钙', value: '7mg', colorClass: 'green' },
|
||
{ label: '磷', value: '20mg', colorClass: 'green' }
|
||
],
|
||
categoryType: 'grain'
|
||
},
|
||
{
|
||
name: '苹果',
|
||
category: '水果类',
|
||
safety: '限量吃',
|
||
safetyClass: 'limited',
|
||
image: 'https://www.figma.com/api/mcp/asset/4bc870ef-b16d-496b-b9ed-16f2cb9a53e1',
|
||
warning: false,
|
||
nutrition: [
|
||
{ label: '蛋白质', value: '0.4g', colorClass: 'green' },
|
||
{ label: '钾', value: '119mg', colorClass: 'orange' },
|
||
{ label: '磷', value: '12mg', colorClass: 'green' }
|
||
],
|
||
categoryType: 'fruit'
|
||
},
|
||
{
|
||
name: '西兰花',
|
||
category: '蔬菜类',
|
||
safety: '谨慎吃',
|
||
safetyClass: 'careful',
|
||
image: 'https://www.figma.com/api/mcp/asset/eb858cbc-78cb-46b1-a9a6-8cc9684dabba',
|
||
warning: false,
|
||
nutrition: [
|
||
{ label: '蛋白质', value: '4.1g', colorClass: 'orange' },
|
||
{ label: '钾', value: '316mg', colorClass: 'red' },
|
||
{ label: '磷', value: '72mg', colorClass: 'red' }
|
||
],
|
||
categoryType: 'vegetable'
|
||
}
|
||
]
|
||
}
|
||
},
|
||
computed: {
|
||
filteredFoodList() {
|
||
return this.foodList
|
||
},
|
||
},
|
||
onLoad(options) {
|
||
if (options && options.category) {
|
||
this.currentCategory = options.category;
|
||
}
|
||
this.loadFoodList();
|
||
},
|
||
methods: {
|
||
async loadFoodList() {
|
||
try {
|
||
const { getFoodList } = await import('@/api/tool.js');
|
||
const result = await getFoodList({
|
||
category: this.currentCategory === 'all' ? '' : this.currentCategory,
|
||
page: 1,
|
||
limit: 100
|
||
});
|
||
const rawList = this.getRawFoodList(result);
|
||
this.imageErrorIds = {};
|
||
this.foodList = (rawList || []).map(item => this.normalizeFoodItem(item));
|
||
} catch (error) {
|
||
console.error('加载食物列表失败:', error);
|
||
}
|
||
},
|
||
// 兼容 result.data.list / result.list / result.data 为数组 等响应结构
|
||
getRawFoodList(result) {
|
||
if (!result) return [];
|
||
const page = result.data !== undefined && result.data !== null ? result.data : result;
|
||
if (page && Array.isArray(page.list)) return page.list;
|
||
if (Array.isArray(page)) return page;
|
||
return [];
|
||
},
|
||
getFoodImage(item) {
|
||
if (!item) return this.defaultPlaceholder;
|
||
const id = item.id != null ? item.id : item.foodId;
|
||
if (id != null && this.imageErrorIds[String(id)]) return this.defaultPlaceholder;
|
||
// 兼容后端 image / image_url / 前端 imageUrl、img、pic、coverImage、cover_image
|
||
const raw = item.imageUrl || item.image || item.image_url || item.img || item.pic || item.coverImage || item.cover_image || '';
|
||
const s = (raw && String(raw).trim()) || '';
|
||
if (!s || s === 'null' || s === 'undefined') return this.defaultPlaceholder;
|
||
const url = (s.startsWith('//') || s.startsWith('http')) ? s : (s.startsWith('/') ? (HTTP_REQUEST_URL || '') + s : s);
|
||
return (url && String(url).trim()) ? url : this.defaultPlaceholder;
|
||
},
|
||
getNutritionList(item) {
|
||
if (!item) return [];
|
||
const arr = item.nutrition || item.nutrients || item.nutritions;
|
||
if (Array.isArray(arr) && arr.length > 0) return arr;
|
||
// 无数组时从扁平字段组装,确保列表始终有营养简介
|
||
const list = [];
|
||
const push = (label, val, unit) => {
|
||
const value = (val != null && val !== '') ? String(val) + (unit || '') : '—';
|
||
list.push({ label, value, colorClass: 'green' });
|
||
};
|
||
push('能量', item.energy, 'kcal');
|
||
push('蛋白质', item.protein, 'g');
|
||
push('钾', item.potassium, 'mg');
|
||
push('磷', item.phosphorus, 'mg');
|
||
push('钠', item.sodium, 'mg');
|
||
push('钙', item.calcium, 'mg');
|
||
return list;
|
||
},
|
||
onFoodImageError(item) {
|
||
const id = item.id != null ? item.id : item.foodId;
|
||
if (id != null && !this.imageErrorIds[String(id)]) {
|
||
this.imageErrorIds[String(id)] = true;
|
||
this.imageErrorIds = { ...this.imageErrorIds };
|
||
}
|
||
},
|
||
normalizeFoodItem(item) {
|
||
const safetyMap = {
|
||
suitable: { safety: '放心吃', safetyClass: 'safe' },
|
||
moderate: { safety: '限量吃', safetyClass: 'limited' },
|
||
restricted: { safety: '谨慎吃', safetyClass: 'careful' },
|
||
forbidden: { safety: '谨慎吃', safetyClass: 'careful' }
|
||
};
|
||
const safety = item.safety != null ? { safety: item.safety, safetyClass: item.safetyClass || 'safe' } : (safetyMap[item.suitabilityLevel] || { safety: '—', safetyClass: 'safe' });
|
||
|
||
// 图片:兼容 image/image_url/imageUrl/img/pic/coverImage/cover_image,相对路径补全,空或无效则由 getFoodImage 用占位图
|
||
const rawImg = item.imageUrl || item.image || item.image_url || item.img || item.pic || item.coverImage || item.cover_image || '';
|
||
const rawStr = (rawImg && String(rawImg).trim()) || '';
|
||
const validRaw = rawStr && rawStr !== 'null' && rawStr !== 'undefined';
|
||
const imageUrl = validRaw && (rawStr.startsWith('//') || rawStr.startsWith('http')) ? rawStr : (validRaw && rawStr.startsWith('/') ? (HTTP_REQUEST_URL || '') + rawStr : (validRaw ? rawStr : ''));
|
||
const image = imageUrl || '';
|
||
|
||
// 营养简介:优先 item.nutrition,其次 item.nutrients(兼容后端),否则由扁平字段 energy/protein/potassium 等组装
|
||
let nutrition = item.nutrition;
|
||
if (Array.isArray(nutrition) && nutrition.length > 0) {
|
||
nutrition = nutrition.map(n => ({
|
||
label: n.label || n.name || n.labelName || '—',
|
||
value: n.value != null ? String(n.value) : '—',
|
||
colorClass: n.colorClass || 'green'
|
||
}));
|
||
} else if (Array.isArray(item.nutrients) && item.nutrients.length > 0) {
|
||
nutrition = item.nutrients.map(n => ({
|
||
label: n.label || n.name || n.labelName || '—',
|
||
value: n.value != null ? String(n.value) : '—',
|
||
colorClass: n.colorClass || 'green'
|
||
}));
|
||
} else {
|
||
// 后端列表仅返回扁平字段,无 nutrition/nutrients 数组,此处组装并始终展示主要项(空值显示 —)
|
||
nutrition = [];
|
||
const push = (label, val, unit) => {
|
||
const value = (val != null && val !== '') ? String(val) + (unit || '') : '—';
|
||
nutrition.push({ label, value, colorClass: 'green' });
|
||
};
|
||
push('能量', item.energy, 'kcal');
|
||
push('蛋白质', item.protein, 'g');
|
||
push('钾', item.potassium, 'mg');
|
||
push('磷', item.phosphorus, 'mg');
|
||
push('钠', item.sodium, 'mg');
|
||
push('钙', item.calcium, 'mg');
|
||
}
|
||
|
||
// 后端详情接口仅接受 Long 类型 id;若列表返回的 id 为非数字(如名称),不传 id,避免详情页请求 400
|
||
const rawId = item.id != null ? item.id : item.foodId;
|
||
const numericId = (rawId !== undefined && rawId !== null && rawId !== '' && !isNaN(Number(rawId)))
|
||
? (typeof rawId === 'number' ? rawId : Number(rawId))
|
||
: undefined;
|
||
return {
|
||
...item,
|
||
id: numericId,
|
||
image,
|
||
imageUrl: image || undefined,
|
||
category: item.category || '',
|
||
safety: safety.safety,
|
||
safetyClass: safety.safetyClass,
|
||
nutrition: Array.isArray(nutrition) ? nutrition : []
|
||
};
|
||
},
|
||
async selectCategory(category) {
|
||
this.currentCategory = category;
|
||
// 切换分类时清空搜索文本,避免搜索状态与分类状态冲突
|
||
this.searchText = '';
|
||
if (this.searchTimer) {
|
||
clearTimeout(this.searchTimer);
|
||
}
|
||
await this.loadFoodList();
|
||
},
|
||
handleSearch() {
|
||
// 防抖:300ms 内不重复触发搜索请求
|
||
if (this.searchTimer) {
|
||
clearTimeout(this.searchTimer);
|
||
}
|
||
this.searchTimer = setTimeout(async () => {
|
||
if (this.searchText.trim()) {
|
||
try {
|
||
const { searchFood } = await import('@/api/tool.js');
|
||
const result = await searchFood({
|
||
keyword: this.searchText.trim(),
|
||
page: 1,
|
||
limit: 100
|
||
});
|
||
const rawList = this.getRawFoodList(result);
|
||
this.imageErrorIds = {};
|
||
this.foodList = (rawList || []).map(item => this.normalizeFoodItem(item));
|
||
} catch (error) {
|
||
console.error('搜索失败:', error);
|
||
}
|
||
} else {
|
||
await this.loadFoodList();
|
||
}
|
||
}, 300);
|
||
},
|
||
goToFoodDetail(item) {
|
||
// 后端详情接口仅接受 Long 类型 id,仅在有有效数字 id 时传 id;始终传 name 供详情页失败时展示
|
||
const rawId = item.id != null ? item.id : (item.foodId != null ? item.foodId : '')
|
||
const numericId = (rawId !== '' && rawId !== undefined && !isNaN(Number(rawId))) ? Number(rawId) : null
|
||
const namePart = item.name ? `&name=${encodeURIComponent(item.name)}` : ''
|
||
const url = numericId !== null
|
||
? `/pages/tool/food-detail?id=${numericId}${namePart}`
|
||
: `/pages/tool/food-detail?name=${encodeURIComponent(item.name || '')}`
|
||
uni.navigateTo({ url })
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.food-page {
|
||
height: 100vh;
|
||
display: flex;
|
||
flex-direction: column;
|
||
background-color: #f4f5f7;
|
||
}
|
||
|
||
/* 搜索框 */
|
||
.search-container {
|
||
background: #ffffff;
|
||
padding: 32rpx;
|
||
border-bottom: 1rpx solid #d0dbea;
|
||
}
|
||
|
||
.search-box {
|
||
display: flex;
|
||
align-items: center;
|
||
height: 88rpx;
|
||
background: #ffffff;
|
||
border: 1rpx solid #d0dbea;
|
||
border-radius: 50rpx;
|
||
padding: 0 32rpx;
|
||
|
||
.search-icon {
|
||
font-size: 32rpx;
|
||
margin-right: 16rpx;
|
||
}
|
||
|
||
.search-input {
|
||
flex: 1;
|
||
font-size: 32rpx;
|
||
color: #3e5481;
|
||
}
|
||
}
|
||
|
||
/* 分类标签 */
|
||
.category-scroll {
|
||
background: #ffffff;
|
||
border-bottom: 1rpx solid #d0dbea;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.category-list {
|
||
display: flex;
|
||
padding: 32rpx;
|
||
gap: 16rpx;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.category-item {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 12rpx;
|
||
height: 67rpx;
|
||
padding: 0 32rpx;
|
||
border-radius: 50rpx;
|
||
border: 1rpx solid #d0dbea;
|
||
background: #ffffff;
|
||
white-space: nowrap;
|
||
|
||
.category-icon {
|
||
font-size: 28rpx;
|
||
}
|
||
|
||
text {
|
||
font-size: 28rpx;
|
||
color: #9fa5c0;
|
||
}
|
||
|
||
&.active {
|
||
background: #ff6b35;
|
||
border-color: #ff6b35;
|
||
|
||
text {
|
||
color: #ffffff;
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 食物列表 */
|
||
.food-scroll {
|
||
flex: 1;
|
||
overflow-y: auto;
|
||
}
|
||
|
||
.food-list-container {
|
||
padding: 32rpx;
|
||
}
|
||
|
||
.food-count {
|
||
font-size: 28rpx;
|
||
color: #9fa5c0;
|
||
margin-bottom: 32rpx;
|
||
}
|
||
|
||
.food-list {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 24rpx;
|
||
}
|
||
|
||
.food-item {
|
||
background: #ffffff;
|
||
border: 1rpx solid #d0dbea;
|
||
border-radius: 32rpx;
|
||
padding: 24rpx;
|
||
display: flex;
|
||
gap: 24rpx;
|
||
}
|
||
|
||
.food-image-wrapper {
|
||
position: relative;
|
||
width: 192rpx;
|
||
height: 192rpx;
|
||
border-radius: 24rpx;
|
||
overflow: hidden;
|
||
background: #f4f5f7;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.food-image {
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
|
||
.warning-badge {
|
||
position: absolute;
|
||
top: 8rpx;
|
||
left: 8rpx;
|
||
background: #ff6464;
|
||
border-radius: 12rpx;
|
||
padding: 4rpx 12rpx;
|
||
font-size: 24rpx;
|
||
}
|
||
|
||
.food-info {
|
||
flex: 1;
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 16rpx;
|
||
}
|
||
|
||
.food-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: flex-start;
|
||
gap: 16rpx;
|
||
}
|
||
|
||
.food-name-wrapper {
|
||
flex: 1;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 16rpx;
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
.food-name {
|
||
font-size: 28rpx;
|
||
color: #2e3e5c;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.safety-tag {
|
||
padding: 4rpx 16rpx;
|
||
border-radius: 50rpx;
|
||
font-size: 24rpx;
|
||
|
||
&.safe {
|
||
background: #e3fff1;
|
||
color: #1fcc79;
|
||
}
|
||
|
||
&.careful {
|
||
background: #ffe8e8;
|
||
color: #ff6464;
|
||
}
|
||
|
||
&.limited {
|
||
background: #fff8e1;
|
||
color: #ff9800;
|
||
}
|
||
}
|
||
|
||
.category-badge {
|
||
background: #fff5f0;
|
||
border: 1rpx solid #ff6b35;
|
||
border-radius: 12rpx;
|
||
padding: 4rpx 16rpx;
|
||
|
||
text {
|
||
font-size: 24rpx;
|
||
color: #ff6b35;
|
||
font-weight: 500;
|
||
}
|
||
}
|
||
|
||
.nutrition-list {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 8rpx;
|
||
}
|
||
|
||
.nutrition-item {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
|
||
.nutrition-label {
|
||
font-size: 24rpx;
|
||
color: #9fa5c0;
|
||
}
|
||
|
||
.nutrition-value {
|
||
font-size: 24rpx;
|
||
|
||
&.green {
|
||
color: #1fcc79;
|
||
}
|
||
|
||
&.red {
|
||
color: #ff6464;
|
||
}
|
||
|
||
&.orange {
|
||
color: #ff9800;
|
||
}
|
||
}
|
||
}
|
||
</style>
|