完成第一版开发

This commit is contained in:
hejin 2025-08-24 16:55:43 +08:00
parent e4b66175f9
commit 327da6f04c
20 changed files with 195 additions and 60 deletions

View File

@ -12,8 +12,8 @@
import { useIndex } from '@/stores/index.js'
onLaunch( async(e) => {
uni.setLocale('en')
useIndex().menuInit()
useIndex().getAppInfo()
})
</script>
<style lang="scss">

View File

@ -119,4 +119,11 @@ export const saveMsg = (data) => {
**/
export const fullTextSearchApi = (params) => {
return request.get('/web/searchText', {params})
}
/**
* @function 获取基础信息
**/
export const appInfoApi = () => {
return request.get('/web/footerInfo')
}

View File

@ -40,7 +40,7 @@
</template>
<script setup>
import { onLoad } from '@dcloudio/uni-app';
import { onLoad, onPullDownRefresh } from '@dcloudio/uni-app';
import { ref, computed, nextTick } from 'vue';
import { useI18n } from 'vue-i18n';
import dayjs from 'dayjs';
@ -96,6 +96,13 @@
{id:121113123,title: 'SINOTRUK HOWO Tractor Truck Head',mainPic:'https://dianliang123.oss-cn-qingdao.aliyuncs.com/user/2025/07/09/55979a0deee24031a38e934c6b06ca20.jpg'}
])
onPullDownRefresh(async() => {
try {
await getInfo()
} catch(err){}
uni.stopPullDownRefresh()
})
onLoad((options) => {
id.value = options.id
getInfo()
@ -105,7 +112,12 @@
<style lang="scss" scoped>
.pages {
padding: 0 18rpx;
/* #ifdef APP */
padding-top: calc(var(--status-bar-height) + 30px);
/* #endif */
/* #ifdef H5 */
padding-top: calc(var(--status-bar-height) + 50px);
/* #endif */
padding-bottom: 200rpx;
overflow: hidden;
::v-deep .tabs {
@ -113,7 +125,10 @@
margin: 0;
height: 100rpx;
position: fixed;
top: 0;
/* #ifdef H5 */
top: calc(var(--status-bar-height) + 44px);
/* #endif */
left: 0;
justify-content: space-around;
background-color: #e4ecff;

View File

@ -14,7 +14,11 @@
:current="swiperCurrent"
@change="swiperChange"
>
<swiper-item v-for="(item,index) in productsImages" :key="index">
<swiper-item
v-for="(item,index) in productsImages"
:key="index"
@click="previewImg(index)"
>
<view class="swiper-item">
<image :src="item" mode="aspectFill"></image>
</view>
@ -182,7 +186,7 @@
</template>
<script setup>
import { onLoad } from '@dcloudio/uni-app';
import { onLoad, onPullDownRefresh } from '@dcloudio/uni-app';
import { ref, computed, nextTick } from 'vue';
import { useI18n } from 'vue-i18n';
import {
@ -318,6 +322,21 @@
})
}
const previewImg = (index) => {
uni.previewImage({
urls: productsImages.value,
current: index
})
}
onPullDownRefresh(async() => {
try {
await getInfo()
await getFormOptions()
} catch(err){}
uni.stopPullDownRefresh()
})
onLoad((options) => {
id.value = options.id
getInfo()
@ -328,7 +347,12 @@
<style lang="scss" scoped>
.pages {
padding: 0 18rpx;
/* #ifdef APP */
padding-top: calc(var(--status-bar-height) + 30px);
/* #endif */
/* #ifdef H5 */
padding-top: calc(var(--status-bar-height) + 50px);
/* #endif */
padding-bottom: 200rpx;
overflow: hidden;
::v-deep .tabs {
@ -336,7 +360,10 @@
margin: 0;
height: 100rpx;
position: fixed;
top: 0;
/* #ifdef H5 */
top: calc(var(--status-bar-height) + 44px);
/* #endif */
left: 0;
justify-content: space-around;
background-color: #e4ecff;

View File

@ -1,3 +1,18 @@
@font-face {
font-family: 'DouyinSansBold'; /* 自定义字体的名称 */
src: url('@/assets/fonts/DouyinSansBold.otf') format('opentype'); /* 字体文件的路径 */
font-weight: normal; /* 字体的粗细 */
font-style: normal; /* 字体的样式 */
}
@font-face {
font-family: 'SourceHanSansCN'; /* 自定义字体的名称 */
src: url('@/assets/fonts/SourceHanSansCN-Regular.otf') format('opentype'); /* 字体文件的路径 */
font-weight: normal; /* 字体的粗细 */
font-style: normal; /* 字体的样式 */
}
view{
box-sizing: border-box;
}

Binary file not shown.

Binary file not shown.

View File

@ -9,7 +9,7 @@
<image class="icon" src="@/assets/images/icon/phone2.png"></image>
<view class="desc">
<label>{{ $t('contactUs.contactUs') }}</label>
<view>0086 182 5311 2969</view>
<view>{{useIndex().appInfo.tel}}</view>
</view>
</view>
@ -17,7 +17,7 @@
<image class="icon" src="@/assets/images/icon/mail2.png"></image>
<view class="desc">
<label>{{ $t('common.E-mail') }}</label>
<view>alicesales@scdtrailer.com</view>
<view>{{useIndex().appInfo.email}}</view>
</view>
</view>
@ -25,7 +25,7 @@
<image class="icon" src="@/assets/images/icon/online.png"></image>
<view class="desc">
<label>{{ $t('common.Online') }}</label>
<view>0086 182 5311 2969</view>
<view>{{useIndex().appInfo.tel}}</view>
</view>
</view>
</view>
@ -40,6 +40,7 @@
<script setup>
import { onLoad } from '@dcloudio/uni-app';
import { ref } from 'vue';
import { useIndex } from '@/stores/index.js';
const emits = defineEmits(['close'])
@ -65,7 +66,12 @@
height: 768rpx;
padding: 74rpx 38rpx 38rpx;
position: absolute;
/* #ifdef APP */
top: 280rpx;
/* #endif */
/* #ifdef H5 */
top: 354rpx;
/* #endif */
left: 50%;
transform: translateX(-50%);
background: url('@/assets/images/bg/online-bg.png') no-repeat;

View File

@ -10,6 +10,7 @@
</template>
<script setup>
import { onShow } from "@dcloudio/uni-app";
import { ref, watch, computed } from 'vue';
import { useScroll } from '@/stores/index.js';
@ -33,6 +34,12 @@
})
useScroll().sendCallback()
}
onShow(() => {
let locale = uni.getLocale()
console.log(locale)
uni.setLocale(locale === 'zh-Hans' ? 'zh-Hans' : 'en')
})
</script>
<style lang="scss" scoped>

View File

@ -140,5 +140,12 @@
"keywords": "China National Heavy Duty Truck Group (CNHTC) HOWO, HOWO Trucks, Heavy Truck Products, Heavy duty Trucks, Commercial Vehicles, HOWO Models, CNHTC Products, HOWO Truck Series, Large Trucks, Commercial Vehicle Products",
"description": "China National Heavy Duty Truck Group Co., Ltd. provides a rich range of HOWO truck products, including various models and configurations. Understand the performance, technical specifications, and industry advantages of our heavy-duty trucks to meet your procurement needs."
}
}
},
"app.Home": "Home",
"app.Product": "Product",
"app.News": "News",
"app.About": "About Us",
"app.Contact": "Contact Us",
"app.Online": "Online",
"app.fulltextsearch": "fulltextsearch"
}

