2025-07-22 09:37:37 +08:00

1099 lines
44 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup>
import {ElNotification, selectGroupKey} from "element-plus";
import {
resourceDelete,
resourceList,
resourcePost,
resourcePut,
resourceGetAllItems,
resourceRowsSelectionPost
} from "@/api/resource.js";
import {ref, toRaw} from "vue";
import {useRoute} from 'vue-router';
import LocalCache from "@/stores/localCache.js";
import empty from '@/components/restful/empty.vue';
import {getWhereConditionDesc} from "@/utils/string.js";
import UserDetail from "@/components/game/userDetail.vue";
import router from "@/router/index.js";
import userStore from "@/stores/user.js";
const props = defineProps({
rowClickDialogBtns: Array,
})
let rowClickDialogBtns = []
if (props.rowClickDialogBtns) {
rowClickDialogBtns = props.rowClickDialogBtns
}
// console.log("btns:", rowClickDialogBtns)
const cachedResource = LocalCache.getCache("resource");
const listRsp = ref({fields_desc: [], rows: []})
const listDataOK = ref(false)
const projectId = cachedResource.meta.projectId
const resource_raw_node = cachedResource;
const hasListPermit = resource_raw_node.meta.methods.get !== undefined && resource_raw_node.meta.methods.get === true;
const globalClickBtns = resource_raw_node.meta.global_click_btns ? resource_raw_node.meta.global_click_btns : [];
let rowClickBtns = resource_raw_node.meta.row_click_btns ? resource_raw_node.meta.row_click_btns : []
rowClickBtns.push(...rowClickDialogBtns)
const rowClickBtnVisibleList = reactive(rowClickBtns.map(() => false))
const rowClickBtnSelectRow = ref(null)
// console.log("global btns:", globalClickBtns)
// console.log("row btns:", rowClickBtns)
const resource_url = cachedResource.meta.resource_url;
const fieldsDescInfo = ref([])
const whereFieldsDescInfo = ref([])
const rows = ref([])
const itemBags = ref([])
const rules = ref({})
const current_page = ref(1)
const page_size = ref(10)
const pageSizes = [10, 20, 50, 100]
const totalRowCount = ref(0)
const selectedItem = ref(null)
const selectedItemNum = ref(0)
const selectedItemBag = ref(null)
// console.log("enter table, resource:", cachedResource)
const handleServerRowData = (fieldsDescInfoData, rowData) => {
for (let i = 0; i < fieldsDescInfoData.length; i++) {
var field = fieldsDescInfoData[i]
// dialogObjectForm.value[field.key] = ''
if (field.required === true) {
rules.value[field.key] = [{required: true, message: field.name + "不能为空", trigger: "blur"}]
}
if (field.type === "items") {
dialogObjectForm.value[field.key] = []
rowData.jsonValue = JSON.stringify(rowData[field.key])
if (field.required === true) {
rules.value[field.key] = [{
required: true,
validator: (rule, value, callback) => {
console.log("触发校验道具列表规则:", dialogObjectForm.value)
if (dialogObjectForm.value.Attach === undefined || dialogObjectForm.value.Attach.length === 0) {
callback(new Error("请至少填写一个奖励道具!"))
} else {
callback()
}
},
trigger: ["blur", "change"],
}]
}
}
const tagStatusColorArray = ["plain", "primary", "success", "info", "waring", "danger"]
if (field.type === "tagStatus") {
for (let k = 0; k < field.choices.length; k++) {
if (rowData[field.key] === field.choices[k].value) {
rowData["tagValue" + field.key] = field.choices[k].desc
rowData["tagColor" + field.key] = tagStatusColorArray[field.choices[k].type]
}
}
}
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].whereDes
find = true
break
}
}
if (!find) {
if (whereFieldsDescInfo.value.length == 0) {
field.isFirstWhereDesc = true
} else {
field.isFirstWhereDesc = false
}
whereFieldsDescInfo.value.push(field)
}
}
}
return rowData
}
const handleServerRowsData = (fieldsDescInfoData, rowsData) => {
let newRowsData = []
rowsData.forEach((rowData) => {
const newRowData = handleServerRowData(fieldsDescInfoData, rowData)
// console.log("new data:", newRowData)
newRowsData.push(newRowData)
})
return newRowsData
}
const listData = async () => {
try {
let listParams = {
page_no: current_page.value,
page_len: page_size.value,
where_conditions: "",
}
// console.log(`查询页:${listParams.page_no},查询页大小:${listParams.page_len}`)
let whereReqConditions = {
conditions: []
}
whereFieldsDescInfo.value.forEach((field) => {
if (field.value1 || field.value2) {
whereReqConditions.conditions.push({
key: field.key,
op: field.where,
value1: field.value1,
value2: field.value2,
})
}
})
listParams.where_conditions = JSON.stringify(whereReqConditions)
// console.log("list params:", listParams)
const rspData = await resourceList(resource_url, listParams);
listRsp.value = rspData;
if (listRsp.value.code !== 200) throw new Error("请求失败,错误码:", listRsp.code);
fieldsDescInfo.value = listRsp.value.data.fields_desc
totalRowCount.value = listRsp.value.data.total_count
rows.value = handleServerRowsData(fieldsDescInfo.value, listRsp.value.data.rows)
itemBags.value = listRsp.value.data.item_bags
listDataOK.value = true
} catch (err) {
console.log(err)
} finally {
}
}
const calcFuncColumnBtnSize = () => {
let btnCount = 0;
if (resource_raw_node.meta.methods.put === true) {
btnCount += 1
}
if (resource_raw_node.meta.methods.delete === true) {
btnCount += 1
}
btnCount += rowClickBtns.length
if (btnCount >= 4) {
return "small"
}
if (btnCount >= 3) {
return "default"
}
return "large"
}
const funcBtnSize = ref("default")
funcBtnSize.value = calcFuncColumnBtnSize()
onMounted(() => {
listData();
})
const curCharacter = userStore().userInfo.character
console.log("当前用户角色:", curCharacter)
const dialogAddVisible = ref(false)
const dialogEditVisible = ref(false)
const dialogAddFormRef = ref(null)
const dialogEditFormRef = ref(null)
const dialogObjectForm = ref({
ServerIDs: [],
Attach: [],
})
const route = useRoute()
let hasRouteQueryParams = false
if (route.query.from != undefined && route.query.from != "") {
Object.keys((route.query)).forEach(key => {
const value = route.query[key]
if (key === "from") {
return
}
dialogObjectForm.value[key] = value
// console.log("进入页面,来自查询参数的数据:", key, value)
})
// console.log("进入页面,来自查询参数的数据:", route.query)
dialogAddVisible.value = true
hasRouteQueryParams = true
}
const tableSelectRows = ref([])
const handleTableSelectRowsSendToServer = (btnInfo, rows) => {
console.log(`选择表格行,类型:${btnInfo},`, rows)
ElMessageBox.confirm("确定要操作吗?").then(() => {
resourceRowsSelectionPost(resource_url, {btn_key: btnInfo.key, rows: rows}).then((res) => {
const resultMsg = res.data.msg
let fileName = res.data.file_name
const needRefresh = res.data.need_refresh
if (fileName !== "") {
// 正则提取文件名(处理编码情况)
const filenameRegex = /filename\*?=(?:UTF-8'')?"?([^";]+)"?/i;
const matches = fileName.match(filenameRegex);
if (matches && matches[1]) {
fileName = decodeURIComponent(matches[1]); // 解码特殊字符
}
// 创建临时链接触发下载
const blob = new Blob([resultMsg]);
const link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = fileName;
link.click();
// 释放内存
window.URL.revokeObjectURL(link.href);
return
}
ElNotification({
title: "操作行数据返回",
message: h('i', {style: 'color: teal'}, resultMsg),
duration: 900,
onClose(vm) {
if (needRefresh) {
location.reload()
}
}
})
// console.log("返回消息:", resultMsg, needRefresh)
}, (err) => {
})
}).catch(() => {
})
}
const handleTableSelectChange = (rows) => {
tableSelectRows.value = rows
}
const tableSelectRows1 = (btnInfo) => {
handleTableSelectRowsSendToServer(btnInfo, tableSelectRows.value)
}
const tableSelectRows2 = (btnInfo, index, row) => {
if (btnInfo.btn_type > 0) {
if (btnInfo.btn_type == 1) {
}
return
}
handleTableSelectRowsSendToServer(btnInfo, [row])
}
const tableSelectRow3 = (i, row) => {
rowClickBtnSelectRow.value = row
rowClickBtnVisibleList[i] = true
console.log("点击按钮:", rowClickBtnSelectRow)
}
const tableSelectRow4 = (btnInfo, row) => {
btnInfo.click_handler(row)
// console.log("点击按钮:", row)
}
const submitAdd = async () => {
try {
await dialogAddFormRef.value.validate(valid => {
if (valid) {
console.log("commit add form:", dialogObjectForm.value)
resourcePost(resource_url, dialogObjectForm.value).then((res) => {
ElNotification({
title: "添加结果通知",
message: "添加成功!如果页面没有变化,刷新一下!",
type: 'success',
duration: 4000,
"show-close": true,
})
const newData = handleServerRowData(fieldsDescInfo.value, res.data.dto)
rows.value.unshift(newData)
// rows.value.push(res.data.dto)
dialogAddVisible.value = false
handleCloseDialog()
}, (err) => {
console.log("添加报错:", err)
})
console.log("提交数据:", dialogObjectForm.value)
}
})
} catch (error) {
console.log("校验失败:", error)
}
}
const submitEdit = async () => {
try {
await dialogEditFormRef.value.validate(valid => {
if (valid) {
const oldIndex = dialogObjectForm.value.oldIndex
const oldData = dialogObjectForm.value.oldData
// 这两句必须因为上一步点击编辑按钮把value = row然后把value.oldIndex = index
// 貌似会引起类字段循环引用,然后发送时候序列化造成死循环
delete dialogObjectForm.value.oldIndex
delete dialogObjectForm.value.oldData
resourcePut(resource_url, dialogObjectForm.value).then((res) => {
ElNotification({
title: "编辑结果通知",
message: "编辑成功!如果页面没有变化,刷新一下!",
type: 'success',
duration: 4000,
"show-close": true,
})
dialogEditVisible.value = false
rows.value[oldIndex] = handleServerRowData(fieldsDescInfo.value, res.data.dto)
handleCloseDialog()
}, (err) => {
console.log("添加报错:", err)
})
console.log("提交数据:", dialogObjectForm.value)
}
})
} catch (error) {
console.log("校验失败:", error)
}
}
const handleEdit = (index, row) => {
dialogObjectForm.value = row
dialogObjectForm.value.oldData = row
dialogObjectForm.value.oldIndex = index
// console.log("edit data:", row)
dialogEditVisible.value = true
}
const handleDelete = (index, row) => {
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)
})
}).catch(() => {
})
}
function itemBagSelectChange() {
console.log("选择礼包:", selectedItemBag.value)
let hasValidInput = false
if (selectedItemBag.value != null) {
selectedItemBag.value.forEach(bag => {
if (bag.name !== undefined && bag.name !== '') {
bag.items.forEach((bagItem) => {
if (typeof dialogObjectForm.value.Attach === typeof "") {
dialogObjectForm.value.Attach = [];
}
let d = {id: bagItem.item_id, num: bagItem.item_num, desc: bagItem.desc, item_type: bagItem.item_type};
dialogObjectForm.value.Attach.push(d);
})
console.log("添加礼包:", bag)
hasValidInput = true;
}
})
}
// if (!hasValidInput) {
// console.log("礼包:", selectedItemBag.value)
// ElMessage('请选择礼包!')
// }
if (dialogAddVisible.value) {
dialogAddFormRef.value.validateField("Attach");
} else if (dialogEditVisible.value) {
// console.log("删除道具,准备校验表单规则", rules.value)
// console.log("删除道具,准备校验表单规则", dialogEditFormRef.value)
dialogEditFormRef.value.validateField("Attach");
}
}
function addItem(fieldDescInfo) {
let hasValidInput = false;
if (selectedItem.value !== null && selectedItem.value.value !== undefined && selectedItem.value.value !== '') {
if (selectedItemNum.value <= 0) {
ElMessage('请输入有效道具数量!')
return;
}
let d = {
id: selectedItem.value.value,
num: Number(selectedItemNum.value),
desc: selectedItem.value.desc,
item_type: selectedItem.value.type
};
console.log("add item:", d)
if (typeof dialogObjectForm.value.Attach === typeof "") {
dialogObjectForm.value.Attach = [];
}
dialogObjectForm.value.Attach.push(d);
hasValidInput = true;
}
if (!hasValidInput) {
console.log("道具:", selectedItem.value)
ElMessage('请选择道具或者礼包!')
}
if (dialogAddVisible.value) {
dialogAddFormRef.value.validateField("Attach");
} else if (dialogEditVisible.value) {
// console.log("删除道具,准备校验表单规则", rules.value)
// console.log("删除道具,准备校验表单规则", dialogEditFormRef.value)
dialogEditFormRef.value.validateField("Attach");
}
}
function deleteItem(row) {
// 移除该对象
let number = dialogObjectForm.value.Attach.findIndex(item => item === row);
dialogObjectForm.value.Attach.splice(number, 1);
if (dialogAddVisible.value) {
dialogAddFormRef.value.validateField("Attach");
} else if (dialogEditVisible.value) {
// console.log("删除道具,准备校验表单规则", rules.value)
dialogEditFormRef.value.validateField("Attach");
}
}
const handleCloseDialog = () => {
// console.log("关闭添加/编辑弹窗")
dialogAddVisible.value = false
dialogEditVisible.value = false
dialogObjectForm.value = {
Attach: [],
}
selectedItem.value = null
selectedItemNum.value = 0
selectedItemBag.value = null
if (hasRouteQueryParams) {
router.replace({
path: route.path,
query: {}
})
}
genRandAccountNum.value = 0
genRandAccountPrefix.value = ""
genRandAccountCharBitNum.value = 5
genRandAccountSuffix.value = ""
}
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 = []
})
}
const resetConditionSearch = () => {
for (let i = 0; i < whereFieldsDescInfo.value.length; i++) {
let field = whereFieldsDescInfo.value[i]
field.value1 = null
field.value2 = null
}
}
const handlePaginationSizeChange = (val) => {
// console.log(`${val} 大小改变`)
if (totalRowCount.value <= 0) {
return
}
if (page_size.value * current_page.value > totalRowCount.value) {
// 当总数据少于页数乘以页大小,就拒绝请求
if (rows.value.length >= totalRowCount.value) {
return
}
}
// console.log(`${page_size.value} 大小改变`)
listData()
}
const handlePaginationCurChange = (val) => {
// console.log(`${val} 页面改变`)
listData()
}
const genRandAccountNum = ref(0)
const genRandAccountPrefix = ref('')
const genRandAccountCharBitNum = ref(5)
const genRandAccountSuffix = ref('')
const randCharArray = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0']
const handleGenRandAccount = () => {
if (genRandAccountNum.value <= 0 || genRandAccountNum.value > 1000) {
alert("数量不合法!!范围[1-1000]")
return
}
if (genRandAccountPrefix.value === "" && genRandAccountSuffix.value === "") {
alert("生成账号的前缀、后缀至少填一个!!")
return
}
if (genRandAccountCharBitNum.value < 3 || genRandAccountCharBitNum.value > 20) {
alert("生成账号的随机字串长度不合法!!范围[3-20]")
return
}
let accountList = []
for (let i = 0; i < genRandAccountNum.value; i++) {
let randStr = ""
for (let j = 0; j < genRandAccountCharBitNum.value; j++) {
randStr += randCharArray[Math.floor(Math.random() * 1000000) % randCharArray.length]
}
const accountName = genRandAccountPrefix.value + randStr + genRandAccountSuffix.value
// console.log("rand account name:", Math.random())
accountList.push(accountName)
}
dialogObjectForm.value.AccountList = accountList.join(",")
}
</script>
<template>
<div class="app-content">
<template v-if="!hasListPermit">
<component :is="empty"></component>
</template>
<template v-else>
<el-container v-if="listDataOK">
<el-header style="margin-bottom: 10px">
<el-row 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" style="margin-right: 10px"></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" style="margin-right: 10px"></el-date-picker>
<!-- </el-col>-->
</template>
<template v-else>
<!-- <el-col :span="calcElColSpan">-->
<el-select v-model="fieldDescInfo.value1"
:placeholder="(fieldDescInfo.multi_choice === true ? '--' + fieldDescInfo.name + '--' : '--' + fieldDescInfo.name + '--')"
style="width: 150px;margin-right: 10px"
filterable v-if="(fieldDescInfo.choices.length > 0)">
<el-option v-for="choice in fieldDescInfo.choices" :key="choice.value" :label="choice.desc"
:value="choice.value"></el-option>
</el-select>
<el-input v-model="fieldDescInfo.value1"
:placeholder="(fieldDescInfo.name + fieldDescInfo.whereDesc)"
style="width: 150px;margin-right: 10px" v-else></el-input>
<!-- </el-col>-->
</template>
</template>
<!-- <el-col :span="calcElColSpan">-->
<el-button @click="listData" type="primary">条件搜索</el-button>
<!-- </el-col>-->
<!-- <el-col :span="calcElColSpan">-->
<el-button @click="resetConditionSearch" type="default">清空条件</el-button>
<!-- </el-col>-->
</el-row>
<el-row style="margin-top: 10px">
<el-button @click="dialogAddVisible = true" size="default" type="primary"
v-if="(resource_raw_node.meta.methods.post === true)">
添加
</el-button>
<el-button v-for="btn in globalClickBtns" size="default" :type="btn.btn_color_type"
@click="tableSelectRows1(btn)">
{{ btn.name }}
</el-button>
</el-row>
</el-header>
<el-main>
<div class="table-content">
<div class="table">
<el-table :data="rows" style="width: 100%" table-layout="auto" stripe
@selection-change="handleTableSelectChange">
<el-table-column type="selection" v-if="globalClickBtns.length > 0">
</el-table-column>
<template v-for="fieldDescInfo in fieldsDescInfo">
<!-- 道具列表 -->
<el-table-column prop="jsonValue" :label="fieldDescInfo.name"
:show-overflow-tooltip="{effect:'light',placement:'top'}"
v-if="(fieldDescInfo.type === 'items')"></el-table-column>
<!-- 状态 -->
<el-table-column :prop="'tagValue'+fieldDescInfo.key" :label="fieldDescInfo.name"
v-else-if="(fieldDescInfo.type === 'tagStatus')">
<template #default="scope">
<el-tag :type="scope.row['tagColor'+fieldDescInfo.key]">{{
scope.row['tagValue' + fieldDescInfo.key]
}}
</el-tag>
<!-- <el-tag type="success" v-else-if="scope.row.Status === '在线'">{{ scope.row.Status }}</el-tag>-->
</template>
</el-table-column>
<el-table-column :prop="fieldDescInfo.key" :label="fieldDescInfo.name"
:show-overflow-tooltip="{effect:'light',placement:'top'}"
v-else-if="(fieldDescInfo.big_column)">
<template #header>
<el-tooltip effect="light" :content="fieldDescInfo.help_text" placement="top"
v-if="fieldDescInfo.help_text !== ''">
<span>{{ fieldDescInfo.name }}</span>
</el-tooltip>
<span v-else>{{ fieldDescInfo.name }}</span>
</template>
</el-table-column>
<!-- 其它普通字段 -->
<el-table-column :prop="fieldDescInfo.key" :label="fieldDescInfo.name" v-else>
<template #header>
<el-tooltip effect="light" :content="fieldDescInfo.help_text" placement="top"
v-if="fieldDescInfo.help_text !== ''">
<span>{{ fieldDescInfo.name }}</span>
</el-tooltip>
<span v-else>{{ fieldDescInfo.name }}</span>
</template>
</el-table-column>
</template>
<el-table-column prop="func" label="功 能">
<template #default="scope">
<el-button :size="funcBtnSize" 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="funcBtnSize" 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>
<template v-for="(btn, index) in rowClickBtns">
<template v-if="btn.btn_type === 0"> <!--直接发送选择行数据到服务器的按钮类型-->
<template v-if="scope.row['ReviewNeedCharacters'] !== undefined &&
scope.row['ReviewNeedCharacters'] !== null">
<el-button
:size="funcBtnSize"
:type="btn.btn_color_type"
@click="tableSelectRows2(btn, scope.$index, scope.row)"
v-if="scope.row['ReviewNeedCharacters'].includes(curCharacter) &&
scope.row['ReviewCheckStatus'] === 'pending'">
{{ btn.name }}
</el-button>
<div v-else/>
</template>
<el-button :size="funcBtnSize" :type="btn.btn_color_type"
@click="tableSelectRows2(btn, scope.$index, scope.row)" v-else>
{{ btn.name }}
</el-button>
</template>
<template v-else-if="btn.btn_type === 1"> <!--带弹窗的按钮类型-->
<el-button :size="funcBtnSize" :type="btn.btn_color_type"
@click="tableSelectRow3(index, scope.row)">
{{ btn.name }}
</el-button>
</template>
<template v-else-if="btn.btn_type === 2"> <!--带点击回调函数的按钮类型-->
<el-button :size="funcBtnSize" :type="btn.btn_color_type"
@click="tableSelectRow4(btn, scope.row)">
{{ btn.name }}
</el-button>
</template>
</template>
</template>
</el-table-column>
</el-table>
</div>
<!-- 表格数据分页 -->
<div class="pagination-container">
<el-pagination
v-model:current-page="current_page"
v-model:page-size="page_size"
:page-sizes="pageSizes"
layout="total, sizes, prev, pager, next, jumper"
:total="totalRowCount"
@size-change="handlePaginationSizeChange"
@current-change="handlePaginationCurChange"
/>
</div>
</div>
<template v-for="(btn, index) in rowClickBtns">
<el-dialog v-model="rowClickBtnVisibleList[index]" :title="btn.name"
@close="rowClickBtnVisibleList[index]=false"
destroy-on-close style="width: 1020px">
<component :is="btn.btn_callback_component" :rowInfo="rowClickBtnSelectRow"
:fieldsDescInfo="fieldsDescInfo"/>
</el-dialog>
</template>
<el-dialog v-model="dialogAddVisible" :mask="true" title="添加" :modal="true"
:before-close="handleCloseDialog"
destroy-on-close>
<el-form ref="dialogAddFormRef" :model="dialogObjectForm" :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="selectedItem" label-position="right">
<el-form-item :label="fieldDescInfo.name" :prop="fieldDescInfo.key" label-width="130px">
<el-tooltip effect="light" :content="fieldDescInfo.help_text" placement="top-start">
<el-select v-model="selectedItem" placeholder="--搜索道具--" style="width: 200px"
filterable remote clearable
:remote-method="handleQueryItem"
:loading="loadingRemoteItems"
value-key="value"
>
<el-option v-for="info in itemChoices" :key="info.value" :label="info.desc+'('+info.value+')'"
:value="info"></el-option>
</el-select>
</el-tooltip>
</el-form-item>
<el-form-item label="数量" prop="num">
<el-input type="number" v-model="selectedItemNum" placeholder="请输入数量" style="width: 100px"/>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="addItem(fieldDescInfo)">添加</el-button>
</el-form-item>
<!-- 选择礼包 -->
<el-form-item v-if="cachedResource.meta.resource !== 'item_bag'">
<el-tooltip effect="light" content="选择礼包,点击添加到奖励列表">
<el-select placeholder="--礼包--" v-model="selectedItemBag" clearable style="width: 150px"
value-key="name" multiple @blur="itemBagSelectChange">
<el-option v-for="bag in itemBags" :key="bag.name" :label="bag.name" :value="bag"></el-option>
</el-select>
</el-tooltip>
</el-form-item>
</el-form>
<el-form-item label="奖励列表" prop="Attach">
<el-table :data="dialogObjectForm.Attach" border>
<el-table-column label="道具id" prop="id"/>
<el-table-column label="数量" prop="num"/>
<el-table-column label="道具名" prop="desc"/>
<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>
</el-form-item>
</template>
<template v-else-if="(fieldDescInfo.readonly !== 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="dialogObjectForm[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="dialogObjectForm[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-if="fieldDescInfo.type === 'randAccount'">
<el-form-item :label="fieldDescInfo.name" :prop="fieldDescInfo.key">
<el-row style="margin-bottom: 10px">
<span>随机数量:</span>
<el-tooltip effect="light" placement="top-start"
content="输入生成账号的数量,数量范围[1-1000],数量太大了后台短时间生成不完,注意多等几分钟会再发放账号">
<el-input type="number" v-model="genRandAccountNum" placeholder="账号数量"
style="width: 90px"/>
</el-tooltip>
<span style="margin-left: 10px">随机模板:</span>
<el-tooltip effect="light" placement="top" content="前缀、后缀必填至少一个">
<el-input v-model="genRandAccountPrefix" placeholder="前缀"
style="width: 100px;margin-right: 5px"></el-input>
</el-tooltip>
<el-tooltip effect="light" placement="top"
content="账号随机混淆字串的位数,范围[3-20],与前缀、后缀一起组成账号">
<el-input type="number" v-model="genRandAccountCharBitNum" placeholder="随机串数量"
style="width: 80px;margin-right: 5px"/>
</el-tooltip>
<el-tooltip effect="light" placement="top" content="前缀、后缀必填至少一个">
<el-input v-model="genRandAccountSuffix" placeholder="后缀"
style="width: 100px;margin-right: 5px"></el-input>
</el-tooltip>
<el-button type="success" @click="handleGenRandAccount">生成</el-button>
</el-row>
<el-input v-model="dialogObjectForm[fieldDescInfo.key]"
:placeholder="fieldDescInfo.help_text" type="textarea"
:autosize="{minRows: 5, maxRows: 20}"></el-input>
</el-form-item>
</template>
<!-- 否则就是普通字段 -->
<template v-else>
<el-form-item :label="fieldDescInfo.name" :prop="fieldDescInfo.key">
<el-input v-model="dialogObjectForm[fieldDescInfo.key]"
:placeholder="fieldDescInfo.help_text" type="textarea"
:autosize="{minRows: 2, maxRows: 10}"
v-if="(fieldDescInfo.type === 'text')"></el-input>
<el-input v-model="dialogObjectForm[fieldDescInfo.key]"
:placeholder="fieldDescInfo.help_text"
v-else></el-input>
</el-form-item>
</template>
</template>
</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="dialogObjectForm" :rules="rules" class="operation_form"
label-width="130px">
<template v-for="fieldDescInfo in fieldsDescInfo">
<!--如果是items类型就是物品下拉框+道具组合-->
<template v-if="(fieldDescInfo.type === 'items')">
<el-row>
<el-form :inline="true" :model="selectedItem" label-position="right"
label-width="130px">
<el-form-item :label="fieldDescInfo.name" :prop="fieldDescInfo.key">
<el-tooltip effect="light" :content="fieldDescInfo.help_text" placement="top-start">
<el-select placeholder="--搜索道具--" v-model="selectedItem" style="width: 200px"
filterable remote :remote-method="handleQueryItem"
:loading="loadingRemoteItems"
value-key="value"
>
<el-option v-for="info in itemChoices" :key="info.value"
:label="info.desc+'('+info.value+')'"
:value="info"></el-option>
</el-select>
</el-tooltip>
</el-form-item>
<el-form-item label="数量" prop="number" label-width="40px">
<el-input type="number" v-model="selectedItemNum" placeholder="请输入数量"
style="width: 100px"/>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="addItem(fieldDescInfo)">添加</el-button>
</el-form-item>
<!-- 选择礼包 -->
<el-form-item v-if="cachedResource.meta.resource !== 'item_bag'">
<el-tooltip effect="light" content="选择礼包,点击添加到奖励列表">
<el-select placeholder="--礼包--" v-model="selectedItemBag" clearable style="width: 150px"
value-key="name" multiple @blur="itemBagSelectChange">
<el-option v-for="bag in itemBags" :key="bag.name" :label="bag.name"
:value="bag"></el-option>
</el-select>
</el-tooltip>
</el-form-item>
</el-form>
</el-row>
<el-form-item label="奖励列表" prop="Attach">
<el-table :data="dialogObjectForm.Attach" border>
<el-table-column label="道具id" prop="id"/>
<el-table-column label="数量" prop="num"/>
<el-table-column label="道具名" prop="desc"/>
<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>
</el-form-item>
</template>
<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="dialogObjectForm[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="dialogObjectForm[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="dialogObjectForm[fieldDescInfo.key]"
:placeholder="fieldDescInfo.help_text" type="textarea"
:autosize="{minRows: 2, maxRows: 10}"
v-if="(fieldDescInfo.type === 'text')"></el-input>
<el-input v-model="dialogObjectForm[fieldDescInfo.key]"
:placeholder="fieldDescInfo.help_text" v-else></el-input>
</el-form-item>
</template>
</template>
<template v-else>
<el-form-item :label="fieldDescInfo.name" :prop="fieldDescInfo.key">
<el-input v-model="dialogObjectForm[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>
<el-form-item>
<el-button @click="submitEdit(dialogEditFormRef)" size="large" type="primary">提交</el-button>
</el-form-item>
</el-form>
</el-dialog>
</el-main>
</el-container>
</template>
</div>
</template>
<style scoped lang="scss">
.app-content {
height: calc(100vh - 100px);
display: flex;
.table-content {
display: flex;
flex-direction: column;
justify-content: space-between;
height: 100%;
overflow: auto;
.table {
flex: 1;
position: relative;
:deep(.el-table) {
flex: 1;
position: absolute;
}
/*控制表格tooltip宽度*/
::v-deep(.el-popper) {
max-width: 640px;
word-break: break-all;
}
}
}
}
.pagination-container .el-pagination {
right: 0;
position: absolute;
height: 25px;
margin-bottom: 50px;
margin-top: 0px;
padding: 10px 30px !important;
z-index: 2;
}
.pagination-container.hidden {
display: none;
}
@media (max-width: 768px) {
.pagination-container .el-pagination > .el-pagination__jump {
display: none !important;
}
.pagination-container .el-pagination > .el-pagination__sizes {
display: none !important;
}
}
</style>