验证码、搜索、

main
lizhong 2 years ago
parent 56a17cb6a2
commit cd79642603

@ -5,16 +5,28 @@
</component>
<component name="ChangeListManager">
<list default="true" id="dc5c5f4b-3a26-4616-b023-f4f048553ff8" name="Changes" comment="socket">
<change afterPath="$PROJECT_DIR$/middleware/isSearch.ts" afterDir="false" />
<change afterPath="$PROJECT_DIR$/pages/search/[id].vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.gitignore" beforeDir="false" afterPath="$PROJECT_DIR$/.gitignore" afterDir="false" />
<change afterPath="$PROJECT_DIR$/pages/[tptsps_id].vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/api/Common.ts" beforeDir="false" afterPath="$PROJECT_DIR$/api/Common.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/assets/style/config.scss" beforeDir="false" afterPath="$PROJECT_DIR$/assets/style/config.scss" afterDir="false" />
<change beforePath="$PROJECT_DIR$/assets/style/var/index.scss" beforeDir="false" afterPath="$PROJECT_DIR$/assets/style/var/index.scss" afterDir="false" />
<change beforePath="$PROJECT_DIR$/components/Banner/Search.vue" beforeDir="false" afterPath="$PROJECT_DIR$/components/Banner/Search.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/components/Banner/homeBanner.vue" beforeDir="false" afterPath="$PROJECT_DIR$/components/Banner/homeBanner.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/components/Footer/Index.vue" beforeDir="false" afterPath="$PROJECT_DIR$/components/Footer/Index.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/components/Header/Index.vue" beforeDir="false" afterPath="$PROJECT_DIR$/components/Header/Index.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/components/HtmlPreview/Index.vue" beforeDir="false" afterPath="$PROJECT_DIR$/components/HtmlPreview/Index.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/components/Login/Index.vue" beforeDir="false" afterPath="$PROJECT_DIR$/components/Login/Index.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/components/MoreBtn/Index.vue" beforeDir="false" afterPath="$PROJECT_DIR$/components/MoreBtn/Index.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/composables/useAppStore.ts" beforeDir="false" afterPath="$PROJECT_DIR$/composables/useAppStore.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/composables/useUserInfo.ts" beforeDir="false" afterPath="$PROJECT_DIR$/composables/useUserInfo.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/layouts/tabLayout.vue" beforeDir="false" afterPath="$PROJECT_DIR$/layouts/tabLayout.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/pages/translate.vue" beforeDir="false" afterPath="$PROJECT_DIR$/pages/translate.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/nuxt.config.ts" beforeDir="false" afterPath="$PROJECT_DIR$/nuxt.config.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/pages/index.vue" beforeDir="false" afterPath="$PROJECT_DIR$/pages/index.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/pages/rules.vue" beforeDir="false" afterPath="$PROJECT_DIR$/pages/rules.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/pages/search/[id].vue" beforeDir="false" afterPath="$PROJECT_DIR$/pages/search/[id].vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/pages/tptsps.vue" beforeDir="false" afterPath="$PROJECT_DIR$/pages/tptsps.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/pages/warning.vue" beforeDir="false" afterPath="$PROJECT_DIR$/pages/warning.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/utils/http.ts" beforeDir="false" afterPath="$PROJECT_DIR$/utils/http.ts" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
@ -45,31 +57,31 @@
<option name="showLibraryContents" value="true" />
<option name="sortByType" value="true" />
</component>
<component name="PropertiesComponent">{
&quot;keyToString&quot;: {
&quot;RunOnceActivity.OpenProjectViewOnStart&quot;: &quot;true&quot;,
&quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;,
&quot;WebServerToolWindowFactoryState&quot;: &quot;true&quot;,
&quot;WebServerToolWindowPanel.toolwindow.highlight.mappings&quot;: &quot;true&quot;,
&quot;WebServerToolWindowPanel.toolwindow.highlight.symlinks&quot;: &quot;true&quot;,
&quot;WebServerToolWindowPanel.toolwindow.show.date&quot;: &quot;false&quot;,
&quot;WebServerToolWindowPanel.toolwindow.show.permissions&quot;: &quot;false&quot;,
&quot;WebServerToolWindowPanel.toolwindow.show.size&quot;: &quot;false&quot;,
&quot;last_opened_file_path&quot;: &quot;/Users/lizhong/Desktop/workspace/ReptileFront/reptileFront_nuxt/assets/images&quot;,
&quot;node.js.detected.package.eslint&quot;: &quot;true&quot;,
&quot;node.js.detected.package.tslint&quot;: &quot;true&quot;,
&quot;node.js.selected.package.eslint&quot;: &quot;(autodetect)&quot;,
&quot;node.js.selected.package.tslint&quot;: &quot;(autodetect)&quot;,
&quot;nodejs_package_manager_path&quot;: &quot;yarn&quot;,
&quot;settings.editor.selected.configurable&quot;: &quot;reference.settings.ide.settings.file-colors&quot;,
&quot;ts.external.directory.path&quot;: &quot;/Applications/WebStorm.app/Contents/plugins/javascript-impl/jsLanguageServicesImpl/external&quot;,
&quot;vue.rearranger.settings.migration&quot;: &quot;true&quot;
<component name="PropertiesComponent"><![CDATA[{
"keyToString": {
"RunOnceActivity.OpenProjectViewOnStart": "true",
"RunOnceActivity.ShowReadmeOnStart": "true",
"WebServerToolWindowFactoryState": "true",
"WebServerToolWindowPanel.toolwindow.highlight.mappings": "true",
"WebServerToolWindowPanel.toolwindow.highlight.symlinks": "true",
"WebServerToolWindowPanel.toolwindow.show.date": "false",
"WebServerToolWindowPanel.toolwindow.show.permissions": "false",
"WebServerToolWindowPanel.toolwindow.show.size": "false",
"last_opened_file_path": "/Users/lizhong/Desktop/workspace/ReptileFront/reptileFront_nuxt/pages",
"node.js.detected.package.eslint": "true",
"node.js.detected.package.tslint": "true",
"node.js.selected.package.eslint": "(autodetect)",
"node.js.selected.package.tslint": "(autodetect)",
"nodejs_package_manager_path": "yarn",
"settings.editor.selected.configurable": "reference.settings.ide.settings.file-colors",
"ts.external.directory.path": "/Applications/WebStorm.app/Contents/plugins/javascript-impl/jsLanguageServicesImpl/external",
"vue.rearranger.settings.migration": "true"
}
}</component>
}]]></component>
<component name="RecentsManager">
<key name="CopyFile.RECENT_KEYS">
<recent name="$PROJECT_DIR$/assets/images" />
<recent name="$PROJECT_DIR$/pages" />
<recent name="$PROJECT_DIR$/assets/images" />
<recent name="$PROJECT_DIR$/api" />
<recent name="$PROJECT_DIR$" />
<recent name="$PROJECT_DIR$/src/assets/images" />
@ -82,7 +94,7 @@
<recent name="$PROJECT_DIR$/src/assets" />
</key>
</component>
<component name="RunManager" selected="npm.dev">
<component name="RunManager" selected="npm.generate">
<configuration name="build" type="js.build_tools.npm" temporary="true" nameIsGenerated="true">
<package-json value="$PROJECT_DIR$/package.json" />
<command value="run" />
@ -115,8 +127,8 @@
</configuration>
<recent_temporary>
<list>
<item itemvalue="npm.dev" />
<item itemvalue="npm.generate" />
<item itemvalue="npm.dev" />
<item itemvalue="npm.build" />
</list>
</recent_temporary>
@ -142,7 +154,8 @@
<workItem from="1679887069532" duration="713000" />
<workItem from="1679913811172" duration="1597000" />
<workItem from="1680008447811" duration="223000" />
<workItem from="1680009330616" duration="25078000" />
<workItem from="1680009330616" duration="25356000" />
<workItem from="1680141026158" duration="22126000" />
</task>
<task id="LOCAL-00001" summary="socket">
<created>1680082088939</created>

@ -7,6 +7,9 @@ export default new class Common extends Http<ResOptions<any>> {
private readonly bottomMenu = '/index/bottomMenu'
private readonly search_url = '/index/search'
private readonly login_url = '/user/login'
private readonly carousel_url = '/index/carousel'
private readonly index_url = '/index/index'
private readonly captcha_url = 'http://research.mcnetmart.com/index.php?s=/captcha'
handleUpload(file: any) {
const formData = new FormData();
formData.append('file', file)
@ -27,5 +30,15 @@ export default new class Common extends Http<ResOptions<any>> {
return this.get(this.search_url, params)
}
getCarousel(){
return this.get(this.carousel_url, {category: '首页'})
}
getIndexConfig(){
return this.get(this.index_url)
}
getCaptcha(){
return this.get(this.captcha_url)
}
}

@ -1,3 +1,4 @@
@import "color";
@import "public";
@import 'var/index';

@ -30,3 +30,13 @@ $layout-mix-sider-fixed-z-index: 550;
$preview-comp-z-index: 1000;
$page-footer-z-index: 99;
@mixin ellipsis-line($line){
word-break: break-word;
display: -webkit-box;
-webkit-line-clamp: $line;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
}

@ -15,9 +15,11 @@
</svg>
</el-icon>
<input
ref="inputData"
placeholder="按照关键词搜索"
:value="searchVal"
@input="onInput"
@keydown.enter="handleSearch"
class="mai-input"
type="text"
/>
@ -27,17 +29,32 @@
</template>
<script lang="ts" setup>
const emits = defineEmits(['search'])
const store = useAppStore()
const inputData = ref()
const searchVal = ref('');
const route = useRoute();
const router = useRouter();
const { prefixCls } = useDesign('banner');
function onInput(ev: { target: { value: string; }; }) {
searchVal.value = ev.target.value;
emits('search', ev.target.value);
}
function handleSearch() {
emits('search', searchVal.value);
handleGoSearch()
}
function handleGoSearch() {
store.setSearchVal(searchVal.value)
// if (route.path.includes('/search')) {
// onInput({target: {value: searchVal.value}})
// }else {
if (searchVal.value) {
if (route.path.includes('/search')) {
onInput({target: {value: searchVal.value}})
router.replace({
path: route.path,
query:{
keywords: searchVal.value
}
})
}else {
router.push({
path: '/search' + route.path,
@ -48,6 +65,9 @@
}
}
// }
}
watchEffect(()=>{
if (route.path.includes('/search')) {
searchVal.value = route.query.keywords as string;

@ -1,25 +1,28 @@
<script lang="ts" setup>
const props = defineProps(['title']);
const { prefixCls } = useDesign('banner');
const bannerList = reactive([
{id:1,img:'/_nuxt/assets/images/commonBanner.png'},
{id:2,img:'/_nuxt/assets/images/commonBanner.png'},
{id:3,img:'/_nuxt/assets/images/commonBanner.png'},
{id:4,img:'/_nuxt/assets/images/commonBanner.png'},
]);
</script>
<template>
<div :class="[prefixCls, `${prefixCls}--white`]">
<el-carousel indicator-position="outside">
<el-carousel-item v-for="item in bannerList" :key="item.id">
<img :src="item.img" alt="" />
<a class="block w-full h-full" :target="item.link ? '_blank' : 'javascript:void(0)'" :href="item.link" >
<el-image class="w-full h-full" fit="cover" :src="item.image" alt="" />
</a>
</el-carousel-item>
</el-carousel>
<!-- <img src="~/assets/images/commonBanner.png" alt="" /> -->
<!-- <h2 class="title">{{ props.title }}</h2> -->
</div>
</template>
<script lang="ts" setup>
import commonApi from "~/api/Common";
const props = defineProps(['title']);
const { prefixCls } = useDesign('banner');
const bannerList = ref([]);
(async function getData() {
const {data} = await commonApi.getCarousel()
bannerList.value = data;
}())
</script>
<style lang="scss" scoped>
@import 'banner';
</style>

@ -7,7 +7,7 @@
</nuxt-link>
</div>
<div :class="`${prefixCls}__copyright`"
>Copyright © 2012-2025 北京中海通科技有限公司版权所有每ICP备xxxxxxxxxxxxxxx号
>{{ store.$state.otherConfig?.icp_record }}
</div
>
</el-footer>
@ -17,10 +17,13 @@
const menuList = ref([]);
const {prefixCls} = useDesign('layout-footer');
const {commonApi} = useApi();
const store = useAppStore()
async function getData() {
const menus = await commonApi.getBottomMenu()
const config = await commonApi.getIndexConfig()
menuList.value = menus.data
store.setConfig(config.data)
}
getData()
</script>

@ -15,7 +15,8 @@
<div class="login-action-wrap flex items-center">
<!-- 首页展示搜索按钮 -->
<el-popover popper-class="search-popper" v-if="activeRoute === '/'" placement="bottom-end" :width="434" trigger="click">
<el-popover popper-class="search-popper" v-if="activeRoute === '/'" placement="bottom-end"
:width="434" trigger="click">
<template #reference>
<el-icon>
<el-icon-search/>
@ -30,7 +31,8 @@
/>
</div>
</el-popover>
<el-divider v-if="activeRoute === '/'" direction="vertical" style="border-left: 1px solid #000"/>
<el-divider v-if="activeRoute === '/'" direction="vertical"
style="border-left: 1px solid #000"/>
<div class="login-btn cursor-pointer" v-if="!token" @click="setLoginVisible(true)"></div>
<el-dropdown popper-class="login-popper" @command="handleCommand" v-else trigger="click">
@ -80,6 +82,7 @@ const defaultActive = computed((): string=>{
}
})
function handleCommand(command: string) {
if (command === '5') {
ElMessageBox.confirm(
@ -111,6 +114,7 @@ function handleCommand(command: string) {
})
}
}
function handleChange(val: any) {
store.setSearchVal('')
activeRoute.value = val.path;
@ -128,6 +132,8 @@ function handleChange(val: any) {
}
function handleSearch() {
store.setSearchVal(keyword.value)
if (keyword.value) {
router.push({
path: '/search/index',
query: {
@ -136,6 +142,8 @@ function handleSearch() {
})
}
}
watch(() => route, (val) => {
activeRoute.value = val.path;
if (val.meta.hasOwnProperty('headerHost') && val.meta.headerHost) {
@ -283,26 +291,31 @@ $prefix-cls: '#{$name-prefix}-header-wrap';
border-radius: 30px;
height: 56px;
border: none;
.el-popper__arrow {
display: none;
}
.el-input {
height: 100%;
margin: 0;
border-radius: 30px;
font-size: 20px;
}
.el-input__wrapper {
padding: 0 30px;
height: 56px;
border-radius: 30px;
border: none;
box-shadow: unset;
.el-input__inner {
height: 56px;
box-shadow: unset;
line-height: 56px;
}
.el-icon {
color: #134A9B;
}

@ -33,7 +33,6 @@
import CssP1 from '/assets/tinymce/skins/ui/oxide/content.min.css?inline';
//@ts-ignore
import CssP2 from '/assets/tinymce/skins/ui/oxide/content.min.css?inline';
import { defineProps } from 'vue';
const props = defineProps(['content']);
</script>

@ -19,7 +19,7 @@
:rules="formRules"
ref="formRef"
>
<el-form-item name="account" class="enter-x">
<el-form-item name="account" prop="account" class="enter-x">
<el-input
size="large"
v-model="formData.account"
@ -27,7 +27,7 @@
class="fix-auto-fill"
/>
</el-form-item>
<el-form-item name="password" class="enter-x">
<el-form-item name="password" prop="password" class="enter-x">
<el-input
type="password"
size="large"
@ -35,14 +35,14 @@
placeholder="请输入密码"
/>
</el-form-item>
<el-form-item name="captcha" class="enter-x">
<el-form-item name="captcha" prop="captcha" class="enter-x">
<el-input
size="large"
v-model="formData.captcha"
placeholder="请输入验证码"
>
<template #append>
<img src="~@/assets/images/testCode.jpg" alt="" />
<img class="cursor-pointer" @click="getCode($event)" src="http://research.mcnetmart.com/index.php?s=/captcha" alt="" />
</template>
</el-input>
</el-form-item>
@ -60,11 +60,13 @@
<script lang="ts" setup>
import { computed, reactive, ref, unref } from 'vue';
import {FormInstance} from "element-plus";
const captcha = ref('')
const userStore = useUserInfo();
const title = computed(()=> import.meta.env.VITE_GLOB_APP_TITLE)
const formRules = ref({
account:{message:'请输入用户名', trigger:'blur', required: true},
password: {message:'请输入密码', trigger:'blur', required: true},
captcha: {message:'请输入验证码', trigger:'blur', required: true},
})
const formRef = ref<FormInstance>();
@ -73,10 +75,10 @@ const loading = ref(false);
const formData = reactive({
account: 'test',
password: '123456',
// captcha: '123456',
captcha: '',
});
const prefixCls = useDesign('login');
const { commonApi } = useApi()
async function handleLogin(formEl: FormInstance | undefined) {
if (!formEl) return;
@ -102,6 +104,14 @@ async function handleLogin(formEl: FormInstance | undefined) {
})
}
async function getCode(ev: any){
// this.src = ''
// this.src = ''
ev.target.setAttribute('src', 'http://research.mcnetmart.com/index.php?s=/captcha&u='+ new Date().getTime())
// captcha.value = await commonApi.getCaptcha() as unknown as string;
}
// getCode()
const loginVisible = ref(userStore.getLoginVisible);
watchEffect(()=>{
loginVisible.value = userStore.getLoginVisible;

@ -3,7 +3,6 @@
</template>
<script setup lang="ts">
import { defineProps } from 'vue';
const props = defineProps(['url']);
const router = useRouter();

@ -5,21 +5,23 @@ export interface AppState {
menuTheme: menu;
homeBanner: boolean;
bannerTitle: string;
searchVal?: string
searchVal: string;
otherConfig?: any
}
const useAppStore = defineStore('app', {
state: (): AppState => ({
menuTheme: 'light',
homeBanner: true,
bannerTitle: '',
searchVal: ''
searchVal: '',
otherConfig: {}
}),
getters:{
getMenuTheme: (state)=> state.menuTheme,
getHomeBanner: (state)=> state.homeBanner,
getBannerTitle: (state)=> state.bannerTitle,
getSearchVal: (state)=> state.searchVal,
getSearchVal: (state): string=> state.searchVal,
},
actions: {
@ -34,6 +36,9 @@ const useAppStore = defineStore('app', {
},
setSearchVal(val: string): void{
this.searchVal = val;
},
setConfig(data:any){
this.otherConfig = data;
}
}

@ -51,6 +51,7 @@ const useUserInfo = defineStore('user', {
getLoginVisible:(state)=> state.loginVisible,
getToken:(state)=> state.token,
},
// @ts-ignore
persist: process.client && {
storage: localStorage,
paths: ['info', 'token']

@ -13,26 +13,38 @@
<Login v-if="loginStatus" />
</template>
<script setup>
<script setup lang="ts">
console.log('tabLayout init........')
const store = useAppStore()
const route = useRoute()
const loginStatus = ref(useUserInfo().getLoginVisible)
const searchVal = ref('')
function handleSearch(val) {
function handleSearch(val: string) {
searchVal.value = val
store.setSearchVal(val)
}
watchEffect(()=>{
loginStatus.value = useUserInfo().getLoginVisible;
console.log('loginStatus>>>', loginStatus.value)
})
onMounted(()=>{
if (route.path.includes('/search')) {
searchVal.value = route.query.keywords
console.log('if? tabLayout search init........', route.path, route.query)
// searchVal.value = route.query.keywords as unknown as string;
store.setSearchVal(route.query.keywords as unknown as string)
}
})
watchEffect(()=>{
store.setSearchVal(searchVal.value)
// searchVal.value = route.query.keywords
// console.log('route.query.keywords>>>', route.query.keywords)
// store.setSearchVal(route.query.keywords)
console.log('tabLayout search init........', route.path)
if (route.path.includes('/search')) {
store.setSearchVal(route.query.keywords as unknown as string)
}
})
// console.log()
</script>

@ -55,8 +55,12 @@ export default defineNuxtConfig({
target: 'http://research.mcnetmart.com/uploads',
prependPath: true,
changeOrigin: true,
}
},
"/index.php": {
target: 'http://research.mcnetmart.com/index.php?s=/captcha',
prependPath: true,
changeOrigin: true,
},
}
}
})

@ -0,0 +1,40 @@
<template>
<div :class="[prefixCls, 'flex full relative']">
<div :class="`${prefixCls}-content pt-24`">
<el-breadcrumb style="position: absolute; top: 80px;left: 120px" :separator-icon="ArrowRight">
<el-breadcrumb-item class="text-2xl" :to="{ path: '/tptsps' }">TBT/SPS通报</el-breadcrumb-item>
<el-breadcrumb-item class="text-2xl">TBT/SPS通报详情</el-breadcrumb-item>
</el-breadcrumb>
<HtmlPreview :content="content" />
</div>
</div>
</template>
<script setup lang="ts">
definePageMeta({
name: 'TBT/SPS通报详情',
hidden: true,
headerHost: false,
parentPath: '/tptsps',
// @ts-ignore
path: '/tptsps/:id'
})
useHead({
title:'TBT/SPS通报'
})
import { ArrowRight } from '@element-plus/icons-vue'
useAppStore().setBannerTitle("预警详情")
const {prefixCls} = useDesign('mai-wrap');
const route = useRoute()
const content = ref('')
async function getData() {
const data = await useApi().warningApi.getWarningDetail(route.params.id)
console.log('data.data.info')
content.value = data.data.info.content;
}
getData()
</script>
<style scoped></style>

@ -23,7 +23,7 @@
<div class="media-img">
<img
style="object-fit: cover"
:src="newsHilight.image" alt=""
:src="store.$state.otherConfig?.information_logo" alt=""
/>
</div>
<div class="newsList">
@ -31,7 +31,6 @@
class="news-item flex items-center justify-between"
v-for="item in newsList"
:key="item.id"
@mouseenter="changeCurrentData(item)"
>
<div class="flex items-center c-item">
<div class="date">
@ -152,6 +151,7 @@ const {prefixCls: prefixNews} = useDesign('news-wrap');
const {prefixCls: prefixInform} = useDesign('inform-wrap');
const {prefixCls: prefixRule} = useDesign('rule-wrap');
const {prefixCls: prefixCase} = useDesign('case-wrap');
const store = useAppStore()
const {getToken, setLoginVisible} = useUserInfo()
const classList = reactive({
news: [`${prefixNews} mai-section`],

@ -4,14 +4,37 @@
<mai-tab :active="currentTab.id" :data-source="tabs" @change="handleChange"/>
</div>
<div :class="`${prefixCls}-content dynamicInfo flex flex-col px-8`" style="border-left: 1px solid #d9d9d9;">
<div class="py-8 cursor-pointer select-none" style="border-bottom: 1px solid #d9d9d9;" v-for="item in content" :key="item.id">
<nuxt-link :to="`/rules/${item.id}`">
<h3 class="text-2xl mb-6 w-full overflow-hidden text-ellipsis">{{ item.title }}</h3>
<p class="text-xl text-zinc-500 mb-6">{{ item.description }}</p>
<p class="">{{ dayjs(item.createtime * 1000).format('YYYY-MM-DD hh:mm:ss') }}</p>
<div class="flex flex-wrap" v-if="content.length">
<div class="p-2 rule-item cursor-pointer flex " v-for="item in content" :key="item.id">
<nuxt-link :to="`/rules/${item.id}`" class="w-full">
<el-card :body-style="{ padding: '0px' }">
<div style="padding: 14px">
<p class="mb-6">{{ dayjs(item.createtime * 1000).format('YYYY-MM-DD') }}</p>
<h4 class="text-2xl mb-2 text-ellipsis overflow-hidden"
style=" line-height:30px;height: 30px;display:inline-block">{{
item.title
}}</h4>
<p style="color: #999" class="rule-desc">{{ item.description }}</p>
<div class="bottom">
<el-button round
style="font-size: 18px; color: #022950; border-color: #022950;"><nuxt-link :to="`/rules/${item.id}`">查看详情</nuxt-link>
</el-button>
</div>
</div>
</el-card>
<!-- <h3 class="text-2xl mb-6 w-full overflow-hidden text-ellipsis">{{ item.title }}</h3>-->
<!-- <p class="text-xl text-zinc-500 mb-6">{{ item.description }}</p>-->
<!-- <p class="">{{ dayjs(item.createtime * 1000).format('YYYY-MM-DD hh:mm:ss') }}</p>-->
</nuxt-link>
</div>
</div>
<div v-else>
<el-empty description="暂无数据" />
</div>
<div class="mt-6">
<Pagination
:current="current"
:total="total"
@ -21,6 +44,7 @@
/>
</div>
</div>
</div>
</template>
<script setup lang="ts">
@ -35,7 +59,7 @@ useHead({
title:'法规标准'
})
import {randomUUID} from '~~/utils';
const {setTotal, current, total, setCurrentPage, limit, pagesRef} = usePagination(1, 4, 0)
const {setTotal, current, total, setCurrentPage, limit, pagesRef} = usePagination(1, 6, 0)
const { technicalApi } = useApi()
const {prefixCls} = useDesign('mai-wrap');
@ -78,9 +102,16 @@ async function getData() {
getData()
</script>
<style scoped lang="less">
<style scoped lang="scss">
.dynamicInfo {
margin-top: 0;
padding-bottom: 100px;
}
.rule-item {
width: calc((100% - 60px) / 3);
}
.rule-desc {
min-height: 76px;
@include ellipsis-line(3);
}
</style>

@ -1,14 +1,19 @@
<template>
<section class="mai-wrap">
<div class="mai-container">
<div class="mai-article py-5" v-for="(item, index) in content" :key="index">
<div class="mai-article py-5" v-if="content.length" v-for="(item, index) in content"
:key="index">
<template v-if="searchType === 0">
<nuxt-link :to="categoryNames[item.category_id].path + '/' + item.id">
<div class="article mb-9">
<div class="title flex items-center mb-5">
<h3 class="text-2xl mr-4">{{ item.title }}</h3>
<span class="category text-md px-4 py-1">{{ categoryNames[item.category_id] }}</span>
<span class="category text-md px-4 py-1">{{
categoryNames[item.category_id].name
}}</span>
</div>
<p class="text-gray-400 ">{{ item.description }}</p>
<p class="text-gray-400 ">{{ item.desc }}</p>
</div>
<div class="article-bottom flex justify-between">
@ -18,6 +23,35 @@
}}</a>
<span class="text-gray-400">{{ item.time }}</span>
</div>
</nuxt-link>
</template>
<template v-else>
<nuxt-link :to="'/' + routes[route.path.split('/')[2]] + '/' + item.id">
<div class="article mb-9">
<div class="title flex items-center mb-5">
<h3 class="text-2xl mr-4">{{ item.title }}</h3>
<span class="category text-md px-4 py-1">{{
routes[route.path.split('/')[2]]
}}</span>
</div>
<p class="text-gray-400 ">{{ item.description }}</p>
</div>
<div class="article-bottom flex justify-between">
<a :target="item.fromLink ? '_blank': ''" class="article-link"
:href="item.fromLink ? item.fromLink: 'javascript:void(0);'">文章来源: {{
item.fromDesc
}}</a>
<span class="text-gray-400">{{
dayjs(item.createtime * 1000).format('YYYY-MM-DD hh:mm:ss')
}}</span>
</div>
</nuxt-link>
</template>
</div>
<div v-else>
<el-empty description="暂无数据"/>
</div>
</div>
<div class="mt-32">
@ -33,6 +67,8 @@
</template>
<script setup lang="ts">
import dayjs from "dayjs";
enum Category {
index,
inform,
@ -42,12 +78,33 @@ enum Category {
}
const categoryNames = reactive({
"1": "动态资讯",
"2": "预警信息",
"3": "法律法规",
"4": "TBT/SPS通报"
"1": {
name:"动态资讯",
path: '/inform'
},
"2":{
name:"预警信息",
path: '/warning'
},
"3": {
name:"法律法规",
path: '/rules'
},
"4": {
name:"TBT/SPS通报",
path: '/tptsps'
},
"5":{
name:"案例",
path: '/case'
},
})
const routes = reactive({
"inform": "动态资讯",
"warning": "预警信息",
"rules": "法律法规",
"case": "案例"
})
definePageMeta({
hidden: true,
middleware: ['is-search'],
@ -57,7 +114,7 @@ definePageMeta({
const route = useRoute()
const store = useAppStore()
const searchVal = computed(() => store.getSearchVal)
const {commonApi} = useApi()
const {commonApi, informationApi, warningApi, caseApi} = useApi()
const {setTotal, current, total, setCurrentPage, limit, pagesRef} = usePagination(1, 6, 0)
const content = ref([
@ -80,31 +137,42 @@ function onChangePage(val: number) {
}
async function getList() {
if (searchVal.value) {
let params = {keyword: searchVal.value, page: current.value, limit}
if (searchType.value === 0) {
const {data} = await commonApi.searchApi({keyword: searchVal.value, page: current.value, limit})
content.value = data.list;
setTotal(data.total);
if (data) {
// loading.value = false;
const {data} = await commonApi.searchApi(params)
setData(data.data, data.total)
} else if (route.path === '/search/inform') {
const {data} = await informationApi.getInformationList(params)
setData(data.data, data.total)
} else if (route.path === '/search/warning') {
const {data} = await warningApi.getWarningList(params)
setData(data.data, data.total)
} else if (route.path === '/search/case') {
const {data} = await caseApi.getCaseList(params)
setData(data.data, data.total)
}
}else {
const {data} = await commonApi.searchApi({keyword: searchVal.value, page: current.value, limit, category_id: searchType.value})
content.value = data.list;
setTotal(data.total);
if (data) {
// loading.value = false;
}
}
function setData(data: Array<any>, total: number) {
content.value = data;
setTotal(total);
}
// onMounted(()=>{
// getList()
// })
//
// watch(() => store.$state.searchVal, () => {
// })
watchEffect(() => {
searchType.value = Category[route.params.id as unknown as any] as unknown as number;
console.log(searchType.value )
onChangePage(1)
getList()
})
</script>
<style lang="scss" scoped>
@ -120,6 +188,7 @@ watchEffect(() => {
.article-link {
color: #0055AB;
}
.category {
color: #022950;
border-radius: 8px;

@ -30,7 +30,7 @@
</el-row>
</el-form>
<el-table v-loading="loading" size="large" border :data="content" :empty-text="'暂无数据'"
:header-cell-style="{background: '#f5f5f5', color:'#333333'}">
:header-cell-style="{background: '#f5f5f5', color:'#333333'}" @cellClick="handleCellClick">
<el-table-column show-overflow-tooltip align="center" label="通报号"
prop="notification_number"></el-table-column>
<el-table-column show-overflow-tooltip align="center" label="通报标题"
@ -61,7 +61,6 @@
import {randomUUID} from '~~/utils';
import dayjs from "dayjs";
import {useThrottleFn} from "@vueuse/core";
definePageMeta({
name: 'TBT/SPS通报',
@ -91,7 +90,7 @@ const currentTab = ref({});
const content = ref([]);
const loading = ref(true);
const {setTotal, current, total, setCurrentPage, limit, pagesRef} = usePagination(1, 6, 0)
const router = useRouter();
const searchData = ref({
notifying_members: '',
notification_time: '',
@ -99,6 +98,12 @@ const searchData = ref({
product: '',
})
function handleCellClick(data: any) {
router.push({
path: '/tptsps/'+ data.id
})
}
function resetData(flag: boolean = true) {
searchData.value = {
notifying_members: '',

@ -64,7 +64,7 @@ const {setTotal, current, total, setCurrentPage, limit, pagesRef} = usePaginatio
const tabs = ref([
{
name: '动态资讯',
name: '预警信息',
id: randomUUID(),
children: [
{name: 'WTO资讯', id: randomUUID()},

@ -47,9 +47,13 @@ const fetch = $fetch.create({
// 响应拦截
onResponse(ctx) {
const {response} = ctx;
console.log('response>>>>>', ctx)
let data = response._data;
console.log('data.type>>>', data.type)
// 在这里判断错误
if (data.code != 1) {
if (data.type && data.type.includes('image')) {
return data;
}else if (data.code != 1) {
transform(ctx)
return Promise.reject(ctx)
}

Loading…
Cancel
Save