|
|
@@ -11,7 +11,7 @@
|
|
|
<el-input v-model="formData.name" placeholder="请输入名称" />
|
|
|
</el-form-item>
|
|
|
<el-form-item label="简介" prop="info" width="100%">
|
|
|
- <el-input v-model="formData.info" placeholder="请输入简介" />
|
|
|
+ <Editor v-model="formData.info" height="150px" />
|
|
|
</el-form-item>
|
|
|
|
|
|
<el-row>
|
|
|
@@ -28,7 +28,7 @@
|
|
|
|
|
|
<el-col :span="12">
|
|
|
<el-form-item label="人物朝向" prop="userDirection">
|
|
|
- <el-radio-group v-model="formData.userDirection" size="large" >
|
|
|
+ <el-radio-group v-model="formData.userDirection" size="large">
|
|
|
<el-radio-button label="上" :value="0" />
|
|
|
<el-radio-button label="右" :value="1" />
|
|
|
<el-radio-button label="下" :value="2" />
|
|
|
@@ -51,42 +51,91 @@
|
|
|
<el-form-item label="地图开始坐标" required>
|
|
|
<div class="coordinate-group">
|
|
|
X:
|
|
|
- <el-input-number v-model="mapStartPointX" placeholder="X轴" :min="1" style="width: 120px;" />
|
|
|
+ <el-input-number
|
|
|
+ v-model="mapStartPointX"
|
|
|
+ placeholder="X轴"
|
|
|
+ :min="1"
|
|
|
+ :step="1"
|
|
|
+ style="width: 120px"
|
|
|
+ />
|
|
|
Y:
|
|
|
- <el-input-number v-model="mapStartPointY" placeholder="Y轴" :min="1" style="width: 120px;" />
|
|
|
+ <el-input-number
|
|
|
+ v-model="mapStartPointY"
|
|
|
+ placeholder="Y轴"
|
|
|
+ :min="1"
|
|
|
+ :step="1"
|
|
|
+ style="width: 120px"
|
|
|
+ />
|
|
|
</div>
|
|
|
</el-form-item>
|
|
|
-
|
|
|
+
|
|
|
<!-- 地图结束坐标 - 拆分为X轴和Y轴 -->
|
|
|
<el-form-item label="地图结束坐标" required>
|
|
|
<div class="coordinate-group">
|
|
|
X:
|
|
|
- <el-input-number v-model="mapEndPointX" placeholder="X轴" :min="1" style="width: 120px;" />
|
|
|
+ <el-input-number
|
|
|
+ v-model="mapEndPointX"
|
|
|
+ placeholder="X轴"
|
|
|
+ :min="1"
|
|
|
+ :step="1"
|
|
|
+ style="width: 120px"
|
|
|
+ />
|
|
|
Y:
|
|
|
- <el-input-number v-model="mapEndPointY" placeholder="Y轴" :min="1" style="width: 120px;" />
|
|
|
+ <el-input-number
|
|
|
+ v-model="mapEndPointY"
|
|
|
+ placeholder="Y轴"
|
|
|
+ :min="1"
|
|
|
+ :step="1"
|
|
|
+ style="width: 120px"
|
|
|
+ />
|
|
|
</div>
|
|
|
</el-form-item>
|
|
|
-
|
|
|
+
|
|
|
<!-- 地图可行走坐标 - 动态添加 -->
|
|
|
<el-form-item label="地图可行走坐标" required>
|
|
|
<div class="walkable-points-container">
|
|
|
<div v-for="(point, index) in walkablePoints" :key="index" class="walkable-point-item">
|
|
|
X:
|
|
|
- <el-input-number v-model="point.x" placeholder="X轴" :min="1" style="width: 100px;" />
|
|
|
+ <el-input-number
|
|
|
+ v-model="point.x"
|
|
|
+ placeholder="X轴"
|
|
|
+ :min="1"
|
|
|
+ :step="1"
|
|
|
+ style="width: 100px"
|
|
|
+ />
|
|
|
Y:
|
|
|
- <el-input-number v-model="point.y" placeholder="Y轴" :min="1" style="width: 100px;" />
|
|
|
- <el-select v-model="point.type" placeholder="类型" style="width: 120px;" clearable>
|
|
|
- <el-option v-for="dict in getIntDictOptions(DICT_TYPE.AI_BLOCKLY_MAP_TYPE)" :key="String(dict.value)" :label="dict.label" :value="dict.value" />
|
|
|
+ <el-input-number
|
|
|
+ v-model="point.y"
|
|
|
+ placeholder="Y轴"
|
|
|
+ :min="1"
|
|
|
+ :step="1"
|
|
|
+ style="width: 100px"
|
|
|
+ />
|
|
|
+ <el-select v-model="point.type" placeholder="类型" style="width: 120px" clearable>
|
|
|
+ <el-option
|
|
|
+ v-for="dict in getStrDictOptions(DICT_TYPE.AI_BLOCKLY_MAP_TYPE)"
|
|
|
+ :key="dict.value"
|
|
|
+ :label="dict.label"
|
|
|
+ :value="dict.value"
|
|
|
+ />
|
|
|
</el-select>
|
|
|
- <el-input v-model="point.tip" placeholder="提示语" style="flex: 1; min-width: 200px;" />
|
|
|
- <el-button @click="removeWalkablePoint(index)" type="danger" circle :disabled="walkablePoints.length <= 1" >
|
|
|
- <Icon icon="ep:delete" /></el-button>
|
|
|
+ <el-input v-model="point.tip" placeholder="提示语" style="flex: 1; min-width: 200px" />
|
|
|
+ <el-button
|
|
|
+ @click="removeWalkablePoint(index)"
|
|
|
+ type="danger"
|
|
|
+ circle
|
|
|
+ :disabled="walkablePoints.length <= 2"
|
|
|
+ >
|
|
|
+ <Icon icon="ep:delete"
|
|
|
+ /></el-button>
|
|
|
</div>
|
|
|
</div>
|
|
|
- <el-button @click="addWalkablePoint" type="primary" style="margin-top: 10px;">+ 添加坐标</el-button>
|
|
|
+ <el-button @click="addWalkablePoint" type="primary" style="margin-top: 10px"
|
|
|
+ >+ 添加坐标</el-button
|
|
|
+ >
|
|
|
</el-form-item>
|
|
|
-
|
|
|
-<!-- <el-form-item label="json数据" prop="jsonData">
|
|
|
+
|
|
|
+ <!-- <el-form-item label="json数据" prop="jsonData">
|
|
|
<el-input
|
|
|
v-model="formData.jsonData"
|
|
|
type="textarea"
|
|
|
@@ -104,11 +153,7 @@
|
|
|
</el-col>
|
|
|
<el-col :span="12">
|
|
|
<el-form-item label="状态" prop="status">
|
|
|
- <el-select
|
|
|
- v-model="formData.status"
|
|
|
- placeholder="请选择状态"
|
|
|
- clearable
|
|
|
- >
|
|
|
+ <el-select v-model="formData.status" placeholder="请选择状态" clearable>
|
|
|
<el-option
|
|
|
v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
|
|
|
:key="dict.value"
|
|
|
@@ -128,7 +173,7 @@
|
|
|
</template>
|
|
|
<script setup lang="ts">
|
|
|
import { MapGameApi, MapGameVO } from '@/api/ai/mapgame'
|
|
|
-import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
|
|
+import { DICT_TYPE, getIntDictOptions, getStrDictOptions } from '@/utils/dict'
|
|
|
|
|
|
/** AI-blockly地图编程游戏 表单 */
|
|
|
defineOptions({ name: 'MapGameForm' })
|
|
|
@@ -144,7 +189,7 @@ const formData = ref({
|
|
|
id: undefined,
|
|
|
name: undefined,
|
|
|
info: undefined,
|
|
|
- userImage: "https://learn-ai.com.cn/admin-api/infra/file/29/get/20251107/user_1762504554550.png",
|
|
|
+ userImage: 'https://learn-ai.com.cn/admin-api/infra/file/29/get/20251107/user_1762504554550.png',
|
|
|
userDirection: 0,
|
|
|
mapTileSize: undefined,
|
|
|
mapStartPoint: undefined,
|
|
|
@@ -153,7 +198,7 @@ const formData = ref({
|
|
|
mapWalkablePoints: undefined,
|
|
|
jsonData: undefined,
|
|
|
sort: undefined,
|
|
|
- status: undefined
|
|
|
+ status: 0
|
|
|
})
|
|
|
|
|
|
// 新增的响应式数据
|
|
|
@@ -166,19 +211,19 @@ const mapEndPointY = ref<number>()
|
|
|
interface WalkablePoint {
|
|
|
x: number
|
|
|
y: number
|
|
|
- type: string | number
|
|
|
+ type: string
|
|
|
tip: string
|
|
|
}
|
|
|
|
|
|
// 可行走点数组
|
|
|
-const walkablePoints = ref<WalkablePoint[]>([{ x: 0, y: 0, type: "", tip: "" }])
|
|
|
+const walkablePoints = ref<WalkablePoint[]>([{ x: 0, y: 0, type: '', tip: '' }])
|
|
|
|
|
|
const formRules = reactive({
|
|
|
name: [{ required: true, message: '名称不能为空', trigger: 'blur' }],
|
|
|
userImage: [{ required: true, message: '人物图标不能为空', trigger: 'blur' }],
|
|
|
mapBackground: [{ required: true, message: '地图背景图不能为空', trigger: 'blur' }],
|
|
|
mapTileSize: [{ required: true, message: '地图方格尺寸不能为空', trigger: 'blur' }],
|
|
|
- userDirection: [{ required: true, message: '人物朝向不能为空', trigger: 'blur' }],
|
|
|
+ userDirection: [{ required: true, message: '人物朝向不能为空', trigger: 'blur' }]
|
|
|
// 注意:这里移除了对mapStartPoint、mapEndPoint和mapWalkablePoints的直接验证
|
|
|
// 因为这些值现在是通过计算得到的
|
|
|
})
|
|
|
@@ -207,7 +252,7 @@ const open = async (type: string, id?: number) => {
|
|
|
console.error('解析地图开始坐标失败:', e)
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
if (data.mapEndPoint) {
|
|
|
try {
|
|
|
const point = JSON.parse(data.mapEndPoint)
|
|
|
@@ -217,13 +262,13 @@ const open = async (type: string, id?: number) => {
|
|
|
console.error('解析地图结束坐标失败:', e)
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
if (data.mapWalkablePoints) {
|
|
|
try {
|
|
|
walkablePoints.value = JSON.parse(data.mapWalkablePoints)
|
|
|
} catch (e) {
|
|
|
console.error('解析地图可行走坐标失败:', e)
|
|
|
- walkablePoints.value = [{ x: 0, y: 0, type: "", tip: "" }]
|
|
|
+ walkablePoints.value = [{ x: 0, y: 0, type: '', tip: '' }]
|
|
|
}
|
|
|
}
|
|
|
} finally {
|
|
|
@@ -235,7 +280,7 @@ defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
|
|
|
|
|
/** 添加可行走点 */
|
|
|
const addWalkablePoint = () => {
|
|
|
- walkablePoints.value.push({ x: 0, y: 0, type: "", tip: "" })
|
|
|
+ walkablePoints.value.push({ x: 0, y: 0, type: '', tip: '' })
|
|
|
}
|
|
|
|
|
|
/** 移除可行走点 */
|
|
|
@@ -253,33 +298,33 @@ const submitForm = async () => {
|
|
|
message.error('地图开始坐标不能为空')
|
|
|
return
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
if (mapEndPointX.value === undefined || mapEndPointY.value === undefined) {
|
|
|
message.error('地图结束坐标不能为空')
|
|
|
return
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
// 检查可行走点数据
|
|
|
- const hasInvalidPoint = walkablePoints.value.some(point =>
|
|
|
- point.x === undefined || point.y === undefined
|
|
|
+ const hasInvalidPoint = walkablePoints.value.some(
|
|
|
+ (point) => point.x === undefined || point.y === undefined
|
|
|
)
|
|
|
-
|
|
|
+
|
|
|
if (hasInvalidPoint) {
|
|
|
message.error('请完善所有可行走点的数据')
|
|
|
return
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
// 表单基础验证
|
|
|
await formRef.value.validate()
|
|
|
-
|
|
|
+
|
|
|
// 准备提交数据 - 转换坐标为JSON格式
|
|
|
const submitData = { ...formData.value } as MapGameVO
|
|
|
-
|
|
|
+
|
|
|
// 设置坐标JSON
|
|
|
submitData.mapStartPoint = JSON.stringify({ x: mapStartPointX.value, y: mapStartPointY.value })
|
|
|
submitData.mapEndPoint = JSON.stringify({ x: mapEndPointX.value, y: mapEndPointY.value })
|
|
|
submitData.mapWalkablePoints = JSON.stringify(walkablePoints.value)
|
|
|
-
|
|
|
+
|
|
|
// 提交请求
|
|
|
formLoading.value = true
|
|
|
try {
|
|
|
@@ -304,7 +349,8 @@ const resetForm = () => {
|
|
|
id: undefined,
|
|
|
name: undefined,
|
|
|
info: undefined,
|
|
|
- userImage: "https://learn-ai.com.cn/admin-api/infra/file/29/get/20251107/user_1762504554550.png",
|
|
|
+ userImage:
|
|
|
+ 'https://learn-ai.com.cn/admin-api/infra/file/29/get/20251107/user_1762504554550.png',
|
|
|
userDirection: 0,
|
|
|
mapTileSize: undefined,
|
|
|
mapStartPoint: undefined,
|
|
|
@@ -313,16 +359,16 @@ const resetForm = () => {
|
|
|
mapWalkablePoints: undefined,
|
|
|
jsonData: undefined,
|
|
|
sort: undefined,
|
|
|
- status: undefined
|
|
|
+ status: 0
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
// 重置新增的响应式数据
|
|
|
mapStartPointX.value = undefined
|
|
|
mapStartPointY.value = undefined
|
|
|
mapEndPointX.value = undefined
|
|
|
mapEndPointY.value = undefined
|
|
|
- walkablePoints.value = [{ x: 0, y: 0, type: "", tip: "" }]
|
|
|
-
|
|
|
+ walkablePoints.value = [{ x: 0, y: 0, type: '', tip: '' }]
|
|
|
+
|
|
|
formRef.value?.resetFields()
|
|
|
}
|
|
|
</script>
|