View File

@ -140,5 +140,12 @@
"keywords": "中国重汽豪沃, 豪沃卡车, 重卡产品, 重型卡车, 商用车, 豪沃车型, 重汽产品, 豪沃卡车系列, 大型卡车, 商用车产品",
"description": "中国重汽豪沃销售有限公司提供丰富的豪沃卡车产品系列,包括各种车型和配置。了解我们的重型卡车性能、技术参数及行业优势,满足您的采购需求。"
}
}
},
"app.Home": "首页",
"app.Product": "产品",
"app.News": "新闻",
"app.About": "关于我们",
"app.Contact": "联系我们",
"app.Online": "在线",
"app.fulltextsearch": "全站搜索"
}

View File

@ -2,7 +2,7 @@ import { createSSRApp,provide,h } from "vue";
import App from "./App.vue";
import { createPinia } from 'pinia';
import { createI18n } from 'vue-i18n';
import zh from './locale/zh.json';
import zh from './locale/zh-Hans.json';
import en from './locale/en.json';
import ConfirmPopup from '@/components/comfirm-popup.vue'; // 全局统一的操作弹窗
import CustomHeader from "@/components/custom-header.vue";

View File

@ -10,34 +10,31 @@
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "China Trailer, Truck, Trailer Parts, Truck Parts Manufacturers and Factory - Price - SINOTRUCK",
"enablePullDownRefresh": true
}
},
{
"path": "pages/products/index",
"style": {
"navigationBarTitleText": "Product",
"enablePullDownRefresh": true
"enablePullDownRefresh": false
}
},
{
"path": "pages/article-page/index",
"style": {
"navigationBarTitleText": "News"
"enablePullDownRefresh": false
}
},
{
"path": "pages/separate/index",
"style": {
"navigationBarTitleText": "About Us",
"enablePullDownRefresh": true
"enablePullDownRefresh": false
}
},
{
"path": "pages/inquiry/index",
"style": {
"navigationBarTitleText": "Contact Us"
"enablePullDownRefresh": false
}
}
],
@ -48,7 +45,6 @@
{
"path": "product-details",
"style": {
"navigationBarTitleText": "Product details",
"enablePullDownRefresh": true,
"navigationStyle": "default"
}
@ -56,7 +52,6 @@
{
"path": "article-details",
"style": {
"navigationBarTitleText": "News detail",
"enablePullDownRefresh": true,
"navigationStyle": "default"
}
@ -64,15 +59,15 @@
{
"path": "online",
"style": {
"navigationBarTitleText": "Online",
"enablePullDownRefresh": true,
"navigationBarTitleText": "%app.Online%",
"enablePullDownRefresh": false,
"navigationStyle": "default"
}
},
{
"path": "search-result",
"style": {
"navigationBarTitleText": "Full text search",
"navigationBarTitleText": "%app.fulltextsearch%",
"enablePullDownRefresh": true,
"navigationStyle": "default"
}
@ -85,31 +80,31 @@
"selectedColor": "#0358ff",
"list": [
{
"text": "Home",
"text": "%app.Home%",
"pagePath": "pages/index/index",
"iconPath": "/static/home.png",
"selectedIconPath": "/static/home-select.png"
},
{
"text": "Product",
"text": "%app.Product%",
"pagePath": "pages/products/index",
"iconPath": "/static/product.png",
"selectedIconPath": "/static/product-select.png"
},
{
"text": "News",
"text": "%app.News%",
"pagePath": "pages/article-page/index",
"iconPath": "/static/news.png",
"selectedIconPath": "/static/news-select.png"
},
{
"text": "About Us",
"text": "%app.About%",
"pagePath": "pages/separate/index",
"iconPath": "/static/aboutus.png",
"selectedIconPath": "/static/aboutus-select.png"
},
{
"text": "Contact Us",
"text": "%app.Contact%",
"pagePath": "pages/inquiry/index",
"iconPath": "/static/contactus.png",
"selectedIconPath": "/static/contactus-select.png"

View File

@ -72,6 +72,7 @@
:scroll-y="true"
:scroll-top="prodScroll"
@scroll="scroll"
@scrolltolower="scrollBottom"
>
<view
class="prod-item"
@ -95,9 +96,12 @@
<script setup>
import { onLoad, onShow } from '@dcloudio/uni-app';
import { ref, computed, watch, nextTick } from 'vue';
import { useI18n } from 'vue-i18n';
import { prodOrNewsCatgApi, articlePageApi, appMaxCatgIdApi } from '@/api';
import { useScroll } from '@/stores/index.js';
const { t } = useI18n()
const total = ref(0)
const prodList = ref([])
const params = ref({
@ -114,13 +118,19 @@
}
return articlePageApi(params.value).then(({data:res}) => {
if (isLoad) {
prodList.value = [...prodList.value,res.data.records]
prodList.value = [...prodList.value,...res.data.records]
} else {
prodList.value = res.data.records
}
total.value = res.data.total
})
}
const scrollBottom = () => {
if (total.value === prodList.value.length) {
return uni.$showTost(t('common.Allloaded'))
}
init(true)
}
const collapseRef = ref()
const collapseValue = ref('0')
@ -217,14 +227,14 @@
})
}
onShow(() => {
})
onLoad(async() => {
onShow(async() => {
await getMaxCatgId()
await catgTreeInit()
init()
})
onLoad(async() => {
})
</script>
<style lang="scss" scoped>
@ -271,6 +281,7 @@
padding: 22rpx 16rpx;
position: relative;
color: #77778b;
font-family: 'SourceHanSansCN';
&:first-child {
&::before {
content: '';

View File

@ -34,7 +34,7 @@
</view>
<view class="panel">
<view class="r-box">
<view class="r-box" @click="goPage('/pages/products/index','tab')">
<view class="title">
<text>{{$t('common.All')}}</text>
<text>{{$t('common.productslowercase')}}</text>
@ -45,16 +45,16 @@
</view>
</view>
<view class="l-box">
<view class="t-box">
<view class="t-box" @click="goPage('/pages/separate/index','tab')">
<view class="title">{{$t('index.companyProfile')}}</view>
<image src="@/assets/images/icon/arrow.png"></image>
</view>
<view class="b-box">
<view>
<view @click="goPage('/pages/article-page/index','tab')">
<text>{{$t('news.news')}}</text>
<text>{{$t('common.Center')}}</text>
</view>
<view>
<view @click="goPage('/pages/inquiry/index','tab')">
<text>{{$t('common.Quick')}}</text>
<text>{{$t('index.contact')}}</text>
</view>
@ -65,7 +65,7 @@
<view class="common-card">
<view class="header">
<text class="title">{{$t('index.PopularProduct')}}</text>
<navigator class="view-more" url="/">
<navigator class="view-more" open-type="switchTab" url="/pages/products/index">
<text>{{$t('common.viewmore')}}</text>
<image src="@/assets/images/icon/view-more.png"></image>
</navigator>
@ -75,6 +75,7 @@
class="product-item"
v-for="item in hotProductList"
:key="item.id"
@click="goPage(`/application/product-details?id=${item.id}`,'nav')"
>
<image class="cover" :src="item.mainPic" mode="aspectFill"></image>
<view class="text-ellipsis title">
@ -87,7 +88,7 @@
<view class="common-card">
<view class="header">
<text class="title">{{$t('menu.Products')}}</text>
<navigator class="view-more" url="/">
<navigator class="view-more" open-type="switchTab" url="/pages/products/index">
<text>{{$t('common.viewmore')}}</text>
<image src="@/assets/images/icon/view-more.png"></image>
</navigator>
@ -97,6 +98,7 @@
class="product-item"
v-for="item in ordinaryProductList"
:key="item.id"
@click="goPage(`/application/product-details?id=${item.id}`,'nav')"
>
<image class="cover" :src="item.mainPic" mode="aspectFill"></image>
<view class="text-ellipsis title">
@ -109,7 +111,7 @@
<view class="common-card">
<view class="header">
<text class="title">{{$t('news.newsCenter')}}</text>
<navigator class="view-more" url="/">
<navigator class="view-more" open-type="switchTab" url="/pages/article-page/index">
<text>{{$t('common.viewmore')}}</text>
<image src="@/assets/images/icon/view-more.png"></image>
</navigator>
@ -119,6 +121,7 @@
class="news-item"
v-for="item in hotNewsList"
:key="item.id"
@click="goPage(`/application/article-details?id=${item.id}`,'nav')"
>
<image class="cover" :src="item.mainPic" mode="aspectFill"></image>
<view class="info">
@ -186,6 +189,18 @@
})
}
const goPage = (url,type) => {
if (type === 'tab') {
uni.switchTab({
url
})
} else {
uni.navigateTo({
url
})
}
}
onPullDownRefresh(async() => {
try {
await getBannerList()
@ -245,6 +260,7 @@
min-height: 252rpx;
margin: 24rpx 0;
display: flex;
font-family: 'DouyinSansBold';
.r-box,.l-box {
flex: 1;
}
@ -273,7 +289,7 @@
}
}
.goto {
width: min-content;
width: max-content;
margin-top: 50rpx;
padding: 6rpx 12rpx;
display: flex;
@ -353,6 +369,7 @@
.title {
color: #015fe8;
font-size: 30rpx;
font-family: 'SourceHanSansCN';
font-weight: bold;
}
.view-more {

View File

@ -9,15 +9,15 @@
<view class="desc">
<view>
<label>{{$t('contactUs.contact')}}: </label>
<text>{{$t('contactUs.contacts')}}</text>
<text>{{useIndex().appInfo.teams}}</text>
</view>
<view>
<label>{{$t('common.tel')}}: </label>
<text>+86-531-6998513</text>
<text>{{useIndex().appInfo.tel}}</text>
</view>
<view>
<label>{{$t('common.addressLabel')}}: </label>
<text>{{$t('contactUs.address')}}</text>
<text>{{useIndex().appInfo.address}}</text>
</view>
</view>
</view>
@ -135,7 +135,7 @@
<image class="icon" src="@/assets/images/icon/phone2.png"></image>
<view class="desc">
<label>{{ $t('contactUs.contactUs') }}</label>
<view>0086 182 5311 2969</view>
<view>{{ useIndex().appInfo.tel }}</view>
</view>
</view>
@ -143,7 +143,7 @@
<image class="icon" src="@/assets/images/icon/mail2.png"></image>
<view class="desc">
<label>{{ $t('common.E-mail') }}</label>
<view>alicesales@scdtrailer.com</view>
<view>{{ useIndex().appInfo.email }}</view>
</view>
</view>
@ -151,7 +151,7 @@
<image class="icon" src="@/assets/images/icon/address.png"></image>
<view class="desc">
<label>{{ $t('common.addressLabel') }}</label>
<view>{{ $t('aboutUs.address') }}</view>
<view>{{ useIndex().appInfo.address }}</view>
</view>
</view>
</view>
@ -161,9 +161,10 @@
</template>
<script setup>
import { onLoad } from '@dcloudio/uni-app';
import { onShow } from '@dcloudio/uni-app';
import { ref, computed } from 'vue';
import { useI18n } from 'vue-i18n'
import { useIndex } from '@/stores/index.js';
import { formOptionsApi, submitFormApi } from '@/api/index.js';
const { t } = useI18n()
@ -232,7 +233,7 @@
})
}
onLoad(() => {
onShow(() => {
getFormOptions()
})
</script>

View File

@ -91,7 +91,8 @@
class="list-scroll"
:scroll-y="true"
:scroll-top="prodScroll"
@scroll="scroll"
@scroll="scroll"
@scrolltolower="scrollBottom"
>
<view
class="prod-item"
@ -115,9 +116,12 @@
<script setup>
import { onLoad, onShow } from '@dcloudio/uni-app';
import { ref, computed, watch, nextTick } from 'vue';
import { useI18n } from 'vue-i18n';
import { prodOrNewsCatgApi, prodPageApi, appMaxCatgIdApi } from '@/api';
import { useScroll } from '@/stores/index.js';
const { t } = useI18n()
const total = ref(0)
const prodList = ref([])
const params = ref({
@ -135,13 +139,19 @@
}
return prodPageApi(params.value).then(({data:res}) => {
if (isLoad) {
prodList.value = [...prodList.value,res.data.records]
prodList.value = [...prodList.value,...res.data.records]
} else {
prodList.value = res.data.records
}
total.value = res.data.total
})
}
const scrollBottom = () => {
if (total.value === prodList.value.length) {
return uni.$showTost(t('common.Allloaded'))
}
init(true)
}
const collapseRef = ref()
const collapseValue = ref('0')
@ -238,14 +248,14 @@
})
}
onShow(() => {
})
onLoad(async() => {
onShow( async() => {
await getMaxCatgId()
await catgTreeInit()
init()
})
onLoad(() => {
})
</script>
<style lang="scss" scoped>
@ -310,6 +320,7 @@
padding: 22rpx 16rpx;
position: relative;
color: #77778b;
font-family: 'SourceHanSansCN';
&:first-child {
&::before {
content: '';

View File

@ -6,7 +6,7 @@
</template>
<script setup>
import { onLoad, onPullDownRefresh } from '@dcloudio/uni-app';
import { onShow, onPullDownRefresh } from '@dcloudio/uni-app';
import { ref } from 'vue';
import { categoryInfoApi, appMaxCatgIdApi } from '@/api/index.js';
@ -35,7 +35,7 @@
uni.stopPullDownRefresh()
})
onLoad(async(options) => {
onShow(async() => {
await getMaxCatgId()
init()
})

View File

@ -1,7 +1,7 @@
import { defineStore } from 'pinia';
import { ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { menuCategoryApi, msgListApi, saveMsg } from '@/api/index.js';
import { menuCategoryApi, msgListApi, saveMsg, appInfoApi } from '@/api/index.js';
import { getUuid } from '@/utils/tool.js';
export const useIndex = defineStore('index',()=>{
@ -44,9 +44,18 @@ export const useIndex = defineStore('index',()=>{
})
}
const appInfo = ref({})
const getAppInfo = () => {
appInfoApi().then(({data:res}) => {
appInfo.value = res.data
})
}
return {
menuInit,
menuTree
menuTree,
appInfo,
getAppInfo
}
})

View File

@ -1,6 +1,6 @@
import uni from "@dcloudio/vite-plugin-uni";
import { defineConfig, loadEnv } from 'vite';
import UniLayouts from '@uni-helper/vite-plugin-uni-layouts'
import UniLayouts from '@uni-helper/vite-plugin-uni-layouts';
export default defineConfig(({ command, mode }) => {
// 根据当前工作目录中的 `mode` 加载 .env 文件
@ -9,8 +9,8 @@ export default defineConfig(({ command, mode }) => {
return {
// vite 配置
plugins: [
uni(),
UniLayouts(),
uni(),
],
base: './',
define: {