Commit 6621cf06 authored by 张俊's avatar 张俊

[feat](公共table): table按钮组件修改

parent 1fd24a26
...@@ -12,7 +12,7 @@ module.exports = { ...@@ -12,7 +12,7 @@ module.exports = {
htmlWhitespaceSensitivity: "css", htmlWhitespaceSensitivity: "css",
insertPragma: false, insertPragma: false,
jsxSingleQuote: false, jsxSingleQuote: false,
printWidth: 100, // 如果属性过多需要换行,减少该值 printWidth: 80, // 如果属性过多需要换行,减少该值
proseWrap: "preserve", proseWrap: "preserve",
quoteProps: "as-needed", quoteProps: "as-needed",
requirePragma: false, requirePragma: false,
......
<template> <template>
<div class="bg-table-btns" ref="bgTableBtnsRef"> <div ref="bgTableBtnsRef" class="bg-table-btns">
<slot></slot> <slot></slot>
<span <el-popover :popper-style="bgTablePopover" trigger="hover" :hide-after="50">
class="bg-table-btn more" <div class="more-box" :style="state.style">
id="more_btn" <span
v-if="state.children.length > limit" v-for="(item, index) in state.lastChildren"
ref="lastEl" :key="'as' + index"
@mouseenter="showMoreBtns" :class="item.disabled ? 'disabled' : ''"
@mouseleave="hideMoreBtns"> @click="action(item.onClick, item.disabled)"
<bg-icon style="font-size: 12px; color: #2b4695" icon="#bg-ic-s-more" /> >{{ item.name }}</span
<teleport to="body"> >
<div </div>
class="more-box" <template #reference>
:style="state.style" <span v-if="state.children.length - 1 > limit" id="more_btn" ref="lastEl" class="bg-table-btn more">
v-if="state.showMore" <bg-icon style="font-size: 12px; color: #2b4695" icon="#bg-ic-s-more" />
@mouseenter="showMoreBtns" </span>
@mouseleave="hideMoreBtns"> <!-- 解决不需显示时警告问题 -->
<span <span v-else></span>
v-for="(item, index) in state.lastChildren" </template>
:key="'as' + index" </el-popover>
@click="action(item.onClick, item.disabled)"
:class="item.disabled ? 'disabled' : ''"
>{{ item.name }}</span
>
</div>
</teleport>
</span>
</div> </div>
</template> </template>
<script setup> <script setup>
import { reactive, ref, onBeforeMount, onMounted, toRefs, provide, useSlots, h, render, nextTick } from "vue"; import { reactive, ref, onBeforeMount, onMounted, toRefs, provide, useSlots, watch, nextTick } from "vue";
const slots = useSlots(); const slots = useSlots();
const props = defineProps({ const props = defineProps({
...@@ -38,6 +31,10 @@ const props = defineProps({ ...@@ -38,6 +31,10 @@ const props = defineProps({
type: Number, type: Number,
default: 3, default: 3,
}, },
tableData: {
type: Array,
default: () => [],
},
}); });
const bgTableBtnsRef = ref(null); const bgTableBtnsRef = ref(null);
...@@ -51,60 +48,72 @@ const state = reactive({ ...@@ -51,60 +48,72 @@ const state = reactive({
showMore: false, showMore: false,
}); });
watch(
() => props.tableData,
() => {
nextTick(() => {
calcTabs();
dealData();
});
},
{
deep: true,
}
);
const action = (event, disable) => { const action = (event, disable) => {
if (disable) { if (disable) {
return; return;
} }
event(); event();
state.showMore = false state.showMore = false;
}; };
const calcTabs = () => { const calcTabs = () => {
let tabSlots = slots.default() || []; let tabSlots = slots.default() || [];
let tempSlots = [];
state.lastChildren = []; state.lastChildren = [];
if (tabSlots) { tabSlots.forEach((e) => {
tabSlots.forEach((e, idx) => { //注释和v-if忽略
if (idx + 2 > props.limit && tabSlots.length > props.limit && e.props) { if (Object.prototype.toString.call(e.children) == "[object String]") {
//v-for 再次遍历
} else if (Object.prototype.toString.call(e.children) == "[object Array]") {
let children = e.children || [];
children.forEach((el) => {
//注释和v-if忽略
if (Object.prototype.toString.call(e.children) == "[object String]") {
console.log(el.type);
} else {
tempSlots.push(el);
}
});
//普通节点
} else {
tempSlots.push(e);
}
});
// debugger;
if (tempSlots) {
tempSlots.forEach((e, idx) => {
if (idx + 2 > props.limit && tempSlots.length > props.limit && e.props) {
// console.log(e);
// console.log(e.props);
state.lastChildren.push(e.props); state.lastChildren.push(e.props);
} }
}); });
} }
}; };
const showMoreBtns = () => {
calcTabs();
dealData();
nextTick(() => {
updateSytle();
if (state.timer) clearTimeout(state.timer);
state.showMore = true;
});
};
const hideMoreBtns = () => {
if (state.timer) clearTimeout(state.timer);
state.timer = setTimeout(() => {
state.showMore = false;
}, 50);
};
const updateSytle = () => {
let { top, right } = lastEl.value.getBoundingClientRect();
let { width } = window.document.body.getBoundingClientRect();
state.style = {
top: `${top + 16}px`,
right: `${width - right - 16}px`,
};
};
const dealData = () => { const dealData = () => {
let children = bgTableBtnsRef.value.children || []; let children = bgTableBtnsRef.value.children || [];
state.children = children; state.children = children;
if (children.length > props.limit) { if (children.length - 1 > props.limit) {
children[props.limit - 1].style.display = "none"; children[props.limit - 1].style.display = "none";
children[props.limit - 1].style.width = "0px"; children[props.limit - 1].style.width = "0px";
state.index = props.limit - 2; state.index = props.limit - 2;
state.lastChildren[0].name = children[props.limit - 1].innerText; state.lastChildren[0].name = children[props.limit - 1].innerText;
} }
for (let index = 0; index < children.length; index++) { for (let index = 0; index < children.length - 1; index++) {
const e = children[index]; const e = children[index];
if (index + 1 > props.limit && e.tagName == "A" && e.className.indexOf("bg-table-btn") !== -1) { if (index + 1 > props.limit && e.tagName == "A" && e.className.indexOf("bg-table-btn") !== -1) {
e.style.display = "none"; e.style.display = "none";
...@@ -114,6 +123,14 @@ const dealData = () => { ...@@ -114,6 +123,14 @@ const dealData = () => {
} }
}; };
const bgTablePopover = {
width: "auto",
maxWidth: "96px",
padding: "4px 0",
minWidth: "60px",
marginTop: "-5px",
};
onMounted(() => { onMounted(() => {
calcTabs(); calcTabs();
dealData(); dealData();
...@@ -126,35 +143,20 @@ onMounted(() => { ...@@ -126,35 +143,20 @@ onMounted(() => {
z-index: 200; z-index: 200;
} }
.more-box {
position: fixed;
padding: 4px 0;
background-color: #ffffff;
box-shadow: 0px 4px 12px 0px rgba(18, 30, 63, 0.1);
border-radius: 4px;
border: solid 1px #e6e9ef;
width: 88px;
z-index: 300;
}
.more-box span { .more-box span {
display: block; display: block;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
word-break: break-all; word-break: break-all;
white-space: nowrap; white-space: nowrap;
display: block; padding: 10px 16px;
padding: 0 16px; color: #404a62;
margin: 0; line-height: 1;
color: #202531; font-size: 14px;
line-height: 34px;
padding-left: 16px;
font-size: 16px;
cursor: pointer; cursor: pointer;
} }
.more-box span:hover { .more-box span:hover {
background-color: #f2f3f7; background-color: #f2f3f7;
color: #202531;
} }
.more-box .disabled { .more-box .disabled {
color: #a9b1c7; color: #a9b1c7;
......
...@@ -9,20 +9,24 @@ ...@@ -9,20 +9,24 @@
<bg-icon style="font-size: 12px; color: #fff; margin-right: 8px" icon="#bg-ic-add"></bg-icon> <bg-icon style="font-size: 12px; color: #fff; margin-right: 8px" icon="#bg-ic-add"></bg-icon>
新增 新增
</el-button> </el-button>
<el-button type="default" @click="deleteAllTips"> 批量删除 </el-button>
<span class="header_info"
>已选择 <span style="color: #202531; font-weight: bold"> {{ state.selected.length }} </span>
</span>
<span class="header_info can_click_text" @click="clearSelected">清空</span>
</div> </div>
</template> </template>
<template v-slot:filter_group> <template v-slot:filter_group>
<div class="left-filter filter_list"> <div class="left-filter filter_list">
<div class="filter_item"> <div class="filter_item">
<span class="filter_title">状态</span> <span class="filter_title">创建时间</span>
<el-select v-model="filter.state" placeholder="请选择" style="width: 300px"> <el-date-picker
<el-option v-model="filter.time"
v-for="(item, index) in stateOptions" type="daterange"
:key="'pushOptions' + index" value-format="yyyy-MM-DD"
:label="item.name" range-separator="至"
:value="item.value"> start-placeholder="开始日期"
</el-option> end-placeholder="结束日期" />
</el-select>
</div> </div>
</div> </div>
<div class="right-action apaas_button"> <div class="right-action apaas_button">
...@@ -31,59 +35,45 @@ ...@@ -31,59 +35,45 @@
</div> </div>
</template> </template>
</bg-filter-group> </bg-filter-group>
<!-- <div class="table_container"> <div class="table_container">
<div class="table bg-scroll"> <div class="table bg-scroll">
<bg-table <bg-table
ref="bgTable" ref="dataTable"
:headers="headers" :headers="headers"
:rows="tableRows" :rows="tableRows"
:isIndex="true" @selectAc="selectRows"
:stripe="true"> :isIndex="true"
<template v-slot:name="{ row }"> :select="true"
<span class="can_click_text" @click="getChildren(row)" v-if="row.children"> :stripe="true">
{{ row.name }} <template v-slot:name="{ row }">
</span> <span class="can_click_text" @click="getChildren(row)" v-if="row.children">
<span v-else> {{ row.name }}
{{ row.name }} </span>
</span> <span v-else>
</template> {{ row.name }}
<template v-slot:updated_time="{ row }"> </span>
{{ row.updated_time.split("+")[0].replace("T", " ").replace("Z", " ") }} </template>
</template> <template v-slot:updated_time="{ row }">
<template v-slot:state="{ row }"> {{ row.updated_time.split("+")[0].replace("T", " ").replace("Z", " ") }}
<bg-switch </template>
@click="changeUseRow(row)" <template v-slot:action="{ row }">
:labels="['否', '是']" <bg-table-btns2 :limit="3" :tableData="tableRows">
:values="[0, 1]" <bg-table-btn @click="useRow(row)">执行任务</bg-table-btn>
v-model="row.state"></bg-switch> <bg-table-btn @click="editRow(row)">编辑</bg-table-btn>
</template> <bg-table-btn @click="copyRow(row, 1)">复制</bg-table-btn>
<template v-slot:action="{ row }"> <bg-table-btn @click="deleteRow(row, 2)">删除</bg-table-btn>
<bg-table-btns2 </bg-table-btns2>
:limit="3"> </template>
<bg-table-btn @click="edit_row(row)" :disabled="row.state == 1" </bg-table>
>编辑</bg-table-btn </div>
> <bg-pagination
<bg-table-btn @click="delete_row(row)" :disabled="row.state == 1" :page="filter.page"
>删除</bg-table-btn :size="filter.size"
> :total="tableTotal"
<bg-table-btn @click="moveRow(row, 1)" :disabled="!row.canMoveUp" @change-page="changePage"
>上移</bg-table-btn @change-size="changeSize">
> </bg-pagination>
<bg-table-btn @click="moveRow(row, 2)" :disabled="!row.canMoveDown" </div>
>下移</bg-table-btn
>
</bg-table-btns2>
</template>
</bg-table>
</div>
<bg-pagination
:page="filter.page"
:size="filter.size"
:total="tableTotal"
@change-page="changePage"
@change-size="changeSize">
</bg-pagination>
</div> -->
</div> </div>
<!-- 新增/编辑弹窗 --> <!-- 新增/编辑弹窗 -->
<!-- <el-dialog <!-- <el-dialog
...@@ -164,36 +154,38 @@ import axios from "@/request/http.js"; ...@@ -164,36 +154,38 @@ import axios from "@/request/http.js";
import { Search } from "@element-plus/icons-vue"; import { Search } from "@element-plus/icons-vue";
import bgBreadcrumb from "@/components/bg-breadcrumb.vue"; import bgBreadcrumb from "@/components/bg-breadcrumb.vue";
const bgForm = ref(null); const bgForm = ref(null);
const dataTable = ref(null);
const headers = [
{
label: "任务名称",
prop: "name",
},
{
label: "执行次数",
prop: "times",
},
{
label: "描述",
prop: "describe",
minWidth: 360,
},
{
label: "创建人",
prop: "person",
},
{
label: "创建时间",
prop: "updated_time",
width: 220,
},
{
label: "操作",
prop: "action",
width: 200,
fixed: "right",
},
];
const headers = computed(() => {
let _headers = [
{
label: "名称",
prop: "name",
},
{
label: "描述",
prop: "describe",
minWidth: 360,
},
{
label: "更新时间",
prop: "updated_time",
width: 220,
},
{
label: "是否启用",
prop: "state",
},
{
label: "操作",
prop: "action",
width: 176,
fixed: "right",
},
];
return _headers;
});
const state = reactive({ const state = reactive({
bgForm, bgForm,
typeList: [], // 分类数据 typeList: [], // 分类数据
...@@ -202,9 +194,10 @@ const state = reactive({ ...@@ -202,9 +194,10 @@ const state = reactive({
nodeId: null, // 当前选中分类的id 用于请求列表 nodeId: null, // 当前选中分类的id 用于请求列表
timer: null, // 定时器 timer: null, // 定时器
tableRows: [], // 表格数据 tableRows: [], // 表格数据
selected: [], //选择数据
tableTotal: 0, // 表格数据条数 tableTotal: 0, // 表格数据条数
filter: { filter: {
state: "", time: "",
search: "", search: "",
page: 1, page: 1,
limit: 10, limit: 10,
...@@ -244,6 +237,16 @@ const state = reactive({ ...@@ -244,6 +237,16 @@ const state = reactive({
fatherRow: null, fatherRow: null,
}); });
const selectRows = (data) => {
state.selected = data.selection;
};
const clearSelected = () => {
dataTable.value.clearTable();
};
const deleteAllTips = () => {};
const dictLevel = ref(1); const dictLevel = ref(1);
const getChildren = (row) => { const getChildren = (row) => {
...@@ -252,33 +255,6 @@ const getChildren = (row) => { ...@@ -252,33 +255,6 @@ const getChildren = (row) => {
state.tableTotal = row.total_children; state.tableTotal = row.total_children;
state.fatherRow = row; state.fatherRow = row;
}; };
const backDict = () => {
dictLevel.value = 1;
state.fatherRow = null;
changePage(1);
};
const nodeClick = (item) => {
state.nodeId = item.id;
dictLevel.value = 1;
state.fatherRow = null;
state.nodeClassifyId = item.classify_id;
state.filter = {
state: "",
search: "",
page: 1,
limit: 10,
};
changePage(1);
}; // 切换字典分类
const searchType = () => {
if (state.timer) {
clearTimeout(state.timer);
}
state.timer = setTimeout(() => {
getTypeList();
}, 500);
}; // 字典分类筛选
const getTypeList = () => { const getTypeList = () => {
let params = { let params = {
...@@ -314,7 +290,7 @@ const filterAction = () => { ...@@ -314,7 +290,7 @@ const filterAction = () => {
const filterClear = () => { const filterClear = () => {
state.filter = { state.filter = {
state: "", time: "",
search: "", search: "",
limit: 10, limit: 10,
page: 1, page: 1,
...@@ -356,18 +332,6 @@ const getTableRows = () => { ...@@ -356,18 +332,6 @@ const getTableRows = () => {
}); });
}; // 获取表格数据 }; // 获取表格数据
const changeUseRow = (row) => {
axios.put(`/apaas/system/v5/dictionary/state?id=${row.id}&state=${row.state}`).then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.msg);
changePage(1);
} else {
ElMessage.error(res.data.data);
row.state = row.state == 0 ? 1 : 0;
}
});
}; // 启用禁用
const changePage = (page) => { const changePage = (page) => {
state.filter.page = page; state.filter.page = page;
getTableRows(); getTableRows();
...@@ -398,151 +362,11 @@ const register = () => { ...@@ -398,151 +362,11 @@ const register = () => {
state.addDialog = true; state.addDialog = true;
}; // 新增字典按钮 }; // 新增字典按钮
const edit_row = (row) => {
axios
.get(`/apaas/system/v5/dictionary/${row.id}`)
.then((res) => {
if (res.data.code == 200) {
state.actionRow = res.data.data;
state.formData = {
name: state.actionRow.name,
describe: state.actionRow.describe,
state: state.actionRow.state,
p_dict_id: state.actionRow.p_dict_id,
};
} else {
ElMessage.error(res.data.data);
}
})
.catch((err) => {
console.log(err);
});
if (state.bgForm) {
nextTick().then(() => {
state.bgForm.validate((valid) => {
if (!valid) {
state.bgForm.clearValidate();
}
});
});
}
state.addType = 2;
state.addDialog = true;
}; // 编辑按钮
const addConfirm = () => {
state.bgForm.validate((valid) => {
if (valid) {
if (state.addType == 1) {
// 新增
let params = {
classify_id: state.nodeClassifyId,
...state.formData,
};
axios.post(`/apaas/system/v5/dictionary/add`, params).then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.msg);
state.addDialog = false;
changePage(1);
} else {
ElMessage.error(res.data.data);
}
});
} else {
// 编辑
let params = {
id: state.actionRow.id,
...state.formData,
};
axios.put(`/apaas/system/v5/dictionary/update`, params).then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.msg);
state.addDialog = false;
changePage(1);
} else {
ElMessage.error(res.data.data);
}
});
}
}
});
}; // 确定新增/编辑
const delete_row = (row) => {
state.dialogDelete = true;
state.actionRow = row;
}; // 删除按钮
const deleteData = () => {
axios.delete(`/apaas/system/v5/dictionary/${state.actionRow.id}`).then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.msg);
state.dialogDelete = false;
changePage(1);
} else {
ElMessage.error(res.data.data);
}
});
}; // 确定删除
const moveRow = (row, type) => {
let index;
state.tableRows.forEach((e, i) => {
if (e.id == row.id) {
index = i;
}
});
let nextRow;
if (type == 1) {
// 上移
nextRow = state.tableRows[index - 1];
} else {
// 下移
nextRow = state.tableRows[index + 1];
}
let params = [
{
id: row.id,
sort: nextRow.sort,
},
{
id: nextRow.id,
sort: row.sort,
},
];
axios
.put(`/apaas/system/v5/dictionary/sort`, [...params])
.then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.msg);
changePage(1);
} else {
ElMessage.error(res.data.data);
}
})
.catch((err) => {
console.log(err);
});
};
onBeforeMount(() => { onBeforeMount(() => {
getTypeList(); getTypeList();
}); });
const { const { tableRows, tableTotal, filter } = toRefs(state);
typeList,
typeKeyword,
nodeClassifyId,
tableRows,
tableTotal,
filter,
stateOptions,
dialogDelete,
addType,
addDialog,
formData,
rules,
} = toRefs(state);
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment