数据大屏路由404修改和运营平台电商交易

This commit is contained in:
lzc 2025-04-02 13:46:49 +08:00
parent 4c6569db65
commit 74419b2f97
35 changed files with 1429 additions and 173 deletions

View File

@ -58,7 +58,7 @@ export const rightApps = [
{
name: 'sub-government-screen-service',
entry: VITE_APP_SUB_GSS,
activeRule: '/sub-government-screen-service/',
activeRule: '/sub-government-screen-service',
title: '数据大屏',
icon: 'images/platform/icon-screen.png',
},
@ -75,10 +75,17 @@ export const defaultApps = [
{
name: 'sub-government-screen-service',
entry: VITE_APP_SUB_GSS,
activeRule: '/sub-government-screen-service/',
activeRule: '/sub-government-screen-service',
title: '数据大屏',
icon: 'images/platform/icon-screen.png',
},
{
name: 'sub-operation-service',
entry: VITE_APP_SUB_OS,
activeRule: '/sub-operation-service',
title: '运营服务',
icon: 'images/platform/icon-home.png',
},
];
// export const microApps = [...defaultApps, ...leftApps, ...rightApps];

View File

@ -1,5 +1,6 @@
<template>
<div class="data-warp" :style="{ 'background-image': 'url(' + getAssetsFile('images/vsualized/screenbg.png') + ')' }">
<!-- :style="{ 'background-image': 'url(' + getAssetsFile('images/vsualized/screenbg.png') + ')' }" -->
<div class="data-warp">
<div class="chart-content">
<div class="top">
<slot v-if="$slots.top" name="top"></slot>
@ -14,27 +15,6 @@
<div class="content">
<slot name="center"></slot>
</div>
<div class="bottom" :style="{ 'background-image': 'url(' + getAssetsFile('images/vsualized/bottombg.jpg') + ')' }">
<div class="b-nav">
<div
v-for="n in navlist"
:key="n.name"
class="b-nav-item"
:style="{
'background-image':
'url(' +
(currentName == n.name ? getAssetsFile('images/vsualized/home/nav-on.png') : getAssetsFile('images/vsualized/home/nav.png')) +
')',
}"
:class="currentName == n.name ? 'nav-act' : 'nav-normal'"
@click="itemAct(n.name)"
>
<!-- <router-link :to="n.name"> -->
<span>{{ n.title }}</span>
<!-- </router-link> -->
</div>
</div>
</div>
</div>
</div>
</template>

View File

@ -0,0 +1,110 @@
<template>
<div class="layout-bottom">
<div class="bottom" :style="{ 'background-image': 'url(' + getAssetsFile('images/vsualized/bottombg.jpg') + ')' }">
<div class="b-nav">
<div
v-for="n in navlist"
:key="n.name"
class="b-nav-item"
:style="{
'background-image':
'url(' +
(currentName == n.name ? getAssetsFile('images/vsualized/home/nav-on.png') : getAssetsFile('images/vsualized/home/nav.png')) +
')',
}"
:class="currentName == n.name ? 'nav-act' : 'nav-normal'"
@click="itemAct(n.name)"
>
<!-- <router-link :to="n.name"> -->
<span>{{ n.title }}</span>
<!-- </router-link> -->
</div>
</div>
</div>
</div>
</template>
<script setup name="layout-bottom">
import { computed, ref } from 'vue';
import { useSettingStore } from '@/store/modules/setting';
import { setPx } from '@/utils';
import { getAssetsFile } from '@/utils';
import { useRoute, useRouter } from 'vue-router';
const route = useRoute();
const router = useRouter();
const SettingStore = useSettingStore();
//
const themeConfig = computed(() => SettingStore.themeConfig);
const isCollapse = computed(() => !SettingStore.isCollapse);
const stylePlaceholder = () => {
return { height: themeConfig.value.showTag ? setPx(90) : setPx(50) };
};
const navlist = ref([
{ title: '首页', name: 'home' },
{ title: '土地资源', name: 'land' },
{ title: '投入品', name: 'inputs' },
{ title: '生产经营主体', name: 'entities' },
{ title: '智慧种植检测', name: 'plant' },
{ title: '智慧养殖检测', name: 'breed' },
{ title: '全流程溯源', name: 'trace' },
{ title: '产业预警决策', name: 'early' },
]);
let currentName = ref(route.name);
const itemAct = (name) => {
console.info('itemAct', name);
currentName.value = name;
router.push({ name: name });
};
</script>
<style lang="scss" scoped>
.layout-bottom {
width: 100%;
text-align: center;
position: absolute;
left: 0;
bottom: 0;
z-index: 100;
.bottom {
height: 98px;
text-align: center;
.b-nav {
margin: auto;
display: inline-flex;
gap: 20px;
.b-nav-item {
display: inline-block;
cursor: pointer;
min-width: 132px;
height: 42px;
text-align: center;
line-height: 38px;
span {
font-size: 14px;
font-weight: bold;
display: inline-flex;
transform: skewX(-8deg);
background: linear-gradient(to bottom, '#ff7e5f', '#548fff');
-webkit-background-clip: text;
letter-spacing: 4px;
text-shadow: -2px 0 0 1px #add8f1;
}
&.nav-act {
color: rgba(255, 255, 255, 1);
}
&.nav-normal {
color: rgba(255, 255, 255, 0.6);
}
}
}
}
}
</style>

View File

@ -31,18 +31,5 @@ const isReload = computed(() => SettingStore.isReload);
<style lang="scss" scoped>
.layout-main {
flex: 1;
display: flex;
width: 100%;
height: 100%;
@include scrollable;
box-sizing: border-box;
&-inner {
padding: 10px;
width: 100%;
background-color: #f5f5f5;
box-sizing: border-box;
}
}
</style>

View File

