This commit is contained in:
胥林川 2025-09-02 17:49:31 +08:00
commit 53502000b3
27 changed files with 956 additions and 114 deletions

View File

@ -1,12 +1,12 @@
# 正式环境
VITE_APP_NAME = 'daimp-front-main'
VITE_APP_TITLE = '全域数字农业产业运营管理平台'
VITE_APP_SUB_OS = '//http://47.109.205.240/sub-operation-service/'
VITE_APP_SUB_OA = '//http://47.109.205.240/sub-operation-admin/'
VITE_APP_SUB_GAS = '//http://47.109.205.240/sub-government-affairs-service/'
VITE_APP_SUB_GAA = '//http://47.109.205.240/sub-government-affairs-admin/'
VITE_APP_SUB_GSS = '//http://47.109.205.240/sub-government-screen-service/'
VITE_APP_SUB_GSR = '//http://47.109.205.240/new-digital-agriculture-screen/'
VITE_APP_SUB_OS = '//https://app.yingyijt.com/sub-operation-service/'
VITE_APP_SUB_OA = '//https://app.yingyijt.com/sub-operation-admin/'
VITE_APP_SUB_GAS = '//https://app.yingyijt.com/sub-government-affairs-service/'
VITE_APP_SUB_GAA = '//https://app.yingyijt.com/sub-government-affairs-admin/'
VITE_APP_SUB_GSS = '//https://app.yingyijt.com/sub-government-screen-service/'
VITE_APP_SUB_GSR = '//https://app.yingyijt.com/new-digital-agriculture-screen/'
# 接口
VITE_APP_BASE_API = '/apis'
VITE_APP_BASE_URL = ''

View File

@ -1,15 +1,15 @@
# 测试环境
VITE_APP_NAME = 'daimp-front-main'
VITE_APP_TITLE = '全域数字农业产业管理平台'
VITE_APP_SUB_OS = '//192.168.18.88/sub-operation-service/'
VITE_APP_SUB_OA = '//192.168.18.88/sub-operation-admin/'
VITE_APP_SUB_GAS = '//192.168.18.88/sub-government-affairs-service/'
VITE_APP_SUB_GAA = '//192.168.18.88/sub-government-admin/'
VITE_APP_SUB_GSS = '//192.168.18.88/sub-government-screen-service/'
VITE_APP_SUB_GSR = '//192.168.18.88/new-digital-agriculture-screen/'
VITE_APP_SUB_OS = '//192.168.18.99/sub-operation-service/'
VITE_APP_SUB_OA = '//192.168.18.99/sub-operation-admin/'
VITE_APP_SUB_GAS = '//192.168.18.99/sub-government-affairs-service/'
VITE_APP_SUB_GAA = '//192.168.18.99/sub-government-admin/'
VITE_APP_SUB_GSS = '//192.168.18.99/sub-government-screen-service/'
VITE_APP_SUB_GSR = '//192.168.18.99/new-digital-agriculture-screen/'
# 接口
VITE_APP_BASE_API = '/apis'
VITE_APP_BASE_URL = ''
VITE_APP_UPLOAD_API = '/uploadApis'
VITE_APP_UPLOAD_URL = ''
VITE_APP_VIST_URL = 'http://192.168.18.88'
VITE_APP_VIST_URL = 'http://192.168.18.99'

View File

