feat(category): 新增随形品类及相关设计功能
- 添加随形品类到数据库初始化脚本和类别列表 - 补充随形品类的视图类型,增加背面图支持 - 更新依赖,新增bcrypt库支持 - 前端子类型面板增加颜色选择逻辑,适配随形品类 - 类别状态管理中,simple类型也加载颜色数据,支持随形品类需求 - 设计生成页新增随形专属参数“形状描述”与自定义输入 - 提示文本根据随形品类调整,指导用户描述设计需求 - 生成设计时将形状描述拼接至最终prompt,提高表达准确性 - 样式优化,新增参数提示文字样式,增强界面友好度 - 初始化脚本清空历史数据,保证每次导入数据全新一致
This commit is contained in:
@@ -105,9 +105,21 @@
|
||||
<path d="M8 12L11 15L16 9" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
</div>
|
||||
<p>点击下方按钮,进入设计生成页面</p>
|
||||
<p>选择颜色后点击下方按钮,进入设计生成页面</p>
|
||||
</div>
|
||||
<div class="action-bar">
|
||||
<!-- 随形等品类的颜色选择 -->
|
||||
<template v-if="colors.length > 0">
|
||||
<ColorPicker
|
||||
v-model="selectedColor"
|
||||
:colors="colors"
|
||||
/>
|
||||
<div v-if="selectedColor" class="action-bar">
|
||||
<button class="btn-primary" @click="goToGenerate">
|
||||
开始设计
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
<div v-else class="action-bar">
|
||||
<button class="btn-primary" @click="goToGenerate">
|
||||
开始设计
|
||||
</button>
|
||||
|
||||
@@ -60,8 +60,11 @@ export const useCategoryStore = defineStore('category', () => {
|
||||
])
|
||||
subTypes.value = subTypesData
|
||||
colors.value = colorsData
|
||||
} else {
|
||||
// simple 类型也加载颜色(如随形品类需要选颜色)
|
||||
const colorsData = await getColorsApi(category.id)
|
||||
colors.value = colorsData
|
||||
}
|
||||
// simple 类型不需要加载额外数据
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
@@ -53,6 +53,27 @@
|
||||
|
||||
<!-- 参数面板 -->
|
||||
<div class="params-panel">
|
||||
<!-- 形状描述(仅随形品类显示) -->
|
||||
<div v-if="isFreeform" class="param-group">
|
||||
<label class="param-label">形状描述 <span class="param-hint">(随形专属)</span></label>
|
||||
<div class="tag-list">
|
||||
<span
|
||||
v-for="opt in shapeOptions"
|
||||
:key="opt"
|
||||
class="tag-item"
|
||||
:class="{ active: shapeDesc === opt }"
|
||||
@click="selectTag('shapeDesc', opt)"
|
||||
>{{ opt }}</span>
|
||||
<el-input
|
||||
v-model="customShape"
|
||||
placeholder="自定义形状"
|
||||
size="small"
|
||||
class="custom-input"
|
||||
@focus="shapeDesc = ''"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 雕刻工艺 -->
|
||||
<div class="param-group">
|
||||
<label class="param-label">雕刻工艺</label>
|
||||
@@ -292,6 +313,12 @@ const prompt = ref('')
|
||||
const generating = computed(() => designStore.generating)
|
||||
const currentDesign = computed(() => designStore.currentDesign)
|
||||
|
||||
// 随形专属:形状描述
|
||||
const isFreeform = computed(() => categoryName.value.includes('随形'))
|
||||
const shapeDesc = ref('')
|
||||
const customShape = ref('')
|
||||
const shapeOptions = ['原石随形', '水滴形', '不规则块状', '鹅卵石形', '片状', '柱状', '扁圆形']
|
||||
|
||||
// 新增参数状态
|
||||
const carvingTechnique = ref('')
|
||||
const designStyle = ref('')
|
||||
@@ -310,11 +337,11 @@ const customScene = ref('')
|
||||
|
||||
// 自定义输入与标签的关联 Map
|
||||
const tagRefs: Record<string, any> = {
|
||||
carvingTechnique, designStyle, motif, sizeSpec, surfaceFinish, usageScene
|
||||
carvingTechnique, designStyle, motif, sizeSpec, surfaceFinish, usageScene, shapeDesc
|
||||
}
|
||||
const customRefs: Record<string, any> = {
|
||||
carvingTechnique: customCarving, designStyle: customStyle, motif: customMotif,
|
||||
sizeSpec: customSize, surfaceFinish: customFinish, usageScene: customScene
|
||||
sizeSpec: customSize, surfaceFinish: customFinish, usageScene: customScene, shapeDesc: customShape
|
||||
}
|
||||
|
||||
// 选择标签时清除对应自定义输入
|
||||
@@ -345,6 +372,7 @@ const sizeOptions = computed(() => {
|
||||
if (name.includes('摆件')) return ['小(约8cm)', '中(约15cm)', '大(约25cm)']
|
||||
if (name.includes('戒')) return ['戒面7号', '戒鞍12号', '戒鞍15号', '戒鞍18号']
|
||||
if (name.includes('表带')) return ['宽18mm', '宽20mm', '宽22mm']
|
||||
if (name.includes('随形')) return ['小(约60mm)', '中(约80mm)', '大(约100mm)', '特大(约150mm)']
|
||||
return ['小', '中', '大']
|
||||
})
|
||||
|
||||
@@ -357,6 +385,9 @@ const promptPlaceholder = computed(() => {
|
||||
if (name.includes('珠') || name.includes('珠子')) {
|
||||
return '请描述您想要的图案,如:回纹、云纹、简单素面...'
|
||||
}
|
||||
if (name.includes('随形')) {
|
||||
return '请描述您想要的设计,如:原石随形雕刻山水、保留皮色的自然形态、利用石形雕刻动物...'
|
||||
}
|
||||
return '请描述您的设计需求...'
|
||||
})
|
||||
|
||||
@@ -365,6 +396,17 @@ const goBack = () => {
|
||||
router.push('/')
|
||||
}
|
||||
|
||||
// 构建最终prompt:随形品类时将形状描述拼接到前面
|
||||
const _buildFinalPrompt = () => {
|
||||
const userPrompt = prompt.value.trim()
|
||||
if (!isFreeform.value) return userPrompt
|
||||
const shape = shapeDesc.value || customShape.value
|
||||
if (shape) {
|
||||
return `形状:${shape},${userPrompt}`
|
||||
}
|
||||
return userPrompt
|
||||
}
|
||||
|
||||
// 生成设计
|
||||
const handleGenerate = async () => {
|
||||
if (!categoryId.value) {
|
||||
@@ -381,7 +423,7 @@ const handleGenerate = async () => {
|
||||
category_id: categoryId.value,
|
||||
sub_type_id: subTypeId.value || undefined,
|
||||
color_id: colorId.value || undefined,
|
||||
prompt: prompt.value.trim(),
|
||||
prompt: _buildFinalPrompt(),
|
||||
carving_technique: carvingTechnique.value || customCarving.value || undefined,
|
||||
design_style: designStyle.value || customStyle.value || undefined,
|
||||
motif: motif.value || customMotif.value || undefined,
|
||||
@@ -589,6 +631,12 @@ $text-light: #999999;
|
||||
color: $text-secondary;
|
||||
margin-bottom: 8px;
|
||||
letter-spacing: 1px;
|
||||
|
||||
.param-hint {
|
||||
font-weight: 400;
|
||||
font-size: 12px;
|
||||
color: $secondary-color;
|
||||
}
|
||||
}
|
||||
|
||||
.tag-list {
|
||||
|
||||
Reference in New Issue
Block a user