@ -6,34 +6,36 @@
* @LastEditTime: 2024-02-05 16:03:31
-->
<template>
<div
class="basic-layout"
:class="{
hideSider: !SettingStore.isCollapse,
}"
>
<Sider />
<div class="basic-layout" :style="{ 'background-image': 'url(' + getAssetsFile('images/vsualized/screenbg.png') + ')' }">
<div class="basic-layout-container">
<Header />
<Main />
<Bottom :name-val="route.name"></Bottom>
</div>
</div>
</template>
<script setup name="layout">
import { getAssetsFile } from '@/utils';
import { useSettingStore } from '@/store/modules/setting';
import Sider from './component/Sider';
import Header from './component/Header';
import Bottom from './component/Bottom';
import Main from './component/Main';
import { useRoute, useRouter } from 'vue-router';
import { onMounted } from 'vue';
const route = useRoute();
const SettingStore = useSettingStore();
onMounted(() => {
console.info('route', route);
});
</script>
<style lang="scss" scoped>
.basic-layout {
width: 100%;
min-width: 1200px;
height: 100%;
height: 100vh;
&.hideSider {
:deep(.layout-sider) {
width: 60px !important;
@ -44,7 +46,6 @@ const SettingStore = useSettingStore();
}
&-container {
position: relative;
margin-left: 210px;
height: 100%;
transition: margin-left 0.28s;
box-sizing: border-box;

View File

@ -21,52 +21,109 @@ export const constantRoutes = [
hidden: true,
},
{
path: '/sub-government-screen-service/home',
name: 'home',
component: () => import('@/views/home/index.vue'),
},
{
path: '/sub-government-screen-service/land',
name: 'land',
component: () => import('@/views/land/index.vue'),
hidden: true,
},
{
path: '/sub-government-screen-service/inputs',
name: 'inputs',
component: () => import('@/views/inputs/index.vue'),
hidden: true,
},
{
path: '/sub-government-screen-service/entities',
name: 'entities',
component: () => import('@/views/entities/index.vue'),
hidden: true,
},
{
path: '/sub-government-screen-service/breed',
name: 'breed',
component: () => import('@/views/breed/index.vue'),
hidden: true,
},
{
path: '/sub-government-screen-service/plant',
name: 'plant',
component: () => import('@/views/plant/index.vue'),
hidden: true,
},
{
path: '/sub-government-screen-service/trace',
name: 'trace',
component: () => import('@/views/trace/index.vue'),
hidden: true,
},
{
path: '/sub-government-screen-service/early',
name: 'early',
component: () => import('@/views/early/index.vue'),
hidden: true,
path: '/sub-government-screen-service',
name: 'layout',
component: Layout,
redirect: '/sub-government-screen-service/home',
meta: { title: '首页', icon: 'House' },
children: [
{
path: '/sub-government-screen-service/home',
component: () => import('@/views/home/index.vue'),
name: 'home',
meta: { title: '首页', icon: 'House' },
},
{
path: '/sub-government-screen-service/land',
component: () => import('@/views/land/index.vue'),
name: 'land',
meta: { title: '土地资源', icon: 'House' },
},
{
path: '/sub-government-screen-service/inputs',
name: 'inputs',
component: () => import('@/views/inputs/index.vue'),
hidden: true,
},
{
path: '/sub-government-screen-service/entities',
name: 'entities',
component: () => import('@/views/entities/index.vue'),
hidden: true,
},
{
path: '/sub-government-screen-service/breed',
name: 'breed',
component: () => import('@/views/breed/index.vue'),
hidden: true,
},
{
path: '/sub-government-screen-service/plant',
name: 'plant',
component: () => import('@/views/plant/index.vue'),
hidden: true,
},
{
path: '/sub-government-screen-service/trace',
name: 'trace',
component: () => import('@/views/trace/index.vue'),
hidden: true,
},
{
path: '/sub-government-screen-service/early',
name: 'early',
component: () => import('@/views/early/index.vue'),
hidden: true,
},
],
},
// {
// path: '/sub-government-screen-service/home',
// name: 'home',
// component: () => import('@/views/home/index.vue'),
// },
// {
// path: '/sub-government-screen-service/land',
// name: 'land',
// component: () => import('@/views/land/index.vue'),
// hidden: true,
// },
// {
// path: '/sub-government-screen-service/inputs',
// name: 'inputs',
// component: () => import('@/views/inputs/index.vue'),
// hidden: true,
// },
// {
// path: '/sub-government-screen-service/entities',
// name: 'entities',
// component: () => import('@/views/entities/index.vue'),
// hidden: true,
// },
// {
// path: '/sub-government-screen-service/breed',
// name: 'breed',
// component: () => import('@/views/breed/index.vue'),
// hidden: true,
// },
// {
// path: '/sub-government-screen-service/plant',
// name: 'plant',
// component: () => import('@/views/plant/index.vue'),
// hidden: true,
// },
// {
// path: '/sub-government-screen-service/trace',
// name: 'trace',
// component: () => import('@/views/trace/index.vue'),
// hidden: true,
// },
// {
// path: '/sub-government-screen-service/early',
// name: 'early',
// component: () => import('@/views/early/index.vue'),
// hidden: true,
// },
];
/**
@ -75,7 +132,7 @@ export const constantRoutes = [
export const notFoundRouter = {
path: '/sub-government-screen-service/:pathMatch(.*)',
name: 'notFound',
redirect: '/sub-government-screen-service/home',
redirect: '/sub-government-screen-service/404',
};
const router = createRouter({

View File

@ -17,9 +17,11 @@ NProgress.configure({ showSpinner: false });
const { VITE_APP_MIAN_URL } = import.meta.env;
const whiteList = [];
router.beforeEach(async (to, from, next) => {
console.info('beforeEach************to', to);
console.info('beforeEach**********from', from);
NProgress.start();
if (typeof to.meta.title === 'string') {
document.title = '政务服务 | ' + to.meta.title;
document.title = '数据大屏 | ' + to.meta.title;
}
const userStore = useUserStore();

View File

@ -1,6 +1,10 @@
# 开发环境
VITE_PORT = 9526
VITE_MODE = 'DEV'
VITE_APP_MIAN = 'daimp-front-main'
VITE_APP_MIAN_URL = 'http://localhost:9000'
VITE_APP_NAME = 'sub-operation-service'
VITE_APP_BASE_API = '/apis'
VITE_APP_BASE_URL = 'http://localhost:8080/'
VITE_APP_BASE_API = '/apis'
VITE_APP_BASE_URL = 'http://192.168.18.99:8080'
VITE_APP_UPLOAD_API = '/uploadApis'
VITE_APP_UPLOAD_URL = 'http://192.168.18.99:9300'

View File

@ -1,5 +1,11 @@
# 生产环境
VITE_MODE = 'PRO'
VITE_APP_MIAN = 'daimp-front-main'
VITE_APP_MIAN_URL = 'http://192.168.18.99:88'
VITE_APP_NAME = 'sub-operation-service'
VITE_APP_BASE_API = 'https://www.localhost.com/8080/api/'
VITE_APP_BASE_URL = 'https://www.localhost.com/8080/'
# 接口
VITE_APP_BASE_API = '/apis'
VITE_APP_BASE_URL = ''
VITE_APP_UPLOAD_API = '/uploadApis'
VITE_APP_UPLOAD_URL = ''

View File

@ -24,4 +24,39 @@ const size = computed(() => SettingStore.themeConfig.globalComSize);
<style lang="scss">
@import './styles/style.scss';
@import './styles/global.scss';
@import '@/styles/iconfont.css';
body {
div {
box-sizing: border-box;
}
.el-input {
--el-input-focus-border-color: #25bf82;
--el-input-focus-border: #25bf82;
::v-deep() {
.el-input__wrapper:focus,
.el-input__wrapper:hover,
.el-input__wrapper .is-focus {
box-shadow: 0 0 0 1px $color-main !important;
}
}
}
.el-button--primary {
--el-button-bg-color: #25bf82;
--el-button-border-color: #25bf82;
--el-button-outline-color: #45dda1;
--el-button-active-color: #158b5c;
--el-button-hover-bg-color: #45dda1;
--el-button-hover-border-color: #45dda1;
--el-button-active-bg-color: #158b5c;
--el-button-active-border-color: #158b5c;
--el-button-disabled-text-color: var(--el-color-white);
--el-button-disabled-bg-color: #45dda1;
--el-button-disabled-border-color: #45dda1;
}
--el-menu-hover-text-color: #25bf82;
--el-menu-hover-bg-color: fff;
}
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 638 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 579 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -1,7 +1,9 @@
const { VITE_APP_NAME } = import.meta.env;
import { qiankunWindow } from 'vite-plugin-qiankun/dist/helper';
const { VITE_APP_MIAN, VITE_APP_NAME } = import.meta.env;
export const GenKey = (key, prefix = `${VITE_APP_NAME}_`) => {
return prefix ? prefix + key : key;
export const GenKey = (key, prefix = VITE_APP_NAME) => {
prefix = qiankunWindow.__POWERED_BY_QIANKUN__ ? VITE_APP_MIAN : VITE_APP_MIAN;
return prefix ? `${prefix}_` + key : key;
};
export const CONSTANTS = {

View File

@ -1,44 +1,59 @@
<template>
<div class="layout-header">
<div class="layout-header-top">
<div class="layout-header-top-left">
<span>您好欢迎来到农业产业服务平台</span>
<el-tag>运营大屏</el-tag>
<el-tag>产业服务APP</el-tag>
<el-tag>产业运营管理</el-tag>
</div>
<div class="layout-header-top-right">
<span>商家中心</span>
<span>个人中心</span>
<span>返回首页</span>
</div>
</div>
<div class="layout-header-bottom">
<div class="layout-header-bottom-left">
<div class="layout-header-bottom-search">
<div class="title">农业产业服务平台</div>
<el-input v-model="keyword" placeholder="请输入关键词进行搜索"></el-input>
<el-button type="primary" @click="Search">搜索</el-button>
<div class="layout-header-warp">
<div class="layout-header">
<div class="layout-header-top">
<div class="layout-header-top-left">
<span class="welcome-msg">您好欢迎来到农业产业服务平台</span>
<div class="left-link">
<div class="iconfont icon-bigScreen"></div>
<span>数据大屏</span>
</div>
<div class="left-link">
<div class="iconfont icon-operation" style="font-size: 12px"></div>
<span>产业运营管理</span>
</div>
</div>
<div class="layout-header-top-right">
<span>商家中心</span>
<span>个人中心</span>
<span @click="toHome" class="back-home">
<div class="iconfont icon-home" style="font-size: 12px"></div>
<span>返回首页</span>
</span>
</div>
</div>
<div class="layout-header-bottom">
<div class="layout-header-bottom-left">
<div class="layout-header-bottom-search">
<div class="title">
<img :src="getAssetsFile('images/logo.png')" />
</div>
<div class="search-warp">
<el-input v-model="keyword" placeholder="请输入关键词进行搜索"></el-input>
<el-button type="primary" @click="Search">搜索</el-button>
</div>
</div>
</div>
<div class="layout-header-bottom-right">
<div class="layout-header-bottom-right-qr">
<div class="layout-header-bottom-right-qr-img">
<img :src="qrImg" alt="" />
<p>下载数农App</p>
</div>
<div class="layout-header-bottom-right-qr-img">
<img :src="qrImg" alt="" />
<p>打开数农小程序</p>
</div>
</div>
</div>
</div>
<div class="layout-header-menu">
<el-menu ellipsis class="layout-header-bottom-menu" mode="horizontal">
<app-link v-for="(item, index) in meuns" :key="index" :to="item.path">
<el-menu-item>{{ item.label }}</el-menu-item>
<el-menu-item active-text-color="#25BF82">{{ item.label }}</el-menu-item>
</app-link>
</el-menu>
</div>
<div class="layout-header-bottom-right">
<div class="layout-header-bottom-right-qr">
<div class="layout-header-bottom-right-qr-img">
<img :src="qrImg" alt="" />
<p>下载数农App</p>
</div>
<div class="layout-header-bottom-right-qr-img">
<img :src="qrImg" alt="" />
<p>打开数农小程序</p>
</div>
</div>
<p>使用数农手机服务更方便</p>
</div>
</div>
</div>
</template>
@ -49,9 +64,11 @@ import { useSettingStore } from '@/store/modules/setting';
import { usePermissionStore } from '@/store/modules/permission';
import { qrImg } from './base64img';
import AppLink from '../Menu/Link.vue';
import { useRoute } from 'vue-router';
import { useRoute, useRouter } from 'vue-router';
import { isEmpty, getAssetsFile } from '@/utils';
const route = useRoute();
const router = useRouter();
const SettingStore = useSettingStore();
const PermissionStore = usePermissionStore();
const cacheRoutes = computed(() => PermissionStore.keepAliveRoutes);
@ -75,6 +92,7 @@ const meuns = ref([
},
{
label: '电商交易',
path: '/sub-operation-service/ecommerce',
},
{
label: '分拣包装',
@ -90,47 +108,105 @@ const meuns = ref([
function Search() {
console.log(keyword.value, 'search');
}
const toHome = () => {
console.info('toHome', router);
router.push('/');
};
</script>
<style lang="scss" scoped>
div {
box-sizing: border-box;
}
.layout-header-warp {
width: 100%;
text-align: center;
background: $color-fff;
.layout-header-menu {
width: 100%;
::v-deep() {
.el-menu {
justify-content: space-around;
border: none !important;
}
.el-menu-item {
font-size: 24px;
}
.el-menu-item:hover {
background: none !important;
color: $color-main;
}
.el-menu-item:active {
background: none !important;
color: $color-main;
}
}
}
}
.layout {
// width: 100%;
// height: 100%;
// box-sizing: border-box;
&-header {
width: 100%;
width: 1200px;
height: 206px;
overflow: hidden;
margin: auto;
&-top {
display: flex;
height: 44px;
justify-content: space-between;
align-items: center;
background-color: #f8f8f8;
padding: 0 32px;
&-left {
line-height: 36px;
font-size: 16px;
.el-tag {
color: #fff;
background-color: #a4adb3;
margin-left: 12px;
border-color: #a4adb3;
.welcome-msg {
font-size: 12px;
color: $color-5a;
}
.left-link {
color: $color-main;
margin: 0 10px;
font-size: 12px;
cursor: pointer;
font-size: 18px;
display: inline-block;
.iconfont {
color: $color-main;
display: inline-block;
margin-right: 2px;
}
.iconfont,
span {
vertical-align: middle;
}
}
}
&-right {
span {
color: #000;
color: $color-000;
margin-left: 25px;
line-height: 36px;
font-size: 16px;
font-size: 12px;
text-align: center;
cursor: pointer;
&:nth-child(1) {
margin-left: 0;
font-weight: bold;
}
&.back-home {
.iconfont {
display: inline-block;
vertical-align: middle;
color: $color-main;
}
span {
margin-left: 6px;
display: inline-block;
vertical-align: middle;
}
color: $color-main;
}
}
}
@ -151,18 +227,31 @@ function Search() {
font-size: 45px;
white-space: nowrap;
}
.el-input {
flex-grow: 1;
max-width: 460px;
margin-left: 40px;
height: 50px;
font-size: 18px;
}
.el-button {
margin-left: 40px;
font-size: 18px;
height: 45px;
padding: 8px 24px;
.search-warp {
width: 100%;
padding-left: 36px;
position: relative;
.el-input {
flex-grow: 1;
height: 50px;
font-size: 18px;
width: 100%;
::v-deep() {
.el-input__wrapper {
padding-right: 100px;
}
}
}
.el-button {
position: absolute;
right: 8px;
top: 50%;
transform: translateY(-50%);
font-size: 18px;
padding: 0 24px;
height: 42px;
}
}
}
.layout-header-bottom-menu {
@ -185,8 +274,8 @@ function Search() {
justify-content: space-between;
&-img {
img {
width: 110px;
height: 110px;
width: 48px;
height: 48px;
}
p {
text-align: center;

View File

@ -8,6 +8,7 @@
import { createRouter, createWebHistory } from 'vue-router';
import { qiankunWindow } from 'vite-plugin-qiankun/dist/helper';
import Layout from '@/layouts/index.vue';
import Views from '@/layouts/Views.vue';
import demo from './modules/demo';
@ -15,32 +16,65 @@ const { VITE_APP_NAME } = import.meta.env;
export const constantRoutes = [
{
path: '/404',
path: '/sub-operation-service/404',
name: '404',
component: () => import('@/views/error/404.vue'),
hidden: true,
},
{
path: '/403',
path: '/sub-operation-service/403',
name: '403',
component: () => import('@/views/error/403.vue'),
hidden: true,
},
{
path: '/',
path: '/sub-operation-service',
name: 'layout',
component: Layout,
redirect: '/home',
redirect: '/sub-operation-service/home',
meta: { title: '首页', icon: 'House' },
children: [
{
path: '/home',
path: '/sub-operation-service/home',
component: () => import('@/views/home/index.vue'),
name: 'home',
meta: { title: '首页', icon: 'House' },
},
],
},
{
path: '/ecommerce',
name: 'ecommerce',
component: Layout,
redirect: '/ecommerce',
meta: { title: '首页', icon: 'House' },
children: [
{
path: '/sub-operation-service/ecommerce',
component: () => import('@/views/ecommerce/index.vue'),
name: 'agricultural',
meta: { title: '农资交易', icon: 'House' },
},
{
path: '/sub-operation-service/purchaser',
component: () => import('@/views/ecommerce/purchaser.vue'),
name: 'purchaser',
meta: { title: '采购商服务', icon: 'House' },
},
{
path: '/sub-operation-service/supplier',
component: () => import('@/views/ecommerce/supplier.vue'),
name: 'supplier',
meta: { title: '供应商服务', icon: 'House' },
},
{
path: '/sub-operation-service/land',
component: () => import('@/views/ecommerce/land.vue'),
name: 'land',
meta: { title: '土地交易', icon: 'House' },
},
],
},
...demo,
];
@ -48,13 +82,13 @@ export const constantRoutes = [
* @Title notFoundRouter(找不到路由)
*/
export const notFoundRouter = {
path: '/:pathMatch(.*)',
path: '/sub-operation-service/:pathMatch(.*)',
name: 'notFound',
redirect: '/404',
redirect: '/sub-operation-service/404',
};
const router = createRouter({
history: createWebHistory(qiankunWindow.__POWERED_BY_QIANKUN__ ? `/${VITE_APP_NAME}/` : '/'), // history
history: createWebHistory(), // history
routes: constantRoutes,
});

View File

@ -1,5 +1,9 @@
// color
$legacy-ie: 10;
$color-main:#25BF82;
$color-5a:#5A5A5A;
$color-000:#000;
$color-fff:#fff;
$color-primary: #20a0ff;
$color-success: #13ce66;
$color-warning: #f7ba2a;
@ -25,6 +29,8 @@ $color-999: #999999;
$color-border-gray: #d1dbe5;
$color-input-border: #dcdfe6;
$color-border: $color-border-gray;
$width-main:1200px;
$color-types: (
primary: (
$color-primary,
@ -58,4 +64,5 @@ $color-types: (
),
);
@import 'utils/utils';

View File

@ -0,0 +1,78 @@
@font-face {
font-family: "iconfont"; /* Project id 4879313 */
src:
url('data:application/x-font-woff2;charset=utf-8;base64,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') format('woff2'),
}
.iconfont {
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-home:before {
content: "\e639";
}
.icon-operation:before {
content: "\e638";
}
.icon-bigScreen:before {
content: "\e74d";
}
.icon-edit:before {
content: "\e74c";
}
.icon-cart:before {
content: "\e74e";
}
.icon-sign:before {
content: "\e74f";
}
.icon-book:before {
content: "\e750";
}
.icon-level:before {
content: "\e751";
}
.icon-finish:before {
content: "\e752";
}
.icon-location:before {
content: "\e753";
}
.icon-time:before {
content: "\e755";
}
.icon-accept:before {
content: "\e756";
}
.icon-bg-chat:before {
content: "\e757";
}
.icon-see:before {
content: "\e758";
}
.icon-auth:before {
content: "\e759";
}
.icon-ci:before {
content: "\e75a";
}

View File

@ -17,3 +17,22 @@
height: auto;
max-height: calc(100vh - 130px);
}
.txt-ellipsis{
display: -webkit-inline-box;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
}
.clamp1{
-webkit-line-clamp: 1;
line-height: 1.5;
max-height: calc(1.5em * 1);
}
.clamp1{
-webkit-line-clamp: 2;
line-height: 1.5;
max-height: calc(1.5em * 2);
}

View File

@ -18,7 +18,7 @@ const whiteList = ['/login', '/auth-redirect']; // 设置白名单
router.beforeEach(async (to, from, next) => {
NProgress.start();
if (typeof to.meta.title === 'string') {
document.title = 'SUB-ADMIN | ' + to.meta.title || '管理系统';
document.title = '运营服务 | ' + to.meta.title || '管理系统';
}
const userStore = useUserStore();

View File

@ -0,0 +1,48 @@
<template>
<div class="ecommerce-banner" :style="{ height: height }">
<el-carousel height="height" motion-blur>
<el-carousel-item v-for="(item, index) in list" :key="index">
<img :src="getAssetsFile(item)" />
</el-carousel-item>
</el-carousel>
</div>
</template>
<script setup>
import { ref, reactive, onMounted, watch } from 'vue';
import { isEmpty, getAssetsFile } from '@/utils';
const props = defineProps({
height: { type: String, default: '320px' },
name: { type: String, default: 'agricultural' },
imglist: {
type: Array,
default: () => {
return [];
},
},
});
let nameVal = ref(props.name);
let list = reactive(props.imglist);
watch(
() => (props.list, props.imglist),
() => {
nameVal.value = props.name;
list = props.imglist;
},
{
immediate: true,
}
);
</script>
<style lang="scss" scoped>
.ecommerce-banner {
width: 100%;
::v-deep() {
.el-carousel__item {
border-radius: 16px !important;
}
}
}
</style>

View File

@ -0,0 +1,55 @@
<template>
<div class="ecommerce-common-warp">
<div class="ecommerce-common-content">
<div class="left-menu">
<slot v-if="$slots.left" name="left"></slot>
<template v-else>
<leftMenu :current-name="currentName"></leftMenu>
</template>
</div>
<div class="common-content">
<slot v-if="$slots.main" name="main"></slot>
<template v-else></template>
</div>
</div>
</div>
</template>
<script setup>
import { ref, reactive, onMounted, watch } from 'vue';
import leftMenu from './leftMenu.vue';
const props = defineProps({
currentName: { type: String, default: 'agricultural' },
});
</script>
<style lang="scss" scoped>
.ecommerce-common-warp {
width: 100%;
height: calc(100vh - 230px);
text-align: center;
.ecommerce-common-content {
width: $width-main;
margin: auto;
height: 100%;
display: inline-flex;
justify-content: space-between;
.left-menu,
.common-content {
height: 100%;
min-height: 100%;
border-radius: 8px;
padding: 8px;
overflow-y: auto;
}
.left-menu {
width: 240px;
background: $color-fff;
}
.common-content {
width: calc(100% - 240px);
margin-left: 16px;
}
}
}
</style>

View File

@ -0,0 +1,158 @@
<template>
<div class="filter-top-warp">
<div v-for="(n, index) in maxLevelAndNodes.LevelKey" :key="index" class="filter-item">
<div class="single-item">
<div class="single-li all" :class="maxLevelAndNodes.LevelVal[n].id == '' ? 'li-act' : ''" @click="selectAll(n)">全部</div>
<div class="not-all">
<div
v-for="(m, indexm) in handlelist(n)"
:key="indexm"
class="single-li"
:class="select[n].id == m.id && ((m.pId && select[n].pId == m.pId) || !m.pId) ? 'li-act' : ''"
@click="selectItem(index, n, m)"
>
{{ m.title }}
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref, reactive, onMounted, watch, computed } from 'vue';
import { isEmpty, getAssetsFile } from '@/utils';
const props = defineProps({
list: {
type: Array,
default: () => {
return [];
},
},
});
let treeList = reactive([]);
watch(
() => props.list,
() => {
treeList = props.list;
},
{
immediate: true,
}
);
const currentLevel = ref(null);
//
const maxLevelAndNodes = computed(() => {
let maxLevel = 0;
const levelMap = {}; //
let LevelKey = [];
let LevelVal = {};
// 使
const stack = [];
// 1
for (const node of treeList) {
stack.push({ node, level: 1 });
}
//
while (stack.length > 0) {
const { node, level } = stack.pop(); //
//
maxLevel = Math.max(maxLevel, level);
//
if (!levelMap[level]) {
levelMap[level] = [];
}
levelMap[level].push(node);
LevelVal[level] = { id: '', pId: node.pId ? node.pId : '' };
//
if (node.children) {
for (const child of node.children) {
stack.push({ node: child, level: level + 1 });
}
}
}
LevelKey = Object.keys(levelMap);
return { maxLevel, levelMap, LevelKey, LevelVal };
});
const select = reactive(maxLevelAndNodes.value.LevelVal);
const handlelist = (key) => {
if (!key || !maxLevelAndNodes.value.levelMap[key]) return [];
let LevelKey = maxLevelAndNodes.value.LevelKey || [];
const originalList = maxLevelAndNodes.value.levelMap[key];
const parentKey = String(Number(key) - 1); // key
const parentVal = select[parentKey]; //
//
if (LevelKey[0] === key || !parentVal || parentVal.id === '') {
return originalList;
}
// pId
if (parentVal && parentVal.id) {
return originalList.filter((m) => m.pId === parentVal.id);
}
//
return [];
};
const selectItem = (index, key, item) => {
if (key && item.id) {
currentLevel.value = index || 0;
select[key] = { id: item.id, pId: item.pId ? item.pId : null };
}
};
const selectAll = (key) => {
select[key].id = '';
};
</script>
<style lang="scss" scoped>
.filter-top-warp {
width: 100%;
border-radius: 16px;
background: $color-fff;
padding: 16px;
text-align: left;
.filter-item {
width: 100%;
}
.single-item {
width: 100%;
display: inline-flex;
justify-content: flex-start;
.single-li {
display: inline-block;
cursor: pointer;
margin: 10px;
font-size: 18px;
&.all {
width: 60px;
}
&.li-act {
color: $color-main;
}
}
.not-all {
display: inline-flex;
justify-content: flex-start;
width: calc(100% - 60px);
flex-wrap: wrap;
.single-li {
}
}
}
}
</style>

View File

@ -0,0 +1,76 @@
<template>
<div class="c-goods-item-warp">
<div class="goods-img">
<el-image :src="getAssetsFile('images/ecommerce/' + 'pic.png')" fit="cover" />
</div>
<div class="goods-name txt-ellipsis clamp1">{{ '遇合堂新款禽泰克家禽通用药250遇合堂新款禽泰克家禽通用药250' }}</div>
<div class="goods-do">
<div class="price txt-ellipsis clamp">25.00</div>
<div class="do">
<div class="iconfont icon-cart"></div>
</div>
</div>
</div>
</template>
<script setup>
import { isEmpty, getAssetsFile } from '@/utils';
</script>
<style lang="scss" scoped>
.c-goods-item-warp {
width: 100%;
padding: 8px;
.goods-img {
width: 100%;
height: 168px;
border-radius: 16px;
overflow: hidden;
::v-deep() {
.el-image {
width: 100%;
height: 168px;
}
}
}
.goods-name {
margin-top: 8px;
font-size: 16px;
color: $color-666;
}
.goods-do {
display: inline-flex;
width: 100%;
justify-content: space-between;
.price {
width: calc(100% - 32px);
text-align: left;
font-size: 22px;
padding-right: 8px;
color: $color-main;
font-weight: 700;
}
.price::before {
content: ' ¥';
font-size: 16px !important;
font-weight: normal !important;
}
.do {
display: inline-block;
width: 32px;
height: 32px;
border-radius: 50%;
text-align: center;
background: $color-main;
position: relative;
cursor: pointer;
.iconfont {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
color: $color-fff;
font-size: 20px;
}
}
}
}
</style>

View File

@ -0,0 +1,84 @@
<template>
<div class="ecommerce-left-menu-warp">
<div class="left-menu">
<view v-for="(n, index) in leftMenu" :key="index" class="left-menu-item" :class="currentIndex == index ? 'active' : ''" @click="toLink(index)">
<div class="item-img">
<img :src="getAssetsFile('images/ecommerce/' + n.icon)" />
</div>
<span class="item-title">{{ n.title }}</span>
</view>
</div>
</div>
</template>
<script setup name="home">
import { ref, reactive, onMounted, watch } from 'vue';
import { isEmpty, getAssetsFile } from '@/utils';
import { useRoute, useRouter } from 'vue-router';
const route = useRoute();
const router = useRouter();
const props = defineProps({
currentName: { type: String, default: 'agricultural' },
});
const leftMenu = reactive([
{ name: 'agricultural', title: '农资交易', icon: 'menu2.png', path: '/sub-operation-service/ecommerce' },
{ name: 'supplier', title: '供应商服务', icon: 'menu1.png', path: '/sub-operation-service/supplier' },
{ name: 'purchaser', title: '采购商服务', icon: 'menu3.png', path: '/sub-operation-service/purchaser' },
{ name: 'land', title: '土地交易', icon: 'menu4.png', path: '/sub-operation-service/land' },
]);
let currentIndex = ref(0);
watch(
() => props.currentName,
() => {
console.info('currentName', props.currentName);
currentIndex.value = leftMenu.findIndex((m) => {
return m.name == props.currentName;
});
},
{ deep: true, immediate: true }
);
const toLink = (index) => {
currentIndex.value = index;
let path = index != undefined ? leftMenu[index].path : null;
if (path) {
router.push(path);
}
};
</script>
<style lang="scss" scoped>
.ecommerce-left-menu-warp {
width: 100%;
height: 100%;
.left-menu {
.left-menu-item {
width: 100%;
display: inline-flex;
justify-content: flex-start;
padding: 16px 0;
cursor: pointer;
&.active {
color: $color-main;
}
.item-img,
.item-title {
vertical-align: middle;
}
.item-img {
display: inline-block;
width: 32px;
height: 32px;
}
.item-title {
display: -webkit-inline-box;
font-size: 20px;
font-weight: 400;
padding-left: 8px;
}
}
}
}
</style>

View File

@ -0,0 +1,85 @@
<template>
<div>
<common current-name="agricultural">
<template #main>
<banner :imglist="bannerList"></banner>
<filtertop :list="treeList"></filtertop>
<div class="goods-list-warp">
<div class="goods-list">
<template v-for="(n, index) in 16" :key="index">
<div class="goods-item">
<goodsItem></goodsItem>
</div>
</template>
</div>
</div>
</template>
</common>
</div>
</template>
<script setup name="ecommerce">
import common from './components/common.vue';
import banner from './components/banner.vue';
import filtertop from './components/filtertop.vue';
import goodsItem from './components/goodsItem.vue';
import { ref, reactive, onMounted, watch, computed } from 'vue';
let treeList = reactive([
{
id: '01',
title: '农用百货',
children: [
{ pId: '01', id: '0101', title: '农具' },
{ pId: '01', id: '0102', title: '农机' },
{ pId: '01', id: '0103', title: '灌溉设备' },
{ pId: '01', id: '0104', title: '防护用品' },
],
},
{
id: '02',
title: '肥料',
children: [
{ pId: '02', id: '0101', title: '有机肥' },
{ pId: '02', id: '0102', title: '水溶肥' },
{ pId: '02', id: '0103', title: '天然肥料' },
],
},
{
id: '03',
title: '农药',
children: [
{ pId: '03', id: '0101', title: '杀虫剂' },
{ pId: '03', id: '0102', title: '杀菌剂' },
{ pId: '03', id: '0103', title: '除草剂' },
{ pId: '03', id: '0104', title: '杀螨剂' },
],
},
]);
let bannerList = reactive(['images/ecommerce/' + 'banner.png', 'images/ecommerce/' + 'banner.png']);
</script>
<style lang="scss" scoped>
.goods-list-warp {
width: 100%;
margin-top: 16px;
.goods-list {
width: 100%;
display: inline-flex;
flex-wrap: wrap;
justify-content: space-around;
gap: 10px;
.goods-item {
display: inline-block;
width: calc((100% - 50px) / 5);
background: $color-fff;
border-radius: 16px;
overflow: hidden;
margin-bottom: 16px;
}
}
/* 添加伪元素占位 */
.goods-list::after {
content: '';
flex: auto;
}
}
</style>

View File

@ -0,0 +1,12 @@
<template>
<div>
<common current-name="land">
<template #main>
<div>土地交易</div>
</template>
</common>
</div>
</template>
<script setup name="ecommerce">
import common from './components/common.vue';
</script>

View File

@ -0,0 +1,156 @@
<template>
<div class="purchaser-index-warp">
<common current-name="purchaser">
<template #main>
<el-row class="purchaser-top">
<el-col :span="12">
<div class="purchaser-top-title">行情动态</div>
<div class="purchaser-charts"></div>
</el-col>
<el-col :span="12">
<div class="purchaser-top-title">近7天热门产品</div>
<div class="purchaser-charts"></div>
</el-col>
</el-row>
<filtertop :list="treeList"></filtertop>
</template>
</common>
</div>
</template>
<script setup name="ecommerce">
import common from './components/common.vue';
import filtertop from './components/filtertop.vue';
import { ref, reactive, onMounted, watch, computed } from 'vue';
let treeList = reactive([
{
id: '01',
title: '农产品',
children: [
{
pId: '01',
id: '0101',
title: '植物性农产品',
children: [
{ pId: '0101', id: '010101', title: '谷物' },
{ pId: '0101', id: '010102', title: '蔬菜' },
{ pId: '0101', id: '010103', title: '水果' },
{ pId: '0101', id: '010104', title: '坚果与油料作物' },
{ pId: '0101', id: '010105', title: '糖料作物' },
{ pId: '0101', id: '010106', title: '纤维作物' },
{ pId: '0101', id: '010107', title: '茶叶' },
{ pId: '0101', id: '010108', title: '咖啡' },
{ pId: '0101', id: '010109', title: '香料' },
],
},
{
pId: '01',
id: '0102',
title: '动物性农产品',
children: [
{ pId: '0102', id: '010201', title: '肉类' },
{ pId: '0102', id: '010202', title: '奶制品' },
{ pId: '0102', id: '010203', title: '蛋类' },
{ pId: '0102', id: '010204', title: '蜂蜜' },
{ pId: '0102', id: '010205', title: '水产品' },
],
},
{
pId: '01',
id: '0103',
title: '特殊农产品',
children: [
{ pId: '0103', id: '010301', title: '花卉与苗木' },
{ pId: '0103', id: '010302', title: '药材' },
{ pId: '0103', id: '010303', title: '菌类' },
],
},
{
pId: '01',
id: '0104',
title: '其他',
children: [{ pId: '0104', id: '010401', title: '饲料' }],
},
],
},
{
id: '02',
title: '种子种苗',
children: [
{
pId: '02',
id: '0101',
title: '花卉种子种苗',
children: [
{ pId: '0101', id: '010101', title: '草本花卉' },
{ pId: '0101', id: '010102', title: '木本花卉' },
{ pId: '0101', id: '010103', title: '野生花卉' },
],
},
{
pId: '02',
id: '0102',
title: '蔬菜种子种苗',
children: [
{ pId: '0102', id: '010201', title: '叶菜类' },
{ pId: '0102', id: '010202', title: '根茎类' },
{ pId: '0102', id: '010203', title: '果实类' },
{ pId: '0102', id: '010204', title: '豆类' },
{ pId: '0102', id: '010205', title: '瓜类' },
],
},
{
pId: '02',
id: '0103',
title: '果树种苗',
children: [
{ pId: '0103', id: '010301', title: '柑橘类' },
{ pId: '0103', id: '010302', title: '仁果类' },
{ pId: '0103', id: '010303', title: '核果类' },
{ pId: '0103', id: '010304', title: '浆果类' },
],
},
{
pId: '02',
id: '0104',
title: '药材种子与种苗',
children: [
{ pId: '0104', id: '010401', title: '寒地龙药' },
{ pId: '0104', id: '010402', title: '常见中药材' },
],
},
{
pId: '02',
id: '0105',
title: '其他作物',
children: [
{ pId: '0105', id: '010501', title: '牧草' },
{ pId: '0105', id: '010502', title: '经济作物' },
{ pId: '0105', id: '010503', title: '观赏树木' },
],
},
],
},
]);
</script>
<style lang="scss" scoped>
.purchaser-index-warp {
width: 100%;
.purchaser-top {
width: 100%;
margin-bottom: 16px;
background: $color-fff;
border-radius: 16px;
overflow: hidden;
padding: 10px;
.purchaser-top-title {
width: 100%;
text-align: left;
font-size: 18px;
}
.purchaser-charts {
width: 100%;
}
}
}
</style>

View File

@ -0,0 +1,164 @@
<template>
<div>
<common current-name="supplier">
<template #main>
<banner name="supplier" :imglist="bannerList"></banner>
<filtertop :list="treeList"></filtertop>
<div class="goods-list-warp">
<div class="goods-list">
<template v-for="(n, index) in 16" :key="index">
<div class="goods-item">
<goodsItem></goodsItem>
</div>
</template>
</div>
</div>
</template>
</common>
</div>
</template>
<script setup name="ecommerce">
import common from './components/common.vue';
import banner from './components/banner.vue';
import filtertop from './components/filtertop.vue';
import goodsItem from './components/goodsItem.vue';
import { ref, reactive, onMounted, watch, computed } from 'vue';
let treeList = reactive([
{
id: '01',
title: '农产品',
children: [
{
pId: '01',
id: '0101',
title: '植物性农产品',
children: [
{ pId: '0101', id: '010101', title: '谷物' },
{ pId: '0101', id: '010102', title: '蔬菜' },
{ pId: '0101', id: '010103', title: '水果' },
{ pId: '0101', id: '010104', title: '坚果与油料作物' },
{ pId: '0101', id: '010105', title: '糖料作物' },
{ pId: '0101', id: '010106', title: '纤维作物' },
{ pId: '0101', id: '010107', title: '茶叶' },
{ pId: '0101', id: '010108', title: '咖啡' },
{ pId: '0101', id: '010109', title: '香料' },
],
},
{
pId: '01',
id: '0102',
title: '动物性农产品',
children: [
{ pId: '0102', id: '010201', title: '肉类' },
{ pId: '0102', id: '010202', title: '奶制品' },
{ pId: '0102', id: '010203', title: '蛋类' },
{ pId: '0102', id: '010204', title: '蜂蜜' },
{ pId: '0102', id: '010205', title: '水产品' },
],
},
{
pId: '01',
id: '0103',
title: '特殊农产品',
children: [
{ pId: '0103', id: '010301', title: '花卉与苗木' },
{ pId: '0103', id: '010302', title: '药材' },
{ pId: '0103', id: '010303', title: '菌类' },
],
},
{
pId: '01',
id: '0104',
title: '其他',
children: [{ pId: '0104', id: '010401', title: '饲料' }],
},
],
},
{
id: '02',
title: '种子种苗',
children: [
{
pId: '02',
id: '0101',
title: '花卉种子种苗',
children: [
{ pId: '0101', id: '010101', title: '草本花卉' },
{ pId: '0101', id: '010102', title: '木本花卉' },
{ pId: '0101', id: '010103', title: '野生花卉' },
],
},
{
pId: '02',
id: '0102',
title: '蔬菜种子种苗',
children: [
{ pId: '0102', id: '010201', title: '叶菜类' },
{ pId: '0102', id: '010202', title: '根茎类' },
{ pId: '0102', id: '010203', title: '果实类' },
{ pId: '0102', id: '010204', title: '豆类' },
{ pId: '0102', id: '010205', title: '瓜类' },
],
},
{
pId: '02',
id: '0103',
title: '果树种苗',
children: [
{ pId: '0103', id: '010301', title: '柑橘类' },
{ pId: '0103', id: '010302', title: '仁果类' },
{ pId: '0103', id: '010303', title: '核果类' },
{ pId: '0103', id: '010304', title: '浆果类' },
],
},
{
pId: '02',
id: '0104',
title: '药材种子与种苗',
children: [
{ pId: '0104', id: '010401', title: '寒地龙药' },
{ pId: '0104', id: '010402', title: '常见中药材' },
],
},
{
pId: '02',
id: '0105',
title: '其他作物',
children: [
{ pId: '0105', id: '010501', title: '牧草' },
{ pId: '0105', id: '010502', title: '经济作物' },
{ pId: '0105', id: '010503', title: '观赏树木' },
],
},
],
},
]);
let bannerList = reactive(['images/ecommerce/' + 'banner1.png', 'images/ecommerce/' + 'banner1.png']);
</script>
<style lang="scss" scoped>
.goods-list-warp {
width: 100%;
margin-top: 16px;
.goods-list {
width: 100%;
display: inline-flex;
flex-wrap: wrap;
justify-content: space-around;
gap: 10px;
.goods-item {
display: inline-block;
width: calc((100% - 50px) / 5);
background: $color-fff;
border-radius: 16px;
overflow: hidden;
margin-bottom: 16px;
}
}
/* 添加伪元素占位 */
.goods-list::after {
content: '';
flex: auto;
}
}
</style>

View File

@ -25,7 +25,7 @@ const useDevMode = true;
export default defineConfig(({ command, mode }) => {
const { VITE_PORT, VITE_APP_NAME, VITE_APP_BASE_API, VITE_APP_BASE_URL, VITE_APP_UPLOAD_API, VITE_APP_UPLOAD_URL } = loadEnv(mode, process.cwd());
const config = {
base: './',
base: '/sub-operation-service/',
build: {
target: 'ESNext',
outDir: 'dist',