553 lines
21 KiB
Vue
Raw Normal View History

2025-04-18 17:17:23 +08:00
<script setup>
2025-04-22 15:46:48 +08:00
import {ElNotification} from "element-plus";
2025-05-04 22:07:13 +08:00
import {resourceDelete, resourceList, resourcePost, resourcePut, resourceGetAllItems} from "@/api/resource.js";
2025-04-22 15:46:48 +08:00
import {ref, toRaw} from "vue";
2025-04-24 20:39:31 +08:00
import {useRoute} from 'vue-router';
2025-04-30 15:46:14 +08:00
import LocalCache from "@/stores/localCache.js";
import empty from '@/components/restful/empty.vue';
2025-05-04 22:07:13 +08:00
import {getWhereConditionDesc} from "@/utils/string.js";
2025-04-26 13:50:26 +08:00
2025-04-27 17:23:19 +08:00
const cachedResource = LocalCache.getCache("resource");
2025-04-24 20:39:31 +08:00
2025-04-22 15:46:48 +08:00
const listRsp = ref({fields_desc: [], rows: []})
2025-04-24 20:39:31 +08:00
const listDataOK = ref(false)
2025-05-04 22:07:13 +08:00
const projectId = cachedResource.meta.projectId
2025-04-27 17:23:19 +08:00
const resource_raw_node = cachedResource;
2025-04-30 15:46:14 +08:00
const hasListPermit = resource_raw_node.meta.methods.get !== undefined && resource_raw_node.meta.methods.get === true;
2025-04-27 17:23:19 +08:00
const resource_url = cachedResource.meta.resource_url;
2025-04-22 15:46:48 +08:00
const fieldsDescInfo = ref([])
2025-05-04 22:07:13 +08:00
const whereFieldsDescInfo = ref([])
const calcElColSpan = ref(0)
2025-04-22 15:46:48 +08:00
const rows = ref([])
const rules = ref({})
2025-04-30 15:46:14 +08:00
const current_page = ref(0)
const page_size = ref(0)
2025-04-24 20:39:31 +08:00
const item = ref({
2025-05-04 22:07:13 +08:00
id: '',
2025-04-24 20:39:31 +08:00
number: 1,
})
2025-04-27 17:23:19 +08:00
// console.log("enter table, resource:", cachedResource)
2025-04-24 20:39:31 +08:00
2025-04-22 15:46:48 +08:00
const listData = async () => {
try {
2025-04-24 20:39:31 +08:00
let listParams = {
page_no: 0,
page_len: 100,
2025-05-04 22:07:13 +08:00
where_conditions: "",
2025-04-24 20:39:31 +08:00
}
2025-05-04 22:07:13 +08:00
let whereReqConditions = {
conditions: []
}
whereFieldsDescInfo.value.forEach((field) => {
if (field.value1) {
whereReqConditions.conditions.push({
key: field.key,
op: field.where,
value1: field.value1,
value2: field.value2,
})
}
})
listParams.where_conditions = JSON.stringify(whereReqConditions)
2025-04-27 17:23:19 +08:00
// console.log("list params:", listParams)
2025-04-24 20:39:31 +08:00
const rspData = await resourceList(resource_url, listParams);
2025-04-22 15:46:48 +08:00
listRsp.value = rspData;
if (listRsp.value.code !== 200) throw new Error("请求失败,错误码:", listRsp.code);
fieldsDescInfo.value = listRsp.value.data.fields_desc
rows.value = listRsp.value.data.rows
for (let i = 0; i < fieldsDescInfo.value.length; i++) {
var field = fieldsDescInfo.value[i]
dialogAddForm.value[field.key] = ''
2025-04-28 15:56:04 +08:00
2025-04-24 20:39:31 +08:00
if (field.required == true) {
2025-04-22 15:46:48 +08:00
rules.value[field.key] = [{required: true, message: field.name + "不能为空", trigger: "blur"}]
}
2025-04-24 20:39:31 +08:00
if (field.type == "items") {
2025-04-28 15:56:04 +08:00
dialogAddForm.value[field.key] = []
2025-04-24 20:39:31 +08:00
for (let j = 0; j < rows.value.length; j++) {
rows.value[j].jsonValue = JSON.stringify(rows.value[j][field.key])
}
}
2025-05-04 22:07:13 +08:00
if (field.where !== "") {
field.value1 = ""
field.value2 = ""
field.whereDesc = getWhereConditionDesc(field.where)
let find = false
for (let i = 0; i < whereFieldsDescInfo.value.length; i++) {
let whereField = whereFieldsDescInfo.value[i]
if (whereField.key === field.key) {
whereFieldsDescInfo.value[i].type = field.type
whereFieldsDescInfo.value[i].where = field.where
whereFieldsDescInfo.value[i].whereDesc = getWhereConditionDesc(field.where)
find = true
break
}
}
if (!find) {
whereFieldsDescInfo.value.push(field)
}
}
2025-04-22 15:46:48 +08:00
}
2025-05-04 22:07:13 +08:00
calcElColSpan.value = 0
// 计算el-col占用24格子的span数量
let calcElColSpanTmp = 1
whereFieldsDescInfo.value.forEach((field) => {
if (field.where === "range") {
calcElColSpanTmp += 2
} else {
calcElColSpanTmp += 1
}
})
calcElColSpan.value = 24/calcElColSpanTmp
console.log("where fields:", whereFieldsDescInfo.value)
2025-04-27 17:23:19 +08:00
// console.log('await list rsp:', listRsp.value, fieldsDescInfo.value, toRaw(rows.value), toRaw(rules.value))
2025-04-22 15:46:48 +08:00
2025-04-24 20:39:31 +08:00
listDataOK.value = true
2025-04-22 15:46:48 +08:00
} catch (err) {
console.log(err)
} finally {
}
}
onMounted(() => {
listData();
})
const dialogAddVisible = ref(false)
const dialogEditVisible = ref(false)
const dialogAddFormRef = ref(null)
const dialogEditFormRef = ref(null)
2025-04-24 20:39:31 +08:00
const dialogAddForm = ref({
ServerIDs: [],
2025-04-28 15:56:04 +08:00
Attach: [],
2025-04-24 20:39:31 +08:00
})
2025-04-22 15:46:48 +08:00
const dialogEditForm = ref({})
2025-04-18 17:43:08 +08:00
2025-04-18 17:17:23 +08:00
2025-04-22 15:46:48 +08:00
const submitAdd = async () => {
try {
await dialogAddFormRef.value.validate(valid => {
if (valid) {
2025-04-24 20:39:31 +08:00
console.log("commit add form:", dialogAddForm.value)
2025-04-22 15:46:48 +08:00
resourcePost(resource_url, dialogAddForm.value).then((res) => {
ElNotification({
title: "添加结果通知",
message: "添加成功!",
type: 'success',
duration: 4000,
"show-close": true,
})
2025-04-24 20:39:31 +08:00
rows.value.push(res.data.dto)
2025-04-22 15:46:48 +08:00
dialogAddVisible.value = false
2025-04-28 15:56:04 +08:00
handleCloseDialog()
2025-04-22 15:46:48 +08:00
}, (err) => {
console.log("添加报错:", err)
})
console.log("提交数据:", dialogAddForm.value)
}
})
} catch (error) {
console.log("校验失败:", error)
}
}
2025-04-18 17:17:23 +08:00
2025-04-22 15:46:48 +08:00
const submitEdit = async () => {
try {
await dialogEditFormRef.value.validate(valid => {
if (valid) {
resourcePut(resource_url, dialogEditForm.value).then((res) => {
ElNotification({
title: "编辑结果通知",
message: "编辑成功!",
type: 'success',
duration: 4000,
"show-close": true,
})
dialogEditVisible.value = false
rows.value[dialogEditForm.value.oldIndex] = res.data.dto
2025-04-28 15:56:04 +08:00
handleCloseDialog()
2025-04-22 15:46:48 +08:00
}, (err) => {
console.log("添加报错:", err)
})
console.log("提交数据:", dialogEditForm.value)
}
})
} catch (error) {
console.log("校验失败:", error)
}
}
2025-04-24 20:39:31 +08:00
const handleEdit = (index, row) => {
2025-04-22 15:46:48 +08:00
dialogEditForm.value.oldData = row
dialogEditForm.value.oldIndex = index
dialogEditForm.value = row
console.log("edit data:", row)
dialogEditVisible.value = true
}
2025-04-24 20:39:31 +08:00
const handleDelete = (index, row) => {
2025-04-28 15:56:04 +08:00
ElMessageBox.confirm("确定要删除吗?").then(() => {
resourceDelete(resource_url, {id: row.ID}).then((res) => {
ElNotification({
title: "删除结果通知",
message: "删除数据[" + row.ID + "]成功!",
type: 'success',
duration: 4000,
"show-close": true,
})
rows.value.splice(index, 1)
}, (err) => {
console.log("delet error:", err)
2025-04-22 15:46:48 +08:00
})
2025-04-28 15:56:04 +08:00
}).catch(() => {
2025-04-22 15:46:48 +08:00
})
2025-04-28 15:56:04 +08:00
2025-04-22 15:46:48 +08:00
}
2025-04-24 20:39:31 +08:00
function addItem(fieldDescInfo) {
if (item.value.id == null || item.value.id == '' || item.value.id < 0) {
ElMessage('请选择道具!')
return;
}
if (item.value.num == null || item.value.num == '' || item.value.num <= 0) {
ElMessage('请输入有效道具数量!')
return;
}
let d = {id: item.value.id, num: Number(item.value.num)};
for (let i = 0; i < fieldDescInfo.choices.length; i++) {
const field = fieldDescInfo.choices[i]
if (field.value === item.value.id) {
d.item_type = field.type
break
}
}
console.log("add item:", d)
if (typeof dialogAddForm.value.Attach === typeof "") {
dialogAddForm.value.Attach = [];
}
dialogAddForm.value.Attach.push(d);
}
function deleteItem(row) {
// 移除该对象
let number = form.value.Attach.findIndex(item => item === row);
dialogAddForm.value.Attach.splice(number, 1);
}
2025-04-22 15:46:48 +08:00
const handleCloseDialog = () => {
2025-04-28 15:56:04 +08:00
console.log("关闭添加/编辑弹窗")
2025-04-22 15:46:48 +08:00
dialogAddVisible.value = false
dialogEditVisible.value = false
2025-04-24 20:39:31 +08:00
dialogAddForm.value = {
Attach: [],
}
2025-04-22 15:46:48 +08:00
dialogEditForm.value = {}
}
2025-04-18 17:17:23 +08:00
2025-05-04 22:07:13 +08:00
const loadingRemoteItems = ref(false)
const itemChoices = ref({})
const handleQueryItem = (itemQueryStr) => {
if (!itemQueryStr) {
itemChoices.value = []
return
}
loadingRemoteItems.value = true
itemQueryStr = itemQueryStr.replace(/[\s\u3000]/g, "")
resourceGetAllItems(projectId).then((res) => {
console.log("获取所有道具返回:", res.data)
console.log("查询字符串:[" + itemQueryStr + "]")
itemChoices.value = res.data.items.filter((item) => {
return item.desc.includes(itemQueryStr)
})
loadingRemoteItems.value = false
}, (err) => {
itemChoices.value = []
})
}
2025-04-18 17:17:23 +08:00
</script>
<template>
2025-04-30 15:46:14 +08:00
<template v-if="!hasListPermit">
<component :is="empty"></component>
</template>
<template v-else>
<el-container v-if="listDataOK">
<el-header>
2025-05-04 22:07:13 +08:00
<el-row :gutter="20" v-if="(whereFieldsDescInfo.length !== 0)">
<template v-for="fieldDescInfo in whereFieldsDescInfo">
<template v-if="(fieldDescInfo.where === 'range')">
<el-col :span="calcElColSpan">
<el-date-picker v-model="fieldDescInfo.value1" type="datetime"
:placeholder="(fieldDescInfo.name + '起始')" format="YYYY/MM/DD HH:mm:ss"
value-format="YYYY/MM/DD HH:mm:ss"></el-date-picker>
</el-col>
<el-col :span="calcElColSpan">
<el-date-picker v-model="fieldDescInfo.value2" type="datetime"
:placeholder="(fieldDescInfo.name + '结束')" format="YYYY/MM/DD HH:mm:ss"
value-format="YYYY/MM/DD HH:mm:ss"></el-date-picker>
</el-col>
</template>
<template v-else>
<el-input v-model="fieldDescInfo.value1"
:placeholder="(fieldDescInfo.name + fieldDescInfo.whereDesc)" style="width: 150px"></el-input>
</template>
</template>
<el-col :span="calcElColSpan">
<el-button @click="listData" type="primary">条件搜索</el-button>
</el-col>
</el-row>
<el-row style="margin-top: 10px">
<el-button @click="dialogAddVisible = true" size="large" type="primary"
v-if="(resource_raw_node.meta.methods.post === true)">
添加
</el-button>
</el-row>
2025-04-30 15:46:14 +08:00
</el-header>
<el-main>
<el-table :data="rows" style="width: 100%" table-layout="auto" stripe>
2025-04-22 15:46:48 +08:00
<template v-for="fieldDescInfo in fieldsDescInfo">
2025-04-30 15:46:14 +08:00
<el-table-column prop="jsonValue" :label="fieldDescInfo.name"
v-if="(fieldDescInfo.type === 'items')"></el-table-column>
<el-table-column :prop="fieldDescInfo.key" :label="fieldDescInfo.name"
v-else></el-table-column>
</template>
<el-table-column prop="func" label="功 能">
<template #default="scope">
<el-button size="default" type="success" @click="handleEdit( scope.$index, scope.row)"
v-if="(resource_raw_node.meta.methods.put === true)">
<el-icon style="vertical-align: middle">
<Edit/>
</el-icon>
<span>编辑</span>
</el-button>
<el-button size="default" type="danger" @click="handleDelete( scope.$index, scope.row)"
v-if="(resource_raw_node.meta.methods.delete === true)">
<el-icon style="vertical-align: middle">
<Delete/>
</el-icon>
<span>删除</span>
</el-button>
2025-04-24 20:39:31 +08:00
</template>
2025-04-30 15:46:14 +08:00
</el-table-column>
</el-table>
<!-- 表格数据分页 -->
<div class="demo-pagination-block">
<div class="demonstration"></div>
<el-pagination
v-model:current-page="current_page"
v-model:page-size="page_size"
:page-sizes="[20, 50, 100]"
layout="total, sizes, prev, pager, next, jumper"
:total="400"
/>
</div>
<el-dialog v-model="dialogAddVisible" :mask="true" title="添加" :modal="true" :before-close="handleCloseDialog"
destroy-on-close>
<el-form ref="dialogAddFormRef" :model="dialogAddForm" :rules="rules" label-position="right"
label-width="130px">
<template v-for="fieldDescInfo in fieldsDescInfo">
<!--如何是items类型就是物品下拉框+道具组合-->
<template v-if="(fieldDescInfo.type === 'items')">
<el-form :inline="true" :model="item" label-position="right">
<el-form-item :label="fieldDescInfo.name" :prop="fieldDescInfo.key" label-width="130px">
<el-tooltip effect="light" :content="fieldDescInfo.help_text" placement="bottom-start">
2025-05-04 22:07:13 +08:00
<el-select v-model="item.id" placeholder="--搜索道具--" style="width: 150px"
filterable remote
:remote-method="handleQueryItem"
:loading="loadingRemoteItems">
<el-option v-for="info in itemChoices" :key="info.value" :label="info.desc"
2025-04-30 15:46:14 +08:00
:value="info.value"></el-option>
</el-select>
</el-tooltip>
</el-form-item>
<el-form-item label="数量" prop="num">
<el-input type="number" v-model="item.num" placeholder="请输入数量" style="width: 150px"/>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="addItem(fieldDescInfo)">添加</el-button>
</el-form-item>
</el-form>
<el-form-item label="奖励列表" prop="Attach">
<el-table :data="dialogAddForm.Attach" border>
<el-table-column label="道具id" prop="id"/>
<el-table-column label="数量" prop="num"/>
<el-table-column label="操作">
<template #default="scope">
<el-button type="danger" size="small" @click="deleteItem(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
2025-04-28 15:56:04 +08:00
</el-form-item>
</template>
2025-04-30 15:46:14 +08:00
<template v-else-if="(fieldDescInfo.readonly !== true)">
2025-04-28 15:56:04 +08:00
<!-- 有可选项的字段走下拉框或者多选框 -->
<template v-if="(fieldDescInfo.choices !== undefined && fieldDescInfo.choices.length > 0)">
<el-form-item :label="fieldDescInfo.name" :prop="fieldDescInfo.key">
<el-tooltip effect="light" :content="fieldDescInfo.help_text" placement="bottom-start">
<el-select :placeholder="(fieldDescInfo.multi_choice === true ? '--多选--' : '--单选--')"
2025-04-30 15:46:14 +08:00
v-model="dialogAddForm[fieldDescInfo.key]" style="width: 150px"
2025-04-28 15:56:04 +08:00
:multiple="(fieldDescInfo.multi_choice === true)">
<el-option v-for="info in fieldDescInfo.choices" :key="info.desc" :label="info.desc"
:value="info.value"></el-option>
</el-select>
</el-tooltip>
</el-form-item>
</template>
<!-- 时间戳字段展示时间选择器 -->
<template v-else-if="(fieldDescInfo.type === 'Time')">
<el-form-item :label="fieldDescInfo.name" :prop="fieldDescInfo.key">
2025-04-30 15:46:14 +08:00
<el-date-picker v-model="dialogAddForm[fieldDescInfo.key]" type="datetime"
2025-04-28 15:56:04 +08:00
placeholder="选个时间" format="YYYY/MM/DD HH:mm:ss"
value-format="YYYY/MM/DD HH:mm:ss"></el-date-picker>
</el-form-item>
</template>
<!-- 否则就是普通字段 -->
<template v-else>
<el-form-item :label="fieldDescInfo.name" :prop="fieldDescInfo.key">
2025-04-30 15:46:14 +08:00
<el-input v-model="dialogAddForm[fieldDescInfo.key]"
2025-04-28 15:56:04 +08:00
:placeholder="fieldDescInfo.help_text"></el-input>
</el-form-item>
</template>
</template>
2025-04-30 15:46:14 +08:00
</template>
<el-form-item>
<el-button @click="submitAdd(dialogAddFormRef)" size="large" type="primary">提交</el-button>
</el-form-item>
</el-form>
</el-dialog>
<el-dialog v-model="dialogEditVisible" :mask="true" title="编辑" :modal="true" :before-close="handleCloseDialog"
destroy-on-close>
<el-form ref="dialogEditFormRef" :model="dialogEditForm" :rules="rules" class="operation_form"
label-width="130px">
<template v-for="fieldDescInfo in fieldsDescInfo">
<!--如果是items类型就是物品下拉框+道具组合-->
<template v-if="(fieldDescInfo.type === 'items')">
<el-form :inline="true" :model="item" label-position="right"
label-width="130px">
<el-form-item :label="fieldDescInfo.name" :prop="fieldDescInfo.key">
<el-tooltip effect="light" :content="fieldDescInfo.help_text" placement="bottom-start">
2025-05-04 22:07:13 +08:00
<el-select placeholder="--搜索道具--" v-model="item.id" style="width: 150px"
filterable remote :remote-method="handleQueryItem" :loading="loadingRemoteItems">
<el-option v-for="info in itemChoices" :key="info.value" :label="info.desc"
2025-04-30 15:46:14 +08:00
:value="info.value"></el-option>
</el-select>
</el-tooltip>
</el-form-item>
<el-form-item label="数量" prop="number">
<el-input type="number" v-model="item.num" placeholder="请输入数量" style="width: 150px"/>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="addItem(fieldDescInfo)">添加</el-button>
</el-form-item>
</el-form>
<el-form-item label="奖励列表" prop="attachmentsList">
<el-table :data="dialogEditForm.Attach" border>
<el-table-column label="道具id" prop="id"/>
<el-table-column label="数量" prop="num"/>
<el-table-column label="操作">
<template #default="scope">
<el-button type="danger" size="small" @click="deleteItem(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
2025-04-28 15:56:04 +08:00
</el-form-item>
</template>
2025-04-30 15:46:14 +08:00
<template v-else-if="(fieldDescInfo.readonly !== true)">
<template v-if="(fieldDescInfo.uneditable !== true)">
<!-- 有可选项的字段走下拉框或者多选框 -->
<template v-if="(fieldDescInfo.choices !== undefined && fieldDescInfo.choices.length > 0)">
<el-form-item :label="fieldDescInfo.name" :prop="fieldDescInfo.key">
<el-tooltip effect="light" :content="fieldDescInfo.help_text" placement="bottom-start">
<el-select :placeholder="(fieldDescInfo.multi_choice === true ? '--多选--' : '--单选--')"
v-model="dialogEditForm[fieldDescInfo.key]" style="width: 150px"
:multiple="(fieldDescInfo.multi_choice === true)">
<el-option v-for="info in fieldDescInfo.choices" :key="info.desc" :label="info.desc"
:value="info.value"></el-option>
</el-select>
</el-tooltip>
</el-form-item>
</template>
<!-- 时间戳字段展示时间选择器 -->
<template v-else-if="(fieldDescInfo.type === 'Time')">
<el-form-item :label="fieldDescInfo.name" :prop="fieldDescInfo.key">
<el-date-picker v-model="dialogEditForm[fieldDescInfo.key]" type="datetime"
placeholder="选个时间" format="YYYY/MM/DD HH:mm:ss"
value-format="YYYY/MM/DD HH:mm:ss"></el-date-picker>
</el-form-item>
</template>
<!-- 否则就是普通字段 -->
<template v-else>
<el-form-item :label="fieldDescInfo.name" :prop="fieldDescInfo.key">
<el-input v-model="dialogEditForm[fieldDescInfo.key]"
:placeholder="fieldDescInfo.help_text"></el-input>
</el-form-item>
</template>
</template>
2025-04-28 15:56:04 +08:00
2025-04-30 15:46:14 +08:00
<template v-else>
<el-form-item :label="fieldDescInfo.name" :prop="fieldDescInfo.key">
<el-input v-model="dialogEditForm[fieldDescInfo.key]"
:placeholder="fieldDescInfo.help_text" disabled></el-input>
</el-form-item>
</template>
</template>
<!-- <el-form-item :label="fieldDescInfo.name" :prop="fieldDescInfo.key">-->
<!-- <el-input v-model="dialogEditForm[fieldDescInfo.key]"></el-input>-->
<!-- </el-form-item>-->
</template>
2025-04-18 17:43:08 +08:00
2025-04-30 15:46:14 +08:00
<el-form-item>
<el-button @click="submitEdit(dialogEditFormRef)" size="large" type="primary">提交</el-button>
</el-form-item>
</el-form>
</el-dialog>
2025-04-18 17:43:08 +08:00
2025-04-30 15:46:14 +08:00
</el-main>
</el-container>
</template>
2025-04-18 17:17:23 +08:00
</template>
2025-04-27 17:23:19 +08:00
<style scoped lang="scss">
2025-04-30 15:46:14 +08:00
.demo-pagination-block {
margin-top: 10px;
.el-pagination {
right: 40px;
position: absolute;
}
}
2025-04-18 17:17:23 +08:00
</style>