团市委web 初始化
16
.eslintrc.js
Normal file
@ -0,0 +1,16 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
parser: 'vue-eslint-parser',
|
||||
parserOptions: {
|
||||
parser: '@typescript-eslint/parser',
|
||||
},
|
||||
extends: ['plugin:vue/vue3-recommended', 'plugin:prettier/recommended'],
|
||||
rules: {
|
||||
'vue/no-v-html': 'off',
|
||||
'vue/v-on-event-hyphenation': 0,
|
||||
'vue/no-template-shadow': 0,
|
||||
'vue/no-setup-props-destructure': 'off',
|
||||
'@intlify/vue-i18n/no-html-messages': 'off',
|
||||
'vue/multi-word-component-names': 0,
|
||||
},
|
||||
}
|
25
.gitignore
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
# Nuxt dev/build outputs
|
||||
.output
|
||||
.data
|
||||
.nuxt
|
||||
.nitro
|
||||
.cache
|
||||
dist
|
||||
|
||||
# Node dependencies
|
||||
node_modules
|
||||
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
|
||||
# Misc
|
||||
.DS_Store
|
||||
.fleet
|
||||
.idea
|
||||
|
||||
# Local env files
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
.vscode
|
15
.prettierignore
Normal file
@ -0,0 +1,15 @@
|
||||
/dist
|
||||
/node_modules
|
||||
*.yml
|
||||
*.yaml
|
||||
tsconfig.json
|
||||
*.svg
|
||||
*.png
|
||||
*.jpg
|
||||
*.jpeg
|
||||
*.scss
|
||||
*.gif
|
||||
*.webp
|
||||
*.ttf
|
||||
index.html
|
||||
*.md
|
12
.prettierrc.js
Normal file
@ -0,0 +1,12 @@
|
||||
module.exports = {
|
||||
singleQuote: true, // 使用单引号代替双引号
|
||||
printWidth: 200, // 超过最大值换行
|
||||
semi: false, // 结尾不用分号
|
||||
useTabs: true, // 缩进使用tab, 不使用空格
|
||||
tabWidth: 4, // tab 样式宽度
|
||||
bracketSpacing: true, // 对象数组, 文字间加空格 {a: 1} => { a: 1 }
|
||||
arrowParens: 'avoid', // 如果可以, 自动去除括号 (x) => x 变为 x => x
|
||||
proseWrap: 'preserve',
|
||||
htmlWhitespaceSensitivity: 'ignore',
|
||||
trailingComma: 'all',
|
||||
}
|
43
LICENSE
Normal file
@ -0,0 +1,43 @@
|
||||
Academic Free License (“AFL”) v. 3.0
|
||||
|
||||
This Academic Free License (the "License") applies to any original work of authorship (the "Original Work") whose owner (the "Licensor") has placed the following licensing notice adjacent to the copyright notice for the Original Work:
|
||||
|
||||
Licensed under the Academic Free License version 3.0
|
||||
|
||||
1) Grant of Copyright License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, for the duration of the copyright, to do the following:
|
||||
|
||||
a) to reproduce the Original Work in copies, either alone or as part of a collective work;
|
||||
b) to translate, adapt, alter, transform, modify, or arrange the Original Work, thereby creating derivative works ("Derivative Works") based upon the Original Work;
|
||||
c) to distribute or communicate copies of the Original Work and Derivative Works to the public, under any license of your choice that does not contradict the terms and conditions, including Licensor’s reserved rights and remedies, in this Academic Free License;
|
||||
d) to perform the Original Work publicly; and
|
||||
e) to display the Original Work publicly.
|
||||
|
||||
2) Grant of Patent License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, under patent claims owned or controlled by the Licensor that are embodied in the Original Work as furnished by the Licensor, for the duration of the patents, to make, use, sell, offer for sale, have made, and import the Original Work and Derivative Works.
|
||||
|
||||
3) Grant of Source Code License. The term "Source Code" means the preferred form of the Original Work for making modifications to it and all available documentation describing how to modify the Original Work. Licensor agrees to provide a machine-readable copy of the Source Code of the Original Work along with each copy of the Original Work that Licensor distributes. Licensor reserves the right to satisfy this obligation by placing a machine-readable copy of the Source Code in an information repository reasonably calculated to permit inexpensive and convenient access by You for as long as Licensor continues to distribute the Original Work.
|
||||
|
||||
4) Exclusions From License Grant. Neither the names of Licensor, nor the names of any contributors to the Original Work, nor any of their trademarks or service marks, may be used to endorse or promote products derived from this Original Work without express prior permission of the Licensor. Except as expressly stated herein, nothing in this License grants any license to Licensor’s trademarks, copyrights, patents, trade secrets or any other intellectual property. No patent license is granted to make, use, sell, offer for sale, have made, or import embodiments of any patent claims other than the licensed claims defined in Section 2. No license is granted to the trademarks of Licensor even if such marks are included in the Original Work. Nothing in this License shall be interpreted to prohibit Licensor from licensing under terms different from this License any Original Work that Licensor otherwise would have a right to license.
|
||||
|
||||
5) External Deployment. The term "External Deployment" means the use, distribution, or communication of the Original Work or Derivative Works in any way such that the Original Work or Derivative Works may be used by anyone other than You, whether those works are distributed or communicated to those persons or made available as an application intended for use over a network. As an express condition for the grants of license hereunder, You must treat any External Deployment by You of the Original Work or a Derivative Work as a distribution under section 1(c).
|
||||
|
||||
6) Attribution Rights. You must retain, in the Source Code of any Derivative Works that You create, all copyright, patent, or trademark notices from the Source Code of the Original Work, as well as any notices of licensing and any descriptive text identified therein as an "Attribution Notice." You must cause the Source Code for any Derivative Works that You create to carry a prominent Attribution Notice reasonably calculated to inform recipients that You have modified the Original Work.
|
||||
|
||||
7) Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that the copyright in and to the Original Work and the patent rights granted herein by Licensor are owned by the Licensor or are sublicensed to You under the terms of this License with the permission of the contributor(s) of those copyrights and patent rights. Except as expressly stated in the immediately preceding sentence, the Original Work is provided under this License on an "AS IS" BASIS and WITHOUT WARRANTY, either express or implied, including, without limitation, the warranties of non-infringement, merchantability or fitness for a particular purpose. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No license to the Original Work is granted by this License except under this disclaimer.
|
||||
|
||||
8) Limitation of Liability. Under no circumstances and under no legal theory, whether in tort (including negligence), contract, or otherwise, shall the Licensor be liable to anyone for any indirect, special, incidental, or consequential damages of any character arising as a result of this License or the use of the Original Work including, without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses. This limitation of liability shall not apply to the extent applicable law prohibits such limitation.
|
||||
|
||||
9) Acceptance and Termination. If, at any time, You expressly assented to this License, that assent indicates your clear and irrevocable acceptance of this License and all of its terms and conditions. If You distribute or communicate copies of the Original Work or a Derivative Work, You must make a reasonable effort under the circumstances to obtain the express assent of recipients to the terms of this License. This License conditions your rights to undertake the activities listed in Section 1, including your right to create Derivative Works based upon the Original Work, and doing so without honoring these terms and conditions is prohibited by copyright law and international treaty. Nothing in this License is intended to affect copyright exceptions and limitations (including “fair use” or “fair dealing”). This License shall terminate immediately and You may no longer exercise any of the rights granted to You by this License upon your failure to honor the conditions in Section 1(c).
|
||||
|
||||
10) Termination for Patent Action. This License shall terminate automatically and You may no longer exercise any of the rights granted to You by this License as of the date You commence an action, including a cross-claim or counterclaim, against Licensor or any licensee alleging that the Original Work infringes a patent. This termination provision shall not apply for an action alleging patent infringement by combinations of the Original Work with other software or hardware.
|
||||
|
||||
11) Jurisdiction, Venue and Governing Law. Any action or suit relating to this License may be brought only in the courts of a jurisdiction wherein the Licensor resides or in which Licensor conducts its primary business, and under the laws of that jurisdiction excluding its conflict-of-law provisions. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any use of the Original Work outside the scope of this License or after its termination shall be subject to the requirements and penalties of copyright or patent law in the appropriate jurisdiction. This section shall survive the termination of this License.
|
||||
|
||||
12) Attorneys’ Fees. In any action to enforce the terms of this License or seeking damages relating thereto, the prevailing party shall be entitled to recover its costs and expenses, including, without limitation, reasonable attorneys' fees and costs incurred in connection with such action, including any appeal of such action. This section shall survive the termination of this License.
|
||||
|
||||
13) Miscellaneous. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable.
|
||||
|
||||
14) Definition of "You" in This License. "You" throughout this License, whether in upper or lower case, means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, "You" includes any entity that controls, is controlled by, or is under common control with you. For purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
15) Right to Use. You may use the Original Work in all ways not otherwise restricted or conditioned by this License or by law, and Licensor promises not to interfere with or be responsible for such uses by You.
|
||||
|
||||
16) Modification of This License. This License is Copyright © 2005 Lawrence Rosen. Permission is granted to copy, distribute, or communicate this License without modification. Nothing in this License permits You to modify this License as applied to the Original Work or to Derivative Works. However, You may modify the text of this License and copy, distribute or communicate your modified version (the "Modified License") and apply it to other original works of authorship subject to the following conditions: (i) You may not indicate in any way that your Modified License is the "Academic Free License" or "AFL" and you may not use those names in the name of your Modified License; (ii) You must replace the notice specified in the first paragraph above with the notice "Licensed under <insert your license name here>" or with a notice of your own that is not confusingly similar to the notice in this License; and (iii) You may not claim that your original works are open source software unless your Modified License has been approved by Open Source Initiative (OSI) and You comply with its license review and certification process.
|
58
README-CDN.md
Normal file
@ -0,0 +1,58 @@
|
||||
# 团市委官网3.0 - CDN图片处理指南
|
||||
|
||||
## 静态生成模式下的CDN图片处理
|
||||
|
||||
本项目已配置为支持在使用 `nuxt generate` 静态生成模式下自动处理图片CDN路径。以下是相关功能和使用方法的说明。
|
||||
|
||||
### 配置说明
|
||||
|
||||
1. CDN基础URL已配置为 `https://cdn.web.0rui.cn/`
|
||||
2. 在 `nuxt.config.ts` 中已添加相关配置
|
||||
3. 创建了专用的CDN图片处理插件和组件
|
||||
|
||||
### 使用方法
|
||||
|
||||
#### 方法一:使用CdnImage组件(推荐)
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<!-- 使用CdnImage组件自动处理CDN路径 -->
|
||||
<CdnImage src="public/img/logo.png" class="image_1" referrerpolicy="no-referrer" />
|
||||
</template>
|
||||
```
|
||||
|
||||
#### 方法二:使用全局$cdnImage方法
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<img :src="$cdnImage('public/img/logo.png')" class="image_1" referrerpolicy="no-referrer" />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const { $cdnImage } = useNuxtApp()
|
||||
</script>
|
||||
```
|
||||
|
||||
### 路径处理规则
|
||||
|
||||
- 以 `public/` 开头的路径会自动转换为 `https://cdn.web.0rui.cn/img/...`
|
||||
- 已经是完整URL的路径(以http://或https://开头)不会被修改
|
||||
- 其他路径会直接拼接CDN基础URL
|
||||
|
||||
### 开发与生产环境
|
||||
|
||||
- 在开发环境中,默认使用本地路径,不进行CDN转换
|
||||
- 在生产环境(静态生成)中,自动应用CDN路径
|
||||
- 如需在开发环境中测试CDN路径,可以使用 `<CdnImage src="..." :forceCdn="true" />` 强制启用CDN
|
||||
|
||||
### 静态生成命令
|
||||
|
||||
```bash
|
||||
# 生成静态网站
|
||||
npm run generate
|
||||
|
||||
# 预览生成的静态网站
|
||||
npm run preview
|
||||
```
|
||||
|
||||
生成的静态文件将位于 `.output/public` 目录中,可以部署到任何静态文件服务器。
|
77
README.md
@ -1,3 +1,76 @@
|
||||
# tuanshiwei-web
|
||||
# 项目CDN配置
|
||||
1.修改nuxt.config.ts中的 cdnDomain
|
||||
|
||||
团市委官网
|
||||
2.修改assets/css/common.scss中的定义数据
|
||||
|
||||
## Setup
|
||||
|
||||
Make sure to install the dependencies:
|
||||
|
||||
```bash
|
||||
# npm
|
||||
npm install
|
||||
|
||||
# pnpm
|
||||
pnpm install
|
||||
|
||||
# yarn
|
||||
yarn install
|
||||
|
||||
# bun
|
||||
bun install
|
||||
```
|
||||
|
||||
## Development Server
|
||||
|
||||
Start the development server on `http://localhost:3000`:
|
||||
|
||||
```bash
|
||||
# npm
|
||||
npm run dev
|
||||
|
||||
# pnpm
|
||||
pnpm run dev
|
||||
|
||||
# yarn
|
||||
yarn dev
|
||||
|
||||
# bun
|
||||
bun run dev
|
||||
```
|
||||
|
||||
## Production
|
||||
|
||||
Build the application for production:
|
||||
|
||||
```bash
|
||||
# npm
|
||||
npm run build
|
||||
|
||||
# pnpm
|
||||
pnpm run build
|
||||
|
||||
# yarn
|
||||
yarn build
|
||||
|
||||
# bun
|
||||
bun run build
|
||||
```
|
||||
|
||||
Locally preview production build:
|
||||
|
||||
```bash
|
||||
# npm
|
||||
npm run preview
|
||||
|
||||
# pnpm
|
||||
pnpm run preview
|
||||
|
||||
# yarn
|
||||
yarn preview
|
||||
|
||||
# bun
|
||||
bun run preview
|
||||
```
|
||||
|
||||
Check out the [deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information.
|
||||
|
73
app.vue
Normal file
@ -0,0 +1,73 @@
|
||||
<template>
|
||||
<n-config-provider :locale="zhCN">
|
||||
<!-- <AppHeader /> -->
|
||||
<NuxtPage />
|
||||
<!-- <AppFooter /> -->
|
||||
</n-config-provider>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { NConfigProvider } from 'naive-ui'
|
||||
import { zhCN, dateZhCN } from 'naive-ui'
|
||||
import $api from '@/service/webRequest'
|
||||
import { useStore } from '~/store'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
const { locale } = useI18n()
|
||||
useSeoMeta({
|
||||
title: '中国共产主义青年团洛阳市委员会',
|
||||
ogTitle: '中国共产主义青年团洛阳市委员会',
|
||||
description: '中国共产主义青年团洛阳市委员会',
|
||||
ogDescription: '中国共产主义青年团洛阳市委员会',
|
||||
ogImage: 'https://example.com/image.png',
|
||||
twitterCard: 'summary_large_image',
|
||||
})
|
||||
const store = useStore()
|
||||
onMounted(() => {
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
#__nuxt {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
scroll-behavior: smooth;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
background: #eee;
|
||||
font-family: Helvetica Neue, Helvetica, Arial, sans-serif;
|
||||
font-size: 14px;
|
||||
color: #000;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background: linear-gradient(90deg, #434343, #434343 1px, #111 0, #111);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: linear-gradient(180deg, #434343, #111);
|
||||
border-radius: 6px;
|
||||
box-shadow: inset 2px 2px 2px rgba(255, 255, 255, 0.25),
|
||||
inset -2px -2px 2px rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: linear-gradient(180deg, #e52e71, #ff8a00);
|
||||
}
|
||||
|
||||
|
||||
</style>
|
44
assets/animate/animate.js
Normal file
@ -0,0 +1,44 @@
|
||||
export function swiperAnimateCache() {
|
||||
const allBoxes = window.document.documentElement.querySelectorAll('.ani')
|
||||
for (var i = 0; i < allBoxes.length; i++) {
|
||||
allBoxes[i].attributes['style']
|
||||
? allBoxes[i].setAttribute('swiper-animate-style-cache', allBoxes[i].attributes['style'].value)
|
||||
: allBoxes[i].setAttribute('swiper-animate-style-cache', ' ')
|
||||
allBoxes[i].style.visibility = 'hidden'
|
||||
}
|
||||
}
|
||||
|
||||
export function swiperAnimate(a) {
|
||||
clearSwiperAnimate()
|
||||
var b = a.slides[a.activeIndex].querySelectorAll('.ani')
|
||||
for (var i = 0; i < b.length; i++) {
|
||||
b[i].style.visibility = 'visible'
|
||||
const effect = b[i].attributes['swiper-animate-effect']
|
||||
? b[i].attributes['swiper-animate-effect'].value
|
||||
: ''
|
||||
b[i].className = b[i].className + ' ' + effect + ' ' + 'animated'
|
||||
const duration = b[i].attributes['swiper-animate-duration']
|
||||
? b[i].attributes['swiper-animate-duration'].value
|
||||
: ''
|
||||
// duration && style
|
||||
const delay = b[i].attributes['swiper-animate-delay']
|
||||
? b[i].attributes['swiper-animate-delay'].value
|
||||
: ''
|
||||
const style = b[i].attributes['style'].value + 'animation-duration:' + duration + ';-webkit-animation-duration:' + duration + ';' + 'animation-delay:' + delay + ';-webkit-animation-delay:' + delay + ';'
|
||||
// delay && (style = style )
|
||||
b[i].setAttribute('style', style)
|
||||
}
|
||||
}
|
||||
|
||||
export function clearSwiperAnimate() {
|
||||
var allBoxes = window.document.documentElement.querySelectorAll('.ani')
|
||||
for (var i = 0; i < allBoxes.length; i++) {
|
||||
allBoxes[i].attributes['swiper-animate-style-cache'] && allBoxes[i].setAttribute('style', allBoxes[i].attributes['swiper-animate-style-cache'].value)
|
||||
allBoxes[i].style.visibility = 'hidden'
|
||||
allBoxes[i].className = allBoxes[i].className.replace('animated', ' ')
|
||||
const effectValue = allBoxes[i].attributes['swiper-animate-effect'].value
|
||||
/* eslint-disable-next-line */
|
||||
allBoxes[i].attributes['swiper-animate-effect'] && (effectValue, allBoxes[i].className = allBoxes[i].className.replace(effectValue, ' '))
|
||||
}
|
||||
}
|
||||
|
6
assets/animate/animate.min.css
vendored
Normal file
32
assets/css/common.scss
Normal file
@ -0,0 +1,32 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
:root {
|
||||
--bg-t2: url('https://cdn.web.0rui.cn/img/t2.png');
|
||||
--bg-c: url('https://cdn.web.0rui.cn/img/bg-c.png');
|
||||
--m1: url('https://cdn.web.0rui.cn/img/m1.png');
|
||||
--bg-b: url('https://cdn.web.0rui.cn/img/bg-b.png');
|
||||
--bg-4: url('https://cdn.web.0rui.cn/img/bg-4.png');
|
||||
--bg-5: url('https://cdn.web.0rui.cn/img/bg-5.png');
|
||||
--qall: url('https://cdn.web.0rui.cn/img/qall.png');
|
||||
--close: url('https://cdn.web.0rui.cn/img/close.png');
|
||||
--t1a: url('https://cdn.web.0rui.cn/img/about/t1a.png');
|
||||
--t1b: url('https://cdn.web.0rui.cn/img/about/t1b.png');
|
||||
--ruanzhu: url('https://cdn.web.0rui.cn/img/about/ruanzhu.png');
|
||||
--allpeople: url('https://cdn.web.0rui.cn/img/allpeople.png');
|
||||
--lianxiyp: url('https://cdn.web.0rui.cn/img/lianxiyp.png');
|
||||
--bg-s: url('https://cdn.web.0rui.cn/img/customer/bg-s.png');
|
||||
--service_023: url('https://cdn.web.0rui.cn/img/service_023.png');
|
||||
--service_033: url('https://cdn.web.0rui.cn/img/service_033.png');
|
||||
--service_048: url('https://cdn.web.0rui.cn/img/service_048.png');
|
||||
--service_033: url('https://cdn.web.0rui.cn/img/service_033.png');
|
||||
--service_051: url('https://cdn.web.0rui.cn/img/service_051.png');
|
||||
--content_top: url('https://cdn.web.0rui.cn/img/content_top.png');
|
||||
--video: url('https://cdn.web.0rui.cn/img/video.png');
|
||||
--wechat1: url('https://cdn.web.0rui.cn/img/wechat1.png');
|
||||
--newstop: url('https://cdn.web.0rui.cn/img/societyduty/newstop.png');
|
||||
}
|
||||
// const cdnUrl = useCdn()
|
||||
|
||||
// ${cdnUrl}
|
1992
assets/index.scss
Normal file
209
components/AppAbout.vue
Normal file
@ -0,0 +1,209 @@
|
||||
<template>
|
||||
<!-- PC端布局 -->
|
||||
<div class="flex justify-between w-full h-full" >
|
||||
<!-- 左边导航栏 -->
|
||||
|
||||
|
||||
<!-- 右边内容栏 -->
|
||||
<div class="rightcon">
|
||||
<div class="ab_top">
|
||||
<div class="ab_col"></div>
|
||||
<div class="ab_tit">团市委职责</div>
|
||||
<div class="ab_col"></div>
|
||||
</div>
|
||||
|
||||
<div class="ab_con">
|
||||
<div>
|
||||
<img src="/img/about/cpc.png" alt="">
|
||||
</div>
|
||||
<div style="margin-left: 100px;">
|
||||
<img src="/img/about/cpcrit.png" alt="">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ab_top" style="margin-top: 30px;">
|
||||
<div class="ab_col"></div>
|
||||
<div class="ab_tit">各部门职能</div>
|
||||
<div class="ab_col"></div>
|
||||
</div>
|
||||
|
||||
<div class="ab_bot" style="margin-top: 10px;">
|
||||
<div class="ab_bot_item" v-for="(item, index) in bmList" :key="index" @mouseenter="mouseenters(index)" >
|
||||
<div class="ab_bot_item_tit">{{item.title}}</div>
|
||||
<div class="ab_bot_item_con three-line-ellipsis">{{item.content}}</div>
|
||||
<div class="ab_bot_item_tel" v-if="item.abshow">
|
||||
<img class="img_tl" src="/img/about/telp.png" alt="">
|
||||
<div class="span_tl">电话:{{item.telnum}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 右分享 -->
|
||||
<!-- <div style="position: absolute;top: 300px;right:36px;" class="flex flex-col fiximg">
|
||||
<img :src="`/img/index/douyin.png`" alt="">
|
||||
<img :src="`/img/index/wb.png`" alt="">
|
||||
<img :src="`/img/index/wx.png`" alt="">
|
||||
<img :src="`/img/index/blbl.png`" alt="">
|
||||
</div> -->
|
||||
<!-- 底部鼠标 -->
|
||||
<div style="position: absolute;bottom: 30px;right:30px;">
|
||||
<img :src="`/img/index/hmouse.png`" alt="">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
const bmList = ref([
|
||||
{ abshow:false,title: '办公室', telnum: '63225071', content: '协调处理机关日常事务;负责团市委重要会议的会务工作;负责机关文秘、信访、保密、网络工作;负责编发内部信息、简报工作;指导全市共青团的调查研究工作;负责对外联系、机关财务、资产、行政后勤等管理工作。' },
|
||||
{ abshow:false,title: '组织部', telnum: '63225070', content: '研究制定全市共青团组织、团干部和团员队伍建设的政策措施;指导推动全市团的基层组织、团员队伍和团干部队伍建设;负责团费收缴、管理和全市团的基层组织统计工作;组织开展全市性先进基层团组织和优秀团员、优秀团干部的评选表彰工作;指导推动团的基层阵地建设和基层组织信息化工作;协助党委管理县级团委的领导班子成员;协助管理在洛的团中央委员、候补委员和团省委委员、候补委员;指导全市团干部的教育培训;负责团市委机关和直属单位的人事管理、机构编制等工作;负责离退休人员的管理服务工作。' },
|
||||
{ abshow:false,title: '宣传部', telnum: '63225062', content: '组织指导全市团员青年的思想道德教育和全市团组织的文化活动;加强青年理想信念教育,引导全市广大青少年践行社会主义核心价值观;指导全市团的宣传工作;指导团员青年理论学习;提供和编写团干部教育材料和团课教材;强化青少年网络思想引领工作,提升网络舆情分析和引导能力;指导青少年活动阵地建设和青少年开展健康有益的活动;负责团市委的新闻、宣传工作,抓好团的宣传队伍建设。' },
|
||||
{ abshow:false,title: '青年发展部', telnum: '63225069', content: '研究制订促进全市青年发展的规划和政策措施,建立和完善青年服务体系;开展促进全市青年就业、创业、创新、创优和全市青年职业文明素养培养、技能培训提升等工作;指导洛阳市青年企业家协会、洛阳市青年农民专业合作社联合会等有关社会团体工作;组织实施对团市委定点扶贫地区的帮扶工作。' },
|
||||
{ abshow:false,title: '学校部(维护青少年权益部)', telnum: '63225067', content: '组织指导全市大中专院校、中学共青团工作,了解掌握学生的思想动态,根据党的教育方针开展团的各项活动;指导青年学生开展社会实践、勤工助学和课外科技、文化活动;培养青年学生创新意识和科技创新能力,推进大学生素质教育;负责市学联的日常事务工作;指导全市少先队工作,研究少年儿童的思想品德教育,协调和配合社会有关部门调查研究,反映情况,制定政策和措施;指导少先队校外阵地建设,组织开展有利于少年儿童健康成长的文化、体育活动;负责少先队宣传工作;抓好少先队辅导员队伍建设;负责少先队洛阳市工作委员会的日常事务工作;宣传贯彻《河南省未成年人保护条例》,负责全市未成年人权益保护工作;负责预防全市青少年违法犯罪工作;研究全市有关青少年发展问题,参与制定保护青少年健康成长的法规、政策;协调处理侵害青少年权益案件;指导青少年社会化服务体系建设;指导青少年报刊工作;承担市未成年人保护委员会办公室的日常工作。' },
|
||||
{ abshow:false,title: '统战联络部', telnum: '63225102', content: '负责全市青年统战工作,在各族各界青年代表人士中开展联谊和交流工作;负责市青联的日常事务及会员团体和委员的联络工作;协助管理在洛全国青联成员、省青联委员;开展青年科技人才和青年留学人员的联系服务工作;开展对台港澳地区青年及青年侨胞的统战工作;负责全市青少年外事工作,开展同国外、境外青少年组织的联络和交流活动。' },
|
||||
{ abshow:false,title: '社会联络部', telnum: '63230538', content: '研究制订全市共青团、青年社会组织参与社会建设的总体规划和政策制度;开展对全市青年社会组织和新兴青年群体的联系服务和引导工作;研究制订全市青年志愿服务工作规划、意见,指导全市青年志愿服务工作;指导建设全市青少年事务社会工作专业人才队伍;协调、指导全市青少年生态环境保护工作;承担全市性青年社团组织的指导和管理工作。' },
|
||||
{ abshow:false,title: '机关党总支', telnum: '63235856', content: '负责机关和直属单位的党群工作。' }
|
||||
|
||||
]);
|
||||
const mouseenters = (index: number) => {
|
||||
bmList.value.forEach((item, index) => {
|
||||
item.abshow = false;
|
||||
})
|
||||
bmList.value[index].abshow = true;
|
||||
}
|
||||
onMounted(() => {
|
||||
// 挂载方法
|
||||
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '@/assets/index.scss';
|
||||
|
||||
|
||||
/* pc端样式 */
|
||||
|
||||
.rightcon{
|
||||
width:1920px;
|
||||
height: 919px;
|
||||
background-image: url('/img/about/ab_bg.png');
|
||||
background-size: 100% 100%;
|
||||
.fiximg{
|
||||
img{
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
}
|
||||
.ab_top{
|
||||
width: 1200px;
|
||||
height: 40px;
|
||||
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-left: 400px;
|
||||
margin-top: 30px;
|
||||
.ab_tit{
|
||||
font-family: Microsoft YaHei;
|
||||
font-weight: bold;
|
||||
font-size: 36px;
|
||||
color: #4E3C3C;
|
||||
margin: 0 30px;
|
||||
}
|
||||
.ab_col{
|
||||
width: 78px;
|
||||
height: 3px;
|
||||
background: #348CDD;
|
||||
}
|
||||
}
|
||||
.ab_con{
|
||||
width:1200px;
|
||||
height: 350px;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-top: 30px;
|
||||
margin-left: 400px;
|
||||
img{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
.ab_bot{
|
||||
width: 1200px;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
flex-wrap: wrap;
|
||||
margin-left: 400px;
|
||||
.ab_bot_item{
|
||||
width: 296px;
|
||||
height: 180px;
|
||||
margin-top: 10px;
|
||||
background-image: url('/img/about/ab_bot.png');
|
||||
background-size: 100% 100%;
|
||||
position: relative;
|
||||
|
||||
.ab_bot_item_tit{
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
font-family: Microsoft YaHei UI;
|
||||
font-weight: 400;
|
||||
font-size: 18px;
|
||||
color: #222222;
|
||||
margin-top: 20px;
|
||||
}
|
||||
.ab_bot_item_con{
|
||||
width: 224px;
|
||||
height: 64px;
|
||||
font-family: Microsoft YaHei UI;
|
||||
font-weight: 400;
|
||||
font-size: 14px;
|
||||
color: #666666;
|
||||
margin:0 auto;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.ab_bot_item_tel{
|
||||
position: absolute;
|
||||
top: 0;left: 0;
|
||||
background-image: url('/img/about/ab_bots.png');
|
||||
background-size: 100% 100%;
|
||||
width: 296px;
|
||||
height: 189px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
.img_tl{
|
||||
margin-top: 40px;
|
||||
width: 46px;
|
||||
height: 46px;
|
||||
}
|
||||
.span_tl{
|
||||
width: 100%;
|
||||
font-family: Microsoft YaHei UI;
|
||||
font-weight: 400;
|
||||
font-size: 18px;
|
||||
color: #FFFEFE;
|
||||
text-align: center;
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
&:hover{
|
||||
cursor: pointer;
|
||||
.ab_bot_item_tit{
|
||||
color: #53A5E4;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</style>
|
141
components/AppFooter.vue
Normal file
@ -0,0 +1,141 @@
|
||||
<template>
|
||||
<!-- PC端布局 -->
|
||||
<div class="group_30 flex-col pc-footer">
|
||||
<div class="text-wrapper_13 flex-row">
|
||||
<NuxtLink to="/">
|
||||
<span class="text_67">企业首页</span>
|
||||
</NuxtLink>
|
||||
<NuxtLink to="/proServices/">
|
||||
<span class="text_68">产品&服务</span>
|
||||
</NuxtLink>
|
||||
<NuxtLink to="/aboutUs/">
|
||||
<span class="text_69">灵睿&我们</span>
|
||||
</NuxtLink>
|
||||
<NuxtLink to="/customerReviews/">
|
||||
<span class="text_70">客户&评价</span>
|
||||
</NuxtLink>
|
||||
<NuxtLink to="/societyDuty/">
|
||||
<span class="text_71">社会&责任</span>
|
||||
</NuxtLink>
|
||||
<NuxtLink to="/concatUs/">
|
||||
<span class="text_72">加入我们</span>
|
||||
</NuxtLink>
|
||||
<span class="text_73">联系电话:400-080-0379</span>
|
||||
</div>
|
||||
<div class="group_31 flex-col"></div>
|
||||
<div class="group_32 flex-row">
|
||||
<div class="text-wrapper_14 flex-col">
|
||||
<span class="text_74">
|
||||
洛阳灵睿网络技术有限公司|洛阳网络公司|洛阳网络推广|洛阳易站通总代理|洛阳本地自媒体|洛阳短视频
|
||||
</span>
|
||||
<span class="text_75">法律顾问:河南森合律师事务机构</span>
|
||||
<span class="text_76">
|
||||
©2021 洛阳灵睿网络技术有限公司 All rights reserved.豫ICP备15023627号-3
|
||||
</span>
|
||||
<span class="text_77">
|
||||
洛阳公司地址:洛阳市 洛龙区 世贸中心D座1816室
|
||||
</span>
|
||||
</div>
|
||||
<img class="image_29" referrerpolicy="no-referrer"
|
||||
src="public/img/wb.png" />
|
||||
<img class="image_30" referrerpolicy="no-referrer"
|
||||
src="public/img/wx.png" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 移动端布局 -->
|
||||
<div class="mobile-footer flex-col">
|
||||
<div class="mobile-nav flex-col">
|
||||
<span class="mobile-nav-item">企业首页</span>
|
||||
<span class="mobile-nav-item">产品&服务</span>
|
||||
<span class="mobile-nav-item">灵睿&我们</span>
|
||||
<span class="mobile-nav-item">客户&评价</span>
|
||||
<span class="mobile-nav-item">社会&责任</span>
|
||||
<span class="mobile-nav-item">联系我们</span>
|
||||
<span class="mobile-contact">联系电话:400-080-0379</span>
|
||||
</div>
|
||||
<div class="mobile-info flex-col">
|
||||
<span class="mobile-company">洛阳灵睿网络技术有限公司</span>
|
||||
<span class="mobile-legal">法律顾问:河南森合律师事务机构</span>
|
||||
<span class="mobile-copyright">©2021 洛阳灵睿网络技术有限公司 All rights reserved.</span>
|
||||
<span class="mobile-icp">豫ICP备15023627号-3</span>
|
||||
<span class="mobile-address">洛阳公司地址:洛阳市 洛龙区 世贸中心D座1816室</span>
|
||||
</div>
|
||||
<div class="mobile-social flex-row">
|
||||
<img class="mobile-social-icon" referrerpolicy="no-referrer" src="public/img/wb.png" />
|
||||
<img class="mobile-social-icon" referrerpolicy="no-referrer" src="public/img/wx.png" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '@/assets/index.scss';
|
||||
|
||||
/* PC端默认样式保持不变 */
|
||||
.mobile-footer {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* 移动端样式 */
|
||||
@media screen and (max-width: 768px) {
|
||||
.pc-footer {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.mobile-footer {
|
||||
display: flex;
|
||||
padding: 20px;
|
||||
background-color: #f8f8f8;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mobile-nav {
|
||||
gap: 15px;
|
||||
margin-bottom: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.mobile-nav-item {
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.mobile-contact {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.mobile-info {
|
||||
gap: 10px;
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.mobile-company {
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.mobile-legal,
|
||||
.mobile-copyright,
|
||||
.mobile-icp,
|
||||
.mobile-address {
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.mobile-social {
|
||||
justify-content: center;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.mobile-social-icon {
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
}
|
||||
}
|
||||
</style>
|
337
components/AppHeader copy.vue
Normal file
@ -0,0 +1,337 @@
|
||||
<template>
|
||||
<div class="page flex-col">
|
||||
<div class="group_1 flex-col" :class="[(isScrolled) && route.name != 'info-id' ? 'topfix' : '']"
|
||||
@mouseenter="openmosee()" @mouseleave="checkBoxHeight()">
|
||||
<div class="flex-row" :style="{justifyContent:coMobile?'space-between':'center',backgroundColor:isMobileMenuOpen?'#ffffff':'transparent',}" :class="route.name == 'info-id' ? 'box_1 box_1_info' : 'box_1'">
|
||||
<img v-if="route.name != 'info-id' && !isScrolled && !isMobileMenuOpen" class="image_1" referrerpolicy="no-referrer"
|
||||
:src="`${cdnUrl}/img/logo.png`" />
|
||||
<img v-if="route.name != 'info-id' && isScrolled || isMobileMenuOpen" class="image_1" referrerpolicy="no-referrer"
|
||||
:src="`${cdnUrl}/img/logo1.png`" />
|
||||
<img v-if="route.name == 'info-id'" class="image_1" referrerpolicy="no-referrer"
|
||||
:src="`${cdnUrl}/img/logo1.png`" />
|
||||
<!-- Desktop Navigation -->
|
||||
<div class="desktop-nav">
|
||||
<div data-title="企业首页"
|
||||
:class="[route.name == 'info-id' ? 'text_black text_1' : 'text_1', { 'text_black': isScrolled }]">
|
||||
<NuxtLink to="/" :class="[route.path === '/' ? 'active' : '']">
|
||||
企业首页
|
||||
</NuxtLink>
|
||||
</div>
|
||||
<div :class="[route.name == 'info-id' ? 'text_black text_1' : 'text_1', { 'text_black': isScrolled }]">
|
||||
<NuxtLink to="/proServices_con/"
|
||||
:class="[route.path === '/proServices/' || route.path === '/proServices_con/' || route.path === '/proServices_con' || route.path === '/proServices' ? 'active' : '']">
|
||||
产品&服务
|
||||
</NuxtLink>
|
||||
</div>
|
||||
<div :class="[route.name == 'info-id' ? 'text_black text_1' : 'text_1', { 'text_black': isScrolled }]">
|
||||
<NuxtLink to="/aboutUs/" :class="[route.path === '/aboutUs/' || route.path === '/aboutUs' ? 'active' : '']">
|
||||
灵睿&我们
|
||||
</NuxtLink>
|
||||
</div>
|
||||
<div :class="[route.name == 'info-id' ? 'text_black text_1' : 'text_1', { 'text_black': isScrolled }]">
|
||||
<NuxtLink to="/customerReviews/"
|
||||
:class="[route.path === '/customerReviews/' || route.path === '/customerReviews' ? 'active' : '']">
|
||||
客户&评价
|
||||
</NuxtLink>
|
||||
</div>
|
||||
<div :class="[route.name == 'info-id' ? 'text_black text_1' : 'text_1', { 'text_black': isScrolled }]">
|
||||
<NuxtLink to="/societyDutyNew/"
|
||||
:class="[route.path === '/societyDuty/' || route.path === '/societyDuty' || route.path === '/societyDutyNew/' || route.path === '/societyDutyNew' ? 'active' : '']">
|
||||
社会&责任
|
||||
</NuxtLink>
|
||||
</div>
|
||||
<div :class="[route.name == 'info-id' ? 'text_black text_1' : 'text_1', { 'text_black': isScrolled }]">
|
||||
<NuxtLink to="/concatUs/"
|
||||
:class="[route.path === '/concatUs/' || route.path === '/concatUs' ? 'active' : '']">
|
||||
加入我们
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Mobile Hamburger Button -->
|
||||
<div class="mobile-menu-btn" @click="toggleMobileMenu">
|
||||
<div class="hamburger" :class="{ 'is-active': isMobileMenuOpen,'is-scrolled':isScrolled }">
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Mobile Navigation -->
|
||||
<div class="mobile-nav" v-if="isMobileMenuOpen">
|
||||
<span @click="openUrl('/')" class="mobile-nav-item">企业首页</span>
|
||||
<span @click="openUrl('/phone_proServices_con/')" class="mobile-nav-item">产品&服务</span>
|
||||
<span @click="openUrl('/aboutUs/')" class="mobile-nav-item">灵睿&我们</span>
|
||||
<span @click="openUrl('/customerReviews/')" class="mobile-nav-item">客户&评价</span>
|
||||
<span @click="openUrl('/societyDutyNew/')" class="mobile-nav-item">社会&责任</span>
|
||||
<span @click="openUrl('/concatUs/')" class="mobile-nav-item">加入我们</span>
|
||||
</div>
|
||||
</div>
|
||||
<transition name="fade-scale" v-if="!coMobile">
|
||||
<div v-if="scrollTop > 1000" class="back-to-top">
|
||||
<img @click="openTop()" :src="`${cdnUrl}/img/get_top.png`" alt="返回顶部" />
|
||||
</div>
|
||||
</transition>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted, onUnmounted } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useStore } from '~/store'
|
||||
const cdnUrl = useCdn()
|
||||
const store = useStore()
|
||||
const route = useRoute()
|
||||
const { locale } = useI18n()
|
||||
const isMobileMenuOpen = ref(false)
|
||||
const isScrolled = ref(false)
|
||||
const scrollTop = ref(0);
|
||||
const handleScroll = () => {
|
||||
isScrolled.value = window.scrollY > 0;
|
||||
scrollTop.value = window.scrollY;
|
||||
}
|
||||
const coMobile = /Mobi|Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
|
||||
onMounted(() => {
|
||||
window.addEventListener('scroll', handleScroll)
|
||||
// 初始化时检查一次滚动位置
|
||||
handleScroll()
|
||||
})
|
||||
const router = useRouter()
|
||||
const openUrl = (url) => {
|
||||
isScrolled.value = false;
|
||||
isMobileMenuOpen.value = false;
|
||||
router.push(url)
|
||||
}
|
||||
const checkBoxHeight = () => {
|
||||
if (window.scrollY == 0) {
|
||||
isScrolled.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener('scroll', handleScroll)
|
||||
})
|
||||
|
||||
const toggleMobileMenu = () => {
|
||||
isMobileMenuOpen.value = !isMobileMenuOpen.value
|
||||
}
|
||||
const openTop = () => {
|
||||
//返回顶部
|
||||
window.scrollTo(0, 0);
|
||||
}
|
||||
const openmosee = () => {
|
||||
if(!coMobile){
|
||||
isScrolled.value = true;
|
||||
}
|
||||
}
|
||||
console.log(route)
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '@/assets/index.scss';
|
||||
|
||||
.group_1 {
|
||||
transition: all 0.3s ease-in-out;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.box_1 {
|
||||
justify-content: center;
|
||||
padding: 0 20px;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
transition: all 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
.topfix {
|
||||
background: rgba(255, 255, 255, 1);
|
||||
-webkit-box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.2);
|
||||
-moz-box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.2);
|
||||
-o-box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.2);
|
||||
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.2);
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 1000;
|
||||
transition: all 0.3s ease-in-out;
|
||||
transform: translateY(0);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.group_1:not(.topfix) {
|
||||
background-color: transparent;
|
||||
box-shadow: none;
|
||||
transform: translateY(0);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.desktop-nav {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 20px;
|
||||
padding-left: 150px;
|
||||
|
||||
@media (max-width: 768px) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.mobile-menu-btn {
|
||||
display: none;
|
||||
cursor: pointer;
|
||||
|
||||
@media (max-width: 768px) {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.hamburger {
|
||||
width: 30px;
|
||||
height: 24px;
|
||||
position: relative;
|
||||
|
||||
span {
|
||||
display: block;
|
||||
position: absolute;
|
||||
height: 3px;
|
||||
width: 100%;
|
||||
background: #ffffff;
|
||||
border-radius: 3px;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:nth-child(1) {
|
||||
top: 0;
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
top: 10px;
|
||||
}
|
||||
|
||||
&:nth-child(3) {
|
||||
top: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
&.is-active {
|
||||
|
||||
span {
|
||||
background-color: #000000;
|
||||
&:nth-child(1) {
|
||||
transform: rotate(45deg);
|
||||
top: 10px;
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
&:nth-child(3) {
|
||||
transform: rotate(-45deg);
|
||||
top: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mobile-nav {
|
||||
display: none;
|
||||
flex-direction: column;
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: white;
|
||||
padding: 20px;
|
||||
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
||||
z-index: 100;
|
||||
|
||||
@media (max-width: 768px) {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.mobile-nav-item {
|
||||
padding: 15px 0;
|
||||
border-bottom: 1px solid #eee;
|
||||
cursor: pointer;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.text_black {
|
||||
color: #000000;
|
||||
transition: color 0.1s ease-in-out;
|
||||
}
|
||||
|
||||
.text_black_w {
|
||||
color: #ffffff;
|
||||
font-weight: 600;
|
||||
transition: color 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
.text_5_info {
|
||||
background-color: #FC7428;
|
||||
height: 90px !important;
|
||||
line-height: 90px !important;
|
||||
padding: 0 20px;
|
||||
color: #ffffff !important;
|
||||
text-align: center;
|
||||
transition: all 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
.box_1_info {
|
||||
height: 90px !important;
|
||||
margin: 0px !important;
|
||||
transition: all 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
.image_1 {
|
||||
transition: all 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
.back-to-top {
|
||||
position: fixed;
|
||||
bottom: 20%;
|
||||
right: 20px;
|
||||
z-index: 1000;
|
||||
|
||||
img {
|
||||
height: 60px;
|
||||
cursor: pointer;
|
||||
transition: transform 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.fade-scale-enter-active,
|
||||
.fade-scale-leave-active {
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.fade-scale-enter-from,
|
||||
.fade-scale-leave-to {
|
||||
opacity: 0;
|
||||
transform: scale(0.8);
|
||||
}
|
||||
|
||||
.fade-scale-enter-to,
|
||||
.fade-scale-leave-from {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
.is-scrolled{
|
||||
span{
|
||||
background-color: #000000;
|
||||
}
|
||||
}
|
||||
</style>
|
117
components/AppHeader.vue
Normal file
@ -0,0 +1,117 @@
|
||||
<template>
|
||||
<!-- 左边导航栏 -->
|
||||
<div class="bgimg">
|
||||
<div class="pc-nav">
|
||||
<div class="pc-nav-item">
|
||||
<img src="/img/index/home1.png" alt=""></img>
|
||||
<span class="span" style="color: #FFA234;">官网首页</span>
|
||||
<img src="/img/index/arrow.png" alt="" style="width: 9px;height: 12px;margin-left: 10px;">
|
||||
</div>
|
||||
<div class="pc-nav-item">
|
||||
<img src="/img/index/aboutus.png" alt=""></img>
|
||||
<span class="span">关于我们</span>
|
||||
</div>
|
||||
<div class="pc-nav-item">
|
||||
<img src="/img/index/news.png" alt=""></img>
|
||||
<span class="span">新闻动态</span>
|
||||
</div>
|
||||
<div class="pc-nav-item">
|
||||
<img src="/img/index/message.png" alt=""></img>
|
||||
<span class="span">信息公开</span>
|
||||
</div>
|
||||
<div class="pc-nav-item">
|
||||
<img src="/img/index/baike.png" alt=""></img>
|
||||
<span class="span">团务百科</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="line_h"></div>
|
||||
<div class="goback">返回首页</div>
|
||||
<div style="margin-top: 50px;margin-left: 40px;">
|
||||
<div class="box_1">无障碍阅读</div>
|
||||
<div class="box_2">进入适老模式</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '@/assets/index.scss';
|
||||
.bgimg{
|
||||
width: 350px;
|
||||
height: 100vh;
|
||||
background-image: url('/img/index/leftHead.png');
|
||||
background-size: 100% 100%;
|
||||
position: absolute;
|
||||
z-index: 1000;
|
||||
.pc-nav {
|
||||
margin-left: 70px;
|
||||
margin-top: 250px;
|
||||
text-align: center;
|
||||
}
|
||||
.pc-nav-item {
|
||||
width: 100%;
|
||||
// height: 18px;
|
||||
font-family: Microsoft YaHei UI;
|
||||
font-weight: bold;
|
||||
font-size: 18px;
|
||||
color: #FFFFFF;
|
||||
text-shadow: 0px 1px 0px rgba(0,0,64,0.4);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 25px;
|
||||
&:hover{
|
||||
cursor: pointer;
|
||||
color: #FFA234;
|
||||
}
|
||||
.span{
|
||||
margin-left: 20px;
|
||||
}
|
||||
}
|
||||
.line_h{
|
||||
width: 220px;
|
||||
height: 1px;
|
||||
background: #FFFFFF;
|
||||
opacity: 0.2;
|
||||
margin-left: 40px;
|
||||
}
|
||||
.goback{
|
||||
width: 72px;
|
||||
height: 17px;
|
||||
font-family: Microsoft YaHei UI;
|
||||
font-weight: 400;
|
||||
font-size: 18px;
|
||||
color: #FFFFFF;
|
||||
margin-left:114px ;
|
||||
margin-top: 20px;
|
||||
}
|
||||
.box_1{
|
||||
width: 200px;
|
||||
height: 58px;
|
||||
line-height: 58px;
|
||||
background: #FFA234;
|
||||
font-family: Microsoft YaHei UI;
|
||||
font-weight: 400;
|
||||
font-size: 18px;
|
||||
text-align: center;
|
||||
color: #FFFFFF;
|
||||
cursor: pointer;
|
||||
}
|
||||
.box_2{
|
||||
width: 200px;
|
||||
height: 58px;
|
||||
line-height: 58px;
|
||||
background: #4EB64B;
|
||||
margin-top: 16px;
|
||||
font-family: Microsoft YaHei UI;
|
||||
font-weight: 400;
|
||||
font-size: 18px;
|
||||
color: #FFFFFF;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
204
components/AppHome.vue
Normal file
@ -0,0 +1,204 @@
|
||||
<template>
|
||||
<!-- PC端布局 -->
|
||||
<div class="flex justify-between w-full h-full" >
|
||||
<!-- 左边导航栏 -->
|
||||
<!-- <div class="bgimg">
|
||||
<div class="pc-nav">
|
||||
<div class="pc-nav-item">
|
||||
<img src="/img/index/home1.png" alt=""></img>
|
||||
<span class="span" style="color: #FFA234;">官网首页</span>
|
||||
<img src="/img/index/arrow.png" alt="" style="width: 9px;height: 12px;margin-left: 10px;">
|
||||
</div>
|
||||
<div class="pc-nav-item">
|
||||
<img src="/img/index/aboutus.png" alt=""></img>
|
||||
<span class="span">关于我们</span>
|
||||
</div>
|
||||
<div class="pc-nav-item">
|
||||
<img src="/img/index/news.png" alt=""></img>
|
||||
<span class="span">新闻动态</span>
|
||||
</div>
|
||||
<div class="pc-nav-item">
|
||||
<img src="/img/index/message.png" alt=""></img>
|
||||
<span class="span">信息公开</span>
|
||||
</div>
|
||||
<div class="pc-nav-item">
|
||||
<img src="/img/index/baike.png" alt=""></img>
|
||||
<span class="span">团务百科</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="line_h"></div>
|
||||
<div class="goback">返回首页</div>
|
||||
<div style="margin-top: 50px;margin-left: 40px;">
|
||||
<div class="box_1">无障碍阅读</div>
|
||||
<div class="box_2">进入适老模式</div>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<!-- 右边内容栏 -->
|
||||
<div class="rightcon">
|
||||
<div class="flex top_search ">
|
||||
<div style="width: 572px;height: 69px;margin-left: 415px;">
|
||||
<img :src="`/img/index/dlogo.png`" alt="" style="width: 100%;height: 100%;object-fit: cover;">
|
||||
</div>
|
||||
<div class="inputform">
|
||||
<input v-model="inputSearch" class="contactInput w-full md:w-[337px]"
|
||||
type="text" placeholder="请输入搜索关键字" />
|
||||
<div class="search_rinput">
|
||||
<img src="/img/index/hmsearch.png" alt="">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 右分享 -->
|
||||
<!-- <div style="position: absolute;top: 300px;right:36px;" class="flex flex-col fiximg">
|
||||
<img :src="`/img/index/douyin.png`" alt="">
|
||||
<img :src="`/img/index/wb.png`" alt="">
|
||||
<img :src="`/img/index/wx.png`" alt="">
|
||||
<img :src="`/img/index/blbl.png`" alt="">
|
||||
</div> -->
|
||||
<!-- 底部鼠标 -->
|
||||
<div style="position: absolute;bottom: 30px;right:30px;">
|
||||
<img :src="`/img/index/hmouse.png`" alt="">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
const inputSearch = ref('');
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '@/assets/index.scss';
|
||||
|
||||
|
||||
/* pc端样式 */
|
||||
// .bgimg{
|
||||
// width: 350px;
|
||||
// height: 100vh;
|
||||
// background-image: url('/img/index/leftHead.png');
|
||||
// background-size: 100% 100%;
|
||||
// position: absolute;
|
||||
// .pc-nav {
|
||||
// margin-left: 70px;
|
||||
// margin-top: 250px;
|
||||
// text-align: center;
|
||||
// }
|
||||
// .pc-nav-item {
|
||||
// width: 100%;
|
||||
// // height: 18px;
|
||||
// font-family: Microsoft YaHei UI;
|
||||
// font-weight: bold;
|
||||
// font-size: 18px;
|
||||
// color: #FFFFFF;
|
||||
// text-shadow: 0px 1px 0px rgba(0,0,64,0.4);
|
||||
// display: flex;
|
||||
// align-items: center;
|
||||
// margin-bottom: 25px;
|
||||
// &:hover{
|
||||
// cursor: pointer;
|
||||
// color: #FFA234;
|
||||
// }
|
||||
// .span{
|
||||
// margin-left: 20px;
|
||||
// }
|
||||
// }
|
||||
// .line_h{
|
||||
// width: 220px;
|
||||
// height: 1px;
|
||||
// background: #FFFFFF;
|
||||
// opacity: 0.2;
|
||||
// margin-left: 40px;
|
||||
// }
|
||||
// .goback{
|
||||
// width: 72px;
|
||||
// height: 17px;
|
||||
// font-family: Microsoft YaHei UI;
|
||||
// font-weight: 400;
|
||||
// font-size: 18px;
|
||||
// color: #FFFFFF;
|
||||
// margin-left:114px ;
|
||||
// margin-top: 20px;
|
||||
// }
|
||||
// .box_1{
|
||||
// width: 200px;
|
||||
// height: 58px;
|
||||
// line-height: 58px;
|
||||
// background: #FFA234;
|
||||
// font-family: Microsoft YaHei UI;
|
||||
// font-weight: 400;
|
||||
// font-size: 18px;
|
||||
// text-align: center;
|
||||
// color: #FFFFFF;
|
||||
// cursor: pointer;
|
||||
// }
|
||||
// .box_2{
|
||||
// width: 200px;
|
||||
// height: 58px;
|
||||
// line-height: 58px;
|
||||
// background: #4EB64B;
|
||||
// margin-top: 16px;
|
||||
// font-family: Microsoft YaHei UI;
|
||||
// font-weight: 400;
|
||||
// font-size: 18px;
|
||||
// color: #FFFFFF;
|
||||
// text-align: center;
|
||||
// cursor: pointer;
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
.rightcon{
|
||||
width:1920px;
|
||||
height: 919px;
|
||||
background-image: url('/img/index/rightcon.png');
|
||||
background-size: 100% 100%;
|
||||
.fiximg{
|
||||
img{
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.top_search{
|
||||
margin-top: 50px;
|
||||
height: 70px;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
.inputform {
|
||||
position: relative;
|
||||
width: 340px;
|
||||
margin-right: 319px;
|
||||
}
|
||||
.contactInput {
|
||||
width: 337px;
|
||||
height: 50px;
|
||||
background: #FFFFFF;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #DEE4E8;
|
||||
padding-left: 15px;
|
||||
}
|
||||
|
||||
.contactInput::placeholder {
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.contactInput:focus {
|
||||
outline: none;
|
||||
}
|
||||
.search_rinput{
|
||||
width: 68px;
|
||||
height: 50px;
|
||||
background: #E6E6E6;
|
||||
border-radius: 0px 8px 8px 0px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
290
components/AppMessage.vue
Normal file
@ -0,0 +1,290 @@
|
||||
<template>
|
||||
<!-- PC端布局 -->
|
||||
<div class="flex justify-between w-full h-full" >
|
||||
<!-- 左边导航栏 -->
|
||||
|
||||
|
||||
<!-- 右边内容栏 -->
|
||||
<div class="rightcon">
|
||||
<div class="flex top_search ">
|
||||
<div style="width: 572px;height: 69px;margin-left: 415px;">
|
||||
<img :src="`/img/index/dlogo.png`" alt="" style="width: 100%;height: 100%;object-fit: cover;">
|
||||
</div>
|
||||
<div class="inputform">
|
||||
<input v-model="inputSearch" class="contactInput w-full md:w-[337px]"
|
||||
type="text" placeholder="请输入搜索关键字" />
|
||||
<div class="search_rinput">
|
||||
<img src="/img/index/hmsearch.png" alt="">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="me_top">
|
||||
<div class="me_col"></div>
|
||||
<div class="me_tit">信息公开</div>
|
||||
<div class="me_col"></div>
|
||||
</div>
|
||||
<div class="re_box">
|
||||
<div class="re_box_item" v-for="(item,index) in MesList" :key="index">
|
||||
<div class="re_title one-line-ellipsis">
|
||||
<div class="dian"></div>
|
||||
<span>{{ item.title }}</span>
|
||||
</div>
|
||||
<div class="re_date">
|
||||
<div class="shu"></div>
|
||||
<div class="right_tex">
|
||||
<span class="span1">{{item.release_time_text.slice(8,10)}}</span>
|
||||
<span class="span2">{{item.release_time_text.slice(0,7)}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="flex flex-row justify-center pages_tsw" style="margin-top: 20px;">
|
||||
<n-pagination v-model:page="page" :page-sizes="[6]" :item-count="total" size="medium"
|
||||
@update:page="getPageList" show-quick-jumper>
|
||||
<template #goto>
|
||||
到第
|
||||
</template>
|
||||
<template #prefix="{ itemCount}">
|
||||
共 {{ itemCount }} 条
|
||||
</template>
|
||||
</n-pagination>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 右分享 -->
|
||||
<!-- <div style="position: absolute;top: 300px;right:36px;" class="flex flex-col fiximg">
|
||||
<img :src="`/img/index/douyin.png`" alt="">
|
||||
<img :src="`/img/index/wb.png`" alt="">
|
||||
<img :src="`/img/index/wx.png`" alt="">
|
||||
<img :src="`/img/index/blbl.png`" alt="">
|
||||
</div> -->
|
||||
<!-- 底部鼠标 -->
|
||||
<div style="position: absolute;bottom: 30px;right:30px;">
|
||||
<img :src="`/img/index/hmouse.png`" alt="">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { NPagination } from 'naive-ui'
|
||||
import $api from '@/service/webRequest'
|
||||
const inputSearch = ref('');
|
||||
const MesList = ref([]);
|
||||
const page = ref(1);
|
||||
const total = ref(0);
|
||||
// 信息公开
|
||||
onMounted(() => {
|
||||
getMesList();
|
||||
})
|
||||
const getPageList = async () => {
|
||||
page.value = page.value;
|
||||
getMesList();
|
||||
}
|
||||
const getMesList = async () => {
|
||||
const res = await $api.post('/api/home.information/index',
|
||||
{
|
||||
limit:6,
|
||||
page:page.value
|
||||
}
|
||||
)
|
||||
total.value = res.data.data.count;
|
||||
MesList.value = res.data.data.list;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '@/assets/index.scss';
|
||||
|
||||
|
||||
/* pc端样式 */
|
||||
|
||||
.rightcon{
|
||||
width:1920px;
|
||||
height: 919px;
|
||||
background-image: url('/img/message/xxgk.png');
|
||||
background-size: 100% 100%;
|
||||
.fiximg{
|
||||
img{
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.top_search{
|
||||
margin-top: 50px;
|
||||
height: 70px;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
.inputform {
|
||||
position: relative;
|
||||
width: 340px;
|
||||
margin-right: 319px;
|
||||
}
|
||||
.contactInput {
|
||||
width: 337px;
|
||||
height: 50px;
|
||||
background: #FFFFFF;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #DEE4E8;
|
||||
padding-left: 15px;
|
||||
}
|
||||
|
||||
.contactInput::placeholder {
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.contactInput:focus {
|
||||
outline: none;
|
||||
}
|
||||
.search_rinput{
|
||||
width: 68px;
|
||||
height: 50px;
|
||||
background: #E6E6E6;
|
||||
border-radius: 0px 8px 8px 0px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.me_top{
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
// margin: 0 auto;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-top: 30px;
|
||||
.me_tit{
|
||||
font-family: Microsoft YaHei;
|
||||
font-weight: bold;
|
||||
font-size: 36px;
|
||||
color: #4E3C3C;
|
||||
margin: 0 30px;
|
||||
}
|
||||
.me_col{
|
||||
width: 78px;
|
||||
height: 3px;
|
||||
background: #348CDD;
|
||||
}
|
||||
}
|
||||
.re_box{
|
||||
width: 1200px;
|
||||
height: 600px;
|
||||
margin: 0 auto;
|
||||
margin-top:40px;
|
||||
padding-left: 60px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
// flex-direction: column;
|
||||
// justify-content: space-between;
|
||||
align-items: center;
|
||||
.re_box_item{
|
||||
width: 1200px;
|
||||
height: 90px;
|
||||
background: #FFFFFF;
|
||||
border: 1px solid #EEF7FF;
|
||||
padding: 20px;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
.re_title{
|
||||
width: 100%;
|
||||
font-family: Microsoft YaHei;
|
||||
font-weight: 400;
|
||||
font-size: 18px;
|
||||
color: #323232;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.dian{
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
background: #3B90DF;
|
||||
border-radius: 50%;
|
||||
margin-right: 15px;
|
||||
}
|
||||
}
|
||||
.re_date{
|
||||
font-family: Microsoft YaHei;
|
||||
font-weight: 400;
|
||||
font-size: 14px;
|
||||
color: #368BDB;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
.shu{
|
||||
background: #EEEEEE;
|
||||
width: 1px;height: 50px;
|
||||
margin-right: 20px;
|
||||
}
|
||||
.right_tex{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 80px;
|
||||
text-align: center;
|
||||
.span1{
|
||||
width: 100%;
|
||||
font-family: Microsoft YaHei;
|
||||
font-weight: 400;
|
||||
font-size: 36px;
|
||||
color: #378EDF;
|
||||
}
|
||||
.span2{
|
||||
width: 100%;
|
||||
font-family: Microsoft YaHei;
|
||||
font-weight: 400;
|
||||
font-size: 16px;
|
||||
color: #378EDF;
|
||||
}
|
||||
}
|
||||
}
|
||||
&:hover{
|
||||
background-image: url('/img/message/listbgxx.png');
|
||||
background-size: 100% 100%;
|
||||
cursor: pointer;
|
||||
.re_date{
|
||||
.shu{
|
||||
background: #FFFFFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.pages_tsw{
|
||||
:deep(.n-pagination .n-pagination-item:not(.n-pagination-item--disabled).n-pagination-item--active) {
|
||||
color: #ffffff;
|
||||
background-color: #388FDF;
|
||||
border: 1px solid #388FDF;
|
||||
}
|
||||
|
||||
:deep(.n-pagination .n-pagination-item:not(.n-pagination-item--disabled):hover.n-pagination-item--button) {
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
:deep(.n-pagination .n-pagination-item:not(.n-pagination-item--disabled):hover) {
|
||||
color: #388FDF;
|
||||
// border: 1px solid #388FDF;
|
||||
}
|
||||
:deep(.n-pagination .n-pagination-item--active:hover) {
|
||||
color: #ffffff !important;
|
||||
// border: 1px solid #388FDF;
|
||||
}
|
||||
:deep(.n-pagination .n-pagination-item) {
|
||||
border: none;
|
||||
width: 42px;
|
||||
height: 30px;
|
||||
font-size: 18px;
|
||||
background: #FFFFFF;
|
||||
}
|
||||
:deep(.n-pagination-quick-jumper){
|
||||
&:after {
|
||||
content: '页'
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
348
components/AppNews.vue
Normal file
@ -0,0 +1,348 @@
|
||||
<template>
|
||||
<!-- PC端布局 -->
|
||||
<div class="flex justify-between w-full h-full" >
|
||||
<!-- 左边导航栏 -->
|
||||
|
||||
|
||||
<!-- 右边内容栏 -->
|
||||
<div class="rightcon">
|
||||
<div class="flex top_search ">
|
||||
<div style="width: 572px;height: 69px;margin-left: 415px;">
|
||||
<img :src="`/img/index/dlogo.png`" alt="" style="width: 100%;height: 100%;object-fit: cover;">
|
||||
</div>
|
||||
<div class="inputform">
|
||||
<input v-model="inputSearch" class="contactInput w-full md:w-[337px]"
|
||||
type="text" placeholder="请输入搜索关键字" />
|
||||
<div class="search_rinput">
|
||||
<img src="/img/index/hmsearch.png" alt="">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="News_box">
|
||||
<div class="lef_box">
|
||||
<div class="lef_boxitem1">
|
||||
<div class="lef_boxitem1_shu"></div>
|
||||
<div class="lef_boxitem1_title">新闻动态</div>
|
||||
</div>
|
||||
<div class="lef_boxitem2" v-for="(item, index) in newsListtyp" :key="index">
|
||||
<div class="lef_boxitem2_title">{{ item.name }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="rig_box">
|
||||
<div class="re_box">
|
||||
<div class="re_box_item" v-for="(item,index) in MesList" :key="index">
|
||||
<div class="re_title">
|
||||
<div class="dian"></div>
|
||||
<span class="one-line-ellipsis" style="width: 720px;">{{ item.title }}</span>
|
||||
</div>
|
||||
<div class="re_date">
|
||||
<div class="shu"></div>
|
||||
<div class="right_tex">
|
||||
<span class="span1">{{item.release_time_text.slice(8,10)}}</span>
|
||||
<span class="span2">{{item.release_time_text.slice(0,7)}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="flex flex-row justify-center pages_tsw" style="margin-top: 20px;">
|
||||
<n-pagination v-model:page="page" :page-sizes="[7]" :item-count="total" size="medium"
|
||||
@update:page="getPageList" show-quick-jumper>
|
||||
<template #goto>
|
||||
到第
|
||||
</template>
|
||||
<template #prefix="{ itemCount}">
|
||||
共 {{ itemCount }} 条
|
||||
</template>
|
||||
</n-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 右分享 -->
|
||||
<!-- <div style="position: absolute;top: 300px;right:36px;" class="flex flex-col fiximg">
|
||||
<img :src="`/img/index/douyin.png`" alt="">
|
||||
<img :src="`/img/index/wb.png`" alt="">
|
||||
<img :src="`/img/index/wx.png`" alt="">
|
||||
<img :src="`/img/index/blbl.png`" alt="">
|
||||
</div> -->
|
||||
<!-- 底部鼠标 -->
|
||||
<div style="position: absolute;bottom: 30px;right:30px;">
|
||||
<img :src="`/img/index/hmouse.png`" alt="">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { NPagination } from 'naive-ui'
|
||||
import $api from '@/service/webRequest'
|
||||
const inputSearch = ref('');
|
||||
const MesList = ref([]);
|
||||
const newsListtyp = ref([]);
|
||||
const page = ref(1);
|
||||
const total = ref(0);
|
||||
// 信息公开
|
||||
onMounted(() => {
|
||||
getMesList();
|
||||
getNewstypeList();
|
||||
})
|
||||
const getPageList = async () => {
|
||||
page.value = page.value;
|
||||
getMesList();
|
||||
}
|
||||
const getMesList = async () => {
|
||||
const res = await $api.post('/api/home.news/index',
|
||||
{
|
||||
limit:7,
|
||||
page:page.value
|
||||
}
|
||||
)
|
||||
total.value = res.data.data.count;
|
||||
MesList.value = res.data.data.list;
|
||||
}
|
||||
const getNewstypeList = async () => {
|
||||
const res = await $api.get('/api/home.news/cate')
|
||||
newsListtyp.value = res.data.data.list;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '@/assets/index.scss';
|
||||
|
||||
|
||||
/* pc端样式 */
|
||||
|
||||
.rightcon{
|
||||
width:1920px;
|
||||
height: 919px;
|
||||
background-image: url('/img/xwdt.png');
|
||||
background-size: 100% 100%;
|
||||
.fiximg{
|
||||
img{
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.top_search{
|
||||
margin-top: 50px;
|
||||
height: 70px;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
.inputform {
|
||||
position: relative;
|
||||
width: 340px;
|
||||
margin-right: 319px;
|
||||
}
|
||||
.contactInput {
|
||||
width: 337px;
|
||||
height: 50px;
|
||||
background: #FFFFFF;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #DEE4E8;
|
||||
padding-left: 15px;
|
||||
}
|
||||
|
||||
.contactInput::placeholder {
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.contactInput:focus {
|
||||
outline: none;
|
||||
}
|
||||
.search_rinput{
|
||||
width: 68px;
|
||||
height: 50px;
|
||||
background: #E6E6E6;
|
||||
border-radius: 0px 8px 8px 0px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.News_box{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
width: 1300px;
|
||||
margin: 0 auto;
|
||||
|
||||
.lef_box{
|
||||
width: 260px;
|
||||
height: 100%;
|
||||
margin-top:48px;
|
||||
margin-left: 100px;
|
||||
.lef_boxitem1{
|
||||
width: 260px;
|
||||
height: 64px;
|
||||
background: linear-gradient(0deg, #338CDE 0%, #3D92E0 100%);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
.lef_boxitem1_title{
|
||||
width: 88px;
|
||||
// height: 22px;
|
||||
font-family: Microsoft YaHei UI;
|
||||
font-weight: bold;
|
||||
font-size: 22px;
|
||||
color: #FFFEFE;
|
||||
}
|
||||
.lef_boxitem1_shu{
|
||||
width: 4px;
|
||||
height: 25px;
|
||||
background: #FFFFFF;
|
||||
margin-right: 20px;
|
||||
}
|
||||
}
|
||||
.lef_boxitem2{
|
||||
width: 260px;
|
||||
height: 64px;
|
||||
background: #FFFFFF;
|
||||
color: #323232;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top:10px ;
|
||||
cursor: pointer;
|
||||
.lef_boxitem2_title{
|
||||
width: 100%;
|
||||
// height: 19px;
|
||||
font-family: Microsoft YaHei;
|
||||
font-weight: 400;
|
||||
font-size: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
&:hover{
|
||||
background: linear-gradient(0deg, rgba(51, 140, 222, 0.12) 0%, rgba(61, 146, 224, 0.12) 100%);
|
||||
color: #3A91DF;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.rig_box{
|
||||
width: 921px;
|
||||
.re_box{
|
||||
width: 100%;
|
||||
height: 680px;
|
||||
margin: 0 auto;
|
||||
margin-top:40px;
|
||||
// padding-left: 60px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-start;
|
||||
align-content: flex-start;
|
||||
gap: 10px;
|
||||
.re_box_item{
|
||||
width: 100%;
|
||||
height: 90px;
|
||||
background: #FFFFFF;
|
||||
border: 1px solid #EEF7FF;
|
||||
padding: 20px;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
.re_title{
|
||||
// width: 640px;
|
||||
font-family: Microsoft YaHei;
|
||||
font-weight: 400;
|
||||
font-size: 18px;
|
||||
color: #323232;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.dian{
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
background: #3B90DF;
|
||||
border-radius: 50%;
|
||||
margin-right: 15px;
|
||||
}
|
||||
}
|
||||
.re_date{
|
||||
font-family: Microsoft YaHei;
|
||||
font-weight: 400;
|
||||
font-size: 14px;
|
||||
color: #368BDB;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
.shu{
|
||||
background: #EEEEEE;
|
||||
width: 1px;height: 50px;
|
||||
margin-right: 20px;
|
||||
}
|
||||
.right_tex{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 80px;
|
||||
text-align: center;
|
||||
.span1{
|
||||
width: 100%;
|
||||
font-family: Microsoft YaHei;
|
||||
font-weight: 400;
|
||||
font-size: 36px;
|
||||
color: #378EDF;
|
||||
}
|
||||
.span2{
|
||||
width: 100%;
|
||||
font-family: Microsoft YaHei;
|
||||
font-weight: 400;
|
||||
font-size: 16px;
|
||||
color: #378EDF;
|
||||
}
|
||||
}
|
||||
}
|
||||
&:hover{
|
||||
background-image: url('/img/message/listbg.png');
|
||||
background-size: 100% 100%;
|
||||
cursor: pointer;
|
||||
.re_date{
|
||||
.shu{
|
||||
background: #FFFFFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.pages_tsw{
|
||||
:deep(.n-pagination .n-pagination-item:not(.n-pagination-item--disabled).n-pagination-item--active) {
|
||||
color: #ffffff;
|
||||
background-color: #388FDF;
|
||||
border: 1px solid #388FDF;
|
||||
}
|
||||
|
||||
:deep(.n-pagination .n-pagination-item:not(.n-pagination-item--disabled):hover.n-pagination-item--button) {
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
:deep(.n-pagination .n-pagination-item:not(.n-pagination-item--disabled):hover) {
|
||||
color: #388FDF;
|
||||
// border: 1px solid #388FDF;
|
||||
}
|
||||
:deep(.n-pagination .n-pagination-item--active:hover) {
|
||||
color: #ffffff !important;
|
||||
// border: 1px solid #388FDF;
|
||||
}
|
||||
|
||||
:deep(.n-pagination .n-pagination-item) {
|
||||
border: none;
|
||||
width: 42px;
|
||||
height: 30px;
|
||||
font-size: 18px;
|
||||
background: #FFFFFF;
|
||||
}
|
||||
:deep(.n-pagination-quick-jumper){
|
||||
&:after {
|
||||
content: '页'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
272
components/AppRegiment.vue
Normal file
@ -0,0 +1,272 @@
|
||||
<template>
|
||||
<!-- PC端布局 -->
|
||||
<div class="flex justify-between w-full h-full" >
|
||||
<!-- 左边导航栏 -->
|
||||
|
||||
<!-- 右边内容栏 -->
|
||||
<div class="rightcon">
|
||||
<div class="flex top_search ">
|
||||
<div style="width: 572px;height: 69px;margin-left: 415px;">
|
||||
<img :src="`/img/index/dlogo.png`" alt="" style="width: 100%;height: 100%;object-fit: cover;">
|
||||
</div>
|
||||
<div class="inputform">
|
||||
<input v-model="inputSearch" class="contactInput w-full md:w-[337px]"
|
||||
type="text" placeholder="请输入搜索关键字" />
|
||||
<div class="search_rinput">
|
||||
<img src="/img/index/hmsearch.png" alt="">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="re_top">
|
||||
<div class="re_col"></div>
|
||||
<div class="re_tit">团务百科</div>
|
||||
<div class="re_col"></div>
|
||||
</div>
|
||||
<!-- 列表 -->
|
||||
<div class="re_box">
|
||||
<div class="re_box_item" v-for="(item,index) in BksList" :key="index">
|
||||
<div class="re_title one-line-ellipsis">
|
||||
{{ item.title }}
|
||||
</div>
|
||||
<div class="re_text three-line-ellipsis">
|
||||
{{ item.subtitle }}
|
||||
</div>
|
||||
<div class="re_date">
|
||||
<div>发布日期:{{item.release_time_text.slice(0,10)}}</div>
|
||||
<div class="re_more">
|
||||
<span>查看更多</span>
|
||||
<img class="re_more_img" src="/img/rightmore.png" alt="" srcset="">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 分页 -->
|
||||
<div class="flex flex-row justify-center pages_tsw" style="margin-top: 20px;">
|
||||
<n-pagination v-model:page="page" :page-sizes="[9]" :item-count="total" size="medium"
|
||||
@update:page="getPageList" show-quick-jumper>
|
||||
<template #goto>
|
||||
到第
|
||||
</template>
|
||||
<template #prefix="{ itemCount}">
|
||||
共 {{ itemCount }} 条
|
||||
</template>
|
||||
</n-pagination>
|
||||
</div>
|
||||
<!-- 右分享 -->
|
||||
<!-- <div class="flex flex-col fiximg" style="position: absolute;top: 100px;right:36px;align-items: center;" >
|
||||
<img :src="`/img/qiqiu.png`" alt=""></img>
|
||||
<img class="imgs" :src="`/img/index/douyin.png`" alt="">
|
||||
<img class="imgs" :src="`/img/index/wb.png`" alt="">
|
||||
<img class="imgs" :src="`/img/index/wx.png`" alt="">
|
||||
<img class="imgs" :src="`/img/index/blbl.png`" alt="">
|
||||
</div> -->
|
||||
<!-- 底部鼠标 -->
|
||||
<div style="position: absolute;bottom: 30px;right:30px;">
|
||||
<img :src="`/img/index/hmouse.png`" alt="">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { NPagination } from 'naive-ui'
|
||||
import $api from '@/service/webRequest'
|
||||
const inputSearch = ref('');
|
||||
const BksList = ref([]);
|
||||
const page = ref(1);
|
||||
const total = ref(0);
|
||||
// 团务百科
|
||||
onMounted(() => {
|
||||
getBksList();
|
||||
})
|
||||
const getPageList = async () => {
|
||||
page.value = page.value;
|
||||
getBksList();
|
||||
}
|
||||
const getBksList = async () => {
|
||||
const res = await $api.post('/api/home.encyclopedia/index',
|
||||
{
|
||||
limit:9,
|
||||
page:page.value
|
||||
}
|
||||
)
|
||||
total.value = res.data.data.count;
|
||||
BksList.value = res.data.data.list;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '@/assets/index.scss';
|
||||
|
||||
|
||||
/* pc端样式 */
|
||||
|
||||
.rightcon{
|
||||
width:1920px;
|
||||
height: 919px;
|
||||
background-image: url('/img/twbk.jpg');
|
||||
background-size: 100% 100%;
|
||||
.fiximg{
|
||||
.imgs{
|
||||
width: 63px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.top_search{
|
||||
margin-top: 50px;
|
||||
height: 70px;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
.inputform {
|
||||
position: relative;
|
||||
width: 340px;
|
||||
margin-right: 319px;
|
||||
}
|
||||
.contactInput {
|
||||
width: 337px;
|
||||
height: 50px;
|
||||
background: #FFFFFF;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #DEE4E8;
|
||||
padding-left: 15px;
|
||||
}
|
||||
|
||||
.contactInput::placeholder {
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.contactInput:focus {
|
||||
outline: none;
|
||||
}
|
||||
.search_rinput{
|
||||
width: 68px;
|
||||
height: 50px;
|
||||
background: #E6E6E6;
|
||||
border-radius: 0px 8px 8px 0px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.re_top{
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-top: 20px;
|
||||
.re_tit{
|
||||
font-family: Microsoft YaHei;
|
||||
font-weight: bold;
|
||||
font-size: 36px;
|
||||
color: #4E3C3C;
|
||||
margin: 0 30px;
|
||||
}
|
||||
.re_col{
|
||||
width: 78px;
|
||||
height: 3px;
|
||||
background: #348CDD;
|
||||
}
|
||||
}
|
||||
.re_box{
|
||||
width: 1200px;
|
||||
// height: 600px;
|
||||
margin: 0 auto;
|
||||
margin-top:40px;
|
||||
padding-left: 60px;
|
||||
display: flex;
|
||||
flex-wrap: wrap; /* 允许换行 */
|
||||
justify-content: flex-start; /* 项目左对齐 */
|
||||
// align-items: flex-start;
|
||||
align-content: flex-start;
|
||||
gap: 20px;
|
||||
.re_box_item{
|
||||
width: 350px;
|
||||
// height: 190px;
|
||||
background: #FFFFFF;
|
||||
border: 1px solid #EEF7FF;
|
||||
padding: 20px;
|
||||
box-sizing: border-box;
|
||||
.re_title{
|
||||
// width: 100%;
|
||||
font-family: Microsoft YaHei;
|
||||
font-weight: bold;
|
||||
font-size: 18px;
|
||||
color: #323232;
|
||||
|
||||
}
|
||||
.re_text{
|
||||
height: 62px;
|
||||
margin-top: 15px;
|
||||
font-family: Microsoft YaHei;
|
||||
font-weight: 400;
|
||||
font-size: 14px;
|
||||
color: #999999;
|
||||
}
|
||||
.re_date{
|
||||
margin-top: 15px;
|
||||
font-family: Microsoft YaHei;
|
||||
font-weight: 400;
|
||||
font-size: 14px;
|
||||
color: #368BDB;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
.re_more{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.re_more_img{
|
||||
padding-left: 10px;
|
||||
// width: 7px;
|
||||
height: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
&:after {
|
||||
content: "";
|
||||
width: 100%;
|
||||
height: 0;
|
||||
margin-top: -20px;
|
||||
}
|
||||
}
|
||||
.pages_tsw{
|
||||
:deep(.n-pagination .n-pagination-item:not(.n-pagination-item--disabled).n-pagination-item--active) {
|
||||
color: #ffffff;
|
||||
background-color: #388FDF;
|
||||
border: 1px solid #388FDF;
|
||||
}
|
||||
|
||||
:deep(.n-pagination .n-pagination-item:not(.n-pagination-item--disabled):hover.n-pagination-item--button) {
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
:deep(.n-pagination .n-pagination-item:not(.n-pagination-item--disabled):hover) {
|
||||
color: #388FDF;
|
||||
// border: 1px solid #388FDF;
|
||||
}
|
||||
:deep(.n-pagination .n-pagination-item--active:hover) {
|
||||
color: #ffffff !important;
|
||||
// border: 1px solid #388FDF;
|
||||
}
|
||||
|
||||
:deep(.n-pagination .n-pagination-item) {
|
||||
border: none;
|
||||
width: 42px;
|
||||
height: 30px;
|
||||
font-size: 18px;
|
||||
background: #FFFFFF;
|
||||
}
|
||||
:deep(.n-pagination-quick-jumper){
|
||||
&:after {
|
||||
content: '页'
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
4
composables/useCdn.ts
Normal file
@ -0,0 +1,4 @@
|
||||
export const useCdn = () => {
|
||||
const nuxtApp = useNuxtApp()
|
||||
return nuxtApp.$cdnUrl
|
||||
}
|
6
global/cookie.ts
Normal file
@ -0,0 +1,6 @@
|
||||
import Cookies from 'js-cookie'
|
||||
|
||||
export const setCookie = Cookies.set.bind(Cookies)
|
||||
export const removeCookie = Cookies.remove.bind(Cookies)
|
||||
|
||||
export const getCookie = Cookies.get.bind(Cookies)
|
21
global/date.ts
Normal file
@ -0,0 +1,21 @@
|
||||
export function formatDate(fmt: string, dt?: Date | string): string {
|
||||
let d = dt
|
||||
if (typeof dt === 'string') {
|
||||
d = new Date(dt as string)
|
||||
} else if (dt === undefined) {
|
||||
d = new Date()
|
||||
}
|
||||
const year = (d as Date).getFullYear()
|
||||
const month = (d as Date).getMonth() + 1
|
||||
const day = (d as Date).getDate()
|
||||
const hours = (d as Date).getHours()
|
||||
const minutes = (d as Date).getMinutes()
|
||||
const seconds = (d as Date).getSeconds()
|
||||
let result = fmt.replace(/Y/g, `${year}`)
|
||||
result = result.replace(/m/g, month > 9 ? `${month}` : `0${month}`)
|
||||
result = result.replace(/d/g, day > 9 ? `${day}` : `0${day}`)
|
||||
result = result.replace(/H/g, hours > 9 ? `${hours}` : `0${hours}`)
|
||||
result = result.replace(/i/g, minutes > 9 ? `${minutes}` : `0${minutes}`)
|
||||
result = result.replace(/s/g, seconds > 9 ? `${seconds}` : `0${seconds}`)
|
||||
return result
|
||||
}
|
166
global/device.ts
Normal file
@ -0,0 +1,166 @@
|
||||
import CallApp from 'callapp-lib'
|
||||
|
||||
// ie 基本上已经不用了
|
||||
export function isIE(UA: string): number {
|
||||
const isIE = UA.indexOf('compatible') > -1 && UA.indexOf('MSIE') > -1 //判断是否IE<11浏览器
|
||||
const isIE11 = UA.indexOf('Trident') > -1 && UA.indexOf('rv:11.0') > -1
|
||||
if (isIE) {
|
||||
const reIE = new RegExp('MSIE (\\d+\\.\\d+);')
|
||||
reIE.test(UA)
|
||||
const fIEVersion = parseFloat(RegExp['$1'])
|
||||
if (fIEVersion == 7) {
|
||||
return 7
|
||||
} else if (fIEVersion == 8) {
|
||||
return 8
|
||||
} else if (fIEVersion == 9) {
|
||||
return 9
|
||||
} else if (fIEVersion == 10) {
|
||||
return 10
|
||||
} else {
|
||||
return 6 //IE版本<=7
|
||||
}
|
||||
} else if (isIE11) {
|
||||
return 11
|
||||
} else {
|
||||
return -1 //不是ie浏览器
|
||||
}
|
||||
}
|
||||
|
||||
function isMac(UA: string): boolean {
|
||||
return /macintosh|mac os x/i.test(UA) ? true : false
|
||||
}
|
||||
|
||||
function isWin32(UA: string): boolean {
|
||||
return /win32|wow32/i.test(UA) ? true : false
|
||||
}
|
||||
|
||||
function isWechat(UA: string): boolean {
|
||||
return /MicroMessenger/i.test(UA) ? true : false
|
||||
}
|
||||
|
||||
function isQQ(UA: string): boolean {
|
||||
return /QQ/i.test(UA) ? true : false
|
||||
}
|
||||
|
||||
function isMoible(UA: string): boolean {
|
||||
return /(Android|webOS|iPhone|iPod|BlackBerry|Mobile)/i.test(UA) ? true : false
|
||||
}
|
||||
|
||||
export function isIOS(UA: string): boolean {
|
||||
return /iPhone|iPad|iPod/i.test(UA) ? true : false
|
||||
}
|
||||
|
||||
function isAndroid(UA: string): boolean {
|
||||
return /Android/i.test(UA) ? true : false
|
||||
}
|
||||
// 返回类型按需设置
|
||||
export function deviceType(UA: string): { type: string; env?: string } {
|
||||
if (isMoible(UA)) {
|
||||
if (isIOS(UA)) {
|
||||
if (isWechat(UA)) {
|
||||
return {
|
||||
type: 'ios',
|
||||
env: 'wechat',
|
||||
}
|
||||
}
|
||||
if (isQQ(UA)) {
|
||||
return {
|
||||
type: 'ios',
|
||||
env: 'qq',
|
||||
}
|
||||
}
|
||||
return {
|
||||
type: 'ios',
|
||||
}
|
||||
}
|
||||
if (isAndroid(UA)) {
|
||||
if (isWechat(UA)) {
|
||||
return {
|
||||
type: 'android',
|
||||
env: 'wechat',
|
||||
}
|
||||
}
|
||||
if (isQQ(UA)) {
|
||||
return {
|
||||
type: 'android',
|
||||
env: 'qq',
|
||||
}
|
||||
}
|
||||
return {
|
||||
type: 'android',
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'mobile',
|
||||
}
|
||||
} else {
|
||||
if (isMac(UA)) {
|
||||
return {
|
||||
type: 'mac',
|
||||
}
|
||||
}
|
||||
let env = ''
|
||||
if (isIE(UA) > 0) {
|
||||
env = 'ie'
|
||||
}
|
||||
// 注意区分 window 的 32位/64位
|
||||
if (isWin32(UA)) {
|
||||
return {
|
||||
type: 'win32',
|
||||
env: env,
|
||||
}
|
||||
}
|
||||
return {
|
||||
type: 'win64',
|
||||
env: env,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function isPC(UA = window.navigator?.userAgent) {
|
||||
const agent = deviceType(UA)
|
||||
return ['pc', 'mac', 'win32', 'win64'].includes(agent.type)
|
||||
}
|
||||
|
||||
// 移动端唤醒应用
|
||||
export function callApp(isIOS: boolean) {
|
||||
let packageName = ''
|
||||
// 一般来说 ios 和 android 的包名不一样
|
||||
if (isIOS) {
|
||||
packageName = 'com.mobile.android.vite.name' // ios 移动端提供
|
||||
} else {
|
||||
packageName = 'com.mobile.ios.vite.name' // android 移动端提供
|
||||
}
|
||||
const appStoreUrl = 'https://itunes.apple.com/cn/app/xxxx' // 填写appstore的下载地址
|
||||
const androidUrl = 'https://yingyongbao' // 软件应用宝地址
|
||||
|
||||
const options = {
|
||||
scheme: {
|
||||
protocol: 'vite', // 移动端设置的
|
||||
},
|
||||
intent: {
|
||||
package: packageName,
|
||||
scheme: 'vite', // 移动端设置的
|
||||
},
|
||||
timeout: 2000,
|
||||
appstore: appStoreUrl,
|
||||
yingyongbao: androidUrl,
|
||||
fallback: 'https://www.xxx.com/',
|
||||
}
|
||||
const callLib = new CallApp(options)
|
||||
callLib.open({
|
||||
path: 'xxx.app/openwith', // 移动端提供
|
||||
callback: () => {
|
||||
if (isIOS) {
|
||||
window.location.href = appStoreUrl // ios 直接跳转到appStore 地址即可
|
||||
} else {
|
||||
// android 跳转
|
||||
const link = document.createElement('a')
|
||||
link.target = '_blank'
|
||||
link.href = androidUrl
|
||||
link.click()
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
40
global/env.ts
Normal file
@ -0,0 +1,40 @@
|
||||
import { isUndef } from './is'
|
||||
|
||||
// 正式环境
|
||||
export const PROD_ENV = {
|
||||
SERVER_URL: 'https://democs.0rui.cn/', // 服务地址
|
||||
IS_DEV: 'false', // 是否是测试环境
|
||||
}
|
||||
|
||||
// 测试环境
|
||||
export const DEV_ENV = {
|
||||
SERVER_URL: '/api/',
|
||||
IS_DEV: 'true',
|
||||
}
|
||||
|
||||
// 假设测试环境的域名是 https://xxx-test.com
|
||||
let isDev = process.env.NODE_ENV === 'development'
|
||||
try {
|
||||
if (!process.server) {
|
||||
isDev = isDev || ['xxx-test.com'].includes(location.host) || false
|
||||
} else {
|
||||
isDev = isDev || process.env.IS_DEV === 'TRUE' || false
|
||||
}
|
||||
} catch (err) {
|
||||
console.log('err in env')
|
||||
}
|
||||
|
||||
export type EnvKey = keyof typeof PROD_ENV
|
||||
|
||||
// 调用这个函数获取当前的环境变量
|
||||
export function getProcessEnv(key: EnvKey): string | void {
|
||||
if (isDev) {
|
||||
if (!isUndef(DEV_ENV[key])) {
|
||||
return DEV_ENV[key]
|
||||
}
|
||||
return ''
|
||||
}
|
||||
if (!isUndef(PROD_ENV[key])) {
|
||||
return PROD_ENV[key]
|
||||
}
|
||||
}
|
84
global/file.ts
Normal file
@ -0,0 +1,84 @@
|
||||
import { isNull } from '@/global/is'
|
||||
|
||||
export function webChooseFile(cb: (file: File) => unknown, accept?: string): void {
|
||||
const id = 'file-selector-99999999'
|
||||
let input = document.getElementById(id) as HTMLInputElement
|
||||
if (isNull(input)) {
|
||||
input = document.createElement('input')
|
||||
input.id = id
|
||||
input.type = 'file'
|
||||
input.style.position = 'fixed'
|
||||
input.style.left = '-10000px'
|
||||
document.body.appendChild(input)
|
||||
} else {
|
||||
input.value = ''
|
||||
}
|
||||
if (accept) {
|
||||
input.accept = accept
|
||||
} else {
|
||||
input.removeAttribute('accept')
|
||||
}
|
||||
input.onchange = (): void => {
|
||||
if (input.files?.length) {
|
||||
cb(input.files[0])
|
||||
}
|
||||
}
|
||||
input.classList.add('selectFile')
|
||||
const e = document.createEvent('MouseEvent') as unknown as Event
|
||||
e.initEvent('click', false, true)
|
||||
input.dispatchEvent(e)
|
||||
}
|
||||
|
||||
export function webMulChooseFile(cb: (file: FileList) => unknown, accept?: string): void {
|
||||
const id = 'file-selector-88888'
|
||||
let input = document.getElementById(id) as HTMLInputElement
|
||||
if (isNull(input)) {
|
||||
input = document.createElement('input')
|
||||
input.id = id
|
||||
input.type = 'file'
|
||||
input.multiple = true
|
||||
input.style.position = 'fixed'
|
||||
input.style.left = '-100000px'
|
||||
document.body.appendChild(input)
|
||||
} else {
|
||||
input.value = ''
|
||||
}
|
||||
if (accept) {
|
||||
input.accept = accept
|
||||
} else {
|
||||
input.removeAttribute('accept')
|
||||
}
|
||||
input.onchange = (): void => {
|
||||
if (input.files?.length) {
|
||||
cb(input.files)
|
||||
}
|
||||
}
|
||||
input.classList.add('selectFile')
|
||||
const e = document.createEvent('MouseEvent') as unknown as Event
|
||||
e.initEvent('click', false, true)
|
||||
input.dispatchEvent(e)
|
||||
}
|
||||
|
||||
export function webDownloadFileByUrl(url: string, name: string): void {
|
||||
const xhr = new XMLHttpRequest()
|
||||
xhr.open('GET', url, true)
|
||||
xhr.responseType = 'blob'
|
||||
xhr.onload = (): void => {
|
||||
if (xhr.status === 200) {
|
||||
const a = document.createElement('a')
|
||||
a.download = name
|
||||
a.href = URL.createObjectURL(xhr.response)
|
||||
a.click()
|
||||
}
|
||||
}
|
||||
xhr.send()
|
||||
}
|
||||
|
||||
export function downloadToTxt(text: string, filename: string) {
|
||||
const element = document.createElement('a')
|
||||
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text))
|
||||
element.setAttribute('download', filename)
|
||||
element.style.display = 'none'
|
||||
document.body.appendChild(element)
|
||||
element.click()
|
||||
}
|
56
global/is.ts
Normal file
@ -0,0 +1,56 @@
|
||||
const { isInteger } = Number
|
||||
const { toString } = Object.prototype
|
||||
|
||||
export function isNumber(v: unknown): v is number {
|
||||
return typeof v === 'number' && !Number.isNaN(v) && Number.isFinite(v)
|
||||
}
|
||||
|
||||
export function isInt(v: unknown): boolean {
|
||||
return isNumber(v) && isInteger(v)
|
||||
}
|
||||
|
||||
export function isFloat(v: unknown): boolean {
|
||||
return isNumber(v) && !isInteger(v)
|
||||
}
|
||||
|
||||
export function isString(v: unknown): v is string {
|
||||
return typeof v === 'string'
|
||||
}
|
||||
|
||||
export function isBoolean(v: unknown): v is boolean {
|
||||
return v === true || v === false
|
||||
}
|
||||
|
||||
export function isFunction(v: unknown): v is (...args: unknown[]) => unknown {
|
||||
return typeof v === 'function'
|
||||
}
|
||||
|
||||
export const { isArray } = Array
|
||||
|
||||
export function isPlainObject(v: unknown): v is Record<string, unknown> {
|
||||
return toString.call(v) === '[object Object]'
|
||||
}
|
||||
|
||||
export function isRegExp(v: unknown): v is RegExp {
|
||||
return v instanceof RegExp
|
||||
}
|
||||
|
||||
export function isDate(v: unknown): v is Date {
|
||||
return v instanceof Date
|
||||
}
|
||||
|
||||
export function isNull(v: unknown): v is null {
|
||||
return v === null
|
||||
}
|
||||
|
||||
export function isDef<T>(v: unknown): v is Exclude<T, null | undefined> {
|
||||
return v !== undefined && v !== null
|
||||
}
|
||||
|
||||
export function isUndef(v: unknown): v is undefined {
|
||||
return v === undefined
|
||||
}
|
||||
|
||||
export function isUndefOrNull(v: unknown): v is null | undefined {
|
||||
return v === undefined || v === null
|
||||
}
|
58
global/storage.ts
Normal file
@ -0,0 +1,58 @@
|
||||
import { isNull, isPlainObject } from '@/global/is'
|
||||
|
||||
// 所有 key 用常量存储起来
|
||||
export enum StorageKeys {
|
||||
TOKEN = 'TOKEN',
|
||||
NAME_LIST = 'NAME_LIST',
|
||||
}
|
||||
|
||||
export function setStorage(key: string, val: string): void {
|
||||
localStorage.setItem(key, val)
|
||||
}
|
||||
|
||||
export function getStorage(key: string): string | null {
|
||||
return localStorage.getItem(key) || ''
|
||||
}
|
||||
|
||||
export function removeStorage(key: string): void {
|
||||
localStorage.removeItem(key)
|
||||
}
|
||||
|
||||
// 判断是否存在
|
||||
export function hasStorage(key: string): boolean {
|
||||
return !isNull(getStorage(key))
|
||||
}
|
||||
// 取数组类型的,直接返回解析后的数组
|
||||
export function getStorageArray(key: string): Array<unknown> | null {
|
||||
const data = localStorage.getItem(key)
|
||||
if (isNull(data)) {
|
||||
return data
|
||||
}
|
||||
try {
|
||||
const arr = JSON.parse(data)
|
||||
if (Array.isArray(arr)) {
|
||||
return arr
|
||||
}
|
||||
localStorage.removeItem(key)
|
||||
} catch (err) {
|
||||
console.log('json parse error getStorageArray', err)
|
||||
}
|
||||
return null
|
||||
}
|
||||
// 取对象类型的,直接返回解析后的对象
|
||||
export function getStorageObject(key: string): Object | null {
|
||||
const data = localStorage.getItem(key)
|
||||
if (data === null) {
|
||||
return data
|
||||
}
|
||||
try {
|
||||
const obj = JSON.parse(data)
|
||||
if (isPlainObject(obj)) {
|
||||
return obj
|
||||
}
|
||||
localStorage.removeItem(key)
|
||||
} catch (err) {
|
||||
console.log('json parse error getStorageObject', err)
|
||||
}
|
||||
return null
|
||||
}
|
77
nuxt.config.ts
Normal file
@ -0,0 +1,77 @@
|
||||
// https://nuxt.com/docs/api/configuration/nuxt-config
|
||||
import { defineNuxtConfig } from 'nuxt/config'
|
||||
|
||||
export default defineNuxtConfig({
|
||||
runtimeConfig: {
|
||||
public: {
|
||||
cdnDomain: 'https://cdn.web.0rui.cn'
|
||||
}
|
||||
},
|
||||
app: {
|
||||
baseURL:'/web/',
|
||||
},
|
||||
|
||||
nitro: {
|
||||
routeRules: {
|
||||
'/**': { trailingSlash: false }
|
||||
}
|
||||
},
|
||||
|
||||
router: {
|
||||
// extendRoutes(routes, resolve) {
|
||||
// routes.push({
|
||||
// name: 'index_info',
|
||||
// path: '/params/:param1', // * 表示可选的多个参数
|
||||
// component: resolve(__dirname, 'pages/index_info.vue')
|
||||
// });
|
||||
// }
|
||||
},
|
||||
|
||||
// 设置为false以启用客户端渲染,适合静态生成
|
||||
ssr: false,
|
||||
|
||||
// 静态生成配置
|
||||
generate: {
|
||||
routes: [
|
||||
'/',
|
||||
'/aboutUs',
|
||||
'/proServices',
|
||||
'/proServices_con',
|
||||
'/societyDuty',
|
||||
'/societyDutyNew',
|
||||
'/concatUs',
|
||||
'/customerReviews'
|
||||
]
|
||||
},
|
||||
|
||||
css: [
|
||||
'swiper/css',
|
||||
'swiper/css/mousewheel',
|
||||
'@/assets/css/common.scss'
|
||||
],
|
||||
|
||||
devtools: { enabled: true },
|
||||
|
||||
postcss: {
|
||||
plugins: {
|
||||
autoprefixer: {},
|
||||
tailwindcss: {},
|
||||
},
|
||||
},
|
||||
|
||||
modules: ['@pinia/nuxt', 'nuxt-icons'],
|
||||
|
||||
vite: {
|
||||
server: {
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: "http://192.168.10.140:8088/api",
|
||||
changeOrigin: true,
|
||||
rewrite: (path) => path.replace(/^\/api/, ''),
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
compatibilityDate: '2025-05-15'
|
||||
})
|
14022
package-lock.json
generated
Normal file
47
package.json
Normal file
@ -0,0 +1,47 @@
|
||||
{
|
||||
"name": "nuxt-app",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "nuxt build",
|
||||
"dev": "nuxt dev",
|
||||
"generate": "nuxt generate",
|
||||
"preview": "nuxt preview",
|
||||
"postinstall": "nuxt prepare",
|
||||
"build:static": "node scripts/build-static.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nuxt/devtools": "latest",
|
||||
"@nuxtjs/i18n": "8.0.0-beta.10",
|
||||
"@typescript-eslint/eslint-plugin": "^6.15.0",
|
||||
"@typescript-eslint/parser": "^6.15.0",
|
||||
"autoprefixer": "^10.4.16",
|
||||
"eslint": "^8.56.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-plugin-prettier": "^5.1.0",
|
||||
"eslint-plugin-vue": "^9.19.2",
|
||||
"naive-ui": "^2.41.0",
|
||||
"nuxt": "^3.8.2",
|
||||
"prettier": "^3.1.1",
|
||||
"sass": "^1.69.5",
|
||||
"tailwindcss": "^3.4.0",
|
||||
"typescript": "^5.3.3",
|
||||
"vue": "^3.3.12",
|
||||
"vue-router": "^4.2.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"@pinia/nuxt": "^0.5.1",
|
||||
"ant-design-vue": "^4.0.8",
|
||||
"axios": "^1.6.2",
|
||||
"callapp-lib": "^3.5.3",
|
||||
"js-cookie": "^3.0.5",
|
||||
"nuxt-icons": "^3.2.1",
|
||||
"pinia": "^2.1.7",
|
||||
"scrollreveal": "^4.0.9",
|
||||
"swiper": "^11.2.5",
|
||||
"vue-i18n": "^9.8.0",
|
||||
"vue-swiper-animate": "^1.0.0"
|
||||
},
|
||||
"browserslist": [
|
||||
"cover 99.5%"
|
||||
]
|
||||
}
|
409
pages/index.vue
Normal file
@ -0,0 +1,409 @@
|
||||
<template>
|
||||
<div style="width: 100%;">
|
||||
<!-- Swiper 容器 -->
|
||||
<div class="group_666" style="position: relative;height: 100vh;">
|
||||
<AppHeader v-if="swiper_exp > 0"/>
|
||||
<swiper class="swiper-container h-full" @swiper="onSwiperNews" v-bind="swiperOptionsNews">
|
||||
<swiper-slide>
|
||||
<img :src="`/img/index/homebg.png`" style="width: 100%;height: 100%;object-fit: cover;">
|
||||
<div style="position: absolute;bottom: 30px;right:30px;">
|
||||
<img :src="`/img/index/hmouse.png`" alt="">
|
||||
</div>
|
||||
</swiper-slide>
|
||||
<!-- 首页 -->
|
||||
<swiper-slide>
|
||||
<AppHome></AppHome>
|
||||
</swiper-slide>
|
||||
<!-- 关于我们 -->
|
||||
<swiper-slide>
|
||||
<AppAbout></AppAbout>
|
||||
</swiper-slide>
|
||||
<!-- 新闻动态 -->
|
||||
<swiper-slide>
|
||||
<AppNews></AppNews>
|
||||
</swiper-slide>
|
||||
<!-- 信息公开 -->
|
||||
<swiper-slide>
|
||||
<AppMessage></AppMessage>
|
||||
</swiper-slide>
|
||||
<!-- 团务百科 -->
|
||||
<swiper-slide>
|
||||
<AppRegiment></AppRegiment>
|
||||
</swiper-slide>
|
||||
</swiper>
|
||||
|
||||
<!-- <div style="position: absolute;width: 100%;z-index: 100;">
|
||||
<div class="flex-row justify-center align-center">
|
||||
|
||||
<div style="position: absolute;bottom: 30px;right:30px;">
|
||||
<img :src="`/img/index/mouse.png`" alt="">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div> -->
|
||||
<!-- 右分享 -->
|
||||
<div v-if="swiper_exp > 0" class="flex flex-col fiximg" style="position: absolute;top: 100px;right:36px;align-items: center;z-index: 111;" >
|
||||
<img :src="`/img/qiqiu.png`" alt=""></img>
|
||||
<img class="imgs" :src="`/img/index/douyin.png`" alt="">
|
||||
<img class="imgs" :src="`/img/index/wb.png`" alt="">
|
||||
<img class="imgs" :src="`/img/index/wx.png`" alt="">
|
||||
<img class="imgs" :src="`/img/index/blbl.png`" alt="">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { Swiper, SwiperSlide } from 'swiper/vue'
|
||||
import { nextTick, ref } from 'vue'
|
||||
import 'swiper/css'
|
||||
import { Autoplay, Navigation, Pagination, Scrollbar, A11y, EffectCoverflow, EffectFade,Mousewheel } from "swiper/modules";
|
||||
import ScrollReveal from 'scrollreveal';
|
||||
import { NNumberAnimation } from 'naive-ui'
|
||||
let modules = [Autoplay, A11y, EffectCoverflow, EffectFade,Mousewheel];
|
||||
|
||||
import "swiper/css";
|
||||
import "swiper/css/navigation";
|
||||
import "swiper/css/pagination";
|
||||
import 'swiper/css/effect-coverflow';
|
||||
import 'swiper/css/mousewheel'
|
||||
import 'swiper/css/grid'
|
||||
import 'swiper/css/effect-fade'
|
||||
import 'swiper/css/autoplay'
|
||||
import * as swiperAni from '@/assets/animate/animate.js'
|
||||
import $api from '@/service/webRequest'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useStore } from '~/store'
|
||||
const cdnUrl = useCdn()
|
||||
|
||||
const { locale } = useI18n()
|
||||
|
||||
let newsSwiper: any = null
|
||||
const onSwiperNews = (swiper: any) => {
|
||||
newsSwiper = swiper
|
||||
swiper.on('slideChange', () => {
|
||||
// 更新当前活动幻灯片索引
|
||||
swiper_exp.value = swiper.realIndex
|
||||
})
|
||||
}
|
||||
const swiper_exp = ref(0);
|
||||
|
||||
const swiperOptionsNews = {
|
||||
autoplay: {
|
||||
delay: 11000,
|
||||
disableOnInteraction: false,
|
||||
},
|
||||
direction: 'horizontal',
|
||||
mousewheel: {
|
||||
releaseOnEdges: true,
|
||||
},
|
||||
slidesPerView: 1,
|
||||
speed: 500,
|
||||
// effect: 'fade',
|
||||
// loop: true,
|
||||
modules: [Mousewheel],
|
||||
// navigation: {
|
||||
// nextEl: '#swipen_prev',
|
||||
// prevEl: '#swipen_next',
|
||||
// },
|
||||
}
|
||||
|
||||
let vesSwiper: any = null
|
||||
const onSwiperExp = (swiper: any) => {
|
||||
vesSwiper = swiper
|
||||
// 监听幻灯片变化事件
|
||||
swiper.on('slideChange', () => {
|
||||
// 更新当前活动幻灯片索引
|
||||
activeSlideIndex.value = swiper.realIndex % 3
|
||||
})
|
||||
}
|
||||
|
||||
const activeSlideIndex = ref(0);
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
onMounted(() => {
|
||||
|
||||
const coMobile = /Mobi|Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
|
||||
|
||||
if (coMobile) {
|
||||
// router.push('/phone_index/')
|
||||
} else {
|
||||
// router.push('/')
|
||||
}
|
||||
nextTick(() => {
|
||||
// 初始化 ScrollReveal
|
||||
setTimeout(() => {
|
||||
animate()
|
||||
}, 500)
|
||||
})
|
||||
})
|
||||
|
||||
const animate = () => {
|
||||
|
||||
const sr = ScrollReveal();
|
||||
sr.reveal('.leftBoxTop', {
|
||||
origin: "left",
|
||||
distance: "1000px",
|
||||
duration: 1300,
|
||||
delay: 100,
|
||||
opacity: 0,
|
||||
scale: 0.9,
|
||||
reset: true,
|
||||
mobile: true,
|
||||
})
|
||||
sr.reveal('.leftBox', {
|
||||
origin: "left",
|
||||
distance: "1000px",
|
||||
duration: 1300,
|
||||
delay: 100,
|
||||
opacity: 0,
|
||||
scale: 0.9,
|
||||
reset: true,
|
||||
mobile: true,
|
||||
})
|
||||
sr.reveal('.rightBox', {
|
||||
origin: "right",
|
||||
distance: "1000px",
|
||||
duration: 1300,
|
||||
delay: 100,
|
||||
opacity: 0,
|
||||
scale: 0.9,
|
||||
reset: true,
|
||||
mobile: true,
|
||||
})
|
||||
sr.reveal('.topBox', {
|
||||
origin: "top",
|
||||
distance: "1000px",
|
||||
duration: 1300,
|
||||
delay: 100,
|
||||
opacity: 0,
|
||||
scale: 0.9,
|
||||
reset: true,
|
||||
mobile: true,
|
||||
})
|
||||
sr.reveal('.bottomBox', {
|
||||
origin: "bottom",
|
||||
distance: "1000px",
|
||||
duration: 1300,
|
||||
delay: 100,
|
||||
opacity: 0,
|
||||
scale: 0.9,
|
||||
reset: true,
|
||||
mobile: true,
|
||||
})
|
||||
sr.reveal('.numberTopBox', {
|
||||
origin: "top",
|
||||
distance: "1000px",
|
||||
duration: 1300,
|
||||
delay: 100,
|
||||
opacity: 0,
|
||||
scale: 0.9,
|
||||
reset: true,
|
||||
mobile: true,
|
||||
beforeReveal: function (el: any) {
|
||||
// numberAnimationInstRef.value.play()
|
||||
// numberAnimationInstRefKH.value.play()
|
||||
// numberAnimationInstRefJS.value.play()
|
||||
// numberAnimationInstRefHY.value.play()
|
||||
},
|
||||
})
|
||||
sr.reveal('.group_29 ', {
|
||||
origin: "bottom",
|
||||
distance: "500px",
|
||||
opacity: 0,
|
||||
scale: 0.9,
|
||||
reset: false,
|
||||
mobile: true,
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "@/assets/animate/animate.min.css";
|
||||
@import "@/assets/index.scss";
|
||||
|
||||
:deep(.dswper .swiper-slide-next) {
|
||||
transform: translate3d(0px, 0px, -507px) rotateX(0deg) rotateY(0deg) scale(1) !important;
|
||||
}
|
||||
|
||||
:deep(.dswper .swiper-slide-prev) {
|
||||
transform: translate3d(0px, 0px, -507px) rotateX(0deg) rotateY(0deg) scale(1) !important;
|
||||
}
|
||||
|
||||
.group_666 .swiper-slide img {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
// transition: 1s linear 2s;
|
||||
// transform: scale(1.1, 1.1);
|
||||
}
|
||||
|
||||
// .group_666 .swiper-slide-active img,
|
||||
// .swiper-slide-duplicate-active img {
|
||||
// transition: 6s linear;
|
||||
// transform: scale(1, 1);
|
||||
// }
|
||||
|
||||
.bottom_imgs {
|
||||
background: var(--qall) no-repeat;
|
||||
width: 1230px;
|
||||
height: 272px;
|
||||
background-size: 100% 100%;
|
||||
margin: 0 auto;
|
||||
|
||||
}
|
||||
|
||||
.content_box {
|
||||
background: var(--m1);
|
||||
width: 561px;
|
||||
height: 521px;
|
||||
z-index: 1;
|
||||
position: absolute;
|
||||
right: -12px;
|
||||
bottom: -13px;
|
||||
background-size: 100%;
|
||||
}
|
||||
|
||||
.contactForm {
|
||||
width: 100%;
|
||||
|
||||
.inputform {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 1200px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#myTextarea {
|
||||
width: 1200px;
|
||||
height: 167px;
|
||||
background: #FFFFFF;
|
||||
border-radius: 6px 6px 6px 6px;
|
||||
opacity: 0.8;
|
||||
padding-left: 20px;
|
||||
padding-top: 20px;
|
||||
resize: none;
|
||||
}
|
||||
|
||||
#myTextarea::placeholder {
|
||||
color: #768597;
|
||||
}
|
||||
|
||||
#myTextarea:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.char-count {
|
||||
position: absolute;
|
||||
bottom: 5px;
|
||||
/* 根据需要调整距离底部的位置 */
|
||||
right: 10px;
|
||||
/* 根据需要调整距离右侧的位置 */
|
||||
font-size: 12px;
|
||||
/* 根据需要调整字体大小 */
|
||||
color: #A8CBFF;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.contactInput {
|
||||
font-size: 18px;
|
||||
height: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
.contactBut {
|
||||
width: 108px;
|
||||
border-radius: 4px 4px 4px 4px;
|
||||
position: absolute;
|
||||
bottom: 20px;
|
||||
right: 30px;
|
||||
height: 36px;
|
||||
background-color: #222222;
|
||||
border: none;
|
||||
font-weight: 400;
|
||||
font-size: 16px;
|
||||
line-height: 28px;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
.pop {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, .8);
|
||||
z-index: 200;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.popCont {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.pop_video_close {
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: -75px;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
background: var(--close) no-repeat 0 0;
|
||||
background-size: 100% auto;
|
||||
border: 6px solid #979797;
|
||||
}
|
||||
|
||||
.pop_video_cont {
|
||||
width: 600px;
|
||||
border: 6px solid #979797;
|
||||
background: #000;
|
||||
}
|
||||
|
||||
.pop_video_cont video {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.hy_my_home {
|
||||
width: 585px;
|
||||
height: 300px;
|
||||
margin: 0 auto;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
transform: scale(1.05);
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.news_my_home {
|
||||
cursor: pointer;
|
||||
|
||||
&:hover .news_title_home {
|
||||
color: coral;
|
||||
}
|
||||
}
|
||||
|
||||
.news_title_home {
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
.fiximg{
|
||||
.imgs{
|
||||
width: 63px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
88
pages/info/[id].vue
Normal file
@ -0,0 +1,88 @@
|
||||
<template>
|
||||
<div style="width: 100%;">
|
||||
<div style="height:90px;background-color: #ffffff;"></div>
|
||||
<div style="background-color: #F8F8F8;padding: 30px;">
|
||||
<div class="content_class" style="">
|
||||
<div style="font-size: 32px;font-weight: 700;color: #323232;">{{ info.title }}</div>
|
||||
<div style="font-size: 14px;font-weight: 400;margin-top: 30px;color: #768597;">
|
||||
<span>发布人:{{ info.author }}</span>
|
||||
<span style="margin-left: 150px;">发布时间:{{ info.release_time_text }} </span>
|
||||
</div>
|
||||
<div style="width: 98%;margin: 20px auto;height: 1px;background-color: #EEEEEE;"></div>
|
||||
<div class="info_content" v-html="info.content"></div>
|
||||
<div style="width: 98%;margin: 20px auto;height: 1px;background-color: #EEEEEE;"></div>
|
||||
<div style="display: flex;justify-content: space-between;align-items: center;">
|
||||
<div>
|
||||
<div @click="openNews(1)" style="cursor: pointer;">上一篇:{{ info.prev != null ? info.prev.title : '暂无' }}
|
||||
</div>
|
||||
<div @click="openNews(2)" style="margin-top: 20px;cursor: pointer;">
|
||||
下一篇:{{ info.next != null ? info.next.title : '暂无' }}</div>
|
||||
</div>
|
||||
<div @click="delWeb">
|
||||
<div
|
||||
style="color: #999999;;cursor: pointer;;border: 1px solid #999999;width: 108px;height: 40px;line-height: 40px;text-align: center;">
|
||||
返回列表</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { nextTick, ref } from 'vue'
|
||||
const route = useRoute()
|
||||
import $api from '@/service/webRequest'
|
||||
import { Item } from 'ant-design-vue/es/menu'
|
||||
const id = ref(route.params.id)
|
||||
const openNews = (type) => {
|
||||
if (type == 1 && info.value.prev != null) {
|
||||
window.open('/info/' + info.value.prev.id, '_self');
|
||||
}
|
||||
if (type == 2 && info.value.next != null) {
|
||||
window.open('/info/' + info.value.next.id, '_self');
|
||||
}
|
||||
}
|
||||
// 新闻数据
|
||||
onMounted(() => {
|
||||
getInfo();
|
||||
})
|
||||
const info = ref({});
|
||||
const getInfo = async () => {
|
||||
const res = await $api.get('/api/home.news/detail?id=' + id.value)
|
||||
console.log(res);
|
||||
info.value = res.data.data;
|
||||
}
|
||||
const delWeb = () => {
|
||||
window.close();
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "@/assets/animate/animate.min.css";
|
||||
@import "@/assets/index.scss";
|
||||
|
||||
.info_content img {
|
||||
width: 80% !important;
|
||||
margin: 0 auto;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.info_content {
|
||||
line-height: 35px;
|
||||
}
|
||||
|
||||
.content_class {
|
||||
width: 60%;
|
||||
min-height: 500px;
|
||||
margin: 0 auto;
|
||||
background-color: #ffffff;
|
||||
padding: 30px;
|
||||
}
|
||||
@media (max-width: 1440px) {
|
||||
.content_class{
|
||||
width: 78%;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
62
plugins/cdn-image.ts
Normal file
@ -0,0 +1,62 @@
|
||||
// 插件用于处理静态生成模式下的图片CDN路径
|
||||
import { defineNuxtPlugin } from '#app'
|
||||
|
||||
export default defineNuxtPlugin(() => {
|
||||
// CDN基础URL
|
||||
const cdnBaseUrl = 'https://cdn.web.0rui.cn/'
|
||||
|
||||
// 创建一个全局方法用于转换图片路径
|
||||
return {
|
||||
provide: {
|
||||
// 转换图片路径为CDN路径
|
||||
cdnImage: (path: string) => {
|
||||
// 如果路径已经是完整的URL,则直接返回
|
||||
if (path.startsWith('http://') || path.startsWith('https://')) {
|
||||
return path
|
||||
}
|
||||
|
||||
// 判断是否为图片资源
|
||||
const isImage = /\.(jpg|jpeg|png|gif|svg|webp)$/i.test(path)
|
||||
if (!isImage) {
|
||||
return path // 非图片资源直接返回原路径
|
||||
}
|
||||
|
||||
// 处理以public开头的路径
|
||||
if (path.startsWith('public/')) {
|
||||
return `${cdnBaseUrl}${path.replace('public/', '')}`
|
||||
}
|
||||
|
||||
// 处理以/public开头的路径
|
||||
if (path.startsWith('/public/')) {
|
||||
return `${cdnBaseUrl}${path.replace('/public/', '')}`
|
||||
}
|
||||
|
||||
// 处理以img/开头的路径
|
||||
if (path.startsWith('img/')) {
|
||||
return `${cdnBaseUrl}${path}`
|
||||
}
|
||||
|
||||
// 处理以/img开头的路径
|
||||
if (path.startsWith('/img/')) {
|
||||
return `${cdnBaseUrl}${path.substring(1)}`
|
||||
}
|
||||
|
||||
// 处理以_nuxt开头的路径
|
||||
if (path.startsWith('/_nuxt/')) {
|
||||
// 提取_nuxt后面的路径部分
|
||||
const pathWithoutPrefix = path.replace('/_nuxt/', '')
|
||||
// 如果路径包含img/,保留该结构
|
||||
if (pathWithoutPrefix.includes('img/')) {
|
||||
return `${cdnBaseUrl}${pathWithoutPrefix}`
|
||||
} else {
|
||||
// 否则添加img/前缀
|
||||
return `${cdnBaseUrl}img/${pathWithoutPrefix}`
|
||||
}
|
||||
}
|
||||
|
||||
// 其他情况,直接拼接CDN基础URL和路径
|
||||
return `${cdnBaseUrl}img/${path}`
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
34
plugins/cdn.ts
Normal file
@ -0,0 +1,34 @@
|
||||
import { defineNuxtPlugin } from '#app'
|
||||
|
||||
export default defineNuxtPlugin((nuxtApp) => {
|
||||
const config = useRuntimeConfig()
|
||||
|
||||
// 定义全局变量
|
||||
const cdnUrl = config.public.cdnDomain
|
||||
console.log(cdnUrl);
|
||||
|
||||
// 在客户端注入 CSS 变量
|
||||
if (process.client) {
|
||||
document.documentElement.style.setProperty('--cdn-domain', cdnUrl)
|
||||
}
|
||||
|
||||
// 只使用一种注入方式
|
||||
return {
|
||||
provide: {
|
||||
cdnUrl
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// 为了 TypeScript 支持
|
||||
declare module '#app' {
|
||||
interface NuxtApp {
|
||||
$cdnUrl: string
|
||||
}
|
||||
}
|
||||
|
||||
declare module '@vue/runtime-core' {
|
||||
interface ComponentCustomProperties {
|
||||
$cdnUrl: string
|
||||
}
|
||||
}
|
19
plugins/i18n.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import { createI18n } from 'vue-i18n'
|
||||
import zh from './locales/zh'
|
||||
import en from './locales/en'
|
||||
|
||||
export const i18n: any = createI18n({
|
||||
legacy: false,
|
||||
globalInjection: true,
|
||||
warnHtmlMessage: false,
|
||||
locale: 'zh',
|
||||
messages: {
|
||||
en,
|
||||
zh,
|
||||
},
|
||||
})
|
||||
export default defineNuxtPlugin(({ vueApp }) => {
|
||||
vueApp.use(i18n)
|
||||
})
|
||||
|
||||
export const $i18n = i18n.global.t.bind(i18n.global)
|
96
plugins/locales/en.ts
Normal file
@ -0,0 +1,96 @@
|
||||
export default {
|
||||
home: 'Home',
|
||||
|
||||
// Index page
|
||||
index_name: 'Henan Navigate Trading Co., Ltd',
|
||||
index_main: 'Main Specialized, Refined, Special and New areas',
|
||||
index_get_to: 'Get To Know US',
|
||||
index_about: 'About US',
|
||||
index_services: 'SERVICES',
|
||||
index_clients: 'CLIENTS',
|
||||
index_news: 'News',
|
||||
index_contact: 'Contact US',
|
||||
index_share: 'Share Wed',
|
||||
|
||||
// Index section 2
|
||||
index_m1: 'Main business areas',
|
||||
index_m2: 'Our main products include steel, pigiron furnace materials, coal, chemical materials, non-ferrous metals, natural gas, agricultural products, etc…',
|
||||
index_m3: 'Learn More',
|
||||
index_m4: 'Industry',
|
||||
index_m4_1: 'Import and export of second-hand mining equipment, accessories, and components.',
|
||||
index_m5: 'Agriculture',
|
||||
index_m5_1: 'Import and export of grain, oil, and upstream raw materials.',
|
||||
index_m6: 'Raw materials',
|
||||
index_m6_1: 'Import and export of chemical, papermaking, grinding tools and other raw materials.',
|
||||
index_m7: 'Navigation',
|
||||
|
||||
// Index section 3
|
||||
index_s1: 'Factory Direct Supply, Excellent Quality',
|
||||
index_s2: 'Market research and analysis: Based on big data analysis, provide in-depth insights into the target market to help you accurately position product needs and seize business opportunities. Supply Chain Management: From supplier screening to logistics distribution, we provide efficient and transparent supply chain solutions to ensure the safe and fast delivery of your goods to their destination. Import and export agency services: Familiar with laws, regulations, and customs policies of various countries, simplify cumbersome procedures, and ensure smooth customs clearance of your goods. Quality control and inspection: Cooperate with third-party testing institutions to strictly control product quality, making your products stand out in the fiercely competitive market. Business consulting services: A professional team provides customized business solutions to help enterprises steadily move forward in the international market.',
|
||||
index_s3: 'Excellent Quality',
|
||||
index_s4: 'Customized Services',
|
||||
index_s5: 'Fast Logistics',
|
||||
|
||||
// Index section 4
|
||||
index_a1: 'About Us',
|
||||
index_a2: "Henan Navigate Trading Co., Ltd. is a professional import and export trading enterprise, mainly engaged in industrial fields such as second-hand mining equipment, accessories and parts, agricultural fields such as grain and oil and upstream raw materials, as well as raw materials such as chemical, papermaking, and grinding tools. The company's headquarters is located in Zhengzhou, Henan Province. As a state-owned enterprise with a background, we have won wide acclaim in the mining and engineering industries with our rich industry experience and professional team.",
|
||||
|
||||
// Index section 5
|
||||
index_n1: 'News Consultation',
|
||||
index_n2: 'OUR LATEST STORIES IN FOCUS',
|
||||
|
||||
// About page
|
||||
about_a1: 'Established in the vibrant year of 2024,Henan Navigate Trading Co Ltd. has emerged as a beacon of innovation and reliability in the global machinery trade landscape. With our roots deeply embedded in the industrious province of Henan, China, we are committed to delivering the highest standards of quality and service to our esteemed clientele across the globe.',
|
||||
about_a2: 'Our Core Philosophy Revolves Around Three Fundamental Principles',
|
||||
about_a3: 'Integrity',
|
||||
about_a4: 'Innovation',
|
||||
about_a5: 'Excellence',
|
||||
about_a6: 'These principles guide our every action, from the procurement of raw materials to the final delivery of our products. We believe that by adhering to these values, we can forge lasting partnerships with our clients and contribute to their success.',
|
||||
about_a7: 'Comprehensive Solutions',
|
||||
about_a8: "We understand that every business has unique requirements, and that's why we offer a wide array of services tailored to the specific needs of our clients. From the import and export of machinery to after-sales support, we provide a seamless experience that ensures the smooth operation of our clients' businesses.",
|
||||
|
||||
// Services page
|
||||
servers_b1: 'Our Services',
|
||||
servers_b2: 'Market research and analysis: Based on big data analysis, provide in-depth insights into the target market to help you accurately position product needs and seize business opportunities. Supply Chain Management: From supplier screening to logistics distribution, we provide efficient and transparent supply chain solutions to ensure the safe and fast delivery of your goods to their destination. Import and export agency services: Familiar with laws, regulations, and customs policies of various countries, simplify cumbersome procedures, and ensure smooth customs clearance of your goods. Quality control and inspection: Cooperate with third-party testing institutions to strictly control product quality, making your products stand out in the fiercely competitive market. Business consulting services: A professional team provides customized business solutions to help enterprises steadily move forward in the international market.',
|
||||
servers_b3: 'Market Analysis and Research',
|
||||
servers_b4: 'We offer in-depth market analysis and research services to help clients understand consumer behavior, market trends, and competitive environments in their target markets, thereby formulating effective market entry strategies.',
|
||||
servers_b5: 'Product Procurement and Supply Management',
|
||||
servers_b6: 'We search and select high-quality suppliers globally to ensure product quality and the stability of the supply chain. At the same time, we provide flexible procurement plans to meet the diverse needs of our clients.',
|
||||
servers_b7: 'Logistics and Warehousing',
|
||||
servers_b8: 'We collaborate with several renowned logistics companies to provide efficient and reliable logistics solutions. Whether by sea, air, or land transport, we can ensure that goods arrive safely and on time at their destinations. Additionally, we offer warehousing management services to help clients optimize their inventory.',
|
||||
servers_b9: 'Trade Financing and Settlement',
|
||||
servers_b10: 'We provide trade financing services to our clients, including the establishment of letters of credit, guarantees, and export tax rebates, to help clients solve cash flow issues. At the same time, we offer various settlement methods to ensure the convenience and security of transactions.',
|
||||
servers_b11: 'Compliance and Risk Management',
|
||||
servers_b12: 'We strictly adhere to international trade regulations and provide clients with compliance consulting and risk assessment services to help clients avoid trade risks and protect their interests.',
|
||||
servers_b13: 'Customer Relationship Management',
|
||||
servers_b14: 'We strictly adhere to international trade regulations and provide clients with compliance consulting and risk assessment services to help clients avoid trade risks and protect their interests.',
|
||||
servers_b15: 'Our Commitment',
|
||||
servers_b16: 'We commit to providing the most professional and considerate service to our clients, no matter where they are. Our goal is to become the most trusted trade partner for our clients and to help them achieve success in the global market.',
|
||||
|
||||
// Clients page
|
||||
clients_b1: 'Cooperative Partner',
|
||||
clients_b2: 'We are committed to establishing mutually beneficial partnerships with customers worldwide. By deeply understanding market demands and customer expectations, we offer customized foreign trade solutions that encompass procurement, logistics, and financial support. Our goal is to help our clients achieve business growth and market expansion through efficient supply chain management and professional market insights.',
|
||||
clients_b3: 'SinopecGroup',
|
||||
clients_b4: 'Cooperating with XX Foreign Trade Company has been a delightful experience. Their professional team and efficient service have left a deep impression on us, not only excelling in project management but also demonstrating exceptional capabilities in ensuring the stability and responsiveness of the supply chain. Moreover, the customized software solutions provided by XX Foreign Trade Company have greatly improved our business efficiency, enabling us to adapt quickly to market changes, optimize our workflow, enhance customer satisfaction.',
|
||||
|
||||
// List page
|
||||
list_b1: 'Latest News',
|
||||
list_b2: 'Latest Industry Trends',
|
||||
list_b3: 'View details',
|
||||
|
||||
// Contact page
|
||||
contact_b1: 'Contact US',
|
||||
contact_b2: 'Your name',
|
||||
contact_b3: 'Your contact information',
|
||||
contact_b4: 'Leave what you want to say',
|
||||
contact_b5: 'Send Out',
|
||||
contact_b6: 'Follow us',
|
||||
|
||||
contact_name_required: 'Name is required',
|
||||
contact_phone_required: 'Phone number is required',
|
||||
contact_message_required: 'Message is required',
|
||||
//提交成功
|
||||
contact_success_title: 'Thank you for your submission',
|
||||
//提交失败
|
||||
contact_fail_title: 'Submission failed',
|
||||
}
|
95
plugins/locales/zh.ts
Normal file
@ -0,0 +1,95 @@
|
||||
export default {
|
||||
home: '首页',
|
||||
// 静态页多语言
|
||||
index_name: '河南纳威格特商贸有限公司',
|
||||
index_main: '主要专业、精细、特色、新领域',
|
||||
index_get_to: '了解我们',
|
||||
index_about: '关于我们',
|
||||
index_services: '客户服务',
|
||||
index_clients: '我的客户',
|
||||
index_news: '最新新闻',
|
||||
index_contact: '联系我们',
|
||||
index_share: '分享',
|
||||
|
||||
// 首页2
|
||||
index_m1: '主营业务领域',
|
||||
index_m2: '我们的主要产品包括钢铁、生铁炉料、煤炭、化工材料、有色金属、天然气、农产品等……',
|
||||
index_m3: '了解更多',
|
||||
index_m4: '工业',
|
||||
index_m4_1: '二手采矿设备、配件和组件的进出口。',
|
||||
index_m5: '农业',
|
||||
index_m5_1: '粮食、油料和上游原材料的进出口。',
|
||||
index_m6: '原材料',
|
||||
index_m6_1: '化工、造纸、磨具等原材料的进出口。',
|
||||
index_m7: '导航',
|
||||
|
||||
// 首页3
|
||||
index_s1: '工厂直供,优质产品',
|
||||
index_s2: '市场研究与分析:基于大数据分析,提供深入的目标市场洞察,帮助您精准定位产品需求,抓住商业机会。供应链管理:从供应商筛选到物流配送,我们提供高效透明的供应链解决方案,确保您的货物安全快速地送达目的地。进出口代理服务:熟悉各国法律法规和海关政策,简化繁琐程序,确保您的货物顺利通关。质量控制与检验:与第三方检测机构合作,严格控制产品质量,使您的产品在激烈的市场竞争中脱颖而出。商务咨询服务:专业团队提供定制化的商务解决方案,帮助企业稳步进军国际市场。',
|
||||
index_s3: '优质产品',
|
||||
index_s4: '定制服务',
|
||||
index_s5: '快速物流',
|
||||
|
||||
// 首页4
|
||||
index_a1: '关于我们',
|
||||
index_a2: '河南导航贸易有限公司是一家专业的进出口贸易企业,主要从事二手采矿设备、配件和部件、粮食和油料及上游原材料、以及化工、造纸和磨具等原材料的进出口业务。公司总部位于河南省郑州市。作为一家具有国资背景的企业,我们凭借丰富的行业经验和专业的团队,在矿业和工程行业赢得了广泛赞誉。',
|
||||
|
||||
// 首页5
|
||||
index_n1: '新闻资讯',
|
||||
index_n2: '我们的最新焦点故事',
|
||||
|
||||
// about
|
||||
about_a1: '成立于充满活力的2024年,河南纳威格特商贸有限公司在全球机械贸易领域崭露头角,成为创新和可靠的典范。我们根植于中国勤劳的河南省,致力于向全球尊贵的客户提供最高标准的质量和服务。',
|
||||
about_a2: '我们的核心理念围绕三个基本原则',
|
||||
about_a3: '诚信',
|
||||
about_a4: '创新',
|
||||
about_a5: '卓越',
|
||||
about_a6: '这些原则指导着我们的每一个行动,从原材料的采购到最终产品的交付。我们相信,通过遵循这些价值观,我们可以与客户建立持久的合作关系,并为他们的成功做出贡献。',
|
||||
about_a7: '全面解决方案',
|
||||
about_a8: '我们理解每个企业都有独特的需求,因此我们提供一系列针对客户需求量身定制的服务。从机械设备的进出口到售后服务,我们提供无缝体验,确保客户的业务顺畅运营。',
|
||||
|
||||
// servers
|
||||
servers_b1: '我们的服务',
|
||||
servers_b2: '市场研究与分析:基于大数据分析,提供深入的目标市场洞察,帮助您精准定位产品需求,抓住商业机会。供应链管理:从供应商筛选到物流配送,我们提供高效透明的供应链解决方案,确保您的货物安全快速地送达目的地。进出口代理服务:熟悉各国法律法规和海关政策,简化繁琐程序,确保您的货物顺利通关。质量控制与检验:与第三方检测机构合作,严格控制产品质量,使您的产品在激烈的市场竞争中脱颖而出。商务咨询服务:专业团队提供定制化的商务解决方案,帮助企业稳步进军国际市场。',
|
||||
servers_b3: '市场分析与研究',
|
||||
servers_b4: '我们提供深入的市场分析和研究服务,帮助客户了解目标市场的消费者行为、市场趋势和竞争环境,从而制定有效的市场进入策略。',
|
||||
servers_b5: '产品采购与供应管理',
|
||||
servers_b6: '我们全球范围内搜索和选择高质量供应商,确保产品质量和供应链的稳定性。同时,我们提供灵活的采购计划,满足客户的多样化需求。',
|
||||
servers_b7: '物流与仓储',
|
||||
servers_b8: '我们与多家知名物流公司合作,提供高效可靠的物流解决方案。无论是海运、空运还是陆运,我们都能确保货物安全准时到达目的地。此外,我们还提供仓储管理服务,帮助客户优化库存。',
|
||||
servers_b9: '贸易融资与结算',
|
||||
servers_b10: '我们为客户提供贸易融资服务,包括信用证开立、担保和出口退税等,帮助客户解决现金流问题。同时,我们提供多种结算方式,确保交易的便捷和安全。',
|
||||
servers_b11: '合规与风险管理',
|
||||
servers_b12: '我们严格遵守国际贸易法规,为客户提供合规咨询和风险评估服务,帮助客户避免贸易风险,保护其利益。',
|
||||
servers_b13: '客户关系管理',
|
||||
servers_b14: '我们严格遵守国际贸易法规,为客户提供合规咨询和风险评估服务,帮助客户避免贸易风险,保护其利益。',
|
||||
servers_b15: '我们的承诺',
|
||||
servers_b16: '我们承诺为客户提供最专业和周到的服务,无论他们身处何地。我们的目标是成为客户最值得信赖的贸易伙伴,帮助他们在全球市场上取得成功。',
|
||||
|
||||
// clients
|
||||
clients_b1: '合作伙伴',
|
||||
clients_b2: '我们致力于与全球客户建立互利共赢的伙伴关系。通过深入了解市场需求和客户期望,我们提供涵盖采购、物流和金融支持的定制化外贸解决方案。我们的目标是通过高效的供应链管理和专业的市场洞察,帮助客户实现业务增长和市场扩展。',
|
||||
clients_b3: '中国石化集团',
|
||||
clients_b4: '与XX外贸公司合作是一次愉快的体验。他们的专业团队和高效服务给我们留下了深刻的印象,不仅在项目管理方面表现出色,还在确保供应链的稳定性和响应能力方面展示了卓越的能力。此外,XX外贸公司提供的定制化软件解决方案极大地提高了我们的业务效率,使我们能够迅速适应市场变化,优化工作流程,提升客户满意度。',
|
||||
|
||||
// list
|
||||
list_b1: '最新新闻',
|
||||
list_b2: '最新行业趋势',
|
||||
list_b3: '查看详情',
|
||||
|
||||
// contact
|
||||
contact_b1: '联系我们',
|
||||
contact_b2: '您的姓名',
|
||||
contact_b3: '您的联系方式',
|
||||
contact_b4: '留言',
|
||||
contact_b5: '发送',
|
||||
contact_b6: '关注我们',
|
||||
|
||||
contact_name_required: '请输入您的姓名',
|
||||
contact_phone_required: '请输入您的联系方式',
|
||||
contact_message_required: '请输入留言内容',
|
||||
//提交成功
|
||||
contact_success: '提交成功',
|
||||
//提交失败
|
||||
contact_error:'提交失败',
|
||||
}
|
7819
pnpm-lock.yaml
generated
Normal file
BIN
public/favicon.ico
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
public/img/about/ab_bg.png
Normal file
After Width: | Height: | Size: 757 KiB |
BIN
public/img/about/ab_bot.png
Normal file
After Width: | Height: | Size: 5.4 KiB |
BIN
public/img/about/ab_bots.png
Normal file
After Width: | Height: | Size: 4.7 KiB |
BIN
public/img/about/cpc.png
Normal file
After Width: | Height: | Size: 126 KiB |
BIN
public/img/about/cpcrit.png
Normal file
After Width: | Height: | Size: 241 KiB |
BIN
public/img/about/cpcrit1.png
Normal file
After Width: | Height: | Size: 220 KiB |
BIN
public/img/about/cpcrit2.png
Normal file
After Width: | Height: | Size: 272 KiB |
BIN
public/img/about/telp.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 17 KiB |
BIN
public/img/index/aboutus.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
public/img/index/aboutus1.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
public/img/index/arrow.png
Normal file
After Width: | Height: | Size: 247 B |
BIN
public/img/index/baike.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
public/img/index/baike1.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
public/img/index/blbl.png
Normal file
After Width: | Height: | Size: 4.4 KiB |
BIN
public/img/index/dlogo.png
Normal file
After Width: | Height: | Size: 129 KiB |
BIN
public/img/index/douyin.png
Normal file
After Width: | Height: | Size: 5.4 KiB |
BIN
public/img/index/fly.png
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
public/img/index/hmouse.png
Normal file
After Width: | Height: | Size: 3.2 KiB |
BIN
public/img/index/hmsearch.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
public/img/index/home.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
public/img/index/home1.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
public/img/index/homebg.png
Normal file
After Width: | Height: | Size: 2.6 MiB |
BIN
public/img/index/leftHead.png
Normal file
After Width: | Height: | Size: 183 KiB |
BIN
public/img/index/message.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
public/img/index/message1.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
public/img/index/news.png
Normal file
After Width: | Height: | Size: 974 B |
BIN
public/img/index/news1.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
public/img/index/rightcon.png
Normal file
After Width: | Height: | Size: 1.6 MiB |
BIN
public/img/index/wb.png
Normal file
After Width: | Height: | Size: 6.2 KiB |
BIN
public/img/index/wx.png
Normal file
After Width: | Height: | Size: 4.8 KiB |
BIN
public/img/index/组 25.png
Normal file
After Width: | Height: | Size: 48 KiB |
BIN
public/img/liuyanb.png
Normal file
After Width: | Height: | Size: 2.5 MiB |
BIN
public/img/message/listbg.png
Normal file
After Width: | Height: | Size: 64 KiB |
BIN
public/img/message/listbgxx.png
Normal file
After Width: | Height: | Size: 77 KiB |
BIN
public/img/message/xxgk.png
Normal file
After Width: | Height: | Size: 1.7 MiB |
BIN
public/img/qiqiu.png
Normal file
After Width: | Height: | Size: 29 KiB |
BIN
public/img/rightmore.png
Normal file
After Width: | Height: | Size: 189 B |
BIN
public/img/twbk.jpg
Normal file
After Width: | Height: | Size: 83 KiB |
BIN
public/img/xwdt.png
Normal file
After Width: | Height: | Size: 2.1 MiB |
100
scripts/build-static.js
Normal file
@ -0,0 +1,100 @@
|
||||
// 静态生成构建脚本
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { execSync } = require('child_process');
|
||||
|
||||
// CDN基础URL
|
||||
const CDN_BASE_URL = 'https://cdn.web.0rui.cn/';
|
||||
|
||||
// 输出目录
|
||||
const OUTPUT_DIR = path.resolve(__dirname, '../.output/public');
|
||||
|
||||
// 执行静态生成
|
||||
console.log('开始执行静态生成...');
|
||||
try {
|
||||
// 执行nuxt generate命令
|
||||
execSync('npm run generate', { stdio: 'inherit' });
|
||||
console.log('静态生成完成!');
|
||||
|
||||
// 检查输出目录是否存在
|
||||
if (!fs.existsSync(OUTPUT_DIR)) {
|
||||
console.error('错误:输出目录不存在!');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log('开始处理HTML文件中的图片路径...');
|
||||
|
||||
// 递归处理目录中的所有HTML文件
|
||||
processDirectory(OUTPUT_DIR);
|
||||
|
||||
console.log('所有HTML文件处理完成!');
|
||||
console.log(`静态网站已生成到: ${OUTPUT_DIR}`);
|
||||
console.log('可以使用 npm run preview 预览生成的静态网站');
|
||||
} catch (error) {
|
||||
console.error('构建过程中发生错误:', error);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归处理目录中的所有HTML文件
|
||||
* @param {string} dir 目录路径
|
||||
*/
|
||||
function processDirectory(dir) {
|
||||
const files = fs.readdirSync(dir);
|
||||
|
||||
for (const file of files) {
|
||||
const filePath = path.join(dir, file);
|
||||
const stat = fs.statSync(filePath);
|
||||
|
||||
if (stat.isDirectory()) {
|
||||
// 递归处理子目录
|
||||
processDirectory(filePath);
|
||||
} else if (file.endsWith('.html')) {
|
||||
// 处理HTML文件
|
||||
processHtmlFile(filePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理HTML文件中的图片路径
|
||||
* @param {string} filePath HTML文件路径
|
||||
*/
|
||||
function processHtmlFile(filePath) {
|
||||
console.log(`处理文件: ${path.relative(OUTPUT_DIR, filePath)}`);
|
||||
|
||||
let content = fs.readFileSync(filePath, 'utf8');
|
||||
|
||||
// 替换HTML中的图片路径
|
||||
// 匹配 src="public/img/xxx.png" 模式
|
||||
content = content.replace(/src=\"(public\/img\/[^\"]+)\"/g, (match, p1) => {
|
||||
return `src=\"${CDN_BASE_URL}${p1.replace('public/', '')}\"`;
|
||||
});
|
||||
|
||||
// 匹配 src=\"/public/img/xxx.png\" 模式
|
||||
content = content.replace(/src=\"(\/public\/img\/[^\"]+)\"/g, (match, p1) => {
|
||||
return `src=\"${CDN_BASE_URL}${p1.replace('/public/', '')}\"`;
|
||||
});
|
||||
|
||||
// 匹配 src=\"/img/xxx.png\" 模式
|
||||
content = content.replace(/src=\"(\/img\/[^\"]+)\"/g, (match, p1) => {
|
||||
return `src=\"${CDN_BASE_URL}${p1.replace('/img/', '')}\"`;
|
||||
});
|
||||
|
||||
// 匹配 src=\"img/xxx.png\" 模式
|
||||
content = content.replace(/src=\"(img\/[^\"]+)\"/g, (match, p1) => {
|
||||
return `src=\"${CDN_BASE_URL}${p1.replace('img/', '')}\"`;
|
||||
});
|
||||
|
||||
// 移除_nuxt前缀的图片路径
|
||||
content = content.replace(/src=\"\/_nuxt\/img\/([^\"]+)\"/g, (match, p1) => {
|
||||
return `src=\"${CDN_BASE_URL}${p1}\"`;
|
||||
});
|
||||
|
||||
// 匹配 src="/_nuxt/assets/images/xxx.png" 模式
|
||||
content = content.replace(/src=\"\/_nuxt\/assets\/images\/([^\"]+)\"/g, (match, p1) => {
|
||||
return `src=\"${CDN_BASE_URL}${p1}\"`;
|
||||
});
|
||||
|
||||
fs.writeFileSync(filePath, content, 'utf8');
|
||||
}
|
3
server/tsconfig.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"extends": "../.nuxt/tsconfig.server.json"
|
||||
}
|
8
service/apiList.ts
Normal file
@ -0,0 +1,8 @@
|
||||
// 系统中所有请求的接口
|
||||
export const APIs = {
|
||||
login: '/login',
|
||||
// 还可以这样分成功能模块
|
||||
user: {
|
||||
Info: '/userinfo',
|
||||
},
|
||||
}
|
29
service/error.ts
Normal file
@ -0,0 +1,29 @@
|
||||
import { AxiosError } from 'axios'
|
||||
|
||||
// 服务器报错返回 Error 的时候的数据结构,可以和后端商量定义,但是所有接口的格式要统一
|
||||
export type ErrorResponse = {
|
||||
status: number // http 状态码,这个是必须的
|
||||
// 其他自定义类型类型
|
||||
}
|
||||
|
||||
class AxiosRequestError extends Error {
|
||||
data: ErrorResponse | undefined
|
||||
|
||||
raw: AxiosError
|
||||
|
||||
isUnAuthorized = false // 权限错误 401
|
||||
|
||||
isServerError = false // 服务器错误 500 等
|
||||
|
||||
constructor(status: number, message: string, raw: AxiosError, data?: ErrorResponse) {
|
||||
// 调用父类「Error」的构造函数
|
||||
super(message)
|
||||
this.data = data // 后端返回的 data
|
||||
this.raw = raw // axios 返回的原始数据
|
||||
this.isUnAuthorized = status === 401
|
||||
this.isServerError = status >= 500
|
||||
this.message = this.message || '' //给用户展示的错误消息,后续可以自定义
|
||||
}
|
||||
}
|
||||
|
||||
export default AxiosRequestError
|
8
service/handleError.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { AxiosError } from 'axios'
|
||||
import AxiosRequestError, { type ErrorResponse } from './error'
|
||||
|
||||
// 把 axios 的 错误 转成 我们已经封装的 AxiosRequestError 类,统一处理
|
||||
export function handleError(error: AxiosError | AxiosRequestError): AxiosRequestError {
|
||||
const err = error instanceof AxiosRequestError ? error : new AxiosRequestError(error.response?.status || 1, error.message, error, error.response?.data as ErrorResponse)
|
||||
return err
|
||||
}
|
26
service/request.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import axios, { type AxiosInstance } from 'axios'
|
||||
import { handleError } from './handleError'
|
||||
|
||||
function createRequestInstance(getServerUrl: () => string): AxiosInstance {
|
||||
//获取域名
|
||||
const serverUrl = window.location.origin;
|
||||
//console.log(serverUrl);
|
||||
const instance = axios.create({
|
||||
timeout: 1000 * 60 * 5, // 超时时间
|
||||
withCredentials: true, // 允许跨域携带cookie
|
||||
baseURL: serverUrl, // 请求地址
|
||||
})
|
||||
|
||||
instance.interceptors.response.use(
|
||||
async res => {
|
||||
return res
|
||||
},
|
||||
async err => {
|
||||
err = await handleError(err)
|
||||
return Promise.reject(err)
|
||||
},
|
||||
)
|
||||
return instance
|
||||
}
|
||||
|
||||
export default createRequestInstance
|
41
service/requestList.ts
Normal file
@ -0,0 +1,41 @@
|
||||
import type { AxiosRequestConfig, AxiosResponse } from 'axios'
|
||||
import createRequestInstance from './request'
|
||||
import { APIs } from './apiList'
|
||||
|
||||
class API {
|
||||
request!: ReturnType<typeof createRequestInstance>
|
||||
|
||||
get!: <T = any, R = AxiosResponse<T>>(url: string, config?: AxiosRequestConfig) => Promise<R>
|
||||
|
||||
delete!: <T = any, R = AxiosResponse<T>>(url: string, config?: AxiosRequestConfig) => Promise<R>
|
||||
|
||||
head!: <T = any, R = AxiosResponse<T>>(url: string, config?: AxiosRequestConfig) => Promise<R>
|
||||
|
||||
options!: <T = any, R = AxiosResponse<T>>(url: string, config?: AxiosRequestConfig) => Promise<R>
|
||||
|
||||
post!: <T = any, R = AxiosResponse<T>>(url: string, data?: any, config?: AxiosRequestConfig) => Promise<R>
|
||||
|
||||
put!: <T = any, R = AxiosResponse<T>>(url: string, data?: any, config?: AxiosRequestConfig) => Promise<R>
|
||||
|
||||
patch!: <T = any, R = AxiosResponse<T>>(url: string, data?: any, config?: AxiosRequestConfig) => Promise<R>
|
||||
|
||||
constructor(options: { getServerUrl: () => string }) {
|
||||
const request = createRequestInstance(options.getServerUrl)
|
||||
this.request = request
|
||||
this.post = request.post.bind(this)
|
||||
this.put = request.put.bind(this)
|
||||
this.get = request.get.bind(this)
|
||||
this.delete = request.delete.bind(this)
|
||||
this.head = request.head.bind(this)
|
||||
this.options = request.options.bind(this)
|
||||
this.patch = request.patch.bind(this)
|
||||
}
|
||||
|
||||
// 这是 API 类的静态函数
|
||||
async getUserInfo() {
|
||||
const res = await this.get(APIs.user.Info)
|
||||
return res
|
||||
}
|
||||
}
|
||||
|
||||
export default API
|
35
service/webRequest.ts
Normal file
@ -0,0 +1,35 @@
|
||||
import API from './requestList'
|
||||
import AxiosRequestError from './error'
|
||||
import { handleError } from './handleError'
|
||||
import { getProcessEnv } from '@/global/env'
|
||||
|
||||
const $api = new API({
|
||||
getServerUrl: () => {
|
||||
return `${getProcessEnv('SERVER_URL') || ''}`
|
||||
},
|
||||
})
|
||||
|
||||
// 请求的拦截器
|
||||
$api.request.interceptors.request.use((config: any) => {
|
||||
const headers = config.headers || {}
|
||||
// 这个地方可以自定义请求头
|
||||
config.headers = {
|
||||
...headers,
|
||||
language: 'en', // 这个是自定义的请求头,还可以加 token 等
|
||||
}
|
||||
return config
|
||||
})
|
||||
|
||||
// 响应的拦截器
|
||||
$api.request.interceptors.response.use(undefined, async (err: AxiosRequestError) => {
|
||||
err = handleError(err) // 调用我们自定义的 错误处理方法
|
||||
if (err.isUnAuthorized) {
|
||||
// 未授权的情况的处理
|
||||
}
|
||||
// 还可以自定义其他的情况的处理
|
||||
|
||||
return Promise.reject(err)
|
||||
})
|
||||
|
||||
// 在 page 页面就可以直接调用这个 $api 请求接口
|
||||
export default $api
|
36
store/index.ts
Normal file
@ -0,0 +1,36 @@
|
||||
import { defineStore, acceptHMRUpdate } from 'pinia'
|
||||
|
||||
export const useStore = defineStore({
|
||||
id: 'index',
|
||||
state: () => ({
|
||||
// 添加临时数据存储字段
|
||||
tempApiData: {}, // 存储API返回的临时数据
|
||||
serApiData: {}, // 存储API返回的临时数据
|
||||
isEnglish: 'zh', // 判断是否是英文
|
||||
}),
|
||||
getters: {
|
||||
// 获取临时API数据的getter
|
||||
getTempApiData: state => state.tempApiData,
|
||||
},
|
||||
actions: {
|
||||
// 保存API返回的临时数据
|
||||
saveTempApiData(data: any) {
|
||||
this.tempApiData = data
|
||||
},
|
||||
saveSerApiData(data: any) {
|
||||
this.serApiData = data
|
||||
},
|
||||
// 判断是否是英文
|
||||
setIsEnglish(value: string) {
|
||||
this.isEnglish = value
|
||||
},
|
||||
// 清除临时数据
|
||||
clearTempApiData() {
|
||||
this.tempApiData = {}
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
if (import.meta.hot) {
|
||||
import.meta.hot.accept(acceptHMRUpdate(useStore, import.meta.hot))
|
||||
}
|
17
tailwind.config.js
Normal file
@ -0,0 +1,17 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
content: ['./components/**/*.{js,vue,ts}', './layouts/**/*.vue', './pages/**/*.vue', './plugins/**/*.{js,ts}', './nuxt.config.{js,ts}', './app.vue'],
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
dark: '#000',
|
||||
},
|
||||
screens: {
|
||||
},
|
||||
transitionDelay: {
|
||||
'5000': '5000ms',
|
||||
}
|
||||
},
|
||||
},
|
||||
plugins: [],
|
||||
}
|
4
tsconfig.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
// https://nuxt.com/docs/guide/concepts/typescript
|
||||
"extends": "./.nuxt/tsconfig.json"
|
||||
}
|