Merge pull request 'feat: 高级筛选样式及交互调整,搜索限制调整' (#13) from al into test

Reviewed-on: #13
pull/14/head
刘释隆 1 year ago
commit 8e0211f801

@ -1,20 +1,29 @@
<script lang="ts">
import { useDialog, useMessage } from 'naive-ui'
import { defineComponent, inject, onMounted, reactive, ref, toRefs, unref, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import QuillModal from './QuillModal.vue'
import RecycleModal from './RecycleModal.vue'
import SearchModal from './SearchModal.vue'
import ShortcutModal from './ShortcutModal.vue'
import UserSettings from './UserSettings.vue'
import { msgPolling } from '@/api/message/message'
import { getImgUrl } from '@/utils/urlUtils'
import { useUser } from '@/store/modules/user'
import { useTaskStore } from '@/store/modules/task'
const taskStore = useTaskStore()
import { useDialog, useMessage } from "naive-ui";
import {
defineComponent,
inject,
onMounted,
reactive,
ref,
toRefs,
unref,
watch,
} from "vue";
import { useRoute, useRouter } from "vue-router";
import QuillModal from "./QuillModal.vue";
import RecycleModal from "./RecycleModal.vue";
import SearchModal from "./SearchModal.vue";
import ShortcutModal from "./ShortcutModal.vue";
import UserSettings from "./UserSettings.vue";
import { msgPolling } from "@/api/message/message";
import { getImgUrl } from "@/utils/urlUtils";
import { useUser } from "@/store/modules/user";
import { useTaskStore } from "@/store/modules/task";
const taskStore = useTaskStore();
export default defineComponent({
name: 'PageHeader',
name: "PageHeader",
components: {
UserSettings,
QuillModal,
@ -30,139 +39,137 @@ export default defineComponent({
type: Boolean,
},
},
emits: ['update:collapsed'],
emits: ["update:collapsed"],
setup() {
const message = useMessage()
const dialog = useDialog()
const message = useMessage();
const dialog = useDialog();
const userStore = useUser()
const useInfo = userStore.getUserInfo
const userStore = useUser();
const useInfo = userStore.getUserInfo;
const name = ''
const name = "";
const state = reactive({
username: name ?? '',
fullscreenIcon: 'FullscreenOutlined',
})
username: name ?? "",
fullscreenIcon: "FullscreenOutlined",
});
const router = useRouter()
const route = useRoute()
const routename = ref(route.meta.title)
const router = useRouter();
const route = useRoute();
const routename = ref(route.meta.title);
// mm
const iconList = ref([
{
icon: 'magnifying-1',
icon: "magnifying-1",
handle: searchHandler,
},
{
icon: 'shortcut-keys',
icon: "shortcut-keys",
handle: shortcutHandler,
},
{
icon: 'suspicious-folder',
icon: "suspicious-folder",
handle: recycleHandler,
},
{
icon: 'memo',
icon: "memo",
handle: quillHandler,
},
{
icon: 'nomessage',
icon: "nomessage",
handle: goMessage,
},
])
]);
watch(
() => route.fullPath,
() => {
routename.value = route.meta.title
},
)
routename.value = route.meta.title;
}
);
const handleDragOver = (event, item) => {
taskStore.setInFile(true)
}
taskStore.setInFile(true);
};
const handleDragLeave = (event, item) => {
taskStore.setInFile(false)
}
taskStore.setInFile(false);
};
const dropdownSelect = (key) => {
router.push({ name: key })
}
router.push({ name: key });
};
// 退
const doLogout = () => {
dialog.info({
title: '提示',
content: '您确定要退出登录吗',
positiveText: '确定',
negativeText: '取消',
title: "提示",
content: "您确定要退出登录吗",
positiveText: "确定",
negativeText: "取消",
onPositiveClick: () => {
userStore.logout().then(() => {
message.success('成功退出登录')
message.success("成功退出登录");
router
.replace({
name: 'Login',
name: "Login",
query: {
// redirect: route.fullPath,
},
})
.finally(() => location.reload())
})
.finally(() => location.reload());
});
},
onNegativeClick: () => {},
})
}
});
};
const quillModalRef = ref(null)
const shortcutModal = ref(null)
const recycleModalRef = ref(null)
const SearchModalRef = ref(null)
const quillModalRef = ref(null);
const shortcutModal = ref(null);
const recycleModalRef = ref(null);
const SearchModalRef = ref(null);
function quillHandler() {
const modal = unref(quillModalRef)! as any
modal.showModal()
const modal = unref(quillModalRef)! as any;
modal.showModal();
}
function shortcutHandler() {
const modal = unref(shortcutModal)! as any
modal.showModal()
const modal = unref(shortcutModal)! as any;
modal.showModal();
}
function recycleHandler() {
const modal = unref(recycleModalRef)! as any
modal.showModal()
const modal = unref(recycleModalRef)! as any;
modal.showModal();
}
function searchHandler() {
const modal = unref(SearchModalRef)! as any
modal.showModal()
const modal = unref(SearchModalRef)! as any;
modal.showModal();
}
function goMessage() {
router.push({ name: 'message-main' })
router.push({ name: "message-main" });
}
async function getMessage() {
const res = await msgPolling()
if (res.data)
iconList.value[4].icon = 'hasmessage'
else
iconList.value[4].icon = 'nomessage'
const res = await msgPolling();
if (res.data) iconList.value[4].icon = "hasmessage";
else iconList.value[4].icon = "nomessage";
}
setInterval(() => {
getMessage()
}, 5000)
getMessage();
}, 5000);
const mousetrap = inject('mousetrap') as any
const mousetrap = inject("mousetrap") as any;
onMounted(() => {
mousetrap.bind('n r', quillHandler)
mousetrap.bind('n t', quillHandler)
mousetrap.bind('n n', recycleHandler)
mousetrap.bind('m m', searchHandler)
})
getMessage();
mousetrap.bind("n r", quillHandler);
mousetrap.bind("n t", quillHandler);
mousetrap.bind("n n", recycleHandler);
mousetrap.bind("m m", searchHandler);
});
return {
...toRefs(state),
@ -183,9 +190,9 @@ export default defineComponent({
getMessage,
handleDragOver,
handleDragLeave,
}
};
},
})
});
</script>
<template>
@ -207,8 +214,16 @@ export default defineComponent({
v-for="item in iconList"
:key="item.icon"
class="layout-header-trigger layout-header-trigger-min"
@dragover.prevent="(e) => { handleDragOver(e, item) }"
@dragleave.prevent="(e) => { handleDragLeave(e, item) }"
@dragover.prevent="
(e) => {
handleDragOver(e, item);
}
"
@dragleave.prevent="
(e) => {
handleDragLeave(e, item);
}
"
>
<div class="back" @click="item.handle">
<SvgIcon :name="item.icon" size="18" />
@ -326,9 +341,7 @@ export default defineComponent({
}
.layout-header-left {
::v-deep(
.n-breadcrumb .n-breadcrumb-item:last-child .n-breadcrumb-item__link
) {
::v-deep(.n-breadcrumb .n-breadcrumb-item:last-child .n-breadcrumb-item__link) {
color: #515a6e;
}
}

@ -146,32 +146,32 @@ function rowProps(row: RowData) {
}
function handleCheck(rowKeys: DataTableRowKey[]) {
console.log(rowKeys, selectionIds.value, "handleCheck");
selectionIds.value = rowKeys;
}
function select(key: number) {
function select(key: number, id: string) {
switch (key) {
case 1:
editSelection();
editSelection(id);
break;
case 2:
deleteSelection();
deleteSelection(id);
break;
default:
break;
}
}
function editSelection() {
function editSelection(id = "") {
// eslint-disable-next-line dot-notation
const $message = window["$message"];
// const $message = window["$message"];
// if (selectionIds.value.length === 0 || selectionIds.value.length > 1) {
// $message.error("");
// return;
// }
if (selectionIds.value.length === 0 || selectionIds.value.length > 1) {
$message.error("请选中一条过滤");
return;
}
const selectedId = selectionIds.value[0];
const selectedId = id;
const selectedFilter = tableData.value.find((item: any) => {
return item.id === selectedId;
});
@ -180,12 +180,12 @@ function editSelection() {
closeModal();
}
function deleteSelection() {
function deleteSelection(id = "") {
// eslint-disable-next-line dot-notation
const $message = window["$message"];
if (selectionIds.value.length === 0) {
$message.error("至少选中一条过滤");
deleteCondition({ ids: id }).then(() => {
query(pagination.page, pagination.pageSize);
});
return;
}
@ -335,12 +335,19 @@ const showSearch = computed(() => {
<div class="del_btn">
<n-button icon-placement="left" size="medium">
<template #icon>
<SvgIcon name="delete-history" size="16" />
<SvgIcon name="delete-history" size="16" />
</template>
删除</n-button>
删除</n-button
>
</div>
<div class="msg">
<span>已选中 <span style="color:#507afd;font-size:16px">{{ selectionIds.length }}</span> </span>
<span
>已选中
<span style="color: #507afd; font-size: 16px">{{
selectionIds.length
}}</span>
</span
>
<a @click="selectionIds = []">清空</a>
</div>
</div>
@ -400,11 +407,10 @@ const showSearch = computed(() => {
width: 300px;
border: 1px solid gray;
}
.del_btn{
.del_btn {
}
.msg{
a{
.msg {
a {
margin-left: 30px;
cursor: pointer;
color: #507afd;

@ -1,10 +1,10 @@
<script lang="ts" setup>
import type { DropdownMixedOption } from 'naive-ui/es/dropdown/src/interface'
import type { PropType } from 'vue'
import type { DropdownMixedOption } from "naive-ui/es/dropdown/src/interface";
import type { PropType } from "vue";
defineOptions({ name: 'Action' })
defineOptions({ name: "Action" });
defineProps({
const props = defineProps({
options: {
type: Array as PropType<DropdownMixedOption[]>,
default: null,
@ -12,18 +12,21 @@ defineProps({
},
select: {
type: Function as PropType<Function>,
default: () => { },
default: () => {},
},
id: {
type: String,
default: '',
default: "",
},
})
});
const fun = (key) => {
props.select(key, props.id);
};
</script>
<template>
<div :data-id="id">
<n-dropdown trigger="hover" :options="options" @select="(select as any)">
<n-dropdown trigger="hover" :options="options" @select="fun">
<SvgIcon name="more-hor" size="20" />
</n-dropdown>
</div>

@ -17,7 +17,10 @@ const props = defineProps({
required: true,
},
});
const ruleForm = reactive({
keyword: "",
});
const ruleformRef = ref();
const emit = defineEmits<{
(e: "show-filter"): void;
(e: "show-custom"): void;
@ -27,7 +30,7 @@ const emit = defineEmits<{
const data = ref<FilterEntity[]>([]);
const unData = ref<FilterEntity[]>([]);
const loading = ref(false);
const loading = ref(false);
const canloadMore = true;
const el = ref<HTMLDivElement | null>(null);
const popover = ref<ComponentRef | null>(null);
@ -74,8 +77,8 @@ useInfiniteScroll(
},
{ distance: 10, interval: 300, canLoadMore: () => false }
);
const showClick =async () => {
getSearchedList('')
const showClick = async () => {
getSearchedList("");
};
async function loadMore() {
@ -92,7 +95,7 @@ async function featchList() {
loading.value = true;
try {
const searchParam: FilterSearchParam = {
search_searchname: { value: keyword.value, op: "like", type: "string" },
search_searchname: { value: ruleForm.keyword, op: "like", type: "string" },
};
const result = await getConditionList(pagination, searchParam, props.type);
const { data } = result;
@ -121,11 +124,8 @@ function generateFilterEntityList(data) {
};
});
const reg = new RegExp(keyword.value, "gi");
const hilightText = searchname.replace(
reg,
`<span>${keyword.value}</span>`
);
const reg = new RegExp(ruleForm.keyword, "gi");
const hilightText = searchname.replace(reg, `<span>${ruleForm.keyword}</span>`);
return {
id,
@ -134,7 +134,7 @@ function generateFilterEntityList(data) {
isDefaultFilter: false,
filterList: list,
reorder,
searchname
searchname,
};
});
@ -143,12 +143,17 @@ function generateFilterEntityList(data) {
function selectHandler(item: FilterEntity) {
(popover.value as any).setShow(false);
currentlySelectedAdvanced.value = item.searchname
currentlySelectedAdvanced.value = item.searchname;
emit("select", item.id);
}
const inputHandler = debounce((word) => {
getSearchedList(word)
ruleForm.keyword = word;
ruleformRef.value.validate();
if (word.length < 2 && word) {
return;
}
getSearchedList(word);
}, 300);
function getSearchedList(word) {
@ -157,7 +162,7 @@ function getSearchedList(word) {
} else {
pagination.pageSize = 10;
}
keyword.value = word;
ruleForm.keyword = word;
featchList().then((list) => {
let dataArr: FilterEntity[] = [];
let unDataArr: FilterEntity[] = [];
@ -195,10 +200,26 @@ function favoriteHandler(event: MouseEvent, item: any) {
}
});
inputHandler(keyword.value);
inputHandler(ruleForm.keyword);
}
}
const rules = {
keyword: [
{
trigger: ["blur", "input", "change"],
level: "error",
validator(_rule, value) {
if (value.length >= 2) {
return true;
} else {
return new Error("搜索关键字最少为两个");
}
},
},
],
};
function unFavoriteHandler(event: MouseEvent, item) {
event.stopImmediatePropagation();
event.stopPropagation();
@ -208,7 +229,7 @@ function unFavoriteHandler(event: MouseEvent, item) {
if (!isDefaultFilter) {
item.favorite = false;
unfavorite(id);
inputHandler(keyword.value);
inputHandler(ruleForm.keyword);
}
}
@ -233,29 +254,37 @@ const moveEnd = () => {
>
<template #trigger>
<div class="wrapper-left-dropdown" @click="showClick">
<span style="font-size: 20px;color: #333333;font-weight: Medium;">{{currentlySelectedAdvanced}}</span>
<SvgIcon :style="{ marginLeft: '5px' }" name="down" size="14" />
<span style="font-size: 20px; color: #333333; font-weight: Medium">{{
currentlySelectedAdvanced
}}</span>
<SvgIcon :style="{ marginLeft: '5px' }" name="down" size="14" color="#999999"/>
</div>
</template>
<n-spin :show="loading">
<div class="wrapper-left-popover">
<n-input
:style="{ '--n-border': '0px' }"
placeholder="请输入关键词"
@input="inputHandler"
>
<template #prefix>
<SvgIcon size="14px" name="magnifying-1" />
</template>
<template #suffix>
<SvgIcon
size="14px"
style="cursor: pointer"
name="setting"
@click="emit('show-filter')"
/>
</template>
</n-input>
<n-form :rules="rules" ref="ruleformRef" :model="ruleForm">
<n-form-item path="keyword">
<n-input
:style="{ '--n-border': '0px' }"
placeholder="请输入关键字"
@input="inputHandler"
:value="ruleForm.keyword"
:minlength="2"
>
<template #prefix>
<SvgIcon size="14px" name="magnifying-1" />
</template>
<template #suffix>
<SvgIcon
size="14px"
style="cursor: pointer"
name="setting"
@click="emit('show-filter')"
/>
</template>
</n-input>
</n-form-item>
</n-form>
<ul ref="el" class="wrapper-left-list">
<li
@ -264,23 +293,28 @@ const moveEnd = () => {
style="display: flex; align-items: center"
@click="selectHandler(item)"
>
<SvgIcon name="drag" size="18" color="#333333" style="margin-right:3px"/>
<SvgIcon
name="drag"
size="18"
color="#333333"
style="margin-right: 3px"
/>
<SvgIcon
v-if="item.favorite && !item.isDefaultFilter"
name="favorite-fill"
color="#fd9b0a"
size="18"
style="margin-right:3px"
style="margin-right: 3px"
@click="unFavoriteHandler($event, item)"
/>
<SvgIcon
v-else-if="!item.favorite && !item.isDefaultFilter"
name="favorite-unfill"
size="18"
style="margin-right:3px"
style="margin-right: 3px"
@click="favoriteHandler($event, item)"
/>
<div v-html="item.name" style="color: #333333;"/>
<div v-html="item.name" style="color: #333333" />
</li>
<!-- filter=".draggable-li[draggable='false']" -->
<VueDraggable
@ -298,14 +332,14 @@ const moveEnd = () => {
class="cursor-move draggable-li fix"
:draggable="true"
>
<SvgIcon name="drag" size="18" style="margin-right:3px"/>
<SvgIcon name="drag" size="18" style="margin-right: 3px" />
<SvgIcon
v-if="item.favorite && !item.isDefaultFilter"
name="favorite-fill"
color="#fd9b0a"
size="18"
fill="#666666"
style="cursor: pointer!important;margin-right:3px;"
style="cursor: pointer !important; margin-right: 3px"
@click="unFavoriteHandler($event, item)"
/>
<SvgIcon
@ -313,10 +347,10 @@ const moveEnd = () => {
name="favorite-unfill"
size="18"
fill="#666666"
style="cursor: pointer!important;margin-right:3px;"
style="cursor: pointer !important; margin-right: 3px"
@click="favoriteHandler($event, item)"
/>
<div v-html="item.name" style="color: #333333;"/>
<div v-html="item.name" style="color: #333333" />
</li>
</VueDraggable>
</ul>

@ -148,43 +148,41 @@ function handleCheck(rowKeys: DataTableRowKey[]) {
selectionIds.value = rowKeys;
}
function select(key: number) {
function select(key: number, id: string) {
switch (key) {
case 1:
editSelection();
editSelection(id);
break;
case 2:
deleteSelection();
deleteSelection(id);
break;
default:
break;
}
}
function editSelection() {
function editSelection(id) {
// eslint-disable-next-line dot-notation
const $message = window["$message"];
if (selectionIds.value.length === 0 || selectionIds.value.length > 1) {
$message.error("请选中一条过滤");
return;
}
const selectedId = selectionIds.value[0];
// const $message = window["$message"];
// if (selectionIds.value.length === 0 || selectionIds.value.length > 1) {
// $message.error("");
// return;
// }
const selectedId = id;
const selectedFilter = tableData.value.find((item: any) => {
return item.id === selectedId;
});
emit("editFilter", selectedFilter);
closeModal();
// closeModal();
}
function deleteSelection() {
function deleteSelection(id = '') {
// eslint-disable-next-line dot-notation
const $message = window["$message"];
if (selectionIds.value.length === 0) {
$message.error("至少选中一条过滤");
deleteCondition({ ids: id }).then(() => {
query(pagination.page, pagination.pageSize);
});
return;
}

Loading…
Cancel
Save