Merge branch 'jie' into main

pull/1/head
lizijiee 1 year ago
commit c29cbf0875

@ -19,6 +19,7 @@
"@vueuse/core": "10.9.0",
"axios": "^1.4.0",
"date-fns": "^2.30.0",
"dayjs": "^1.11.10",
"esno": "^0.16.3",
"file-saver": "^2.0.5",
"imagesloaded": "^5.0.0",

@ -1,5 +1,5 @@
import { IzCustomlevel, IzCustomname, IzCustomtype, IzfirmVue, IzProductVue, IzProjecttype, IzProjectVue, IztaskrromVue, IztaskstatusVue, IzVisitcity, IzvisitproVue, PictureDownloadVue, PictureTypeVue, PictureUploadVue, PlanVue, ReportUserVue, SimilarityVue, TimeVue } from '@/views/home/aside/comp/items'
import type { Component } from 'vue'
import { IzCustomlevel, IzCustomname, IzCustomtype, IzProductVue, IzProjectVue, IzProjecttype, IzShowVue, IzVisitcity, IzfirmVue, IztaskrromVue, IztaskstatusVue, IzvisitproVue, PictureDownloadVue, PictureTypeVue, PictureUploadVue, PlaceHolderVue, PlanVue, ReportUserVue, SimilarityVue, TimeVue } from '@/views/home/aside/comp/items'
export interface AsideEntity {
label: string
@ -52,7 +52,7 @@ export const asideMap: Recordable<AsideEntity> = {
izyear: {
label: '年份',
defaultValue: null,
isDefaultFilter: false,
isDefaultFilter: true,
key: 'izyear',
component: TimeVue,
},
@ -72,28 +72,28 @@ export const asideMap: Recordable<AsideEntity> = {
inFilterList: false,
},
izcustomtype: {
label: '客户类型',
label: '拜访客户类型',
defaultValue: null,
isDefaultFilter: false,
key: 'izcustomtype',
component: IzCustomtype,
},
izcustomlevel: {
label: '客户级别',
label: '拜访客户级别',
defaultValue: null,
isDefaultFilter: false,
key: 'izcustomlevel',
component: IzCustomlevel,
},
izcustomname: {
label: '客户名称',
label: '拜访客户名称',
defaultValue: null,
isDefaultFilter: false,
key: 'izcustomname',
component: IzCustomname,
},
izprojecttype: {
label: '项目类型',
label: '拜访项目类型',
defaultValue: null,
isDefaultFilter: false,
key: 'izprojecttype',
@ -114,14 +114,14 @@ export const asideMap: Recordable<AsideEntity> = {
component: IztaskstatusVue,
},
izvisitpro: {
label: '拜访省份',
label: '拜访省份/直辖市',
defaultValue: null,
isDefaultFilter: false,
key: 'izvisitpro',
component: IzvisitproVue,
},
izvisitcity: {
label: '发布地区',
label: '拜访城市',
defaultValue: null,
isDefaultFilter: false,
key: 'izvisitcity',
@ -141,38 +141,31 @@ export const asideMap: Recordable<AsideEntity> = {
key: 'izproductname',
component: IzProductVue,
},
izdesc: {
label: '添加备注',
defaultValue: null,
isDefaultFilter: false,
key: 'izdesc',
component: PlaceHolderVue,
inFilterList: false,
render: false,
},
izsearchmanager: {
label: '自定义筛选',
defaultValue: null,
isDefaultFilter: false,
key: 'izsearchmanager',
component: PlaceHolderVue,
inFilterList: false,
render: false,
},
izshow: {
label: '分类',
defaultValue: null,
isDefaultFilter: false,
key: 'izshow',
component: IzShowVue,
},
izsearch: {
label: '自定义过滤',
defaultValue: null,
isDefaultFilter: false,
key: 'izsearch',
component: PlaceHolderVue,
inFilterList: false,
render: false,
},
// izdesc: {
// label: '添加备注',
// defaultValue: null,
// isDefaultFilter: false,
// key: 'izdesc',
// component: PlaceHolderVue,
// inFilterList: false,
// render: false,
// },
// izsearchmanager: {
// label: '自定义筛选',
// defaultValue: null,
// isDefaultFilter: false,
// key: 'izsearchmanager',
// component: PlaceHolderVue,
// inFilterList: false,
// render: false,
// },
// izsearch: {
// label: '自定义过滤',
// defaultValue: null,
// isDefaultFilter: false,
// key: 'izsearch',
// component: PlaceHolderVue,
// inFilterList: false,
// render: false,
// },
}

@ -101,8 +101,8 @@ const options = computed(() => {
<div class="header">
<n-avatar :src="getImgUrl(useInfo.usericon)" round style="width:53px; height:53px" />
<div style="margin-left: 12px">
<span style="display: block; font-size: 21px">{{ useInfo.username }}</span>
<span style="display: block; font-size: 16px">{{ useInfo.departname }}</span>
<span style="display: block;" class="user-name">{{ useInfo.username }}</span>
<span style="display: block;" class="depart-name">{{ useInfo.departname }}</span>
</div>
</div>
<div class="trigger">
@ -120,7 +120,7 @@ const options = computed(() => {
<div class="trigger" @click="logOut">
退出登录
</div>
<div class="container" v-show="changeFlag" style="position: absolute;right:332px;width: 220px;padding:24px 0">
<div class="container sub-container" v-show="changeFlag" style="position: absolute;right:17vw;width: 11.5vw;padding:24px 0">
<div class="trigger" v-for="option in options" :key="option.key" @click="handleSelect(option)">
{{ option.label }}
</div>
@ -130,6 +130,18 @@ const options = computed(() => {
</template>
<style lang="less" scoped>
@media screen and (min-width: 1920px) {
.container {
.header{
.user-name{
font-size: 21px;
}
.depart-name{
font-size: 16px;
}
}
}
}
.setting {
display: flex;
align-items: center;
@ -142,7 +154,7 @@ const options = computed(() => {
border-radius: 10px;
justify-content: center;
background-color: #ffffff;
width: 320px;
width: 16vw;
position: relative;
.header {

@ -27,7 +27,7 @@ const emit = defineEmits<{
const data = ref<FilterEntity[]>([]);
const unData = ref<FilterEntity[]>([]);
let loading = false;
const loading = ref(false);
const canloadMore = true;
const el = ref<HTMLDivElement | null>(null);
const popover = ref<ComponentRef | null>(null);
@ -36,6 +36,7 @@ const pagination = reactive({
pageSize: 300,
});
const keyword = ref("");
const currentlySelectedAdvanced = ref("高级筛选");
onMounted(() => {
// data.value = generateDefaultConfig()
@ -73,12 +74,12 @@ useInfiniteScroll(
},
{ distance: 10, interval: 300, canLoadMore: () => false }
);
const showClick = () => {
inputHandler("");
const showClick =async () => {
getSearchedList('')
};
async function loadMore() {
if (loading || el.value == null) return;
if (loading.value || el.value == null) return;
const more = await featchList();
@ -88,7 +89,7 @@ async function loadMore() {
}
async function featchList() {
loading = true;
loading.value = true;
try {
const searchParam: FilterSearchParam = {
search_searchname: { value: keyword.value, op: "like", type: "string" },
@ -102,7 +103,7 @@ async function featchList() {
} catch (error) {
return [];
} finally {
loading = false;
loading.value = false;
}
}
@ -123,7 +124,7 @@ function generateFilterEntityList(data) {
const reg = new RegExp(keyword.value, "gi");
const hilightText = searchname.replace(
reg,
`<span style='color:#FF0000'>${keyword.value}</span>`
`<span>${keyword.value}</span>`
);
return {
@ -133,6 +134,7 @@ function generateFilterEntityList(data) {
isDefaultFilter: false,
filterList: list,
reorder,
searchname
};
});
@ -141,10 +143,15 @@ function generateFilterEntityList(data) {
function selectHandler(item: FilterEntity) {
(popover.value as any).setShow(false);
currentlySelectedAdvanced.value = item.searchname
emit("select", item.id);
}
const inputHandler = debounce((word) => {
getSearchedList(word)
}, 300);
function getSearchedList(word) {
if (word) {
pagination.pageSize = 300;
} else {
@ -163,13 +170,13 @@ const inputHandler = debounce((word) => {
}
});
data.value = dataArr.sort(
(a, b) => Number((a as any).reorder) - Number((b as any).reorder)
(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)
);
});
}, 300);
}
function favoriteHandler(event: MouseEvent, item: any) {
event.stopImmediatePropagation();
@ -226,7 +233,7 @@ const moveEnd = () => {
>
<template #trigger>
<div class="wrapper-left-dropdown" @click="showClick">
<span style="font-size: 20px;color: #333333;font-weight: Medium;">高级筛选</span>
<span style="font-size: 20px;color: #333333;font-weight: Medium;">{{currentlySelectedAdvanced}}</span>
<SvgIcon :style="{ marginLeft: '5px' }" name="down" size="14" />
</div>
</template>
@ -234,7 +241,7 @@ const moveEnd = () => {
<div class="wrapper-left-popover">
<n-input
:style="{ '--n-border': '0px' }"
placeholder="请输入关键"
placeholder="请输入关键"
@input="inputHandler"
>
<template #prefix>
@ -257,20 +264,23 @@ const moveEnd = () => {
style="display: flex; align-items: center"
@click="selectHandler(item)"
>
<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"
@click="unFavoriteHandler($event, item)"
/>
<SvgIcon
v-else-if="!item.favorite && !item.isDefaultFilter"
name="favorite-unfill"
size="18"
style="margin-right:3px"
@click="favoriteHandler($event, item)"
/>
<div v-html="item.name" />
<div v-html="item.name" style="color: #333333;"/>
</li>
<!-- filter=".draggable-li[draggable='false']" -->
<VueDraggable
@ -288,20 +298,25 @@ const moveEnd = () => {
class="cursor-move draggable-li fix"
:draggable="true"
>
<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;"
@click="unFavoriteHandler($event, item)"
/>
<SvgIcon
v-else-if="!item.favorite && !item.isDefaultFilter"
name="favorite-unfill"
size="18"
fill="#666666"
style="cursor: pointer!important;margin-right:3px;"
@click="favoriteHandler($event, item)"
/>
<div v-html="item.name" />
<div v-html="item.name" style="color: #333333;"/>
</li>
</VueDraggable>
</ul>
@ -356,17 +371,17 @@ const moveEnd = () => {
height: 200px;
overflow-x: hidden;
overflow-y: auto;
scrollbar-width: none; /* firefox */
-ms-overflow-style: none; /* IE 10+ */
scrollbar-width: thin; /* firefox */
-ms-overflow-style: thin; /* IE 10+ */
&::-webkit-scrollbar {
display: none;
display: thin;
}
li {
font-size: 14px;
line-height: 22px;
padding: 5px 12px;
padding: 8px 12px;
&:hover {
background-color: #f3f8ff;

@ -1,5 +1,6 @@
<script lang="ts" setup>
import { ref } from 'vue'
import dayjs from 'dayjs';
import { onMounted, ref } from 'vue';
const props = defineProps<{
value: [number, number] | null
@ -15,6 +16,18 @@ const time = ref<[number, number] | null>(props.value)
function onChange(value: [number, number]) {
emit('update:value', value)
}
onMounted(() => {
//
const currentDate = dayjs();
//
const endDate = currentDate.toDate();
const startDate = currentDate.subtract(3, 'month').toDate();
//
time.value = [startDate.getTime(), endDate.getTime()];
setTimeout(() => {
onChange([startDate.getTime(), endDate.getTime()])
},300)
})
</script>
<template>
@ -22,7 +35,7 @@ function onChange(value: [number, number]) {
<n-collapse :default-expanded-names="['1']" arrow-placement="right">
<n-collapse-item :title="label" name="1">
<n-space>
<n-date-picker v-model:value="time" type="daterange" clearable @update:value="onChange" >
<n-date-picker v-model:value="time" type="daterange" clearable @update:value="onChange">
<template #separator>
</template>
@ -37,10 +50,12 @@ function onChange(value: [number, number]) {
.wrapper {
padding: 10px;
}
::v-deep(.n-collapse-item-arrow){
::v-deep(.n-collapse-item-arrow) {
color: #999999 !important;
}
::v-deep(.n-input__separator){
color: #999999 !important;;
}
</style>
::v-deep(.n-input__separator) {
color: #999999 !important;
;
}</style>

@ -1,24 +1,24 @@
import PictureTypeVue from './PictureType.vue'
import PlanVue from './Plan.vue'
import ReportUserVue from './ReportUser.vue'
import PictureDownloadVue from './PictureDownload.vue'
import TimeVue from './Time.vue'
import RegionVue from './Region.vue'
import PictureUploadVue from './PictureUpload.vue'
import SimilarityVue from './Similarity.vue'
import PlaceHolderVue from './PlaceHolder.vue'
import IzShowVue from './IzShow.vue'
import IzProjectVue from './IzProject.vue'
import IztaskrromVue from './Iztaskrrom.vue'
import IztaskstatusVue from './Iztaskstatus.vue'
import IzvisitproVue from './Izvisitpro.vue'
import IzfirmVue from './Izfirm.vue'
import IzCustomlevel from './IzCustomlevel.vue'
import IzCustomname from './IzCustomname.vue'
import IzCustomtype from './IzCustomtype.vue'
import IzfirmVue from './Izfirm.vue'
import IzProductVue from './IzProduct.vue'
import IzProjectVue from './IzProject.vue'
import IzProjecttype from './IzProjecttype.vue'
import IzVisitcity from './IzVisitcity.vue'
import IzStatus from './IzStatus.vue'
import IztaskrromVue from './Iztaskrrom.vue'
import IztaskstatusVue from './Iztaskstatus.vue'
import IzVisitcity from './IzVisitcity.vue'
import IzvisitproVue from './Izvisitpro.vue'
import PictureDownloadVue from './PictureDownload.vue'
import PictureTypeVue from './PictureType.vue'
import PictureUploadVue from './PictureUpload.vue'
import PlaceHolderVue from './PlaceHolder.vue'
import PlanVue from './Plan.vue'
import RegionVue from './Region.vue'
import ReportUserVue from './ReportUser.vue'
import SimilarityVue from './Similarity.vue'
import TimeVue from './Time.vue'
export { IzProjecttype, IzStatus, IzVisitcity, IzCustomlevel, IzCustomtype, IzCustomname, IzfirmVue, IzProductVue, IzvisitproVue, IztaskstatusVue, IztaskrromVue, IzProjectVue, PictureDownloadVue, PictureUploadVue, PlaceHolderVue, RegionVue, SimilarityVue, ReportUserVue, PlanVue, PictureTypeVue, TimeVue }
export { IzProjecttype, IzStatus, IzVisitcity, IzCustomlevel, IzCustomtype, IzCustomname, IzfirmVue, IzProductVue, IzvisitproVue, IztaskstatusVue, IztaskrromVue, IzProjectVue, IzShowVue, PictureDownloadVue, PictureUploadVue, PlaceHolderVue, RegionVue, SimilarityVue, ReportUserVue, PlanVue, PictureTypeVue, TimeVue }

@ -17,6 +17,7 @@ import { computed, nextTick, onMounted, onUnmounted, onUpdated, reactive, ref, u
import GeneratePackageModal from './modal/GeneratePackageModal.vue'
import LoginSuccessModal from './modal/LoginSuccessModal.vue'
import PackageSettingsModal from './modal/PackageSettingsModal.vue'
import type { PictureSortParam } from "/#/api"
const deviceHeight = ref(600)
let _masonry: null | Masonry = null
@ -35,7 +36,10 @@ const LoginSuccessModalRef = ref(null)
const loading = ref(false)
const message = useMessage()
const totalCount = ref(0)
const sortBy = ref<'asc' | 'desc'>('desc')
const sortBy: PictureSortParam = {
orderbyname: "asc",
orderbyvalue: "pictureResult",
};
const imageRef = ref<ComponentElRef | null>()
let canloadMore = true
let filterId = null
@ -64,7 +68,7 @@ const layout = debounce(() => {
_masonry = new Masonry(masonryRef.value as any, {
itemSelector: '.grid-item',
gutter: 18,
gutter: 17,
columnWidth: 182,
percentPosition: true,
stagger: 10,
@ -128,7 +132,7 @@ async function featchList() {
const asideParams = unref(configStore.getAsideValue)
const params = filterId ? { userSearchId: filterId } : asideParams
const result = await getPictureList({ ...pagination, ...contentParams, ...params, ordertype: sortBy.value })
const result = await getPictureList({ ...pagination, ...contentParams, ...params, ...sortBy })
const { data, pageCount, total } = result
totalCount.value = total
canloadMore = pageCount >= pagination.pageNo && pageCount > 0
@ -261,8 +265,9 @@ function getAvatar(url: string): string {
return url ? getImgUrl(url) : avatar
}
function sortHandler() {
sortBy.value = sortBy.value === 'asc' ? 'desc' : 'asc'
function sortHandler(orderby: "pictureResult" | "fromuptime") {
sortBy.orderbyvalue = orderby;
sortBy.orderbyname = sortBy.orderbyname === "asc" ? "desc" : "asc";
refreshHandler()
}
async function downloadImage(item) {
@ -338,10 +343,14 @@ function previewHandler(index: number,event: MouseEvent) {
<SvgIcon class="gap" name="arrow-botton" size="14" />
</div>
</n-popselect>
<!-- <div style="margin-left: 15px;cursor: pointer;color:#323233" @click="sortHandler()">
<div style="margin-left: 15px;cursor: pointer;color:#323233" @click="sortHandler('pictureResult')">
<span>相似度排序</span>
<SvgIcon style="margin-left: 8px;" name="sort" size="12" />
</div> -->
</div>
<div style="margin-left: 15px;cursor: pointer;color:#323233" @click="sortHandler('fromuptime')">
<span>时间排序</span>
<SvgIcon style="margin-left: 8px;" name="sort" size="12" />
</div>
</div>
<span style="font-size: 16px;color:#494949"> <span style="color:#7899fd;font-weight: 500;">{{ totalCount }}</span> </span>
</div>
@ -380,10 +389,10 @@ function previewHandler(index: number,event: MouseEvent) {
<n-avatar :src="getAvatar(item.uphead)" class="avatar" round />
<span>{{ item.upname }}</span>
</div>
<div class="right">
<!-- <div class="right">
<span :style="{ marginRight: '5px' }">分类</span>
<span>{{ item.ocrPictureclass?.classname }}</span>
</div>
</div> -->
</div>
</div>
</div>

2
types/home.d.ts vendored

@ -8,6 +8,8 @@ export interface Filter {
export interface FilterEntity {
id: string
name: string // 过滤名称
createtime: string // 创建时间
searchname: string // 搜索名称
favorite: boolean// 是否收藏
isDefaultFilter: boolean// 默认筛选
filterList: Filter[] // 过滤项列表

Loading…
Cancel
Save