merge junjie_dev into master
update: 头部搜索能力补全 Created-by: user8949 Commit-by: @user8949 Merged-by: user8949 Description: update: 头部搜索功能补全 update: 头部搜索能力补全 update: 头部搜索能力补全 See merge request: hk_openRepo/OpenRepo_Portal!52
This commit is contained in:
@@ -5,7 +5,7 @@
|
|||||||
<d-row :gutter="16">
|
<d-row :gutter="16">
|
||||||
<d-col :span="8">
|
<d-col :span="8">
|
||||||
<d-form-item field="name" label="软件名称">
|
<d-form-item field="name" label="软件名称">
|
||||||
<d-input placeholder="请输入软件名称" v-model="formData.searchWord"/>
|
<d-input placeholder="请输入软件名称" v-model="formData.softwareName"/>
|
||||||
</d-form-item>
|
</d-form-item>
|
||||||
</d-col>
|
</d-col>
|
||||||
<d-col :span="8">
|
<d-col :span="8">
|
||||||
@@ -37,6 +37,18 @@
|
|||||||
</d-form-item>
|
</d-form-item>
|
||||||
</d-col>
|
</d-col>
|
||||||
</d-row>
|
</d-row>
|
||||||
|
<d-row :gutter="16">
|
||||||
|
<d-col :span="8">
|
||||||
|
<d-form-item field="interestTag" label="兴趣标签">
|
||||||
|
<d-input v-model="formData.interestTag"/>
|
||||||
|
</d-form-item>
|
||||||
|
</d-col>
|
||||||
|
<d-col :span="8">
|
||||||
|
<d-form-item field="industry" label="行业">
|
||||||
|
<d-input v-model="formData.industry"/>
|
||||||
|
</d-form-item>
|
||||||
|
</d-col>
|
||||||
|
</d-row>
|
||||||
<slot name="operation">
|
<slot name="operation">
|
||||||
<gc-form-operation style="display: flex; justify-content: center; gap: 8px;">
|
<gc-form-operation style="display: flex; justify-content: center; gap: 8px;">
|
||||||
<d-button style="width: 96px; height: 32px;" variant="solid" @click="submitForm">搜索</d-button>
|
<d-button style="width: 96px; height: 32px;" variant="solid" @click="submitForm">搜索</d-button>
|
||||||
@@ -59,10 +71,12 @@ const props = defineProps({
|
|||||||
type: Object,
|
type: Object,
|
||||||
default: () => ({
|
default: () => ({
|
||||||
licenseName: '',
|
licenseName: '',
|
||||||
searchWord: '',
|
softwareName: '',
|
||||||
softwareVersion: '',
|
softwareVersion: '',
|
||||||
dependentSoftware: '',
|
dependentSoftware: '',
|
||||||
programmingLanguage: '',
|
programmingLanguage: '',
|
||||||
|
interestTag: '',
|
||||||
|
industry: '',
|
||||||
dateRange: ['', '']
|
dateRange: ['', '']
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -91,10 +105,12 @@ const submitForm = () => {
|
|||||||
const cancel = () => {
|
const cancel = () => {
|
||||||
formData.value = {
|
formData.value = {
|
||||||
licenseName: '',
|
licenseName: '',
|
||||||
searchWord: '',
|
softwareName: '',
|
||||||
softwareVersion: '',
|
softwareVersion: '',
|
||||||
dependentSoftware: '',
|
dependentSoftware: '',
|
||||||
programmingLanguage: '',
|
programmingLanguage: '',
|
||||||
|
interestTag: '',
|
||||||
|
industry: '',
|
||||||
dateRange: ['', '']
|
dateRange: ['', '']
|
||||||
}
|
}
|
||||||
emit('cancel');
|
emit('cancel');
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<d-input
|
<d-input
|
||||||
:key="$route.path + $route.query?.val" id="golbalSearch" class="g-header-search"
|
:key="$route.path + $route.query?.val" id="golbalSearch" class="g-header-search"
|
||||||
v-model.trim="searchStr" placeholder="输入搜索内容..." @keyup.enter="search" @clear="handleClear" clearable >
|
v-model.trim="softwareName" placeholder="请输入软件名称搜索" @clear="handleClear" clearable >
|
||||||
<template #prepend>
|
<template #prepend>
|
||||||
<d-dropdown @toggle="onCateToggle($event)">
|
<d-dropdown>
|
||||||
<div class="flex items-center gap-1 cursor-pointer">
|
<div class="flex items-center gap-1 cursor-pointer">
|
||||||
{{ searchType }}
|
{{ searchType }}
|
||||||
<d-icon :rotate="cateRotate" name="icon-chevron-down-2"></d-icon>
|
<d-icon :rotate="cateRotate" name="icon-chevron-down-2"></d-icon>
|
||||||
@@ -37,12 +37,18 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted, watch, onUnmounted, reactive } from 'vue';
|
import { ref, onMounted, watch, onUnmounted, reactive } from 'vue';
|
||||||
import { useRoute, useRouter } from 'vue-router';
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
|
import { useGlobalInfoStore } from '@/stores/Global';
|
||||||
import microApp from '@micro-zoe/micro-app';
|
import microApp from '@micro-zoe/micro-app';
|
||||||
|
|
||||||
|
const emit = defineEmits('updateSearch');
|
||||||
|
const globalInfo = useGlobalInfoStore();
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const searchStr = ref(route?.query?.val || '');
|
|
||||||
const searchType = ref('软件');
|
const softwareName = ref(globalInfo.headerSearch.softwareName);
|
||||||
|
const searchType = ref(globalInfo.headerSearch.searchType);
|
||||||
|
|
||||||
const position = ref(['right-start', 'right-end']);
|
const position = ref(['right-start', 'right-end']);
|
||||||
const industryOptions = ref(['通信', '军工', '金融', '能源']);
|
const industryOptions = ref(['通信', '军工', '金融', '能源']);
|
||||||
|
|
||||||
@@ -50,17 +56,15 @@ const placeholder = ref('「开搜」:一搜即达,开发者的AI搜索');
|
|||||||
|
|
||||||
const onCategoryChange = (event) => {
|
const onCategoryChange = (event) => {
|
||||||
searchType.value = event;
|
searchType.value = event;
|
||||||
|
globalInfo.updateHeaderSearch({ softwareName: softwareName.value, searchType: searchType.value });
|
||||||
}
|
}
|
||||||
|
|
||||||
const search = () => {
|
const search = () => {
|
||||||
if (!searchStr.value) {
|
window.open(`/repoList?softwareName=${softwareName.value ? softwareName.value : ''}&searchType=${searchType.value}`, '_blank')
|
||||||
document.querySelector('#golbalSearch').blur();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
router.push({ name: 'Search', query: { searchWord: searchStr.value || '', type: route?.query?.type || 'software' }});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleClear = () => {
|
const handleClear = () => {
|
||||||
router.push({ name: 'home' });
|
globalInfo.updateHeaderSearch({ softwareName: ''.value, searchType: searchType.value });
|
||||||
};
|
};
|
||||||
|
|
||||||
watch(() => route.query?.val, (newVal) => {
|
watch(() => route.query?.val, (newVal) => {
|
||||||
@@ -70,7 +74,7 @@ watch(() => route.query?.val, (newVal) => {
|
|||||||
const handleDataChange = ({ name, type, data }) => {
|
const handleDataChange = ({ name, type, data }) => {
|
||||||
if (name === 'micoro-app-homeweb-app') {
|
if (name === 'micoro-app-homeweb-app') {
|
||||||
if (type === 'keyword-change') {
|
if (type === 'keyword-change') {
|
||||||
searchStr.value = data;
|
softwareName.value = data;
|
||||||
}
|
}
|
||||||
if (type === 'route-change') {
|
if (type === 'route-change') {
|
||||||
//
|
//
|
||||||
@@ -79,7 +83,9 @@ const handleDataChange = ({ name, type, data }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
globalInfo.updateHeaderSearch({ softwareName: route.query.softwareName ? route.query.softwareName : '', searchType: route.query.searchType || '软件' });
|
||||||
|
softwareName.value = route.query.softwareName;
|
||||||
|
searchType.value = route.query.searchType || '软件';
|
||||||
});
|
});
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,10 @@ export const useGlobalInfoStore = defineStore('globalInfo', () => {
|
|||||||
const showTools = ref(true); // 是否展示工具栏
|
const showTools = ref(true); // 是否展示工具栏
|
||||||
const namespaceType = ref(-1); // 0 - 用户 1 - 组织
|
const namespaceType = ref(-1); // 0 - 用户 1 - 组织
|
||||||
const globalTheme = ref('light'); // 网站主题
|
const globalTheme = ref('light'); // 网站主题
|
||||||
|
const headerSearch = ref({
|
||||||
|
searchType: '软件',
|
||||||
|
softwareName: ''
|
||||||
|
})
|
||||||
|
|
||||||
const menuInfo = computed(() => {
|
const menuInfo = computed(() => {
|
||||||
// 当前菜单
|
// 当前菜单
|
||||||
@@ -63,6 +67,11 @@ export const useGlobalInfoStore = defineStore('globalInfo', () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const updateHeaderSearch = (data: any) => {
|
||||||
|
headerSearch.value = { ...data };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置菜单标题旁的数字(如:mr数量,成员数量)
|
* 设置菜单标题旁的数字(如:mr数量,成员数量)
|
||||||
* @param id 菜单id
|
* @param id 菜单id
|
||||||
@@ -107,6 +116,7 @@ export const useGlobalInfoStore = defineStore('globalInfo', () => {
|
|||||||
showTools,
|
showTools,
|
||||||
namespaceType,
|
namespaceType,
|
||||||
globalTheme,
|
globalTheme,
|
||||||
|
headerSearch,
|
||||||
setMenuType,
|
setMenuType,
|
||||||
updateMenuNum,
|
updateMenuNum,
|
||||||
setMenuInfo,
|
setMenuInfo,
|
||||||
@@ -114,6 +124,7 @@ export const useGlobalInfoStore = defineStore('globalInfo', () => {
|
|||||||
setIsNotFound,
|
setIsNotFound,
|
||||||
setShowTools,
|
setShowTools,
|
||||||
setNamespaceType,
|
setNamespaceType,
|
||||||
setGlobalTheme
|
setGlobalTheme,
|
||||||
|
updateHeaderSearch
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -87,11 +87,11 @@
|
|||||||
@click="openWarningDetail(item, index)"
|
@click="openWarningDetail(item, index)"
|
||||||
>
|
>
|
||||||
<span>{{ item.subject }}</span>
|
<span>{{ item.subject }}</span>
|
||||||
<d-tag :color="tagMap[item.importance]" size="sm">{{ item.importance }}</d-tag>
|
<d-tag v-if="item.importance" :color="tagMap[item.importance].color" size="sm">{{ tagMap[item.importance].text }}</d-tag>
|
||||||
</div>
|
</div>
|
||||||
<div class="time-container">
|
<div class="time-container">
|
||||||
<d-icon name="icon-time"></d-icon>
|
<d-icon name="icon-time"></d-icon>
|
||||||
{{ item.pulishTime }}
|
{{ item.publishTime }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -117,7 +117,8 @@ import { useAccount } from '@/utils/hooks/useAccount';
|
|||||||
import AdvanceSearch from '@/components/AdvanceSearch/index.vue';
|
import AdvanceSearch from '@/components/AdvanceSearch/index.vue';
|
||||||
import { getHomeNoticeList } from '@/api/jyh';
|
import { getHomeNoticeList } from '@/api/jyh';
|
||||||
import EarlyWarningDetail from '@/views/Jyh/PersonalCenter/Detail/EarlyWarningDetail.vue';
|
import EarlyWarningDetail from '@/views/Jyh/PersonalCenter/Detail/EarlyWarningDetail.vue';
|
||||||
|
import { useGlobalInfoStore } from '@/stores/Global';
|
||||||
|
const { updateHeaderSearch } = useGlobalInfoStore();
|
||||||
const { accountInfo } = useAccount();
|
const { accountInfo } = useAccount();
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
@@ -141,10 +142,23 @@ const homeSearch = ref(null);
|
|||||||
const dropdownWidth = ref(0);
|
const dropdownWidth = ref(0);
|
||||||
const selectedCate = ref('软件');
|
const selectedCate = ref('软件');
|
||||||
const tagMap = {
|
const tagMap = {
|
||||||
高: '#f66f6a',
|
'Critical': {
|
||||||
中: '#fac20a',
|
text: '致命',
|
||||||
低: '#5e7ce0'
|
color: '#c7000b'
|
||||||
};
|
},
|
||||||
|
'High': {
|
||||||
|
text: '高',
|
||||||
|
color: '#f66f6a'
|
||||||
|
},
|
||||||
|
'Medium': {
|
||||||
|
text: '中',
|
||||||
|
color: '#fac20a'
|
||||||
|
},
|
||||||
|
'Low': {
|
||||||
|
text: '低',
|
||||||
|
color: '#5e7ce0'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const searchInput = ref(null);
|
const searchInput = ref(null);
|
||||||
const openAdvancedSearch = () => {
|
const openAdvancedSearch = () => {
|
||||||
@@ -184,7 +198,8 @@ const updateDropdownWidth = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const search = () => {
|
const search = () => {
|
||||||
router.push({ name: 'Search', query: { searchWord: searchStr.value, searchType: selectedCate.value } });
|
updateHeaderSearch({ searchWord: searchStr.value, searchType: selectedCate.value })
|
||||||
|
router.push({ name: 'Search' });
|
||||||
};
|
};
|
||||||
|
|
||||||
const onCategoryChange = (cate) => {
|
const onCategoryChange = (cate) => {
|
||||||
@@ -431,7 +446,7 @@ getNoticeList();
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
width: 120px;
|
width: 140px;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<div class="sub-title mt-3">
|
<div class="sub-title mt-3">
|
||||||
<div>
|
<div>
|
||||||
<span>重要性</span>
|
<span>重要性</span>
|
||||||
<d-tag type="danger" size="sm">{{warningData.importance}}</d-tag>
|
<d-tag size="sm" :color="tagMap[warningData.importance].color">{{tagMap[warningData.importance].text}}</d-tag>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="propsData.type === 'system'">
|
<div v-if="propsData.type === 'system'">
|
||||||
<d-button v-show="mode === 'readonly'" class="edit-btn" icon="icon-edit" variant="text" title="编辑" @click="handleModeChange"/>
|
<d-button v-show="mode === 'readonly'" class="edit-btn" icon="icon-edit" variant="text" title="编辑" @click="handleModeChange"/>
|
||||||
@@ -39,6 +39,24 @@ const toolbarConfig = [
|
|||||||
['h1', 'h2', 'bold', 'italic', 'strike', 'underline', 'color', 'font'],
|
['h1', 'h2', 'bold', 'italic', 'strike', 'underline', 'color', 'font'],
|
||||||
['ul', 'ol', 'checklist', 'code', 'link', 'image', 'table'],
|
['ul', 'ol', 'checklist', 'code', 'link', 'image', 'table'],
|
||||||
];
|
];
|
||||||
|
const tagMap = {
|
||||||
|
'Critical': {
|
||||||
|
text: '致命',
|
||||||
|
color: '#c7000b'
|
||||||
|
},
|
||||||
|
'High': {
|
||||||
|
text: '高',
|
||||||
|
color: '#f66f6a'
|
||||||
|
},
|
||||||
|
'Medium': {
|
||||||
|
text: '中',
|
||||||
|
color: '#fac20a'
|
||||||
|
},
|
||||||
|
'Low': {
|
||||||
|
text: '低',
|
||||||
|
color: '#5e7ce0'
|
||||||
|
}
|
||||||
|
}
|
||||||
const mode = ref('readonly');
|
const mode = ref('readonly');
|
||||||
console.log(propsData.warningData)
|
console.log(propsData.warningData)
|
||||||
warningData.value = propsData.warningData ?? {
|
warningData.value = propsData.warningData ?? {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
</AdvanceSearch>
|
</AdvanceSearch>
|
||||||
<div class="jyh-form-operation">
|
<div class="jyh-form-operation">
|
||||||
<d-button @click="getReleaseList" class="mr-2" variant="solid">搜索</d-button>
|
<d-button @click="getReleaseList" class="mr-2" variant="solid">搜索</d-button>
|
||||||
<d-button variant="solid" color="secondary">清空</d-button>
|
<d-button variant="solid" color="secondary" @click="clear">清空</d-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="left-btn">
|
<div class="left-btn">
|
||||||
<d-button v-if="isLogin" class="output-btn" icon="icon-share" variant="text">导出</d-button>
|
<d-button v-if="isLogin" class="output-btn" icon="icon-share" variant="text">导出</d-button>
|
||||||
@@ -124,6 +124,7 @@ import { useAccountStore } from '@/stores/user';
|
|||||||
const { formatTime } = useTimeFormat();
|
const { formatTime } = useTimeFormat();
|
||||||
import { releasePage } from '@/api/jyh';
|
import { releasePage } from '@/api/jyh';
|
||||||
import { useTimeFormat } from '@/utils/hooks/useTimeFormat';
|
import { useTimeFormat } from '@/utils/hooks/useTimeFormat';
|
||||||
|
import { useGlobalInfoStore } from '@/stores/Global';
|
||||||
const { namespace } = getOrgInfo();
|
const { namespace } = getOrgInfo();
|
||||||
const userInfo = useAccountStore();
|
const userInfo = useAccountStore();
|
||||||
const { isLogin } = storeToRefs(userInfo);
|
const { isLogin } = storeToRefs(userInfo);
|
||||||
@@ -138,16 +139,28 @@ const typeOptions = reactive(['主软件', '依赖软件']);
|
|||||||
const riskOptions = reactive(['低', '中', '高']);
|
const riskOptions = reactive(['低', '中', '高']);
|
||||||
const useTypeOptions = reactive(['软件', '文档', '文档+软件']);
|
const useTypeOptions = reactive(['软件', '文档', '文档+软件']);
|
||||||
const isUseOptions = reactive(['是', '否']);
|
const isUseOptions = reactive(['是', '否']);
|
||||||
|
const globalInfo = useGlobalInfoStore();
|
||||||
|
const headerSearch = ref(globalInfo.headerSearch)
|
||||||
const newFormData = ref({
|
const newFormData = ref({
|
||||||
licenseName: '',
|
licenseName: '',
|
||||||
searchType: 'software',
|
searchType: headerSearch.value.searchType ? headerSearch.value.searchType : 'software',
|
||||||
searchWord: '',
|
softwareName: '',
|
||||||
softwareVersion: '',
|
softwareVersion: '',
|
||||||
dependentSoftware: '',
|
dependentSoftware: '',
|
||||||
programmingLanguage: '',
|
programmingLanguage: '',
|
||||||
|
interestTag: '',
|
||||||
|
industry: '',
|
||||||
dateRange: ['', '']
|
dateRange: ['', '']
|
||||||
})
|
})
|
||||||
|
|
||||||
|
watch(() => globalInfo.headerSearch, (newVal: any) => {
|
||||||
|
headerSearch.value = newVal;
|
||||||
|
console.log(newVal)
|
||||||
|
newFormData.value.searchType = newVal.searchType;
|
||||||
|
newFormData.value.softwareName = newVal.softwareName;
|
||||||
|
getReleaseList();
|
||||||
|
}, { deep: true })
|
||||||
|
|
||||||
const pager = ref({
|
const pager = ref({
|
||||||
total: 10,
|
total: 10,
|
||||||
pageIndex: 1,
|
pageIndex: 1,
|
||||||
@@ -195,6 +208,22 @@ const showColumnList = ref(false);
|
|||||||
const countryModalRef = ref(null);
|
const countryModalRef = ref(null);
|
||||||
const orgModalRef = ref(null);
|
const orgModalRef = ref(null);
|
||||||
|
|
||||||
|
// 清空高级搜索
|
||||||
|
const clear = () => {
|
||||||
|
newFormData.value = {
|
||||||
|
licenseName: '',
|
||||||
|
searchType: headerSearch.value.searchType ? headerSearch.value.searchType : 'software',
|
||||||
|
softwareName: '',
|
||||||
|
softwareVersion: '',
|
||||||
|
dependentSoftware: '',
|
||||||
|
programmingLanguage: '',
|
||||||
|
interestTag: '',
|
||||||
|
industry: '',
|
||||||
|
dateRange: ['', '']
|
||||||
|
}
|
||||||
|
getReleaseList();
|
||||||
|
}
|
||||||
|
|
||||||
// 打开模态框的方法
|
// 打开模态框的方法
|
||||||
const openCountryModal = () => {
|
const openCountryModal = () => {
|
||||||
if (countryModalRef.value) {
|
if (countryModalRef.value) {
|
||||||
@@ -304,11 +333,13 @@ const getReleaseList = async() => {
|
|||||||
if (!error && data) {
|
if (!error && data) {
|
||||||
tableData.value = data.data.records;
|
tableData.value = data.data.records;
|
||||||
pager.value.total = data.data.total;
|
pager.value.total = data.data.total;
|
||||||
|
|
||||||
|
console.log(tableData.value)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
onMounted(async() => {
|
onMounted(async() => {
|
||||||
getReleaseList();
|
// getReleaseList();
|
||||||
});
|
});
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
@@ -317,18 +348,6 @@ onMounted(() => {
|
|||||||
...query
|
...query
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
// 监听路由变化,更新 searchWord
|
|
||||||
watch(
|
|
||||||
() => route.query.searchWord, // 监听路由的 searchWord 参数
|
|
||||||
(newSearchWord) => {
|
|
||||||
if (newSearchWord) {
|
|
||||||
newFormData.value.searchWord = newSearchWord; // 更新组件的 searchWord
|
|
||||||
getReleaseList(); // 重新调用接口
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ immediate: true } // 立即执行一次
|
|
||||||
);
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|||||||
Reference in New Issue
Block a user