feat: 样式修复

pull/218/head
刘释隆 1 year ago
parent 1e74d0ac80
commit e0a4bc292a

@ -1,29 +1,68 @@
<script lang="ts" setup>
import { defineProps, onMounted, ref } from 'vue'
import { gettaskToolsCount } from '@/api/home/main'
import { defineProps, onMounted, ref } from "vue";
import { gettaskToolsCount } from "@/api/home/main";
defineProps({
hasColor: {
type: Boolean,
default: () => false,
},
})
});
const data = ref()
const data = ref([
{
link: "count",
title: "任务总数",
count: 0,
},
{
link: "wait",
title: "待审批",
count: 0,
},
{
link: "done",
title: "已审批",
count: 0,
},
{
link: "resolve",
title: "通过",
count: 0,
color: "#03c984",
},
{
link: "reject",
title: "不通过",
count: 0,
color: "#ff8b8b",
},
{
link: "reimg",
title: "图片重复数",
count: 0,
},
{
link: "breakcount",
title: "小结重复数",
count: 0,
},
]);
function initRem() {
const designWidth = 1440
const rempPx = 16
const scale = window.innerWidth / designWidth
document.documentElement.style.fontSize = `${scale * rempPx}px`
const designWidth = 1440;
const rempPx = 16;
const scale = window.innerWidth / designWidth;
document.documentElement.style.fontSize = `${scale * rempPx}px`;
}
onMounted(() => {
initRem()
getData()
})
initRem();
getData();
});
async function getData() {
const {
data: {
const { data } = await gettaskToolsCount();
if (data) {
const {
total,
treat,
alreadyApprove,
@ -31,62 +70,72 @@ async function getData() {
repeat,
approvedCount,
notGoCount,
},
} = await gettaskToolsCount()
data.value = [
{
link: 'count',
title: '任务总数',
count: total,
},
{
link: 'wait',
title: '待审批',
count: treat,
},
{
link: 'done',
title: '已审批',
count: alreadyApprove,
},
{
link: 'resolve',
title: '通过',
count: approvedCount,
color: '#03c984',
},
{
link: 'reject',
title: '不通过',
count: notGoCount,
color: '#ff8b8b',
},
{
link: 'reimg',
title: '图片重复数',
count: repeat,
},
{
link: 'breakcount',
title: '小结重复数',
count: repeatedNodules,
},
]
} = data;
data.value = [
{
link: "count",
title: "任务总数",
count: total,
},
{
link: "wait",
title: "待审批",
count: treat,
},
{
link: "done",
title: "已审批",
count: alreadyApprove,
},
{
link: "resolve",
title: "通过",
count: approvedCount,
color: "#03c984",
},
{
link: "reject",
title: "不通过",
count: notGoCount,
color: "#ff8b8b",
},
{
link: "reimg",
title: "图片重复数",
count: repeat,
},
{
link: "breakcount",
title: "小结重复数",
count: repeatedNodules,
},
];
}
}
</script>
<template>
<div class="header_wrap">
<div v-for="(item, index) in data" :key="index" class="header_item">
<SvgIcon :name="item.link" />
<div class="data_wrap">
<div class="data_title" :style="hasColor ? `color:${item.color || ''}` : ''">
{{ item.count }}
</div>
<div class="data_content">
{{ item.title }}
<div class="header_wrap" :style="hasColor ? '' : 'margin-top: 7.375rem;'">
<div v-for="(item, index) in data" :key="index" class="header_box">
<div class="header_item">
<SvgIcon :name="item.link" :style="index == 0 ? 'margin-left:0.5rem' : ''" />
<div class="data_wrap">
<div class="data_title" :style="hasColor ? `color:${item.color || ''}` : ''">
{{ item.count }}
</div>
<div class="data_content">
{{ item.title }}
</div>
</div>
</div>
<div
class="line"
:style="
hasColor
? 'margin-left:2.5rem;margin-right:2.0625rem'
: 'margin-left:1.25rem;margin-right:0.8125rem'
"
/>
</div>
<SvgIcon size="14px" style="cursor: pointer" name="setting" class="settingSvg" />
</div>
@ -99,41 +148,48 @@ async function getData() {
align-items: center;
justify-content: space-between;
padding: 1rem 1rem 1rem 3.125rem;
background: #fff;
background: #f5f7f9;
margin-bottom: 1rem;
.header_item {
min-width: 10%;
// 180-62 header
padding-left: 2.125rem;
.header_box {
display: flex;
flex-flow: row nowrap;
align-items: center;
justify-content: center;
svg {
width: 2.75rem !important;
height: 2.75rem !important;
}
.data_wrap {
margin-left: 0.8125rem;
.data_title {
font-size: 1.125rem;
font-family: HarmonyOS Sans SC, HarmonyOS Sans SC-Bold;
font-weight: 900;
text-align: left;
color: #202020;
line-height: 1.4375rem;
text-align: center;
white-space: nowrap;
min-width: 10%;
.header_item {
display: flex;
flex-flow: row nowrap;
align-items: center;
justify-content: center;
svg {
width: 2.75rem !important;
height: 2.75rem !important;
}
.data_content {
opacity: 0.6;
font-size: 0.75rem;
font-family: PingFang SC, PingFang SC-Regular;
font-weight: 500;
text-align: center;
color: #202020;
line-height: 1rem;
text-align: center;
white-space: nowrap;
.data_wrap {
margin-left: 0.75rem;
.data_title {
font-size: 1.125rem;
font-family: HarmonyOS Sans SC, HarmonyOS Sans SC-Bold;
font-weight: 900;
text-align: left;
color: #202020;
line-height: 1.4375rem;
text-align: center;
white-space: nowrap;
}
.data_content {
opacity: 0.6;
font-size: 0.75rem;
font-family: PingFang SC, PingFang SC-Regular;
font-weight: 500;
text-align: center;
color: #202020;
line-height: 1rem;
text-align: center;
white-space: nowrap;
}
}
}
}
@ -142,4 +198,9 @@ async function getData() {
width: 1rem !important;
height: 1rem !important;
}
.line {
width: 0.0625rem;
height: 1.25rem;
background: #e8e8e8;
}
</style>

@ -1,48 +1,48 @@
<script lang="ts" setup>
import { defineEmits, reactive, ref } from 'vue'
import { QuillEditor } from '@vueup/vue-quill'
import '@vueup/vue-quill/dist/vue-quill.snow.css'
import { debounce } from 'lodash-es'
import { queryNote, saveNote } from '@/api/home/main'
import { defineEmits, reactive, ref } from "vue";
import { QuillEditor } from "@vueup/vue-quill";
import "@vueup/vue-quill/dist/vue-quill.snow.css";
import { debounce } from "lodash-es";
import { queryNote, saveNote } from "@/api/home/main";
const emit = defineEmits(['close'])
const emit = defineEmits(["close"]);
const quillEditor = ref()
const quillEditor = ref();
const cardStyle = {
'width': '500px',
'--n-padding-bottom': '17px',
'--n-padding-left': '24px',
}
"width": "500px",
"--n-padding-bottom": "17px",
"--n-padding-left": "24px",
};
const note = ref('<p>sss</p>')
const note = ref("<p>sss</p>");
const options = reactive({
modules: {
toolbar: [
['bold', 'italic', 'underline', 'strike'], // toggled buttons
[{ align: '' }, { align: 'center' }, { align: 'right' }, { align: 'justify' }],
["bold", "italic", "underline", "strike"], // toggled buttons
[{ align: "" }, { align: "center" }, { align: "right" }, { align: "justify" }],
],
},
theme: 'snow',
placeholder: '',
})
theme: "snow",
placeholder: "",
});
function initHandler() {
queryNote()
.then((res) => {
if (res.data)
note.value = res.data.notecontent
note.value = res.data.notecontent;
console.log('note:', note.value)
console.log("note:", note.value);
})
.catch(e => console.log(e))
.catch(e => console.log(e));
}
const saveHandler = debounce(() => {
const content = quillEditor.value.getHTML()
saveNote(content)
}, 800)
const content = quillEditor.value.getHTML();
saveNote(content);
}, 800);
</script>
<template>
@ -53,7 +53,7 @@ const saveHandler = debounce(() => {
备注信息
</div>
<SvgIcon
size="24"
size="20"
name="close-none-border"
class="close_box"
@click="emit('close')"
@ -87,9 +87,9 @@ const saveHandler = debounce(() => {
.title {
font-size: 18px;
font-family: PingFang SC, PingFang SC-Medium;
font-weight: Medium;
color: #333333;
margin-bottom: 24px;
font-weight: 500;
}
.ql-toolbar.ql-snow {

@ -1,99 +1,99 @@
<script setup lang="ts">
import { nextTick, onMounted, onUnmounted, reactive, ref, toRefs } from 'vue'
import { debounce } from 'lodash-es'
import { useRoute, useRouter } from 'vue-router'
import { deleteSearch, getSearchList, historySearch } from '@/api/search/search'
import { storage } from '@/utils/Storage'
import { nextTick, onMounted, onUnmounted, reactive, ref, toRefs } from "vue";
import { debounce } from "lodash-es";
import { useRoute, useRouter } from "vue-router";
import { deleteSearch, getSearchList, historySearch } from "@/api/search/search";
import { storage } from "@/utils/Storage";
const emit = defineEmits(['close'])
const emit = defineEmits(["close"]);
const value = ref('')
const showList = ref(false)
const historyList: any = ref([])
const handlerShowList = () => (showList.value = true)
const router = useRouter()
const route = useRoute()
const value = ref("");
const showList = ref(false);
const historyList: any = ref([]);
const handlerShowList = () => (showList.value = true);
const router = useRouter();
const route = useRoute();
const state = reactive({
resultList: [],
}) as any
}) as any;
const { resultList } = toRefs(state)
const { resultList } = toRefs(state);
const inputHandler = debounce((keyword) => {
if (keyword)
handlerSearch(keyword)
}, 500)
handlerSearch(keyword);
}, 500);
//
async function handlerSearch(value) {
const res = await getSearchList({
search: value,
})
if (res.code === 'OK') {
});
if (res.code === "OK") {
state.resultList = [
{
title: '图检审批',
path: 'worksheet',
title: "图检审批",
path: "worksheet",
data: res.data.ai,
},
{
title: '任务审批管理',
path: 'task',
title: "任务审批管理",
path: "task",
data: res.data.preliminary,
},
{
title: '任务终审管理',
path: 'final',
title: "任务终审管理",
path: "final",
data: res.data.final,
},
]
];
}
}
function handlerHistory(name) {
value.value = name
handlerSearch(name)
value.value = name;
handlerSearch(name);
}
//
async function deleteHistory() {
const res = await deleteSearch({})
if (res.code === 'OK')
historyList.value = []
const res = await deleteSearch({});
if (res.code === "OK")
historyList.value = [];
}
//
async function getHistory() {
const res = await historySearch({})
if (res.code === 'OK')
historyList.value = res.data
const res = await historySearch({});
if (res.code === "OK")
historyList.value = res.data;
}
getHistory()
getHistory();
function goPath(item, id) {
const desiredObject = item.data.find((item) => {
return item.id === id
})
storage.set('isSearch', true)
router.push({ name: item.path, query: { id, searchContent: desiredObject.name } })
emit('close')
return item.id === id;
});
storage.set("isSearch", true);
router.push({ name: item.path, query: { id, searchContent: desiredObject.name } });
emit("close");
}
function highlightText(text, query) {
if (!query)
return text
const regex = new RegExp(query, 'gi')
return text;
const regex = new RegExp(query, "gi");
const highlightedText = text.replace(regex, (match) => {
return `<span style="color:#507AFD" class="highlight">${match}</span>`
})
return `<span style="color:#507AFD" class="highlight">${match}</span>`;
});
return highlightedText
return highlightedText;
}
onMounted(() => {
setTimeout(() => (value.value = ''))
handlerShowList()
handlerSearch('')
})
setTimeout(() => (value.value = ""));
handlerShowList();
handlerSearch("");
});
</script>
<template>
@ -105,12 +105,19 @@ onMounted(() => {
<n-input
v-model:value="value"
placeholder="搜索任务ID、任务名称、提报人、拜访终端"
placeholder-style="width:304px;height:22px;margin:17px 0 17px 12px;"
style="font-size: 16px; font-weight: 500; color: #333333"
type="text"
@input="inputHandler"
@mousedown="handlerShowList"
>
<template #prefix>
<SvgIcon name="magnifying-1" size="18" />
<SvgIcon
name="magnifying-1"
width="21"
height="20"
style="margin: 10px 0 10px 4px"
/>
</template>
</n-input>
</div>
@ -157,7 +164,7 @@ onMounted(() => {
class="list_item"
@click="goPath(item, sitem.id)"
>
<SvgIcon name="task-icon" size="16" />
<SvgIcon name="task-icon" size="16" style="margin-left: 16px" />
<span class="name" v-html="highlightText(sitem.name, value)" />
</div>
</div>
@ -167,10 +174,11 @@ onMounted(() => {
<style lang="less" scoped>
.input_wrap {
width: 60%;
// width: 60%;
width: 808px;
position: absolute;
top: 20%;
left: 20%;
left: 30%;
box-shadow: none !important;
.ip_box {
@ -192,6 +200,8 @@ onMounted(() => {
border-radius: 8px;
overflow: hidden;
box-shadow: 0px 12px 12px 0px rgba(80, 122, 253, 0.15), 0px 0px 0px 0.5px #d4e3fc;
// width: 808px;
// height: 56px;
}
.list_box {
@ -201,22 +211,25 @@ onMounted(() => {
box-shadow: 0px 12px 12px 0px rgba(80, 122, 253, 0.15);
margin-top: 15px;
padding: 8px 16px;
width: 802px;
height: 400px;
.list_classfiy_item {
margin-bottom: -2px;
.list_title {
font-size: 12px;
font-family: PingFang SC, PingFang SC-Regular;
font-weight: Regular;
color: #999999;
line-height: 17px;
margin: 10px 0 10px 5px;
margin: 6px 0 12px 0;
font-weight: 500;
}
.list_item {
display: flex;
flex-flow: row nowrap;
align-items: center;
margin-bottom: 10px;
margin: 16px 0;
}
}
}
@ -228,12 +241,15 @@ onMounted(() => {
.history-list {
align-items: center;
padding-bottom: 9px;
// margin-bottom:12;12+26=38
padding: 26px 12px 12px 0;
}
.name {
margin-left: 5px;
margin-left: 8px;
cursor: pointer;
font-weight: 500;
color: #333333;
}
.tag-wrap {
@ -242,8 +258,10 @@ onMounted(() => {
flex: 1;
overflow-y: hidden;
overflow-x: auto;
margin: 9px 0 9px 29px;
.tag {
font-weight: 500;
padding: 0 12px;
height: 22px;
border: 1px solid #e4e7ed;

@ -1,29 +1,33 @@
<script lang="ts" setup>
import { defineOptions, ref } from 'vue'
import Quill from '@/components/RichEditor/Quill.vue'
import { defineOptions, ref } from "vue";
import Quill from "@/components/RichEditor/Quill.vue";
defineOptions({ name: 'FilterModal' })
defineOptions({ name: "FilterModal" });
const emit = defineEmits(['showNewFilter'])
const emit = defineEmits(["showNewFilter"]);
const show = ref(false)
const show = ref(false);
function showModal() {
show.value = true
show.value = true;
}
function closeModal() {
show.value = false
show.value = false;
}
defineExpose({
showModal,
})
});
</script>
<template>
<div>
<n-modal v-model:show="show" transform-origin="center">
<n-modal
v-model:show="show"
transform-origin="center"
style="margin: calc(13%-147px) auto 0 !important"
>
<Quill @close="show = false" />
</n-modal>
</div>

@ -1,49 +1,71 @@
<script lang="ts" setup>
import { defineOptions, ref } from 'vue'
import { defineOptions, ref } from "vue";
defineOptions({ name: 'ShortcutModal' })
defineOptions({ name: "ShortcutModal" });
const show = ref(false)
const show = ref(false);
const cardStyle = {
'width': '800px',
'--n-padding-bottom': '10px',
'--n-padding-left': '10px',
'padding-bottom':'100px'
}
"width": "800px",
"--n-padding-bottom": "10px",
"--n-padding-left": "10px",
"padding-bottom": "100px",
};
function showModal() {
show.value = true
show.value = true;
}
function closeModal() {
show.value = false
show.value = false;
}
defineExpose({
showModal,
})
});
</script>
<template>
<div>
<n-modal v-model:show="show" transform-origin="center">
<n-card :style="cardStyle" :bordered="false" size="huge" role="dialog" aria-modal="true">
<n-modal
v-model:show="show"
transform-origin="center"
style="width: 808px; height: 606px; margin: -27px auto 0 !important"
>
<n-card
:style="cardStyle"
:bordered="false"
size="huge"
role="dialog"
aria-modal="true"
>
<div class="wrapper">
<div class="wrapper-header">
<span class="wrapper-left">全局快捷键</span>
<div class="wrapper-right">
<img class="img-question" src="@/assets/images/question.png" alt="">查看快捷键的信息
<img
class="img-question"
src="@/assets/images/question.png"
alt=""
style="width: 18px; height: 18px"
>查看快捷键的信息
<img class="img-close" src="@/assets/images/close.png" alt="" @click="closeModal">
<img
class="img-close"
src="@/assets/images/close.png"
alt=""
style="width: 20px; height: 20px"
@click="closeModal"
>
</div>
</div>
<n-divider />
<n-divider style="margin-bottom: 32px" />
<div class="title">
全局快捷方式
</div>
<div class="wrapper-global">
<table style="margin-left: 100px;">
<table style="margin-left: 47px; width: 180px">
<tr>
<td><div class="key" data-key="g h" /></td>
<td>进入一键查看主页</td>
@ -73,7 +95,7 @@ defineExpose({
<td>打开可疑文件夹</td>
</tr>
</table>
<table style="height: 30%;margin-left: 180px;">
<table style="height: 30%; margin-left: 180px">
<tr>
<td><div class="key" data-key="[" /></td>
<td>隐藏/显示当前场景左侧筛选区</td>
@ -96,29 +118,36 @@ defineExpose({
</tr>
</table>
</div>
<n-divider />
<div class="title">
<n-divider style="margin: 24px 24px 32px 24px; color: #d9d9d9" />
<div class="title" style="margin-top: -16.5px">
任务审批/任务终审/AI工单明细动作
</div>
<div class="wrapper-request">
<table style="margin-left: 100px;">
<table style="margin-left: 47px; width: 180px">
<tr>
<td><div class="key" data-key="p p" /></td>
<td style="text-align: left; width: 53px">
<div class="key" data-key="p p" />
</td>
<td>通过</td>
</tr>
<tr>
<td><div class="key" data-key="x x" /></td>
<td style="text-align: left">
<div class="key" data-key="x x" />
</td>
<td>不通过</td>
</tr>
</table>
<table style="margin-left: 155px;">
<table style="margin-left: 180px">
<tr>
<td><div class="key" data-key="c" /></td>
<td>关闭关闭当前场景弹窗</td>
</tr>
<tr>
<td><div class="key" data-key="&larr;" /><span>/</span><div class="key" data-key="&rarr;" /></td>
<td>
<div class="key" data-key="&larr;" />
<span>/</span>
<div class="key" data-key="&rarr;" />
</td>
<td>打开上一条/下一条信息切换</td>
</tr>
</table>
@ -142,54 +171,56 @@ defineExpose({
</template>
<style lang="less" scoped>
.wrapper-footer{
.wrapper-footer {
margin-top: -20px;
}
.wrapper {
.wrapper-header{
padding: 14px;
.wrapper-header {
padding: 14px 0 14px 0;
padding-bottom: 0;
}
.img-question{
.img-question {
width: 16px;
height: 16px;
margin: 0 2px;
}
.img-close{
.img-close {
width: 16px;
height: 16px;
margin-left: 16px;
cursor: pointer;
}
.wrapper-right{
.wrapper-right {
font-size: 16px;
font-family: PingFang SC, PingFang SC-Regular;
font-weight: Regular;
font-weight: 400;
text-align: left;
color: #666666;
line-height: 22px;
display: flex;
align-items: center
align-items: center;
}
.wrapper-left{
.wrapper-left {
font-size: 18px;
font-family: PingFang SC, PingFang SC-Medium;
font-weight: 600;
text-align: left;
color: #333333;
color: #000000;
line-height: 25px;
}
.title{
.title {
font-size: 14px;
font-weight: 600;
margin-bottom: 10px;
padding-left: 30px;
padding-left: 47px;
color: #333333;
font-weight: 600;
// 线24px
}
&-header {
display: flex;
@ -220,7 +251,7 @@ defineExpose({
}
&-icon {
background: #FFF;
background: #fff;
display: inline-block;
width: 18px;
height: 1px;
@ -228,32 +259,31 @@ defineExpose({
-webkit-transform: rotate(45deg);
&:after {
content: '';
content: "";
display: block;
width: 18px;
height: 1px;
background: #FFF;
background: #fff;
transform: rotate(-90deg);
-webkit-transform: rotate(-90deg);
}
}
}
&-request,&-global{
&-request,
&-global {
display: flex;
table{
tr td:first-child{
table {
tr td:first-child {
text-align: right;
padding-right: 10px;
color: #515457;
}
tr td{
tr td {
color: #333333;
}
tr span{
tr span {
padding: 0 10px;
}
}
@ -269,13 +299,14 @@ defineExpose({
display: inline-block;
box-sizing: content-box;
font-size: 16px;
font-weight: bold;
text-align: center;
padding: 2px 6px;
border: 1px solid #d6d6d6;
border-left: 3px solid #d6d6d6;
border-bottom: 3px solid #d6d6d6;
background-color: #fdfdfd;
// color: #333333;
font-weight: bold;
}
.key[data-key]::after {

@ -1,92 +1,92 @@
<script lang="ts" setup>
import { computed, inject, onMounted, ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { useUser } from '@/store/modules/user'
import { getImgUrl } from '@/utils/urlUtils'
import defaultAvatar from '@/assets/icons/avatar.svg'
import { computed, inject, onMounted, ref } from "vue";
import { useRoute, useRouter } from "vue-router";
import { useUser } from "@/store/modules/user";
import { getImgUrl } from "@/utils/urlUtils";
import defaultAvatar from "@/assets/icons/avatar.svg";
const emit = defineEmits<{
(e: 'logout'): void
}>()
(e: "logout"): void
}>();
const router = useRouter()
const router = useRouter();
const userStore = useUser()
const userStore = useUser();
const useInfo = userStore.getUserInfo
const useInfo = userStore.getUserInfo;
const aiDisabled = ref(false)
const aiDisabled = ref(false);
function handleSelect(row) {
userStore.updateTenantId(row.key)
location.reload()
userStore.updateTenantId(row.key);
location.reload();
}
function logIt(e) {
return false
return false;
}
//
function goHome(e) {
router.push({ name: 'home' })
router.push({ name: "home" });
}
//
function goTask(e) {
router.push({ name: 'task-main' })
router.push({ name: "task-main" });
}
// AI
function goWorksheet(e) {
router.push({ name: 'worksheet-main' })
router.push({ name: "worksheet-main" });
}
//
function goFinal(e) {
router.push({ name: 'final-main' })
router.push({ name: "final-main" });
}
const mousetrap = inject('mousetrap') as any
const mousetrap = inject("mousetrap") as any;
onMounted(() => {
mousetrap.bind('g h', goHome)
mousetrap.bind('g t', goTask)
mousetrap.bind('g a', goWorksheet)
mousetrap.bind('g e', goFinal)
})
mousetrap.bind("g h", goHome);
mousetrap.bind("g t", goTask);
mousetrap.bind("g a", goWorksheet);
mousetrap.bind("g e", goFinal);
});
const showPopover = ref(false)
const popRef = ref(null)
const changeFlag = ref(false)
const showPopover = ref(false);
const popRef = ref(null);
const changeFlag = ref(false);
const iconName = computed(() => {
return showPopover.value ? 'expand' : 'collapse'
})
return showPopover.value ? "expand" : "collapse";
});
function handleUpdateShow(show: boolean) {
showPopover.value = show
showPopover.value = show;
}
function logOut() {
(popRef.value as any).setShow(false)
emit('logout')
(popRef.value as any).setShow(false);
emit("logout");
}
const currentCompanyName = computed(() => {
const deptlist = useInfo.deptlist
const currentId = userStore.getTenantId
const current = deptlist.find(item => item.deptno === currentId)
return current?.departname || 'name'
})
const deptlist = useInfo.deptlist;
const currentId = userStore.getTenantId;
const current = deptlist.find(item => item.deptno === currentId);
return current?.departname || "name";
});
const options = computed(() => {
const deptlist = useInfo.deptlist
const deptlist = useInfo.deptlist;
return deptlist.map((item) => {
return {
label: item.departname,
key: item.deptno,
}
})
})
};
});
});
</script>
<template>
@ -155,9 +155,11 @@ const options = computed(() => {
.header {
.user-name {
font-size: 16px;
font-weight: 600;
}
.depart-name {
font-size: 12px;
font-weight: 600;
}
}
}
@ -194,6 +196,8 @@ const options = computed(() => {
padding: 13px 20px;
cursor: pointer;
color: #333333;
font-size: 13px;
font-weight: 600;
}
.trigger:hover {

@ -1,14 +1,14 @@
<script lang="ts" setup>
import { useInfiniteScroll } from '@vueuse/core'
import { debounce } from 'lodash-es'
import { onMounted, reactive, ref, watch } from 'vue'
import type { FilterSearchParam } from '/#/api'
import type { Filter, FilterEntity } from '/#/home'
import { VueDraggable } from 'vue-draggable-plus'
import { asideMap } from '@/config/aside'
import { favorite, getConditionList, sort, unfavorite } from '@/api/home/filter'
import { useInfiniteScroll } from "@vueuse/core";
import { debounce } from "lodash-es";
import { onMounted, reactive, ref, watch } from "vue";
import type { FilterSearchParam } from "/#/api";
import type { Filter, FilterEntity } from "/#/home";
import { VueDraggable } from "vue-draggable-plus";
import { asideMap } from "@/config/aside";
import { favorite, getConditionList, sort, unfavorite } from "@/api/home/filter";
defineOptions({ name: 'AdvanceFilter' })
defineOptions({ name: "AdvanceFilter" });
const props = defineProps({
type: {
@ -16,42 +16,42 @@ const props = defineProps({
default: 0,
required: true,
},
})
});
const emit = defineEmits<{
(e: 'show-filter'): void
(e: 'show-custom'): void
(e: 'update:search'): void
(e: 'select', id: string)
}>()
(e: "show-filter"): void
(e: "show-custom"): void
(e: "update:search"): void
(e: "select", id: string)
}>();
const ruleForm = reactive({
keyword: '',
})
const ruleformRef = ref()
const data = ref<FilterEntity[]>([])
const unData = ref<FilterEntity[]>([])
const loading = ref(false)
const canloadMore = true
const el = ref<HTMLDivElement | null>(null)
const popover = ref<ComponentRef | null>(null)
keyword: "",
});
const ruleformRef = ref();
const data = ref<FilterEntity[]>([]);
const unData = ref<FilterEntity[]>([]);
const loading = ref(false);
const canloadMore = true;
const el = ref<HTMLDivElement | null>(null);
const popover = ref<ComponentRef | null>(null);
const pagination = reactive({
pageNo: 1,
pageSize: 300,
})
const keyword = ref('')
const currentlySelectedAdvanced = ref('高级筛选')
});
const keyword = ref("");
const currentlySelectedAdvanced = ref("高级筛选");
onMounted(() => {
// data.value = generateDefaultConfig()
})
});
//
function generateDefaultConfig(): FilterEntity[] {
return Object.keys(asideMap).reduce((acc, key) => {
const { label, defaultValue, isDefaultFilter } = asideMap[key]
const { label, defaultValue, isDefaultFilter } = asideMap[key];
if (isDefaultFilter === true) {
const config = {
id: '',
id: "",
name: label,
favorite: false,
isDefaultFilter,
@ -61,73 +61,73 @@ function generateDefaultConfig(): FilterEntity[] {
value: defaultValue,
},
],
}
return [...acc, config]
};
return [...acc, config];
}
else {
return acc
return acc;
}
}, [])
}, []);
}
useInfiniteScroll(
el as any,
() => {
loadMore()
loadMore();
},
{ distance: 10, interval: 300, canLoadMore: () => false },
)
);
async function showClick() {
getSearchedList('')
getSearchedList("");
}
async function loadMore() {
if (loading.value || el.value == null)
return
return;
const more = await featchList()
const more = await featchList();
if (more.length === 0)
return
return;
data.value.push(...more)
data.value.push(...more);
}
async function featchList() {
loading.value = true
loading.value = true;
try {
const searchParam: FilterSearchParam = {
search_searchname: { value: ruleForm.keyword, op: 'like', type: 'string' },
}
const result = await getConditionList(pagination, searchParam, props.type)
const { data } = result
search_searchname: { value: ruleForm.keyword, op: "like", type: "string" },
};
const result = await getConditionList(pagination, searchParam, props.type);
const { data } = result;
// pagination.pageNo += 1
// canloadMore = pageCount >= pagination.pageNo
const entityList = generateFilterEntityList(data)
return entityList
const entityList = generateFilterEntityList(data);
return entityList;
}
catch (error) {
return []
return [];
}
finally {
loading.value = false
loading.value = false;
}
}
//
function generateFilterEntityList(data) {
const filterEntityList = data.map((item) => {
const { searchname, iztop, ocrUsersearchchildList, id, reorder } = item
const { searchname, iztop, ocrUsersearchchildList, id, reorder } = item;
const list = ocrUsersearchchildList.map((item) => {
const { searchfield, searchvalue } = item
const { searchfield, searchvalue } = item;
return {
key: searchfield,
value: searchvalue,
}
})
};
});
const reg = new RegExp(ruleForm.keyword, 'gi')
const hilightText = searchname.replace(reg, `<span>${ruleForm.keyword}</span>`)
const reg = new RegExp(ruleForm.keyword, "gi");
const hilightText = searchname.replace(reg, `<span>${ruleForm.keyword}</span>`);
return {
id,
@ -137,128 +137,128 @@ function generateFilterEntityList(data) {
filterList: list,
reorder,
searchname,
}
})
};
});
return filterEntityList
return filterEntityList;
}
function selectHandler(item: FilterEntity) {
(popover.value as any).setShow(false)
currentlySelectedAdvanced.value = item.searchname
emit('select', item.id)
(popover.value as any).setShow(false);
currentlySelectedAdvanced.value = item.searchname;
emit("select", item.id);
}
const inputHandler = debounce((word) => {
ruleForm.keyword = word
ruleformRef.value.validate()
ruleForm.keyword = word;
ruleformRef.value.validate();
if (word.length < 2 && word)
return
return;
getSearchedList(word)
}, 300)
getSearchedList(word);
}, 300);
function getSearchedList(word, isScroll = false) {
if (word)
pagination.pageSize = 300
pagination.pageSize = 300;
if (!word)
pagination.pageSize = 10
pagination.pageSize = 10;
if (isScroll)
pagination.pageSize = 300
pagination.pageSize = 300;
ruleForm.keyword = word
ruleForm.keyword = word;
featchList().then((list) => {
const dataArr: FilterEntity[] = []
const unDataArr: FilterEntity[] = []
const dataArr: FilterEntity[] = [];
const unDataArr: FilterEntity[] = [];
list.forEach((item) => {
if (item.favorite && !item.isDefaultFilter)
dataArr.push(item)
dataArr.push(item);
if (!item.favorite && !item.isDefaultFilter)
unDataArr.push(item)
})
unDataArr.push(item);
});
data.value = dataArr.sort(
(a, b) => Number(new Date(a.createtime)) - Number(new Date(b.createtime)),
)
);
unData.value = unDataArr.sort(
(a, b) => Number((a as any).reorder) - Number((b as any).reorder),
)
})
);
});
}
function favoriteHandler(event: MouseEvent, item: any) {
event.stopImmediatePropagation()
event.stopPropagation()
event.stopImmediatePropagation();
event.stopPropagation();
const { isDefaultFilter, id } = item
const { isDefaultFilter, id } = item;
if (!isDefaultFilter) {
item.favorite = true
favorite(id)
item.favorite = true;
favorite(id);
data.value.forEach((v, index) => {
if (v.id == id)
sort(v.id, 0)
else sort(v.id, index + 1)
})
sort(v.id, 0);
else sort(v.id, index + 1);
});
inputHandler(ruleForm.keyword)
inputHandler(ruleForm.keyword);
}
}
const rules = {
keyword: [
{
trigger: ['blur', 'input', 'change'],
level: 'error',
trigger: ["blur", "input", "change"],
level: "error",
validator(_rule, value) {
if (value.length >= 2)
return true
else return new Error('搜索关键字最少为两个')
return true;
else return new Error("搜索关键字最少为两个");
},
},
],
}
};
function unFavoriteHandler(event: MouseEvent, item) {
event.stopImmediatePropagation()
event.stopPropagation()
event.stopImmediatePropagation();
event.stopPropagation();
const { isDefaultFilter, id } = item
const { isDefaultFilter, id } = item;
if (!isDefaultFilter) {
item.favorite = false
unfavorite(id)
inputHandler(ruleForm.keyword)
item.favorite = false;
unfavorite(id);
inputHandler(ruleForm.keyword);
}
}
function handleScroll(event) {
let timer
let timer;
if (timer) {
clearTimeout(timer)
clearTimeout(timer);
}
else {
timer = setTimeout(() => {
getSearchedList('', true)
}, 2000)
getSearchedList("", true);
}, 2000);
}
}
function moveEnd() {
unData.value.forEach((v, index) => {
sort(v.id, index)
})
sort(v.id, index);
});
}
function setCurrentlySelectedAdvanced(value: string) {
currentlySelectedAdvanced.value = value
currentlySelectedAdvanced.value = value;
}
defineExpose({
setCurrentlySelectedAdvanced,
})
});
</script>
<template>
@ -422,13 +422,12 @@ defineExpose({
justify-content: space-between;
align-items: center;
position: absolute;
left: 0;
top: -10px;
width: 100%;
padding: 17px 16px;
border-bottom: 1px solid #e8e8e8;
z-index: 10;
background: #ffffff;
left: 0;
&-left {
display: flex;
@ -487,6 +486,12 @@ defineExpose({
.wrapper-left-popover {
width: 248px;
height: 288px;
position: absolute;
left: 0;
top: -10px;
border: 1px solid #f3f8ff;
z-index: 10000;
background: #fff;
}
::v-deep(.wrapper-left-popover .n-form-item) {
display: block !important;

@ -8,132 +8,135 @@ import {
reactive,
ref,
unref,
} from "vue";
import { NDataTable } from "naive-ui";
import type { DataTableColumns, DataTableRowKey } from "naive-ui";
import type { SortableEvent } from "sortablejs";
import Sortable from "sortablejs";
import { debounce } from "lodash-es";
import Action from "../Action.vue";
import { deleteCondition, getConditionList, sort } from "@/api/home/filter";
import type { FilterSearchParam } from "/#/api";
import selection from "naive-ui/es/_internal/selection";
import SvgIcon from "@/components/Icon/SvgIcon.vue";
import { useModal } from "naive-ui";
const modal = useModal();
defineOptions({ name: "FilterModal" });
const $message = window["$message"];
} from 'vue'
import { NDataTable, useModal } from 'naive-ui'
import type { DataTableColumns, DataTableRowKey } from 'naive-ui'
import type { SortableEvent } from 'sortablejs'
import Sortable from 'sortablejs'
import { debounce } from 'lodash-es'
import selection from 'naive-ui/es/_internal/selection'
import Action from '../Action.vue'
import { deleteCondition, getConditionList, sort } from '@/api/home/filter'
import type { FilterSearchParam } from '/#/api'
import SvgIcon from '@/components/Icon/SvgIcon.vue'
defineOptions({ name: 'FilterModal' })
const props = defineProps({
type: {
type: Number,
default: () => 0,
},
});
})
const emit = defineEmits<{
(e: "showNewFilter"): void;
(e: "editFilter", filter: any): void;
(e: "handleOk", item: any): void;
}>();
(e: 'showNewFilter'): void
(e: 'editFilter', filter: any): void
(e: 'handleOk', item: any): void
}>()
const modal = useModal()
const tableData = ref<Array<RowData>>([])
const keyword = ref('')
const $message = window.$message
const show = ref(false);
const show = ref(false)
const cardStyle = {
width: "808px",
height: "840px",
"--n-padding-bottom": "10px",
"--n-padding-left": "10px",
};
"width": '808px',
"height": '840px',
'--n-padding-bottom': '10px',
'--n-padding-left': '10px',
}
interface RowData {
id: string;
searchname: string;
createby: string;
createtime: string;
updateby: string;
updatetime: string;
id: string
searchname: string
createby: string
createtime: string
updateby: string
updatetime: string
}
function sortData(row) {
console.log("sortData", row);
if (row.order == "descend") {
console.log('sortData', row)
if (row.order == 'descend') {
tableData.value.sort(
(a, b) =>
new Date(a[row.columnKey]).getTime() - new Date(b[row.columnKey]).getTime()
);
} else if (row.order == "ascend") {
new Date(a[row.columnKey]).getTime() - new Date(b[row.columnKey]).getTime(),
)
}
else if (row.order == 'ascend') {
tableData.value.sort(
(a, b) =>
new Date(b[row.columnKey]).getTime() - new Date(a[row.columnKey]).getTime()
);
} else {
new Date(b[row.columnKey]).getTime() - new Date(a[row.columnKey]).getTime(),
)
}
else {
tableData.value.sort(
(a, b) => Number((a as any).reorder) - Number((b as any).reorder)
);
(a, b) => Number((a as any).reorder) - Number((b as any).reorder),
)
}
}
const columns: DataTableColumns<RowData> = [
{
type: "selection",
type: 'selection',
},
{
title: "操作",
key: "action",
title: '操作',
key: 'action',
render(row) {
return h(Action, {
options: [
{ label: "编辑", key: 1 },
{ label: "删除", key: 2 },
{ label: '编辑', key: 1 },
{ label: '删除', key: 2 },
],
id: row.id,
select,
});
})
},
},
// j
{
title: "名称",
key: "searchname",
title: '名称',
key: 'searchname',
ellipsis: {
tooltip: true,
},
},
{
title: "创建者",
key: "createby",
title: '创建者',
key: 'createby',
},
{
title: "创建时间",
key: "createtime",
title: '创建时间',
key: 'createtime',
width: 180,
renderSorterIcon: ({ order }) => {
if (order === false) return h(SvgIcon, { name: "sort-2" });
if (order === "ascend") return h(SvgIcon, { name: "sort-1" });
if (order === "descend") return h(SvgIcon, { name: "sort-3" });
if (order === false)
return h(SvgIcon, { name: 'sort-2' })
if (order === 'ascend')
return h(SvgIcon, { name: 'sort-1' })
if (order === 'descend')
return h(SvgIcon, { name: 'sort-3' })
},
sorter: (row1, row2) => {
// tableData.value.sort(
// (a, b) => new Date(a?.createtime).getTime() - new Date(b?.createtime).getTime()
// );
return new Date(row1?.createtime).getTime() - new Date(row2?.createtime).getTime();
// )
return new Date(row1?.createtime).getTime() - new Date(row2?.createtime).getTime()
},
},
{
title: "更新者",
key: "updateby",
title: '更新者',
key: 'updateby',
},
{
title: "更新时间",
key: "updatetime",
title: '更新时间',
key: 'updatetime',
width: 180,
},
];
const total = ref(0);
const loading = ref(true);
]
const total = ref(0)
const loading = ref(true)
const pagination = reactive({
page: 1,
pageCount: 1,
@ -141,231 +144,233 @@ const pagination = reactive({
showSizePicker: true,
pageSizes: [
{
label: "10 每页",
label: '10 每页',
value: 10,
},
{
label: "15 每页",
label: '15 每页',
value: 15,
},
{
label: "30 每页",
label: '30 每页',
value: 30,
},
{
label: "50 每页",
label: '50 每页',
value: 50,
},
],
showQuickJumper: true,
prefix: () => `${total.value} 条数据`,
});
const tableData = ref<Array<RowData>>([]);
const keyword = ref("");
})
async function query(page: number, pageSize: number) {
const searchParam: FilterSearchParam = {
search_searchname: { value: keyword.value, op: "like", type: "string" },
};
search_searchname: { value: keyword.value, op: 'like', type: 'string' },
}
const result = await getConditionList(
{ pageNo: page, pageSize },
searchParam,
props.type
);
const { data, pageCount, total: totalCount } = result;
tableData.value = data;
pagination.page = page;
total.value = totalCount;
pagination.pageCount = pageCount;
loading.value = false;
props.type,
)
const { data, pageCount, total: totalCount } = result
tableData.value = data
pagination.page = page
total.value = totalCount
pagination.pageCount = pageCount
loading.value = false
}
function afterLeave() {
pagination.page = 1;
pagination.pageCount = 1;
pagination.pageSize = 10;
pagination.page = 1
pagination.pageCount = 1
pagination.pageSize = 10
}
const selectionIds = ref<DataTableRowKey[]>([]);
const selectionIds = ref<DataTableRowKey[]>([])
const rowKey = (row: RowData) => row.id;
const rowKey = (row: RowData) => row.id
function rowProps(row: RowData) {
return {
"data-id": row.id,
};
'data-id': row.id,
}
}
function handleCheck(rowKeys: DataTableRowKey[]) {
selectionIds.value = rowKeys;
selectionIds.value = rowKeys
}
function select(key: number, id: string) {
switch (key) {
case 1:
editSelection(id);
break;
editSelection(id)
break
case 2:
const modalInst = modal.create({
title: "确认提示",
content: "确认删除该条过滤条件吗?",
positiveText: "确定",
negativeText: "取消",
preset: "dialog",
title: '确认提示',
content: '确认删除该条过滤条件吗?',
positiveText: '确定',
negativeText: '取消',
preset: 'dialog',
onPositiveClick: () => deleteSelection(id),
onNegativeClick: () => modalInst.destroy(),
});
break;
})
break
default:
break;
break
}
}
function editSelection(id) {
// const $message = window["$message"];
// const $message = window['$message']
// if (selectionIds.value.length === 0 || selectionIds.value.length > 1) {
// $message.error("");
// return;
// $message.error('')
// return
// }
const selectedId = id;
const selectedId = id
const selectedFilter = tableData.value.find((item: any) => {
return item.id === selectedId;
});
return item.id === selectedId
})
emit("editFilter", selectedFilter);
closeModal();
emit('editFilter', selectedFilter)
closeModal()
}
function deleteSelection(id = "") {
function deleteSelection(id = '') {
if (selectionIds.value.length === 0) {
deleteCondition({ ids: id }).then(() => {
query(pagination.page, pagination.pageSize);
});
return;
query(pagination.page, pagination.pageSize)
})
return
}
const modalInst = modal.create({
title: "确认提示",
content: "确认删除所选过滤条件吗?",
positiveText: "确定",
negativeText: "取消",
preset: "dialog",
title: '确认提示',
content: '确认删除所选过滤条件吗?',
positiveText: '确定',
negativeText: '取消',
preset: 'dialog',
onPositiveClick: () =>
deleteCondition({ ids: selectionIds.value.join(",") }).then(() => {
selectionIds.value = [];
query(pagination.page, pagination.pageSize);
deleteCondition({ ids: selectionIds.value.join(',') }).then(() => {
selectionIds.value = []
query(pagination.page, pagination.pageSize)
}),
onNegativeClick: () => modalInst.destroy(),
});
})
}
async function handlePageChange(currentPage) {
if (loading.value) return;
pagination.page = currentPage;
const { pageSize } = pagination;
await query(currentPage, pageSize);
if (loading.value)
return
pagination.page = currentPage
const { pageSize } = pagination
await query(currentPage, pageSize)
}
async function handlePageSizeChange(currentPageSize) {
if (loading.value) return;
if (loading.value)
return
const { page } = pagination;
pagination.pageSize = currentPageSize;
await query(page, currentPageSize);
const { page } = pagination
pagination.pageSize = currentPageSize
await query(page, currentPageSize)
}
function handleClick() {
emit("showNewFilter");
closeModal();
emit('showNewFilter')
closeModal()
}
let sortTable: Sortable | null = null;
const tableRef = ref<InstanceType<typeof NDataTable>>();
let sortTable: Sortable | null = null
const tableRef = ref<InstanceType<typeof NDataTable>>()
async function showModal() {
show.value = true;
show.value = true
const { page, pageSize } = pagination;
await query(page, pageSize);
const { page, pageSize } = pagination
await query(page, pageSize)
nextTick(() => {
if (sortTable !== null) destory();
const el: HTMLDivElement = tableRef.value?.$el;
const tbody: HTMLElement | null = el.querySelector("tbody.n-data-table-tbody")!;
if (tbody) sortTable = Sortable.create(tbody, { onEnd, onMove });
});
if (sortTable !== null)
destory()
const el: HTMLDivElement = tableRef.value?.$el
const tbody: HTMLElement | null = el.querySelector('tbody.n-data-table-tbody')!
if (tbody)
sortTable = Sortable.create(tbody, { onEnd, onMove })
})
}
let relatedId = "";
let insertafter = false;
let relatedId = ''
let insertafter = false
// TODO: bug
function onEnd(event: SortableEvent) {
const data = unref(tableData);
const oldElem = data[event.oldIndex!];
data.splice(event.oldIndex!, 1);
data.splice(event.newIndex!, 0, oldElem);
const data = unref(tableData)
const oldElem = data[event.oldIndex!]
data.splice(event.oldIndex!, 1)
data.splice(event.newIndex!, 0, oldElem)
const dragId = oldElem.id;
const dragId = oldElem.id
const index = data.findIndex((item) => {
return item.id === relatedId;
});
return item.id === relatedId
})
// -1+1
const order = insertafter ? index - 1 : index + 1;
const order = insertafter ? index - 1 : index + 1
// console.log('dragid:', dragId, 'order:', order)
sort(dragId, order);
sort(dragId, order)
}
function onMove(evt: any) {
relatedId = evt.related?.dataset?.id;
insertafter = evt.willInsertAfter;
relatedId = evt.related?.dataset?.id
insertafter = evt.willInsertAfter
// console.log(`${evt.dragged.dataset.id},${evt.related}`, 'insertafter', evt.willInsertAfter)
}
function destory() {
sortTable && sortTable.destroy();
sortTable = null;
sortTable && sortTable.destroy()
sortTable = null
}
onUnmounted(() => {
destory();
});
destory()
})
function closeModal() {
selectionIds.value = [];
show.value = false;
selectionIds.value = []
show.value = false
}
defineExpose({
showModal,
query,
pagination,
});
})
const inputHandler = debounce((word) => {
keyword.value = word;
query(1, 5);
}, 300);
keyword.value = word
query(1, 5)
}, 300)
const showSearch = computed(() => {
return selectionIds.value.length > 0;
});
return selectionIds.value.length > 0
})
const handleOk = () => {
function handleOk() {
if (selectionIds.value.length > 1) {
$message.error("只能选择一条筛选条件");
return;
$message.error('只能选择一条筛选条件')
return
}
if (selectionIds.value.length == 1) {
const selectedId = selectionIds.value[0];
let item = tableData.value.find((v) => v.id == selectedId);
emit("handleOk", item);
}
if (selectionIds.value.length == 0) {
emit("handleOk", "");
const selectedId = selectionIds.value[0]
const item = tableData.value.find(v => v.id == selectedId)
emit('handleOk', item)
}
closeModal();
};
if (selectionIds.value.length == 0)
emit('handleOk', '')
closeModal()
}
</script>
<template>
@ -374,9 +379,9 @@ const handleOk = () => {
v-model:show="show"
transform-origin="center"
display-directive="if"
@after-leave="afterLeave"
:mask-closable="false"
class="modal_wrapper"
@after-leave="afterLeave"
>
<n-card
:style="cardStyle"
@ -396,8 +401,7 @@ const handleOk = () => {
'font-weight': '600',
}"
class="wrapper-info-title"
>基本信息</span
>
>基本信息</span>
</div>
</div>
@ -429,13 +433,11 @@ const handleOk = () => {
</n-button>
</div>
<div class="msg">
<span
>已选中
<span>已选中
<span style="color: #507afd; font-size: 16px">{{
selectionIds.length
}}</span>
</span
>
</span>
<a @click="selectionIds = []">清空</a>
</div>
</div>
@ -482,8 +484,9 @@ const handleOk = () => {
padding: 14px;
&-title {
font-weight: bold;
font-size: 20px;
font-weight: 600;
color: #333333;
font-size: 18px;
height: 24px;
}
@ -521,7 +524,8 @@ const handleOk = () => {
}
&-table {
margin-top: 17px;
//17-> 34-24/2+x
margin-top: 12px;
}
&-footer {
@ -537,8 +541,9 @@ const handleOk = () => {
&:before {
background-color: #1980ff;
content: "";
width: 5px;
border-radius: 2px;
width: 4px;
height: 18px;
border-radius: 3px;
top: 0;
left: 3px;
bottom: 0;
@ -555,7 +560,6 @@ const handleOk = () => {
}
}
.del_btn {
margin-left: 12px;
color: #333333;
font-weight: 500;
}
@ -580,9 +584,7 @@ const handleOk = () => {
font-size: 14px !important;
color: #000000 !important;
}
::v-deep(.n-data-table
.n-data-table-tr:not(.n-data-table-tr--summary):hover
> .n-data-table-td) {
::v-deep(.n-data-table .n-data-table-td) {
color: #666666 !important;
font-size: 14px !important;
}
@ -590,8 +592,6 @@ const handleOk = () => {
position: relative;
left: -80px;
}
.modal_wrapper {
}
::v-deep(.n-input .n-input__input-el) {
height: 24px;
}

@ -1,21 +1,4 @@
<script lang="ts" setup>
import {
createPackage,
getCheckDuplicateStatus,
getLastCheckNo,
getPictureList,
oneClickCheckTaskPackage,
queryPageListByCheckNo,
removeCheckDuplicate,
} from "@/api/home/main";
import avatar from "@/assets/images/avatar.jpg";
import { timeOptions, viewOptions } from "@/config/home";
import { useWindowSizeFn } from "@/hooks/event/useWindowSizeFn";
import { useConfig } from "@/store/modules/asideConfig";
import { getViewportOffset } from "@/utils/domUtils";
import { hideDownload } from "@/utils/image";
import emitter from "@/utils/mitt";
import { getImgUrl } from "@/utils/urlUtils";
import { EllipsisHorizontal, EyeOutline as EyeOutlineIcon } from "@vicons/ionicons5";
import { Download as DownloadIcon, Upload as UploadIcon } from "@vicons/tabler";
import { Icon } from "@vicons/utils";
@ -38,6 +21,7 @@ import {
unref,
watch,
} from "vue";
import axios from "axios";
import CheckingTaskModal from "./modal/CheckingTaskModal.vue";
import FinishPackageModal from "./modal/FinishPackageModal.vue";
import GeneratePackageModal from "./modal/GeneratePackageModal.vue";
@ -47,8 +31,27 @@ import QueryRepeatedTasksModal from "./modal/QueryRepeatedTasksModal.vue";
import type { PictureSortParam } from "/#/api";
import defaultAvatar from "@/assets/icons/avatar.svg";
import baseImg from "@/assets/images/baseImg.png";
import axios from "axios";
import { getImgUrl } from "@/utils/urlUtils";
import emitter from "@/utils/mitt";
import { hideDownload } from "@/utils/image";
import { getViewportOffset } from "@/utils/domUtils";
import { useConfig } from "@/store/modules/asideConfig";
import { useWindowSizeFn } from "@/hooks/event/useWindowSizeFn";
import { timeOptions, viewOptions } from "@/config/home";
import avatar from "@/assets/images/avatar.jpg";
import {
createPackage,
getCheckDuplicateStatus,
getLastCheckNo,
getPictureList,
oneClickCheckTaskPackage,
queryPageListByCheckNo,
removeCheckDuplicate,
} from "@/api/home/main";
const listData = ref<any[]>([]);
const timer = ref();
const showClose = ref(false);
const deviceHeight = ref(600);
let _masonry: null | Masonry = null;
let _imagesload: any;
@ -97,9 +100,11 @@ const listStyle = computed(() => {
});
const layout = debounce(() => {
if (masonryRef.value == null || el.value == null) return;
if (masonryRef.value == null || el.value == null)
return;
if (_masonry !== null) (_masonry as any).addItems();
if (_masonry !== null)
(_masonry as any).addItems();
_masonry = new Masonry(masonryRef.value as any, {
itemSelector: ".grid-item",
@ -113,7 +118,8 @@ const layout = debounce(() => {
_imagesload.on("done", (instance) => {
(_masonry as any).layout();
if (!el.value) return;
if (!el.value)
return;
loading.value = false;
});
@ -128,7 +134,7 @@ useInfiniteScroll(
() => {
loadMore();
},
{ distance: 10, canLoadMore: () => canloadMore }
{ distance: 10, canLoadMore: () => canloadMore },
);
onUpdated(() => {
@ -152,8 +158,8 @@ const viewLabel = computed(() => {
return item?.label;
});
let isAllowDownload = ref(true);
let calNum = ref(0);
const isAllowDownload = ref(true);
const calNum = ref(0);
const searchValue = ref("");
const isInitSeaerch = ref(false); //
@ -176,18 +182,17 @@ watch(
listData.value = more;
isInitSeaerch.value = false;
// configStore.setSearchValue("");
} else {
}
else {
isInitSeaerch.value = true;
pagination.pageNo = 0;
const more = await featchList();
listData.value = more;
isInitSeaerch.value = false;
}
}
},
);
const listData = ref<any[]>([]);
async function featchList(userSearchId?: string) {
loading.value = true;
try {
@ -206,15 +211,15 @@ async function featchList(userSearchId?: string) {
data: [],
total: 0,
};
let sortObj: any = {}; // rao start
if (sortBy.orderbyvalue == "pictureResult") {
const sortObj: any = {}; // rao start
if (sortBy.orderbyvalue == "pictureResult")
sortObj.ordertype = sortBy.orderbyname;
} else if (sortBy.orderbyvalue == "fromuptime") {
else if (sortBy.orderbyvalue == "fromuptime")
sortObj.orderByTime = sortBy.orderbyname;
}
if (params["izsimilarity"] && typeof params["izsimilarity"] != "string") {
params["izsimilarity"] = params["izsimilarity"].join("-");
}
if (params.izsimilarity && typeof params.izsimilarity != "string")
params.izsimilarity = params.izsimilarity.join("-");
// rao end
if (checkTaskStatus.value === 2 && isRefresh) {
@ -226,7 +231,8 @@ async function featchList(userSearchId?: string) {
checkDuplicateNo: checkDuplicateNo.value,
upUserName: searchValue,
});
} else {
}
else {
result = await getPictureList({
...pagination,
...contentParams,
@ -253,14 +259,16 @@ async function featchList(userSearchId?: string) {
});
return list;
} catch (error) {
}
catch (error) {
canloadMore = false;
return [];
}
}
async function loadMore() {
if (loading.value || el.value == null) return;
if (loading.value || el.value == null)
return;
const more = await featchList();
// if(isInitSeaerch.value) {
@ -272,15 +280,15 @@ async function loadMore() {
const gridHeight = computed(() => {
let height = "";
if (viewMode.value === "masonry") {
if (viewMode.value === "masonry")
height = "";
} else if (viewMode.value === "horizontalVersion") {
else if (viewMode.value === "horizontalVersion")
height = "145px";
} else if (viewMode.value === "verticalVersion") {
else if (viewMode.value === "verticalVersion")
height = "300px";
} else if (viewMode.value === "3:4") {
else if (viewMode.value === "3:4")
height = "240px";
}
return height;
});
@ -290,52 +298,53 @@ async function oneCheck() {
console.log("searchValue", asideVal, searchValue.value);
if (asideVal.izyear && asideVal.izyear.length == 2) {
asideVal.izyear =
dayjs(asideVal.izyear[0]).format("YYYY/MM/DD") +
"-" +
dayjs(asideVal.izyear[1]).format("YYYY/MM/DD");
}
if (asideVal["izsimilarity"] && typeof asideVal["izsimilarity"] != "string") {
asideVal["izsimilarity"] = asideVal["izsimilarity"].join("-");
asideVal.izyear
= `${dayjs(asideVal.izyear[0]).format("YYYY/MM/DD")
}-${
dayjs(asideVal.izyear[1]).format("YYYY/MM/DD")}`;
}
if (asideVal.izsimilarity && typeof asideVal.izsimilarity != "string")
asideVal.izsimilarity = asideVal.izsimilarity.join("-");
const tasksLoadingModal = queryRepeatedTasksModalRef.value as any;
console.log("calNum.value111111111111111", calNum.value, checkTaskStatus.value);
if (calNum.value == 0 && isRefresh.value) {
if (timer.value) {
if (timer.value)
clearInterval(timer.value);
}
timer.value = setInterval(() => {
console.log("calNum.value2222222222222", calNum.value, checkTaskStatus.value);
if (checkDuplicateNo.value) {
getCheckDuplicateStatus(checkDuplicateNo.value).then((res) => {
if (res.code === "OK") {
checkTaskStatus.value = res.data.status;
if (calNum.value < 90) {
if (calNum.value < 90)
calNum.value = calNum.value + 10;
}
configStore.setTimeNum(calNum.value);
if (checkTaskStatus.value === 2 || checkTaskStatus.value === 3) {
if (checkTaskStatus.value === 2) {
if (checkTaskStatus.value === 2)
message.success("任务执行完毕,正在刷新数据...");
} else {
else
message.error("查询异常");
}
tasksLoadingModal.closeOnlyModal();
configStore.setTimeNum(100);
if (timer.value) {
if (timer.value)
clearInterval(timer.value);
}
setTimeout(() => {
configStore.setTimeNum(0);
}, 1000);
reset();
loadMore();
}
} else {
if (timer.value) {
}
else {
if (timer.value)
clearInterval(timer.value);
}
}
});
}
@ -347,13 +356,14 @@ async function oneCheck() {
tasksLoadingModal.showModal();
return;
}
//
//
oneClickCheckTaskPackage(asideVal).then((res) => {
if (res.code === "OK") {
checkDuplicateNo.value = res.data.checkDuplicateNo;
checkTaskStatus.value = res.data.status;
tasksLoadingModal.showModal(); // rao
} else {
}
else {
message.error(res.message || "查重失败");
}
});
@ -367,13 +377,13 @@ async function showAddPackage() {
modal.showModal();
}
//,
// ,
async function tasksLoadingCloseCallback() {
const checkingTaskModal = checkingTaskModalRef.value as any;
checkingTaskModal.showModal();
if (isRefresh.value) {
if (isRefresh.value)
refresh(true);
}
}
async function showLoginSuccessModal() {
@ -398,7 +408,7 @@ async function commitHandler(settingParam) {
packageIdRef.value = res.data.id;
modal.closeModal();
finishModal.showModal();
//
//
checkDuplicateNo.value = "";
checkTaskStatus.value = null;
}
@ -418,9 +428,9 @@ onMounted(() => {
// });
//
getLastCheckNo().then((res) => {
if (res.code === "OK") {
if (res.code === "OK")
checkDuplicateNo.value = res.data;
}
});
nextTick(() => {
computeListHeight();
@ -442,7 +452,7 @@ watch(
(newVal, oldVal) => {
refreshHandler();
},
{ deep: true }
{ deep: true },
);
function reset() {
@ -459,7 +469,8 @@ function reset() {
async function refreshHandler(filtersearchId?: any) {
reset();
if (filtersearchId) filterId = filtersearchId;
if (filtersearchId)
filterId = filtersearchId;
nextTick(() => {
setTimeout(() => {
@ -468,7 +479,7 @@ async function refreshHandler(filtersearchId?: any) {
() => {
loadMore();
},
{ distance: 10, canLoadMore: () => canloadMore }
{ distance: 10, canLoadMore: () => canloadMore },
);
}, 300);
});
@ -497,9 +508,8 @@ async function downloadImage(item) {
cache: "default",
});
//
if (!response.ok) {
if (!response.ok)
throw new Error(`HTTP error! Status: ${response.status}`);
}
// Blob
const blob = await response.blob();
@ -519,7 +529,8 @@ async function downloadImage(item) {
//
URL.revokeObjectURL(link.href);
document.body.removeChild(link);
} catch (error) {
}
catch (error) {
console.error("下载图片时发生错误:", error);
}
}
@ -532,8 +543,6 @@ function previewHandler(index: number, event: MouseEvent) {
(imageRef.value?.[index] as any).click();
}
const timer = ref();
/**
* 检查查重状态
*/
@ -551,35 +560,36 @@ function refresh(val?: any) {
// }
if (
(checkTaskStatus.value === 2 || checkTaskStatus.value === 3) &&
isRefresh.value
(checkTaskStatus.value === 2 || checkTaskStatus.value === 3)
&& isRefresh.value
) {
configStore.setTimeNum(100);
checkingTaskModal.closeModal();
isRefresh.value = false;
if (checkTaskStatus.value === 2) {
if (checkTaskStatus.value === 2)
message.success("任务执行完毕,正在刷新数据...");
} else {
else
message.error("查询异常");
}
if (timer.value) {
if (timer.value)
clearInterval(timer.value);
}
reset();
loadMore();
configStore.setTimeNum(0);
} else if (checkTaskStatus.value === 1) {
return;
}
else if (checkTaskStatus.value === 1) {
}
}
});
return;
}
}
/**
* 取消查重任务
*/
function cancel(val) {
function cancel() {
if (checkTaskStatus.value === 1) {
removeCheckDuplicate(checkDuplicateNo.value).then((res) => {
if (res.code === "OK") {
@ -591,13 +601,13 @@ function cancel(val) {
}
}
const renderIcon = (icon: Component) => {
function renderIcon(icon: Component) {
return () => {
return h(NIcon, null, {
default: () => h(icon),
});
};
};
}
const dropdownOptions = ref([
{
@ -617,10 +627,10 @@ const dropdownOptions = ref([
},
]);
const loadImgOver = (item) => {
function loadImgOver(item) {
console.log("loadImgOver", item);
setTimeout(() => (item.loadOver = true), 2000);
};
}
defineExpose({
showLoginSuccessModal,
@ -671,7 +681,7 @@ defineExpose({
<div class="dropdown">
<!-- <span>{{ viewLabel || '请选择' }}</span> -->
<span>视图</span>
<SvgIcon class="gap" name="arrow-botton" size="14" />
<SvgIcon class="gap" name="arrow-botton" size="16" />
</div>
</n-popselect>
<div
@ -679,21 +689,20 @@ defineExpose({
@click="sortHandler('fromuptime')"
>
<span>时间排序</span>
<SvgIcon style="margin-left: 8px" name="sort" size="12" />
<SvgIcon style="margin-left: 8px" name="sort" size="16" />
</div>
<div
style="margin-left: 15px; cursor: pointer; color: #323233"
@click="sortHandler('pictureResult')"
>
<span>相似度排序</span>
<SvgIcon style="margin-left: 8px" name="sort" size="12" />
<SvgIcon style="margin-left: 8px" name="sort" size="16" />
</div>
</div>
<span style="font-size: 16px; color: #333"
>
<span style="color: #507afd; font-weight: 500">{{ totalCount }}</span> </span
>
<span style="font-size: 16px; color: #333">
<span style="color: #507afd; font-weight: 500">{{ totalCount }}</span> </span>
</div>
<n-spin :show="loading">
<div ref="el" class="scroll" :style="listStyle">
<!-- <n-scrollbar :on-scroll="scrollHandler"> -->
@ -709,16 +718,22 @@ defineExpose({
class="wrapper-content-item-img" :class="{ 'wrapper-content-item-img-fit': viewMode !== 'masonry' }"
:src="item.imgUrl"
> -->
<n-image
ref="imageRef"
class="img"
:img-props="{ onClick: hideDownload }"
:img-props="{
onClick: ($event) => {
hideDownload($event);
showClose = true;
},
}"
:class="{
'img-fit': viewMode === 'horizontalVersion',
'img-full': viewMode === '3:4' || viewMode === 'verticalVersion',
}"
:preview-src="item.imgUrl"
:src="item.thumburl"
ref="imageRef"
/>
<!-- @load="loadImgOver(item)" -->
<!-- <n-image
@ -731,13 +746,13 @@ defineExpose({
v-show="!item.loadOver"
/> -->
<div class="percent" v-if="item.similar != -1">
<div v-if="item.similar != -1" class="percent">
<SvgIcon size="42" :name="item.similar == 100 ? 'error_tag' : 'tag'" />
<div class="val">
{{ `${item.similar}%` }}
</div>
</div>
<div class="glass" v-if="isAllowDownload">
<div v-if="isAllowDownload" class="glass">
<SvgIcon
size="16"
name="download"
@ -753,7 +768,9 @@ defineExpose({
<template #trigger>
<span>{{ item.imgName }}</span>
</template>
{{ item.imgName }}
<span
style="font-size: 12px; margin-top: 4px; margin-bottom: 16px"
>{{ item.imgName }}</span>
</n-tooltip>
</div>
<div class="icon-wrap" @click="previewHandler(index, $event)">
@ -787,11 +804,14 @@ defineExpose({
<GeneratePackageModal ref="generateModalRef" />
<QueryRepeatedTasksModal
ref="queryRepeatedTasksModalRef"
@closeCallback="tasksLoadingCloseCallback"
@close-callback="tasksLoadingCloseCallback"
/>
<LoginSuccessModal ref="LoginSuccessModalRef" />
<FinishPackageModal ref="finishPackageModal" :id="packageIdRef" />
<FinishPackageModal :id="packageIdRef" ref="finishPackageModal" />
<CheckingTaskModal ref="checkingTaskModalRef" @refresh="refresh" @cancel="cancel" />
<!-- <div class="close_box" v-show="showClose" @click="showClose = false">
<SvgIcon size="24" name="close-none-border" />
</div> -->
</div>
</template>
@ -914,6 +934,7 @@ defineExpose({
overflow: hidden;
position: relative;
transition: 0.5s;
margin: 0 6px 10px 6px;
.glass {
position: absolute;
@ -940,7 +961,9 @@ defineExpose({
border-radius: 7px;
.img-name {
width: 70%;
// width: 70%;
width: 15px;
height: 15px;
color: #fff;
/* 设置文本溢出时的样式为省略号 */
text-overflow: ellipsis;
@ -1026,4 +1049,10 @@ defineExpose({
text-align: center;
}
}
.close_box {
position: absolute;
right: 10%;
top: 20%;
z-index: 10000000000000000000;
}
</style>

@ -1,101 +1,101 @@
<script lang="ts" setup>
import { useInfiniteScroll } from '@vueuse/core'
import { defineProps, onMounted, onUnmounted, reactive, ref, watch } from 'vue'
import ListItem from './ListItem.vue'
import emitter from '@/utils/mitt'
import { useTaskStore } from '@/store/modules/task'
import { useInfiniteScroll } from "@vueuse/core";
import { defineProps, onMounted, onUnmounted, reactive, ref, watch } from "vue";
import ListItem from "./ListItem.vue";
import emitter from "@/utils/mitt";
import { useTaskStore } from "@/store/modules/task";
defineProps({
showFieldList: {
type: Array,
default: () => [],
},
})
const taskStore = useTaskStore()
const data = ref<any[]>([])
const activeId = ref('')
const el = ref<HTMLDivElement | null>(null)
const keyword = ref('')
const canloadMore = ref(true)
const isLoading = ref(false)
const searchId = ref('')
});
const taskStore = useTaskStore();
const data = ref<any[]>([]);
const activeId = ref("");
const el = ref<HTMLDivElement | null>(null);
const keyword = ref("");
const canloadMore = ref(true);
const isLoading = ref(false);
const searchId = ref("");
const pagination = reactive({
pageNo: 0,
pageSize: 30,
})
});
function selectHandler(item, index: number) {
activeId.value = item.id
console.log(activeId.value, item.id)
console.log(index)
taskStore.setActive(index, item.id)
activeId.value = item.id;
console.log(activeId.value, item.id);
console.log(index);
taskStore.setActive(index, item.id);
}
useInfiniteScroll(
el as any,
() => {
loadMore()
loadMore();
},
{ distance: 10, interval: 1500, canLoadMore: () => canloadMore.value },
)
);
async function loadMore() {
if (isLoading.value || el.value == null)
return
isLoading.value = true
return;
isLoading.value = true;
try {
const more = await fetchList()
data.value.push(...more)
const more = await fetchList();
data.value.push(...more);
}
finally {
isLoading.value = false
isLoading.value = false;
}
}
//
async function fetchList() {
try {
pagination.pageNo += 1
pagination.pageNo += 1;
const result = await taskStore.fetchApprovalList({
...pagination,
keyword: keyword.value,
userSearchId: searchId.value,
})
const { data, pageCount } = result
canloadMore.value = pageCount >= pagination.pageNo
return data || []
});
const { data, pageCount } = result;
canloadMore.value = pageCount >= pagination.pageNo;
return data || [];
}
catch (error) {
canloadMore.value = false
return []
canloadMore.value = false;
return [];
}
}
watch(
() => taskStore.activeId,
(newVal) => {
activeId.value = newVal
activeId.value = newVal;
},
)
);
watch(
() => taskStore.inFileId,
async (newVal) => {
const newlist = []
const filterid = newVal.taskname
console.log(filterid)
const index = data.value.findIndex(person => person.fromtaskname === filterid)
const ovelist = data.value.filter(item => item.fromtaskname !== filterid)
const newlist = [];
const filterid = newVal.taskname;
console.log(filterid);
const index = data.value.findIndex(person => person.fromtaskname === filterid);
const ovelist = data.value.filter(item => item.fromtaskname !== filterid);
ovelist.map((item) => {
newlist.push(item)
return item
})
data.value = newlist
activeId.value = newlist[index].id
newlist.push(item);
return item;
});
data.value = newlist;
activeId.value = newlist[index].id;
taskStore.setActive(index, newlist[index].id)
taskStore.setActive(index, newlist[index].id);
// taskStore.setActive(index)
// activeId.value = data[index+1].id
// selectHandler(data[index].id, index)
@ -108,55 +108,55 @@ watch(
taskStore.setActive(2)
alert(1) */
},
)
);
function reset() {
pagination.pageNo = 0
pagination.pageSize = 30
canloadMore.value = true
data.value.length = 0
taskStore.reset()
pagination.pageNo = 0;
pagination.pageSize = 30;
canloadMore.value = true;
data.value.length = 0;
taskStore.reset();
}
async function search(word: string) {
keyword.value = word
reset()
keyword.value = word;
reset();
useInfiniteScroll(
el as any,
() => {
loadMore()
loadMore();
},
{ distance: 10, canLoadMore: () => canloadMore.value },
)
);
}
onMounted(() => {
emitter.on('refresh', refreshHandler)
emitter.on('filter', async (id) => {
await reset()
searchId.value = id
data.value = await fetchList()
activeId.value = data.value[0].id
console.log(data.value)
})
})
emitter.on("refresh", refreshHandler);
emitter.on("filter", async (id) => {
await reset();
searchId.value = id;
data.value = await fetchList();
activeId.value = data.value[0]?.id;
console.log(data.value);
});
});
onUnmounted(() => {
emitter.off('refresh', refreshHandler)
})
emitter.off("refresh", refreshHandler);
});
async function refreshHandler() {
search('')
search("");
}
function setStatusName(text) {
const index = taskStore.getCurrentIndex
data.value[index].statshisText = text
const index = taskStore.getCurrentIndex;
data.value[index].statshisText = text;
}
defineExpose({
search,
setStatusName,
})
});
</script>
<template>

Loading…
Cancel
Save