@ -48,9 +48,7 @@ router.beforeEach(async (to, from, next) => {
}
}
} else {
next();
// if (whiteList.indexOf(to.path) !== -1) {
// next();
// } else {

View File

@ -46,9 +46,9 @@ const gotoPage = (row) => {
background-size: cover;
.platform-title {
height: 156px;
line-height: 50px;
line-height: 80px;
width: 98%;
font-size: 100px;
font-size: 90px;
text-align: center;
color: #fff;
transform: skewX(-10deg); /* 沿X轴倾斜-15度 */
@ -141,7 +141,6 @@ const gotoPage = (row) => {
height: 100px;
line-height: 80px;
padding-top: 80px;
margin-bottom: 0;
}
.platform-panel-item .icon {
width: 200px;

View File

@ -1,8 +1,8 @@
# 生产环境
VITE_MODE = 'PRO'
VITE_APP_MIAN = 'daimp-front-main'
# VITE_APP_MIAN_URL = 'http://47.109.205.240:88'
VITE_APP_MIAN_URL = 'http://192.168.18.14:8080'
VITE_APP_MIAN_URL = 'http://47.109.205.240'
# VITE_APP_MIAN_URL = 'http://192.168.18.14:8080'
VITE_APP_NAME = 'sub-government-affairs-service'
# 接口
VITE_APP_BASE_API = '/apis'

View File

@ -52,7 +52,6 @@ router.beforeEach(async (to, from, next) => {
// next(`/login?redirect=${to.path}`);
window.location.href = `/login?redirect=${encodeURIComponent(to.fullPath)}`;
}
}
});

View File

@ -24,6 +24,14 @@ export default defineConfig(({ command, mode }) => {
minify: 'terser',
rollupOptions: {
external: ['echarts-liquidfill'], // 显式声明外部依赖
output: {
manualChunks: {
// 手动分块示例
vue: ['vue', 'vue-router', 'pinia'],
echarts: ['echarts'],
vendor: ['lodash', 'axios'],
},
},
},
},
server: {

View File

@ -14,6 +14,7 @@ declare module 'vue' {
CodeDialog: typeof import('./src/components/code-dialog/index.vue')['default']
copy: typeof import('./src/components/custom-scroll-title copy/index.vue')['default']
CostomImg: typeof import('./src/components/costomImg.vue')['default']
CostomTabs: typeof import('./src/components/costomTabs.vue')['default']
CustomBack: typeof import('./src/components/customBack.vue')['default']
CustomCarouselPicture: typeof import('./src/components/custom-carousel-picture/index.vue')['default']
CustomEchartBar: typeof import('./src/components/custom-echart-bar/index.vue')['default']

View File

@ -12,7 +12,7 @@
</template>
<script setup name="app">
import { computed } from 'vue';
import { computed, onMounted, ref } from 'vue';
import { useSettingStore } from '@/store/modules/setting';
// element
import zhCn from 'element-plus/es/locale/lang/zh-cn';
@ -20,6 +20,26 @@ import zhCn from 'element-plus/es/locale/lang/zh-cn';
const SettingStore = useSettingStore();
//
const size = computed(() => SettingStore.themeConfig.globalComSize);
import menuList from '@/layouts/component/header/menu.js';
const meuns = ref(menuList);
import { useRoute } from 'vue-router';
import { useMenuStore } from '@/store/modules/menuStore';
const route = useRoute();
const menuStore = useMenuStore();
onMounted(() => {
let item = meuns.value.find((item) => route.path.indexOf(item.path) > -1);
// console.log('item', item);
if (item) {
menuStore.setMenuLabel(item.label);
menuStore.setMenuPath(item.path);
} else {
menuStore.setMenuLabel('智慧种植');
menuStore.setMenuPath('/sub-operation-service/smartFarm');
}
// console.log(menuStore.activeMenuLabel);
// console.log(menuStore.activeMenuPath);
});
</script>
<style lang="scss">

View File

@ -0,0 +1,469 @@
<template>
<!-- tabs少数据时用这个多数据时单行会两端有切换箭头 -->
<!-- <div class="coustom-tabs-container" :style="{ fontSize: props.fontSize }">
<el-tabs v-model="active1Current" @tab-change="handle1Click">
<el-tab-pane v-for="item in tabsLivel1Data" :key="item.id" :label="item.name" :name="item.id"> </el-tab-pane>
</el-tabs>
<el-tabs v-show="showLivel >= 2 && tabsLivel2Data.length > 0" v-model="active2Current" @tab-change="handle2Click">
<el-tab-pane v-for="item in tabsLivel2Data" :key="item.id" :label="item.name" :name="item.id"> </el-tab-pane>
</el-tabs>
<el-tabs v-show="showLivel >= 3 && tabsLivel3Data.length > 0" v-model="active3Current" @tab-change="handle3Click">
<el-tab-pane v-for="item in tabsLivel3Data" :key="item.id" :label="item.name" :name="item.id"> </el-tab-pane>
</el-tabs>
</div> -->
<!-- 自定义选项卡样式 -->
<div class="coustom-div-container" :style="{ fontSize: props.fontSize }">
<!-- 第一级选项卡 - 改为使用 div 模拟 -->
<div class="custom-tabs-container">
<div
v-for="item in tabsLivel1Data"
:key="item.id"
class="custom-tab-item"
:class="{
active: active1Current === item.id,
'all-tab': item.isAll,
}"
@click="handleCustomTabClick(1, item)"
>
{{ item.name }}
</div>
</div>
<!-- 第二级选项卡 -->
<div v-if="showLivel >= 2 && tabsLivel2Data.length > 0" class="custom-tabs-container">
<div
v-for="item in tabsLivel2Data"
:key="item.id"
class="custom-tab-item"
:class="{
active: active2Current === item.id,
'all-tab': item.isAll,
}"
@click="handleCustomTabClick(2, item)"
>
{{ item.name }}
</div>
</div>
<!-- 第三级选项卡 -->
<div v-if="showLivel >= 3 && tabsLivel3Data.length > 0" class="custom-tabs-container">
<div
v-for="item in tabsLivel3Data"
:key="item.id"
class="custom-tab-item"
:class="{
active: active3Current === item.id,
'all-tab': item.isAll,
}"
@click="handleCustomTabClick(3, item)"
>
{{ item.name }}
</div>
</div>
</div>
</template>
<script setup>
import { ref, watch, computed, onMounted, nextTick } from 'vue';
const props = defineProps({
list: {
type: Array,
required: true,
default: () => [
// {
// id: '71',
// level: 2,
// name: '',
// parentId: '60',
// children: [
// {
// id: '7101',
// level: 3,
// name: '',
// parentId: '71',
// },
// {
// id: '7102',
// level: 3,
// name: '',
// parentId: '71',
// },
// {
// id: '7103',
// level: 3,
// name: '',
// parentId: '71',
// },
// ],
// },
// {
// id: '72',
// level: 2,
// name: '',
// parentId: '60',
// children: [
// {
// id: '7201',
// level: 3,
// name: '',
// parentId: '72',
// },
// {
// id: '7202',
// level: 3,
// name: '',
// parentId: '72',
// },
// ],
// },
// {
// id: '73',
// level: 2,
// name: '',
// parentId: '60',
// children: [
// {
// id: '7301',
// level: 3,
// name: '',
// parentId: '73',
// },
// {
// id: '7302',
// level: 3,
// name: '',
// parentId: '73',
// },
// ],
// },
],
},
showLivel: {
type: Number,
default: 3,
validator: (value) => [1, 2, 3].includes(value),
},
fontSize: {
type: String,
default: '18px',
},
});
const emit = defineEmits(['select', 'change']);
// ID
const active1Current = ref('');
const active2Current = ref('');
const active3Current = ref('');
// ""
const createAllOption = (level, parentId = null) => {
return {
id: `all-level-${level}`,
name: '全部',
level: level,
parentId: parentId,
isAll: true, //
};
};
//
const tabsLivel1Data = computed(() => {
const allOption = createAllOption(1);
return [allOption, ...props.list];
});
const tabsLivel2Data = computed(() => {
if (!active1Current.value) return [];
// ""
if (active1Current.value === 'all-level-1') {
const allChildren = props.list.flatMap((item) => item.children || []);
// ""
return allChildren.length > 0 ? [createAllOption(2, active1Current.value), ...allChildren] : [];
}
//
const selectedItem = props.list.find((item) => item.id === active1Current.value);
const children = selectedItem?.children || [];
// ""
return children.length > 0 ? [createAllOption(2, active1Current.value), ...children] : [];
});
const tabsLivel3Data = computed(() => {
if (!active2Current.value) return [];
let children = [];
//
if (active2Current.value === 'all-level-2') {
//
if (active1Current.value === 'all-level-1') {
children = props.list.flatMap((item) => (item.children ? item.children.flatMap((child) => child.children || []) : []));
} else {
const level1Item = props.list.find((item) => item.id === active1Current.value);
children = level1Item?.children ? level1Item.children.flatMap((child) => child.children || []) : [];
}
} else {
//
let parentItem = null;
if (active1Current.value === 'all-level-1') {
for (const level1Item of props.list) {
if (level1Item.children) {
const found = level1Item.children.find((item) => item.id === active2Current.value);
if (found) {
parentItem = found;
break;
}
}
}
} else {
const level1Item = props.list.find((item) => item.id === active1Current.value);
parentItem = level1Item?.children?.find((item) => item.id === active2Current.value);
}
children = parentItem?.children || [];
}
// ""
return children.length > 0 ? [createAllOption(3, active2Current.value), ...children] : [];
});
//
const initializeSelection = () => {
if (tabsLivel1Data.value.length > 0) {
//
active1Current.value = tabsLivel1Data.value[0].id;
if (props.showLivel >= 2 && tabsLivel2Data.value.length > 0) {
//
active2Current.value = tabsLivel2Data.value[0].id;
if (props.showLivel >= 3 && tabsLivel3Data.value.length > 0) {
//
active3Current.value = tabsLivel3Data.value[0].id;
}
}
//
emitSelection();
}
};
//
const getSelectedItems = () => {
const selectedItems = [];
//
if (active1Current.value) {
const level1Item = tabsLivel1Data.value.find((item) => item.id === active1Current.value);
if (level1Item) {
selectedItems.push({
id: level1Item.id,
name: level1Item.name,
isAll: level1Item.isAll || false,
...level1Item,
});
}
}
//
if (active2Current.value && props.showLivel >= 2) {
const level2Item = tabsLivel2Data.value.find((item) => item.id === active2Current.value);
if (level2Item) {
selectedItems.push({
id: level2Item.id,
name: level2Item.name,
isAll: level2Item.isAll || false,
...level2Item,
});
}
}
//
if (active3Current.value && props.showLivel >= 3) {
const level3Item = tabsLivel3Data.value.find((item) => item.id === active3Current.value);
if (level3Item) {
selectedItems.push({
id: level3Item.id,
name: level3Item.name,
isAll: level3Item.isAll || false,
...level3Item,
});
}
}
return selectedItems;
};
//
const emitSelection = () => {
const selectedItems = getSelectedItems();
emit('select', selectedItems);
emit('change', selectedItems);
};
//
const handle1Click = (tabName) => {
active1Current.value = tabName;
//
if (props.showLivel >= 2) {
const allOption = tabsLivel2Data.value.find((item) => item.isAll);
active2Current.value = allOption ? allOption.id : '';
}
if (props.showLivel >= 3) {
const allOption = tabsLivel3Data.value.find((item) => item.isAll);
active3Current.value = allOption ? allOption.id : '';
}
emitSelection();
};
//
const handle2Click = (tabName) => {
active2Current.value = tabName;
//
if (props.showLivel >= 3) {
const allOption = tabsLivel3Data.value.find((item) => item.isAll);
active3Current.value = allOption ? allOption.id : '';
}
emitSelection();
};
//
const handle3Click = (tabName) => {
active3Current.value = tabName;
emitSelection();
};
//
const handleCustomTabClick = (level, item) => {
switch (level) {
case 1:
active1Current.value = item.id;
if (props.showLivel >= 2) {
const allOption = tabsLivel2Data.value.find((item) => item.isAll);
active2Current.value = allOption ? allOption.id : '';
}
if (props.showLivel >= 3) {
const allOption = tabsLivel3Data.value.find((item) => item.isAll);
active3Current.value = allOption ? allOption.id : '';
}
break;
case 2:
active2Current.value = item.id;
if (props.showLivel >= 3) {
const allOption = tabsLivel3Data.value.find((item) => item.isAll);
active3Current.value = allOption ? allOption.id : '';
}
break;
case 3:
active3Current.value = item.id;
break;
}
emitSelection();
};
// props.list
watch(
() => props.list,
(newList) => {
if (newList && newList.length > 0) {
nextTick(() => {
initializeSelection();
});
}
},
{ immediate: true, deep: true }
);
//
onMounted(() => {
if (props.list && props.list.length > 0) {
initializeSelection();
}
});
</script>
<style lang="scss" scoped>
// tabs
.coustom-tabs-container {
width: 100%;
.el-tabs {
margin-bottom: 10px;
:deep(.el-tabs__header) {
margin: 0;
}
:deep(.el-tabs__item) {
padding: 0 16px;
height: 32px;
line-height: 32px;
font-size: v-bind('props.fontSize') !important;
}
//
:deep(.el-tabs__item:first-child) {
color: #67c23a; // 绿
font-weight: 500;
}
:deep(.el-tabs__nav-wrap:after) {
background-color: transparent;
}
}
}
//
.coustom-div-container {
width: 100%;
}
.custom-tabs-container {
display: flex;
flex-wrap: wrap; /* 关键属性:允许换行 */
gap: 12px; /* 选项卡之间的间距 */
background: #fff;
border-radius: 8px;
margin-bottom: 16px;
}
.custom-tab-item {
padding: 0 8px;
cursor: pointer;
transition: all 0.3s ease;
white-space: nowrap;
/* 使用传入的字体大小 */
font-size: v-bind('props.fontSize');
&:hover {
color: $color-main;
}
&.active {
color: $color-main;
}
&.all-tab {
color: #323232;
&.active {
color: $color-main;
}
&:hover {
color: $color-main;
}
}
}
/* 响应式调整 */
@media (max-width: 768px) {
.custom-tab-item {
padding: 6px 12px;
font-size: 14px;
}
}
</style>

View File

@ -60,8 +60,8 @@
</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 active-text-color="#25BF82">{{ item.label }}</el-menu-item>
<app-link v-for="(item, index) in meuns" :key="index" :to="item.path" @click="clickMenu(item)">
<el-menu-item :style="{ color: activeLabel == item.label ? '#25BF82' : '' }">{{ item.label }}</el-menu-item>
</app-link>
</el-menu>
</div>
@ -70,52 +70,36 @@
</template>
<script setup name="layout-header">
import { ref, onMounted, onBeforeUnmount } from 'vue';
import { ref, onMounted, onBeforeUnmount, watch } from 'vue';
import { qrImg } from './base64img';
import AppLink from '../Menu/Link.vue';
import { useRouter } from 'vue-router';
import { getAssetsFile } from '@/utils';
import { getGoodNum } from '@/apis/agricultural.js';
import { useMethodsStore } from '@/store/modules/methods';
import { useMenuStore } from '@/store/modules/menuStore';
const router = useRouter();
const keyword = ref('');
const meuns = ref([
{
label: '智慧种植',
path: '/sub-operation-service/smartFarm',
},
{
label: '电商交易',
path: '/sub-operation-service/ecommerce',
},
{
label: '农事服务',
path: '/sub-operation-service/farmService',
},
{
label: '分拣包装',
path: '/sub-operation-service/packaging',
},
{
label: '仓储物流',
path: '/sub-operation-service/warehouseLogistics',
},
{
label: '涉农金融',
path: '/sub-operation-service/finance',
},
{
label: '公共品牌',
path: '/sub-operation-service/brand',
},
{
label: '综合看板',
path: '/sub-operation-service/dashboard',
},
]);
import menuList from './menu.js';
const meuns = ref(menuList);
const menuStore = useMenuStore();
const activeLabel = ref(menuStore.activeMenuLabel);
const clickMenu = (item) => {
menuStore.setMenuLabel(item.label);
menuStore.setMenuPath(item.path);
activeLabel.value = item.label;
};
watch(
() => menuStore.getMenuLabel(),
(newValue) => {
console.log('menuStore.getMenuLabel()', newValue);
activeLabel.value = newValue;
}
);
const goodNum = ref(0);

View File

@ -0,0 +1,35 @@
const menuList = [
{
label: '智慧种植',
path: '/sub-operation-service/smartFarm',
},
{
label: '电商交易',
path: '/sub-operation-service/ecommerce',
},
{
label: '农事服务',
path: '/sub-operation-service/farmService',
},
{
label: '分拣包装',
path: '/sub-operation-service/packaging',
},
{
label: '仓储物流',
path: '/sub-operation-service/warehouseLogistics',
},
{
label: '涉农金融',
path: '/sub-operation-service/finance',
},
{
label: '公共品牌',
path: '/sub-operation-service/brand',
},
{
label: '综合看板',
path: '/sub-operation-service/dashboard',
},
];
export default menuList;

View File

@ -0,0 +1,26 @@
import { defineStore } from 'pinia';
export const useMenuStore = defineStore({
id: 'menuStore',
state: () => ({
activeMenuLabel: localStorage.getItem('activeMenuLabel') || '智慧种植',
activeMenuPath: localStorage.getItem('activeMenuPath') || '/sub-operation-service/smartFarm',
}),
getters: {},
actions: {
setMenuLabel(val) {
this.activeMenuLabel = val;
localStorage.setItem('activeMenuLabel', val);
},
getMenuLabel() {
return this.activeMenuLabel;
},
setMenuPath(val) {
this.activeMenuPath = val;
localStorage.setItem('activeMenuPath', val);
},
getMenuPath() {
return this.activeMenuPath;
},
},
});

View File

@ -23,7 +23,7 @@ router.beforeEach(async (to, from, next) => {
const userStore = useUserStore();
const hasToken = userStore.hasToken();
console.log('sub-operation-service************hasToken', hasToken);
// console.log('sub-operation-service************hasToken', hasToken);
if (hasToken) {
if (to.path === '/login') {
// 如果已登录,请重定向到主页
@ -49,7 +49,7 @@ router.beforeEach(async (to, from, next) => {
} else {
if (whiteList.indexOf(to.path) !== -1) {
// next();
window.location.href = `/login?redirect=${encodeURIComponent(to.fullPath)}`;
window.location.href = `/login?redirect=${encodeURIComponent(to.fullPath)}`;
} else {
next(`/login?redirect=${to.path}`);
}

View File

@ -208,7 +208,7 @@
<script setup>
import common from './components/common.vue';
import banner from './components/banner.vue';
import { onMounted, reactive, ref, computed } from 'vue';
import { onMounted, reactive, ref, computed, watch } from 'vue';
import { getAssetsFile } from '@/utils';
import { qrImg } from '@/layouts/component/Header/base64img.js';
import evaluate from './components/evaluate.vue';
@ -226,6 +226,7 @@ const goodId = route.query.id; // 获取参数
const pId = route.query.pid;
const currentWeight = ref(0);
const showPhone = ref(false);
const jumpType = ref('1');
let bannerList = reactive(['images/ecommerce/' + 'banner.png', 'images/ecommerce/' + 'banner.png']);
const tabList = reactive([
@ -401,6 +402,8 @@ let saveInfo = reactive({
});
onMounted(() => {
jumpType.value = route.query.type ?? '1';
showDetail.value = false;
// const num = Number(pId);
getGoodDetail(goodId)
@ -472,7 +475,14 @@ const formattedData = (data) => {
};
const toCodeDetail = () => {
router.push('/sub-operation-service/ecommerce-agricultural/ecommerce-agriculturalDetail/source?id=' + goodId);
console.log(jumpType.value);
if (jumpType.value === '1') {
//
router.push('/sub-operation-service/ecommerce-agricultural/ecommerce-agriculturalDetail/source?id=' + goodId);
} else if (jumpType.value === '2') {
//
router.push('/sub-operation-service/ecommerce-supplier/detail/source?id=' + goodId);
}
};
const toBack = (level) => {

View File

@ -116,40 +116,70 @@ 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 === '') {
// id
// console.log('originalList', originalList);
if (key === '1') {
return originalList;
}
// pId
if (parentVal && parentVal.id) {
//.sort((a, b) => a.id.localeCompare(b.id))
//
if (key === '2') {
// ""id
if (!parentVal || parentVal.id === '') {
return originalList;
}
//
return originalList.filter((m) => m.parentId === parentVal.id);
}
//
if (parentVal && parentVal.id) {
return originalList.filter((m) => m.parentId === parentVal.id);
}
//
return [];
};
const selectItem = (index, key, item) => {
console.log('selectItem', key);
console.log('selectItem', item);
if (key && item.id) {
currentLevel.value = index || 0;
select[key] = { id: item.id, parentId: item.parentId ? item.parentId : null };
emit('select', { id: item.id });
// ""
const currentLevelNum = Number(key);
const LevelKey = maxLevelAndNodes.value.LevelKey || [];
LevelKey.forEach((level) => {
const levelNum = Number(level);
if (levelNum > currentLevelNum) {
select[level] = { id: '', parentId: '' };
}
});
emit('select', select);
}
};
const selectAll = (key) => {
select[key].id = '';
console.log('selectAll', key);
console.log('selectAll', select);
//
const levelNum = Number(key);
const LevelKey = maxLevelAndNodes.value.LevelKey || [];
//
LevelKey.forEach((level) => {
const levelInt = Number(level);
if (levelInt >= levelNum) {
select[level] = { id: '', parentId: '' };
}
});
emit('select', select);
};

View File

@ -64,6 +64,7 @@ import { useMethodsStore } from '@/store/modules/methods';
import { ElMessage, ElMessageBox } from 'element-plus';
const route = useRoute();
const router = useRouter();
const emit = defineEmits(['toDetail']);
const props = defineProps({
data: {
@ -151,10 +152,11 @@ const openDialog = (data) => {
const toDetail = (id, pid) => {
if (props.type === 2) {
router.push('/sub-operation-service/ecommerce-supplier/detail?id=' + id + '&pid=' + pid);
router.push('/sub-operation-service/ecommerce-supplier/detail?id=' + id + '&pid=' + pid + '&type=' + 2);
} else {
router.push('/sub-operation-service/ecommerce-agricultural/ecommerce-agriculturalDetail?id=' + id + '&pid=' + pid);
router.push('/sub-operation-service/ecommerce-agricultural/ecommerce-agriculturalDetail?id=' + id + '&pid=' + pid + '&type=' + 1);
}
// emit('toDetail', id, pid);
};
</script>
<style lang="scss" scoped>

View File

@ -33,14 +33,23 @@ let currentIndex = ref(0);
watch(
() => props.currentName,
() => {
console.info('currentName', props.currentName);
// console.info('currentName', props.currentName);
currentIndex.value = leftMenu.findIndex((m) => {
return m.name == props.currentName;
});
},
{ deep: true, immediate: true }
);
watch(
() => route.path,
() => {
// console.info('route.path', route.path);
currentIndex.value = leftMenu.findIndex((m) => {
return route.path.indexOf(m.path) > -1;
});
},
{ deep: true, immediate: true }
);
const toLink = (index) => {
currentIndex.value = index;
let path = index != undefined ? leftMenu[index].path : null;
@ -51,6 +60,7 @@ const toLink = (index) => {
</script>
<style lang="scss" scoped>
.ecommerce-left-menu-warp {
padding: 0 30px 0 10px;
width: 100%;
height: 100%;
.left-menu {

View File

@ -3,12 +3,42 @@
<common current-name="agricultural">
<template #main>
<!-- <banner :imglist="bannerList"></banner> -->
<filtertop :list="treeList" @select="selected" @search="search"></filtertop>
<!-- 原来的顶部筛选组件不好用 -->
<!-- <filtertop :list="treeList" @select="selected" @search="search"></filtertop> -->
<!-- 顶部筛选条件 -->
<div class="filter-container">
<div style="width: 40%; margin-left: 10px; margin-bottom: 10px">
<div class="search-container">
<div class="search-box">
<input v-model="searchName" type="text" placeholder="请输入农资商品名称" class="search-input" />
<button class="search-button" @click.stop="onQuery()">
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<circle cx="11" cy="11" r="8"></circle>
<line x1="21" y1="21" x2="16.65" y2="16.65"></line>
</svg>
</button>
</div>
</div>
</div>
<costomTabs :list="treeList" @change="changeTabs"></costomTabs>
</div>
<div class="goods-list-warp">
<div class="goods-list">
<template v-for="(n, index) in list" :key="n.id">
<div class="goods-item">
<goodsItem :data="n"></goodsItem>
<goodsItem :data="n" :type="1"></goodsItem>
</div>
</template>
</div>
@ -32,6 +62,7 @@ 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 costomTabs from '@/components/costomTabs.vue';
import { ref, reactive, onMounted, onBeforeMount, onUnmounted, watch, computed } from 'vue';
import { transaction, agriculturalList } from '@/apis/agricultural';
let treeList = reactive([
@ -71,7 +102,24 @@ onBeforeMount(() => {
getTree();
getList();
});
const changeTabs = (paramsArr) => {
console.log('tabs选项', paramsArr);
let level1Id = 0;
let level2Id = 0;
let level3Id = 0;
if (paramsArr.length >= 1) {
level1Id = paramsArr[0]?.name == '全部' ? 0 : paramsArr[0]?.id || 0;
}
if (paramsArr.length >= 2) {
level2Id = paramsArr[1]?.name == '全部' ? 0 : paramsArr[1]?.id || 0;
}
if (paramsArr.length >= 3) {
level3Id = paramsArr[2]?.name == '全部' ? 0 : paramsArr[2]?.id || 0;
}
console.log('处理后的ID:', level1Id, level2Id, level3Id);
};
//
const getTree = () => {
transaction().then((res) => {
@ -84,6 +132,7 @@ const getTree = () => {
};
//
let searchName = ref('');
let list = reactive([]);
let params = reactive({
current: 1,
@ -119,9 +168,11 @@ const getList = (data) => {
};
// let bannerList = reactive(['images/ecommerce/' + 'banner.png', 'images/ecommerce/' + 'banner1.png']);
const onQuery = () => {
getList({ searchName: searchName.value });
};
const search = (data) => {
getList(data);
getList();
};
const selected = (data) => {
@ -161,11 +212,60 @@ const selected = (data) => {
background: $color-fff;
}
}
/* 添加伪元素占位 */
.goods-list::after {
content: '';
flex: auto;
}
}
//
.filter-container {
padding: 16px 16px 6px 16px;
width: 100%;
border-radius: 16px;
text-align: left;
background: $color-fff;
//
.search-container {
display: flex;
justify-content: center;
padding: 0 16px 0 0;
.search-box {
position: relative;
width: 100%;
max-width: 600px;
}
.search-input {
width: 100%;
padding: 10px;
border: 1px solid black;
border-radius: 14px;
font-size: 14px;
color: #333;
outline: none;
transition: border-color 0.3s;
}
.search-input:focus {
border-color: #409eff;
}
.search-input::placeholder {
color: #999;
}
.search-button {
position: absolute;
right: -10px;
top: 55%;
transform: translateY(-50%);
background: transparent;
border: none;
cursor: pointer;
padding: 4px;
color: #000;
}
.search-button:hover {
color: #409eff;
}
}
}
</style>

View File

@ -3,7 +3,37 @@
<common current-name="supplier">
<template #main>
<!-- <banner name="supplier" :imglist="bannerList"></banner> -->
<filtertop :list="treeList" @select="selected" @search="search"></filtertop>
<!-- 原来的顶部筛选组件不好用 -->
<!-- <filtertop :list="treeList" @select="selected" @search="search"></filtertop> -->
<!-- 顶部筛选条件 -->
<div class="filter-container">
<div style="width: 40%; margin-left: 10px; margin-bottom: 10px">
<div class="search-container">
<div class="search-box">
<input v-model="searchName" type="text" placeholder="请输入农资商品名称" class="search-input" />
<button class="search-button" @click.stop="onQuery()">
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<circle cx="11" cy="11" r="8"></circle>
<line x1="21" y1="21" x2="16.65" y2="16.65"></line>
</svg>
</button>
</div>
</div>
</div>
<costomTabs :list="treeList" @change="changeTabs"></costomTabs>
</div>
<div class="goods-list-warp">
<div class="goods-list">
<template v-for="(n, index) in list" :key="n.id">
@ -53,6 +83,7 @@ let list = reactive([
// goodPrice: '25',
// },
]);
let searchName = ref('');
let params = reactive({
current: 1,
size: 10,
@ -65,6 +96,24 @@ let pagination = reactive({
total: 4,
});
let bannerList = reactive(['images/ecommerce/' + 'banner1.png', 'images/ecommerce/' + 'banner1.png']);
const changeTabs = (paramsArr) => {
console.log('tabs选项', paramsArr);
let level1Id = 0;
let level2Id = 0;
let level3Id = 0;
if (paramsArr.length >= 1) {
level1Id = paramsArr[0]?.name == '全部' ? 0 : paramsArr[0]?.id || 0;
}
if (paramsArr.length >= 2) {
level2Id = paramsArr[1]?.name == '全部' ? 0 : paramsArr[1]?.id || 0;
}
if (paramsArr.length >= 3) {
level3Id = paramsArr[2]?.name == '全部' ? 0 : paramsArr[2]?.id || 0;
}
console.log('处理后的ID:', level1Id, level2Id, level3Id);
};
const getList = (data) => {
if (data) {
params.goodName = data.searchName;
@ -84,6 +133,9 @@ onMounted(() => {
getTree();
});
const onQuery = () => {
getList({ searchName: searchName.value });
};
const search = (data) => {
getList(data);
};
@ -151,4 +203,54 @@ const selected = (data) => {
flex: auto;
}
}
//
.filter-container {
padding: 16px 16px 6px 16px;
width: 100%;
border-radius: 16px;
text-align: left;
background: $color-fff;
//
.search-container {
display: flex;
justify-content: center;
padding: 0 16px 0 0;
.search-box {
position: relative;
width: 100%;
max-width: 600px;
}
.search-input {
width: 100%;
padding: 10px;
border: 1px solid black;
border-radius: 14px;
font-size: 14px;
color: #333;
outline: none;
transition: border-color 0.3s;
}
.search-input:focus {
border-color: #409eff;
}
.search-input::placeholder {
color: #999;
}
.search-button {
position: absolute;
right: -10px;
top: 55%;
transform: translateY(-50%);
background: transparent;
border: none;
cursor: pointer;
padding: 4px;
color: #000;
}
.search-button:hover {
color: #409eff;
}
}
}
</style>

View File

@ -92,7 +92,7 @@ const queryList = () => {
if (tableData.value[i].content.length > 80) {
tableData.value[i].content += '......';
}
console.log(tableData.value[i].content, tableData.value[i].content.length);
// console.log(tableData.value[i].content, tableData.value[i].content.length);
}
}
});

View File

@ -2,7 +2,7 @@
<div class="ecommerce-left-menu-warp">
<div class="left-menu">
<div>
<img :src="getAssetsFile('images/logo3.png')?.href" style="width: 90%" />
<img :src="getAssetsFile('images/logo3.png')?.href" style="width: 90%; cursor: pointer" @click="toHome" />
</div>
<view
v-for="(n, index) in leftMenu"
@ -39,6 +39,9 @@ const leftMenu = reactive([
// { name: 'myBrand', title: '', icon: 'menu6-1.png', path: '/sub-operation-service/myBrand' },
// { name: 'addressList', title: '', icon: 'menu7-1.png', path: '/sub-operation-service/addressList' },
]);
const toHome = () => {
router.push('/sub-operation-service/smartFarm/main');
};
let currentIndex = ref(0);

View File

@ -50,10 +50,22 @@ watch(
}
);
import menuList from '@/layouts/component/header/menu.js';
const meuns = ref(menuList);
import { useMenuStore } from '@/store/modules/menuStore';
const menuStore = useMenuStore();
const toLink = (item) => {
currentLink.value = item.name;
if (item.path && item.path != '') {
if (item.name == 'home') {
menuStore.setMenuLabel('智慧种植');
menuStore.setMenuPath('/sub-operation-service/smartFarm');
router.push(item.path);
} else {
let obj = meuns.value.find((el) => el.name == item.name);
console.log('obj', obj);
menuStore.setMenuLabel(obj.label);
menuStore.setMenuPath(obj.path);
router.push(obj.path);
}
};
</script>

View File

@ -44,30 +44,32 @@
<ischeck :value="g.ischeck" size="24px"></ischeck>
</div>
</div>
<div class="good-img" @click="toCheckGood(index, indexg)">
<!-- <costomImg :url="g.productImgUrl" :is-view="false"></costomImg> -->
<img class="good-img" style="border-radius: 5px" :src="g.productImgUrl.split('?')[0]" alt="" />
</div>
<div class="good-info" @click="toCheckGood(index, indexg)">
<div class="good-info-pos">
<div class="txt-ellipsis clamp2">{{ g.productName || '--' }}</div>
<div class="good-row-info" @click="goDetail(g, indexg)">
<div class="good-img">
<!-- <costomImg :url="g.productImgUrl" :is-view="false"></costomImg> -->
<img class="good-img" style="border-radius: 5px" :src="g.productImgUrl.split('?')[0]" alt="" />
</div>
</div>
<div class="good-price-num">
<div class="good-price-num-pos">
<div class="price" @click="toCheckGood(index, indexg)">{{ g.netWeightInfoVO?.goodSpecs }}</div>
<div class="total" @click="toCheckGood(index, indexg)">{{ (g.price * g.quantity).toFixed(2) }}</div>
<div class="num">
<div class="right-item">
<el-input-number v-model="g.quantity" :min="1" @change="numberChange(g.quantity, index, indexg)">
<template #suffix>
<span>{{ g.unit }}</span>
</template>
</el-input-number>
</div>
<div class="good-info">
<div class="good-info-pos">
<div class="txt-ellipsis clamp2">{{ g.productName || '--' }}</div>
</div>
<div class="good-del" @click="doSingleDel(index, indexg)">
<span>删除</span>
</div>
<div class="good-price-num">
<div class="good-price-num-pos">
<div class="price">{{ g.netWeightInfoVO?.goodSpecs }}</div>
<div class="total">{{ (g.price * g.quantity).toFixed(2) }}</div>
<div class="num">
<div class="right-item">
<el-input-number v-model="g.quantity" :min="1" @change="numberChange(g.quantity, index, indexg)">
<!-- <template #suffix>
<span>{{ g.unit }}</span>
</template> -->
</el-input-number>
</div>
</div>
<div class="good-del" @click="doSingleDel(index, indexg)">
<span>删除</span>
</div>
</div>
</div>
</div>
@ -170,6 +172,16 @@ const pagination = (value) => {
});
};
const jumpType = ref('1'); //12
const goDetail = (item, indexg) => {
console.log(item, indexg);
if (jumpType.value === 2) {
router.push('/sub-operation-service/ecommerce-supplier/detail?id=' + item.productId + '&type=' + 2);
} else {
router.push('/sub-operation-service/ecommerce-agricultural/ecommerce-agriculturalDetail?id=' + item.productId + '&type=' + 1);
}
};
function addIsCheckProperty(data) {
if (!data) return;
@ -584,6 +596,11 @@ function removeCheckedItems(data) {
width: 100%;
gap: 16px;
}
.good-row-info {
flex: 1;
display: flex;
gap: 16px;
}
.good-do,
.good-img,
.good-info,
@ -630,7 +647,7 @@ function removeCheckedItems(data) {
}
.price {
font-weight: 400;
width: 200px;
width: 180px;
}
.total {
font-weight: 700;

View File

@ -2,7 +2,7 @@
<div class="ecommerce-left-menu-warp">
<div class="left-menu">
<div>
<img :src="getAssetsFile('images/logo3.png')?.href" style="width: 90%" />
<img :src="getAssetsFile('images/logo3.png')?.href" style="width: 90%; cursor: pointer" @click="toHome" />
</div>
<view
v-for="(n, index) in leftMenu"
@ -40,6 +40,10 @@ const leftMenu = reactive([
{ name: 'addressList', title: '我的地址', icon: 'menu7-1.png', path: '/sub-operation-service/addressList' },
]);
const toHome = () => {
router.push('/sub-operation-service/smartFarm/main');
};
let currentIndex = ref(0);
watch(

View File

@ -50,10 +50,22 @@ watch(
}
);
import menuList from '@/layouts/component/header/menu.js';
const meuns = ref(menuList);
import { useMenuStore } from '@/store/modules/menuStore';
const menuStore = useMenuStore();
const toLink = (item) => {
currentLink.value = item.name;
if (item.path && item.path != '') {
if (item.name == 'home') {
menuStore.setMenuLabel('智慧种植');
menuStore.setMenuPath('/sub-operation-service/smartFarm');
router.push(item.path);
} else {
let obj = meuns.value.find((el) => el.name == item.name);
console.log('obj', obj);
menuStore.setMenuLabel(obj.label);
menuStore.setMenuPath(obj.path);
router.push(obj.path);
}
};
</script>

View File

@ -37,7 +37,7 @@
</div>
<div v-if="o.orderItemInfos && o.orderItemInfos.length > 0" class="order-item-content">
<div class="content-list">
<div v-for="(g, indexg) in o.orderItemInfos" :key="indexg" class="good-item">
<div v-for="(g, indexg) in o.orderItemInfos" :key="indexg" class="good-item" @click="goInfo(o.id)">
<div class="good-img">
<img class="good-img" :src="g.productImage" alt="" />
<!-- <costomImg
@ -388,6 +388,7 @@ const doCancel = (id) => {
padding-left: 16px;
width: 100%;
gap: 16px;
cursor: pointer;
}
.good-img,
.good-info,