This commit is contained in:
姚俊旭 2025-05-23 16:42:59 +08:00
commit 61be13b963
30 changed files with 438 additions and 385 deletions

View File

@ -12,5 +12,6 @@ VITE_APP_SUB_GSR = '//localhost:9530/new-digital-agriculture-screen/'
# 接口 # 接口
VITE_APP_BASE_API = '/apis' VITE_APP_BASE_API = '/apis'
VITE_APP_BASE_URL = 'http://192.168.18.99:8080' VITE_APP_BASE_URL = 'http://192.168.18.99:8080'
# VITE_APP_BASE_URL = 'http://192.168.18.14:8080'//线下测试
VITE_APP_UPLOAD_API = '/uploadApis' VITE_APP_UPLOAD_API = '/uploadApis'
VITE_APP_UPLOAD_URL = 'http://192.168.18.99:8080' VITE_APP_UPLOAD_URL = 'http://192.168.18.99:8080'

View File

@ -16,7 +16,7 @@
</template> </template>
</el-input> </el-input>
</el-form-item> </el-form-item>
<el-form-item v-if="captchaEnabled" prop="code"> <!-- <el-form-item v-if="captchaEnabled" prop="code">
<el-input v-model="loginForm.code" auto-complete="off" placeholder="验证码" style="width: 63%" @keyup.enter="handleLogin"> <el-input v-model="loginForm.code" auto-complete="off" placeholder="验证码" style="width: 63%" @keyup.enter="handleLogin">
<template #prefix> <template #prefix>
<svg-icon icon-class="validCode" class="el-input__icon input-icon" /> <svg-icon icon-class="validCode" class="el-input__icon input-icon" />
@ -25,7 +25,7 @@
<div class="login-code"> <div class="login-code">
<img :src="codeUrl" class="login-code-img" @click="getCode" /> <img :src="codeUrl" class="login-code-img" @click="getCode" />
</div> </div>
</el-form-item> </el-form-item> -->
<el-checkbox v-model="loginForm.rememberMe" style="margin: 0px 0px 25px 0px">记住密码</el-checkbox> <el-checkbox v-model="loginForm.rememberMe" style="margin: 0px 0px 25px 0px">记住密码</el-checkbox>
<el-form-item style="width: 100%"> <el-form-item style="width: 100%">
<el-button :loading="loading" size="large" type="primary" style="width: 100%" @click.prevent="handleLogin"> <el-button :loading="loading" size="large" type="primary" style="width: 100%" @click.prevent="handleLogin">
@ -61,13 +61,13 @@ export default {
username: 'admin', username: 'admin',
password: 'admin123', password: 'admin123',
rememberMe: false, rememberMe: false,
code: '', code: '1',
uuid: '', uuid: '',
}, },
loginRules: { loginRules: {
username: [{ required: true, trigger: 'blur', message: '请输入您的账号' }], username: [{ required: true, trigger: 'blur', message: '请输入您的账号' }],
password: [{ required: true, trigger: 'blur', message: '请输入您的密码' }], password: [{ required: true, trigger: 'blur', message: '请输入您的密码' }],
code: [{ required: true, trigger: 'change', message: '请输入验证码' }], // code: [{ required: true, trigger: 'change', message: '' }],
}, },
loading: false, loading: false,
// //

View File

@ -31,14 +31,14 @@ export default defineConfig(({ command, mode }) => {
'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Origin': '*',
}, },
proxy: { proxy: {
// 仅 Brand 模块走子应用 DevServer // // 仅 Brand 模块走子应用 DevServer
'/api/brand': { // '/api/brand': {
target: 'http://localhost:9526', // target: 'http://localhost:9526',
changeOrigin: true, // changeOrigin: true,
// 如果想去掉 /api/brand 前缀(比如子应用实际监听的是 /brand/... // // 如果想去掉 /api/brand 前缀(比如子应用实际监听的是 /brand/...
// 可以加一个 rewrite // // 可以加一个 rewrite
// rewrite: path => path.replace(/^\/api\/brand/, '/brand'), // // rewrite: path => path.replace(/^\/api\/brand/, '/brand'),
}, // },
[VITE_APP_BASE_API]: { [VITE_APP_BASE_API]: {
target: VITE_APP_BASE_URL, target: VITE_APP_BASE_URL,
changeOrigin: true, changeOrigin: true,

View File

@ -6,5 +6,7 @@ VITE_APP_MIAN_URL = 'http://localhost:9000'
VITE_APP_NAME = 'sub-government-affairs-service' VITE_APP_NAME = 'sub-government-affairs-service'
VITE_APP_BASE_API = '/apis' VITE_APP_BASE_API = '/apis'
VITE_APP_BASE_URL = 'http://192.168.18.99:8080' VITE_APP_BASE_URL = 'http://192.168.18.99:8080'
# VITE_APP_BASE_URL = 'http://192.168.18.14:8080'
VITE_APP_UPLOAD_API = '/uploadApis' VITE_APP_UPLOAD_API = '/uploadApis'
VITE_APP_UPLOAD_URL = 'http://192.168.18.99:9300' VITE_APP_UPLOAD_URL = 'http://192.168.18.99:9300'
# VITE_APP_UPLOAD_URL = 'http://192.168.18.14:8080'

View File

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

View File

@ -0,0 +1,54 @@
import request from '@/utils/axios';
// 获取网格列表
export const GetGridList = (params = {}) => {
return request('/land-resource/gridManage/page', {
method: 'get',
params,
});
};
// 网格员管理 - 列表
export function GetMemberList(params = {}) {
return request('/land-resource/grid-member/page', {
method: 'GET',
params,
});
}
// 网格员管理 - 新增
export function AddMember(data = {}) {
return request('/land-resource/grid-member', {
method: 'POST',
data,
});
}
// 网格员管理 - 修改
export function UpdateMember(data = {}) {
return request('/land-resource/grid-member', {
method: 'PUT',
data,
});
}
// 网格员管理 - 删除
export function DeleteMember(id) {
return request(`/land-resource/grid-member/${id}`, {
method: 'DELETE',
});
}
// // 网格员管理 - 导出
// export function ExportMember() {
// return request('/land-resource/grid-member/export', {
// method: 'POST',
// });
// }
export function ExportMember(data = {}) {
return request('/land-resource/grid-member/export', {
method: 'POST',
data,
responseType: 'blob', // 明确告诉 axios 返回 blob
});
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -1,10 +1,3 @@
<!--
* @Description:
* @Author: zenghua.wang
* @Date: 2023-06-20 14:29:45
* @LastEditors: zenghua.wang
* @LastEditTime: 2024-01-26 23:04:29
-->
<template> <template>
<div class="layout-hamburger" @click="handleCollapse"> <div class="layout-hamburger" @click="handleCollapse">
<el-icon v-if="isCollapse" class="icon"><expand /></el-icon> <el-icon v-if="isCollapse" class="icon"><expand /></el-icon>

View File

@ -7,8 +7,8 @@
--> -->
<template> <template>
<div class="logo"> <div class="logo">
<!-- <img src="/images/logo.png" class="logo-picture" /> --> <!-- <img src="../../../assets/images/logo.png" class="logo-picture" />
<h2 v-show="!isCollapse" class="logo-title">{{ VITE_APP_TITLE }}</h2> <h2 v-show="!isCollapse" class="logo-title">{{ VITE_APP_TITLE }}</h2> -->
</div> </div>
</template> </template>
@ -43,5 +43,9 @@ const { VITE_APP_TITLE } = import.meta.env;
line-height: 35px; line-height: 35px;
color: $color-primary; color: $color-primary;
} }
.logo-picture {
width: 100%;
height: 50px;
}
} }
</style> </style>

View File

@ -1,10 +1,3 @@
<!--
* @Description:
* @Author: zenghua.wang
* @Date: 2024-01-27 16:02:43
* @LastEditors: zenghua.wang
* @LastEditTime: 2024-04-12 21:12:01
-->
<template> <template>
<el-icon v-if="icon.includes('icon')" :class="`iconfont ${icon}`" :size="size" /> <el-icon v-if="icon.includes('icon')" :class="`iconfont ${icon}`" :size="size" />
<el-icon v-else :size="size"> <component :is="icon" /></el-icon> <el-icon v-else :size="size"> <component :is="icon" /></el-icon>

View File

@ -1,10 +1,3 @@
<!--
* @Description:
* @Author: zenghua.wang
* @Date: 2023-06-20 14:29:45
* @LastEditors: zenghua.wang
* @LastEditTime: 2024-01-27 09:29:36
-->
<template> <template>
<component :is="type" v-bind="linkProps(to)"> <component :is="type" v-bind="linkProps(to)">
<slot /> <slot />

View File

@ -1,10 +1,3 @@
<!--
* @Description:
* @Author: zenghua.wang
* @Date: 2023-06-20 14:29:45
* @LastEditors: zenghua.wang
* @LastEditTime: 2024-01-27 16:07:37
-->
<template> <template>
<template v-if="!item.hidden"> <template v-if="!item.hidden">
<template v-if="!item.alwaysShow && hasOneShowingChild(item.children, item)"> <template v-if="!item.alwaysShow && hasOneShowingChild(item.children, item)">
@ -15,21 +8,41 @@
</el-menu-item> </el-menu-item>
</layout-link> </layout-link>
</template> </template>
<template v-else-if="level === 2 && !isCollapse">
<el-dropdown trigger="hover" placement="right-start" :show-timeout="100" @visible-change="(val) => (isDropdownOpen = val)">
<span class="el-dropdown-link el-menu-item" @mouseenter.prevent>
<layout-icon :size="20" :icon="item.meta?.icon" />
<span>{{ item.meta?.title }}</span>
<el-icon class="arrow-icon" v-if="item.children?.length">
<component :is="isDropdownOpen ? 'arrow-left' : 'arrow-right'" />
</el-icon>
</span>
<template #dropdown>
<el-menu class="third-level-menu el-menu--vertical el-menu--popup-container" :default-active="$route.path" @select="$router.push">
<el-menu-item v-for="child in item.children" :key="child.path" :index="child.path">
<layout-icon :size="20" :icon="child.meta?.icon" />
<span>{{ child.meta?.title }}</span>
</el-menu-item>
</el-menu>
</template>
</el-dropdown>
</template>
<el-sub-menu v-else :index="item.path" teleported> <el-sub-menu v-else :index="item.path" teleported>
<template #title> <template #title>
<layout-icon :size="20" :icon="item?.meta?.icon" /> <layout-icon :size="20" :icon="item?.meta?.icon" />
<span>{{ item.meta && item.meta?.title }}</span> <span>{{ item.meta && item.meta?.title }}</span>
</template> </template>
<sub-item v-for="child in item.children" :key="child.path" :item="child" /> <sub-item v-for="child in item.children" :key="child.path" :item="child" :level="level + 1" />
</el-sub-menu> </el-sub-menu>
</template> </template>
</template> </template>
<script setup name="sub-item"> <script setup name="sub-item">
import { ref } from 'vue'; import { ref, computed } from 'vue';
// import { isExternal } from '@/utils/validate.js'; // import { isExternal } from '@/utils/validate.js';
import LayoutLink from './Link'; import LayoutLink from './Link';
import LayoutIcon from './Icon'; import LayoutIcon from './Icon';
import { useSettingStore } from '@/store/modules/setting';
// import path from 'path-browserify'; // import path from 'path-browserify';
defineProps({ defineProps({
@ -37,6 +50,10 @@ defineProps({
type: Object, type: Object,
required: true, required: true,
}, },
level: {
type: Number,
default: 1,
},
basePath: { basePath: {
type: String, type: String,
default: '', default: '',
@ -44,6 +61,10 @@ defineProps({
}); });
const onlyOneChild = ref(null); const onlyOneChild = ref(null);
const SettingStore = useSettingStore();
const isDropdownOpen = ref(false);
const isCollapse = computed(() => !SettingStore.isCollapse);
const hasOneShowingChild = (children = [], parent) => { const hasOneShowingChild = (children = [], parent) => {
const showingChildren = children.filter((item) => { const showingChildren = children.filter((item) => {
// //
@ -79,3 +100,25 @@ const hasOneShowingChild = (children = [], parent) => {
// return path.resolve(props.basePath, routePath); // return path.resolve(props.basePath, routePath);
// }; // };
</script> </script>
<style scoped>
.third-level-menu {
background: #fff;
border-radius: 4px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
min-width: 180px;
}
.el-dropdown-link {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
box-sizing: border-box;
}
.arrow-icon {
margin-left: auto;
font-size: 14px;
color: #999;
}
</style>

View File

@ -1,10 +1,3 @@
<!--
* @Description:
* @Author: zenghua.wang
* @Date: 2024-01-27 20:01:45
* @LastEditors: zenghua.wang
* @LastEditTime: 2024-03-30 14:32:07
-->
<template> <template>
<div class="layout-sider" :class="{ 'has-logo': themeConfig.showLogo }"> <div class="layout-sider" :class="{ 'has-logo': themeConfig.showLogo }">
<Logo v-if="themeConfig.showLogo" :is-collapse="isCollapse" /> <Logo v-if="themeConfig.showLogo" :is-collapse="isCollapse" />
@ -19,7 +12,7 @@
:collapse-transition="false" :collapse-transition="false"
:collapse="isCollapse" :collapse="isCollapse"
> >
<SubItem v-for="item in permissionRoutes" :key="item.path" :item="item" /> <SubItem v-for="item in permissionRoutes" :key="item.path" :item="item" :level="1" />
</el-menu> </el-menu>
</el-scrollbar> </el-scrollbar>
</div> </div>

View File

@ -1,10 +1,3 @@
<!--
* @Description: layout
* @Author: zenghua.wang
* @Date: 2024-01-26 20:13:37
* @LastEditors: zenghua.wang
* @LastEditTime: 2024-02-05 16:03:31
-->
<template> <template>
<div <div
class="basic-layout" class="basic-layout"

View File

@ -47,10 +47,10 @@ export const constantRoutes = [
...resourceRouter, ...resourceRouter,
...productOperateMainRoutes, ...productOperateMainRoutes,
...inputSuppliesRoutes, ...inputSuppliesRoutes,
produceGoods, // produceGoods,
...plantingAndBreedingRouter, // ...plantingAndBreedingRouter,
...traceRouter, ...traceRouter,
...systemRouter, // ...systemRouter,
]; ];
/** /**

View File

@ -34,30 +34,30 @@ const inputSuppliesRoutes = [
component: () => import('@/views/inputSuppliesManage/material/fertilizer/index.vue'), component: () => import('@/views/inputSuppliesManage/material/fertilizer/index.vue'),
meta: { title: '肥料管理', icon: '' }, meta: { title: '肥料管理', icon: '' },
}, },
{ // {
path: '/sub-government-affairs-service/material/pesticide', // path: '/sub-government-affairs-service/material/pesticide',
name: 'input-supplies-pesticide', // name: 'input-supplies-pesticide',
component: () => import('@/views/inputSuppliesManage/material/pesticide/index.vue'), // component: () => import('@/views/inputSuppliesManage/material/pesticide/index.vue'),
meta: { title: '农药管理', icon: '' }, // meta: { title: '农药管理', icon: '' },
}, // },
{ // {
path: '/sub-government-affairs-service/material/ratPoison', // path: '/sub-government-affairs-service/material/ratPoison',
name: 'input-supplies-ratPoison', // name: 'input-supplies-ratPoison',
component: () => import('@/views/inputSuppliesManage/material/ratPoison/index.vue'), // component: () => import('@/views/inputSuppliesManage/material/ratPoison/index.vue'),
meta: { title: '兽药管理', icon: '' }, // meta: { title: '兽药管理', icon: '' },
}, // },
{ {
path: '/sub-government-affairs-service/material/seed', path: '/sub-government-affairs-service/material/seed',
name: 'input-supplies-seed', name: 'input-supplies-seed',
component: () => import('@/views/inputSuppliesManage/material/seed/index.vue'), component: () => import('@/views/inputSuppliesManage/material/seed/index.vue'),
meta: { title: '种源管理', icon: '' }, meta: { title: '种子管理', icon: '' },
},
{
path: '/sub-government-affairs-service/material/farmMachinery',
name: 'input-supplies-farmMachinery',
component: () => import('@/views/inputSuppliesManage/material/farmMachinery/index.vue'),
meta: { title: '农机管理', icon: '' },
}, },
// {
// path: '/sub-government-affairs-service/material/farmMachinery',
// name: 'input-supplies-farmMachinery',
// component: () => import('@/views/inputSuppliesManage/material/farmMachinery/index.vue'),
// meta: { title: '农机管理', icon: '' },
// },
], ],
}, },
{ {
@ -72,12 +72,12 @@ const inputSuppliesRoutes = [
component: () => import('@/views/inputSuppliesManage/enterpriseDealerCheck/index.vue'), component: () => import('@/views/inputSuppliesManage/enterpriseDealerCheck/index.vue'),
meta: { title: '企业经销商抽检', icon: '' }, meta: { title: '企业经销商抽检', icon: '' },
}, },
{ // {
path: '/sub-government-affairs-service/useSupervise', // path: '/sub-government-affairs-service/useSupervise',
name: 'useSupervise', // name: 'useSupervise',
component: () => import('@/views/inputSuppliesManage/useSupervise/index.vue'), // component: () => import('@/views/inputSuppliesManage/useSupervise/index.vue'),
meta: { title: '使用监管', icon: '' }, // meta: { title: '使用监管', icon: '' },
}, // },
{ {
path: '/sub-government-affairs-service/leaseSupervise', path: '/sub-government-affairs-service/leaseSupervise',
name: 'leaseSupervise', name: 'leaseSupervise',

View File

@ -8,37 +8,37 @@ export default [
redirect: '/sub-government-affairs-service/mainHome', redirect: '/sub-government-affairs-service/mainHome',
meta: { title: '生产经营主体', icon: 'icon-shop' }, meta: { title: '生产经营主体', icon: 'icon-shop' },
children: [ children: [
{ // {
path: '/sub-government-affairs-service/mainHome', // path: '/sub-government-affairs-service/mainHome',
component: () => import('@/views/productOperateMain/home/index.vue'), // component: () => import('@/views/productOperateMain/home/index.vue'),
name: 'mainHome', // name: 'mainHome',
meta: { title: '数据可视化管理', icon: '' }, // meta: { title: '数据可视化管理', icon: '' },
}, // },
{ {
path: '/sub-government-affairs-service/individual', path: '/sub-government-affairs-service/individual',
component: () => import('@/views/productOperateMain/individual/index.vue'), component: () => import('@/views/productOperateMain/individual/index.vue'),
name: 'individual', name: 'individual',
meta: { title: '个体户', icon: '' }, meta: { title: '农户', icon: '' },
},
{
path: '/sub-government-affairs-service/collective',
component: () => import('@/views/productOperateMain/collective/index.vue'),
name: 'collective',
meta: { title: '村集体', icon: '' },
}, },
// {
// path: '/sub-government-affairs-service/collective',
// component: () => import('@/views/productOperateMain/collective/index.vue'),
// name: 'collective',
// meta: { title: '村集体', icon: '' },
// },
{ {
path: '/sub-government-affairs-service/coop', path: '/sub-government-affairs-service/coop',
component: () => import('@/views/productOperateMain/coOp/index.vue'), component: () => import('@/views/productOperateMain/coOp/index.vue'),
name: 'coop', name: 'coop',
meta: { title: '合作社', icon: '' }, meta: { title: '农企合作社', icon: '' },
},
{
path: '/sub-government-affairs-service/enterprise',
component: () => import('@/views/productOperateMain/enterprise/index.vue'),
name: 'enterprise',
meta: { title: '经营企业', icon: '' },
}, },
// { // {
// path: '/sub-government-affairs-service/enterprise',
// component: () => import('@/views/productOperateMain/enterprise/index.vue'),
// name: 'enterprise',
// meta: { title: '经营企业', icon: '' },
// },
// {
// path: '/sub-government-affairs-service/individual', // path: '/sub-government-affairs-service/individual',
// component: () => import('@/views/productOperateMain/individual/index.vue'), // component: () => import('@/views/productOperateMain/individual/index.vue'),
// name: 'individual', // name: 'individual',

View File

@ -21,27 +21,27 @@ export default [
children: [ children: [
{ {
path: '/sub-government-affairs-service/add-grid', path: '/sub-government-affairs-service/add-grid',
component: () => import('@/views/resource/grid/index.vue'), component: () => import('@/views/resource/grid/AddGrid.vue'),
name: 'add', name: 'add',
meta: { title: '新增网格', icon: '' }, meta: { title: '新增网格', icon: '' },
}, },
{ {
path: '/sub-government-affairs-service/add--grid-member', path: '/sub-government-affairs-service/add--grid-member',
component: () => import('@/views/resource/grid/AddGridMember.vue'), component: () => import('@/views/resource/grid/GridMember.vue'),
name: 'member', name: 'member',
meta: { title: '新增网格员', icon: '' }, meta: { title: '新增网格员', icon: '' },
}, },
{ // {
path: '/sub-government-affairs-service/grid--management', // path: '/sub-government-affairs-service/grid--management',
component: () => import('@/views/resource/grid/GridManagement.vue'), // component: () => import('@/views/resource/grid/GridManagement.vue'),
name: 'management', // name: 'management',
meta: { title: '网格化管理', icon: '' }, // meta: { title: '网格化管理', icon: '' },
}, // },
], ],
}, },
...annualplanRouters, ...annualplanRouters,
...landsRoutes, ...landsRoutes,
...statisticsRoutes, // ...statisticsRoutes,
...dictRoutes, ...dictRoutes,
], ],
}, },

View File

@ -8,12 +8,12 @@ export default [
redirect: '/sub-government-affairs-service/analysis-land', redirect: '/sub-government-affairs-service/analysis-land',
meta: { title: '统计分析', icon: 'icon-test' }, meta: { title: '统计分析', icon: 'icon-test' },
children: [ children: [
{ // {
path: '/sub-government-affairs-service/analysis-land', // path: '/sub-government-affairs-service/analysis-land',
component: () => import('@/views/resource/statisticAnalysis/land/index.vue'), // component: () => import('@/views/resource/statisticAnalysis/land/index.vue'),
name: 'analysis-land', // name: 'analysis-land',
meta: { title: '土地利用与规划分析', icon: '' }, // meta: { title: '土地利用与规划分析', icon: '' },
}, // },
{ {
path: '/sub-government-affairs-service/analysis-agriculture', path: '/sub-government-affairs-service/analysis-agriculture',
name: 'analysis-agriculture', name: 'analysis-agriculture',

View File

@ -13,7 +13,7 @@ export default [
path: '/sub-government-affairs-service/record', path: '/sub-government-affairs-service/record',
name: 'record', name: 'record',
component: Views, component: Views,
meta: { title: '种植档案', icon: 'Tickets' }, meta: { title: '种植档案', icon: 'Tickets' },
redirect: '/sub-government-affairs-service/record-base', redirect: '/sub-government-affairs-service/record-base',
children: [ children: [
{ {
@ -26,7 +26,7 @@ export default [
path: '/sub-government-affairs-service/record-seed', path: '/sub-government-affairs-service/record-seed',
component: () => import('@/views/trace/record/seed/index.vue'), component: () => import('@/views/trace/record/seed/index.vue'),
name: 'record-seed', name: 'record-seed',
meta: { title: '种档案', icon: '' }, meta: { title: '种档案', icon: '' },
}, },
], ],
}, },

View File

@ -6,13 +6,13 @@
<b class="statistic-title">综合数据统计</b> <b class="statistic-title">综合数据统计</b>
<el-row :gutter="16" style="margin-top: 40px"> <el-row :gutter="16" style="margin-top: 40px">
<el-col :span="8" class="text-center"> <el-col :span="8" class="text-center">
<p>农村人口</p> <p>人口</p>
<avue-count-up end="27.88" :decimals="2" class="text-primary" /> <avue-count-up end="27.88" :decimals="2" class="text-primary" />
<em>万人</em> <em>万人</em>
</el-col> </el-col>
<el-col :span="8" class="text-center"> <el-col :span="8" class="text-center">
<p>耕地面积</p> <p>耕地面积</p>
<avue-count-up end="103.88" :decimals="2" class="text-warning" /> <avue-count-up end="17" :decimals="2" class="text-warning" />
<em>万亩</em> <em>万亩</em>
</el-col> </el-col>
<el-col :span="8" class="text-center"> <el-col :span="8" class="text-center">
@ -38,7 +38,8 @@
<el-row :gutter="16" style="margin-bottom: 20px"> <el-row :gutter="16" style="margin-bottom: 20px">
<el-col :span="12"> <el-col :span="12">
<el-card shadow="hover"> <el-card shadow="hover">
<custom-echart-bar :chart-data="state.breedingData" height="400px" :option="state.breedingOption" /> <!-- <custom-echart-bar :chart-data="state.breedingData" height="400px" :option="state.breedingOption" /> -->
<custom-echart-pie :chart-data="state.businessData" height="400px" :option="state.businessOption" />
</el-card> </el-card>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
@ -51,14 +52,15 @@
<el-row :gutter="16" style="margin-bottom: 20px"> <el-row :gutter="16" style="margin-bottom: 20px">
<el-col :span="12"> <el-col :span="12">
<el-card shadow="hover"> <el-card shadow="hover">
<custom-echart-pie :chart-data="state.businessData" height="400px" :option="state.businessOption" /> <!-- <custom-echart-pie :chart-data="state.businessData" height="400px" :option="state.businessOption" /> -->
</el-card>
</el-col>
<el-col :span="12">
<el-card shadow="hover">
<custom-echart-mixin :chart-data="state.codingData" :option="state.codingOption" height="400px" /> <custom-echart-mixin :chart-data="state.codingData" :option="state.codingOption" height="400px" />
</el-card> </el-card>
</el-col> </el-col>
<!-- <el-col :span="12">
<el-card shadow="hover">
<custom-echart-mixin :chart-data="state.codingData" :option="state.codingOption" height="400px" />
</el-card>
</el-col> -->
</el-row> </el-row>
</div> </div>
</template> </template>
@ -85,11 +87,11 @@ const state = reactive({
}, },
yAxis: { yAxis: {
type: 'value', type: 'value',
name: '亩', name: '亩',
}, },
tooltip: { tooltip: {
formatter: function (params) { formatter: function (params) {
return `${params.name}${params.value}`; return `${params.name}${params.value}`;
}, },
}, },
barStyle: { barStyle: {
@ -101,16 +103,16 @@ const state = reactive({
}, },
}, },
areaData: [ areaData: [
{ value: 230, name: '耿马镇' }, { value: 2, name: '耿马镇' },
{ value: 165, name: '勐永镇' }, { value: 6, name: '勐永镇' },
{ value: 217, name: '勐撒镇' }, { value: 4, name: '勐撒镇' },
{ value: 200, name: '孟定镇' }, { value: 2, name: '孟定镇' },
{ value: 305, name: '大兴乡' }, { value: 3, name: '大兴乡' },
], ],
breedingOption: { breedingOption: {
color: ['#41b879', '#fed500'], color: ['#41b879', '#fed500'],
title: { title: {
text: '种殖综合数据统计', text: '种殖综合数据统计',
textStyle: { textStyle: {
color: '#333', color: '#333',
}, },
@ -131,9 +133,9 @@ const state = reactive({
}, },
breedingData: [ breedingData: [
{ value: 230, name: '种植面积', unit: '亩' }, { value: 230, name: '种植面积', unit: '亩' },
{ value: 165, name: '养殖面积', unit: '亩' }, // { value: 165, name: '', unit: '' },
{ value: 217, name: '种植基地', unit: '个' }, { value: 217, name: '种植基地', unit: '个' },
{ value: 200, name: '养殖基地', unit: '个' }, // { value: 200, name: '', unit: '' },
], ],
inputsOption: { inputsOption: {
color: ['#ffd500'], color: ['#ffd500'],
@ -192,9 +194,9 @@ const state = reactive({
}, },
inputsData: [ inputsData: [
{ value: 75, name: '农药使用', type: '投入品', max: 100, unit: '吨' }, { value: 75, name: '农药使用', type: '投入品', max: 100, unit: '吨' },
{ value: 38, name: '农机使用', type: '投入品', max: 100, unit: '台' }, // { value: 38, name: '使', type: '', max: 100, unit: '' },
{ value: 74, name: '种使用', type: '投入品', max: 100, unit: '吨' }, { value: 74, name: '种使用', type: '投入品', max: 100, unit: '吨' },
{ value: 55, name: '兽药使用', type: '投入品', max: 100, unit: '千克' }, // { value: 55, name: '使', type: '', max: 100, unit: '' },
{ value: 65, name: '肥料使用', type: '投入品', max: 100, unit: '吨' }, { value: 65, name: '肥料使用', type: '投入品', max: 100, unit: '吨' },
], ],
businessOption: { businessOption: {
@ -233,12 +235,12 @@ const state = reactive({
], ],
}, },
businessData: [ businessData: [
{ value: 28, name: '个体户' }, { value: 217, name: '农户' },
{ value: 358, name: '村集体' }, // { value: 358, name: '' },
{ value: 217, name: '合作社' }, { value: 28, name: '农企/合作社' },
{ value: 128, name: '农资企业' }, // { value: 128, name: '' },
{ value: 22, name: '种源企业' }, // { value: 22, name: '' },
{ value: 41, name: '生产加工企业' }, // { value: 41, name: '' },
], ],
codingOption: { codingOption: {
color: ['#41b879', '#ffd500'], color: ['#41b879', '#ffd500'],

View File

@ -21,7 +21,8 @@
@row-update="handleRowUpdate" @row-update="handleRowUpdate"
> >
<template #menu="{ row }"> <template #menu="{ row }">
<el-button type="primary">详情</el-button> <!-- <el-button type="primary">详情</el-button> -->
暂无
</template> </template>
</avue-crud> </avue-crud>
</section> </section>
@ -154,16 +155,65 @@ async function getData(resetPage) {
searchCondition.value searchCondition.value
); );
console.log('params', params); console.log('params', params);
for (let i = 0; i < 14; i++) { data.value = [
data.value.push({ {
taskNum: '20220101' + `${i}${i}${i}${i}${i}`, taskNum: '202451211',
taskType: i % 2 == 0 ? '0' : '1', taskType: '0',
enterpriseName: '上海XX有限公司', enterpriseName: '合肥丰乐种业股份有限公司',
enterpriseOwner: '张三', enterpriseOwner: '戴登安',
phone: '123456789', phone: '18785733748',
status: i % 2 == 0 ? '0' : '1', status: '0',
}); },
} {
taskNum: '202471241',
taskType: '0',
enterpriseName: '山东登海种业股份有限公司',
enterpriseOwner: '唐世伟',
phone: '18785733748',
status: '0',
},
{
taskNum: '2024111241',
taskType: '0',
enterpriseName: '甘肃省敦煌种业股份有限公司',
enterpriseOwner: '李世晓',
phone: '15685474526',
status: '0',
},
{
taskNum: '2024112244',
taskType: '1',
enterpriseName: '河南秋乐种业科技股份有限公司',
enterpriseOwner: '侯传伟',
phone: '17485693256',
status: '1',
},
{
taskNum: '2024122242',
taskType: '0',
enterpriseName: '安徽荃银高科种业股份有限公司',
enterpriseOwner: '应敏杰',
phone: '18423568745',
status: '0',
},
{
taskNum: '2024122242',
taskType: '0',
enterpriseName: '辽宁东亚种业有限公司',
enterpriseOwner: '杨永华',
phone: '15236989568',
status: '0',
},
{
taskNum: '202472255',
taskType: '0',
enterpriseName: '云南广大种业有限公司',
enterpriseOwner: '王云贵',
phone: '13888965335',
status: '0',
},
];
pageData.value.total = data.value.length; pageData.value.total = data.value.length;
_loading.value = false; _loading.value = false;
} }

View File

@ -1,6 +1,6 @@
<template> <template>
<section class="custom-page"> <section class="custom-page">
<h2>基本信息</h2> <h2>基本信息</h2>
<TypeMenu v-if="materialTypes['4'].length > 1" v-model:type="_type" :types="materialTypes['4']" /> <TypeMenu v-if="materialTypes['4'].length > 1" v-model:type="_type" :types="materialTypes['4']" />
<br /> <br />
<avue-crud <avue-crud
@ -77,7 +77,7 @@ const option = ref({
menuWidth: 160, menuWidth: 160,
column: [ column: [
{ {
label: '种名称', label: '种名称',
prop: 'keywords', prop: 'keywords',
hide: true, hide: true,
search: true, search: true,
@ -86,9 +86,9 @@ const option = ref({
editDisplay: false, editDisplay: false,
}, },
{ {
label: '种名称', label: '种名称',
prop: 'seedName', prop: 'seedName',
rules: customRules({ msg: '请输入种名称' }), rules: customRules({ msg: '请输入种名称' }),
}, },
{ {
prop: 'manufacturer', prop: 'manufacturer',

View File

@ -4,7 +4,6 @@
ref="crudRef" ref="crudRef"
v-model:search="searchCondition" v-model:search="searchCondition"
v-model:page="pageData" v-model:page="pageData"
:table-loading="_loading"
:option="option" :option="option"
:data="data" :data="data"
@search-change=" @search-change="

View File

@ -53,20 +53,20 @@ const state = reactive({
...CRUD_OPTIONS, ...CRUD_OPTIONS,
// addBtnText: '', // addBtnText: '',
column: [ column: [
{ // {
label: '网格区', // label: '',
prop: 'gridArea', // prop: 'gridArea',
search: true, // search: true,
width: 200, // width: 200,
addDisplay: false, // addDisplay: false,
editDisplay: false, // editDisplay: false,
viewDisplay: true, // viewDisplay: true,
rules: { // rules: {
required: true, // required: true,
message: '请输入', // message: '',
trigger: 'blur', // trigger: 'blur',
}, // },
}, // },
{ {
label: '网格名称', label: '网格名称',
prop: 'gridName', prop: 'gridName',
@ -80,7 +80,7 @@ const state = reactive({
{ {
label: '网格区域', label: '网格区域',
prop: 'gridAreaName', prop: 'gridAreaName',
width: 300, // width: 300,
display: false, display: false,
rules: { rules: {
required: true, required: true,
@ -117,24 +117,24 @@ const state = reactive({
trigger: 'blur', trigger: 'blur',
}, },
}, },
{ // {
label: '网格管理员', // label: '',
prop: 'gridManager', // prop: 'gridManager',
rules: { // rules: {
required: true, // required: true,
message: '请输入', // message: '',
trigger: 'blur', // trigger: 'blur',
}, // },
}, // },
{ // {
label: '联系方式', // label: '',
prop: 'contactInfo', // prop: 'contactInfo',
rules: { // rules: {
required: true, // required: true,
message: '请输入', // message: '',
trigger: 'blur', // trigger: 'blur',
}, // },
}, // },
{ {
label: '省', label: '省',
prop: 'provinceCode', prop: 'provinceCode',
@ -172,7 +172,7 @@ const state = reactive({
span: 24, span: 24,
rows: 4, rows: 4,
overHidden: true, overHidden: true,
width: 200, // width: 200,
}, },
{ {
label: '创建时间', label: '创建时间',

View File

@ -28,159 +28,99 @@
</avue-crud> </avue-crud>
</div> </div>
</template> </template>
<script setup> <script setup>
import { reactive, ref } from 'vue'; import { reactive, ref } from 'vue';
import { useApp } from '@/hooks'; import { useApp } from '@/hooks';
import { CRUD_OPTIONS } from '@/config'; import { CRUD_OPTIONS } from '@/config';
import { isEmpty, downloadFile } from '@/utils'; import { isEmpty, downloadFile } from '@/utils';
import { useUserStore } from '@/store/modules/user'; import { useUserStore } from '@/store/modules/user';
import { compact } from 'lodash';
import { GetEntityList, AddEntity, UpdateEntity, DeleteEntity, ExportEntity } from '@/apis/resource/grid'; //
import { GetGridList, GetMemberList, AddMember, UpdateMember, DeleteMember, ExportMember } from '@/apis/resource/member';
const { VITE_APP_BASE_API } = import.meta.env; const { VITE_APP_BASE_API } = import.meta.env;
const app = useApp(); const app = useApp();
const UserStore = useUserStore(); const UserStore = useUserStore();
const crudRef = ref(null); const crudRef = ref(null);
const state = reactive({ const state = reactive({
loading: false, loading: false,
query: { query: { current: 1, size: 10 },
current: 1,
size: 10,
},
form: {}, form: {},
selection: [], selection: [],
gridOptions: [],
options: { options: {
...CRUD_OPTIONS, ...CRUD_OPTIONS,
// addBtnText: '',
column: [ column: [
{ {
label: '网格区', label: '网格员姓名',
prop: 'gridArea', prop: 'memberName',
searchLabelWidth: 100,
search: true, search: true,
width: 200,
addDisplay: false,
editDisplay: false,
viewDisplay: true,
rules: { rules: {
required: true, required: true,
message: '请输入', message: '请输入网格员姓名',
trigger: 'blur', trigger: 'blur',
}, },
}, },
{ {
label: '网格名称', label: '所属行政区域',
prop: 'gridName',
search: true,
rules: {
required: true,
message: '请输入',
trigger: 'blur',
},
},
{
label: '网格区域',
prop: 'gridAreaName', prop: 'gridAreaName',
width: 300, width: 300,
display: false, searchLabelWidth: 110,
search: true,
rules: { rules: {
required: true, required: true,
message: '请输入', message: '请输入所属区域',
trigger: 'blur', trigger: 'blur',
}, },
}, },
{ {
label: '网格区域', label: '所属网格',
prop: 'cities', prop: 'gridId',
type: 'cascader', type: 'select',
hide: true, width: 200,
addDisplay: true, search: true,
editDisplay: true, dicData: [], // mounted
viewDisplay: false,
// multiple: true,
// checkStrictly: true,
// collapseTags: true,
// emitPath: false,
// checkDescendants: false,
props: { props: {
label: 'areaName', label: 'gridName',
value: 'areaCode', value: 'id',
children: 'areaChildVOS',
}, },
dicUrl: `${VITE_APP_BASE_API}/system/area/region?areaCode=530000`,
dicHeaders: {
authorization: UserStore.token,
},
dicFormatter: (res) => res.data ?? [],
rules: { rules: {
required: true, required: true,
message: '请选择', message: '请选择所属网格',
trigger: 'blur', trigger: 'change',
}, },
}, },
{ {
label: '网格管理员', label: '管理员标识',
prop: 'gridManager', prop: 'adminFlag',
rules: { type: 'radio',
required: true, dicData: [
message: '请输入', { label: '是', value: '1' },
trigger: 'blur', { label: '否', value: '0' },
}, ],
valueDefault: '0',
hide: true, // false
}, },
{ {
label: '联系方式', label: '电话号码',
prop: 'contactInfo', prop: 'phone',
rules: { rules: [
required: true, { required: true, message: '请输入电话号码', trigger: 'blur' },
message: '请输入', { pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号码' },
trigger: 'blur', ],
},
},
{
label: '省',
prop: 'provinceCode',
hide: true,
display: false,
},
{
label: '市',
prop: 'cityCode',
hide: true,
display: false,
},
{
label: '县/区',
prop: 'gridAreaCode',
hide: true,
display: false,
},
{
label: '乡镇',
prop: 'townCode',
hide: true,
display: false,
},
{
label: '乡镇',
prop: 'village',
hide: true,
display: false,
}, },
{ {
label: '备注', label: '备注',
prop: 'note', prop: 'note',
type: 'textarea', type: 'textarea',
span: 24, span: 24,
rows: 4, rows: 3,
overHidden: true, overHidden: true,
width: 200, width: 200,
}, },
{
label: '创建时间',
prop: 'createTime',
width: 200,
hide: true,
display: false,
},
], ],
actions: [ actions: [
{ {
@ -210,10 +150,9 @@ const state = reactive({
currentRow: {}, currentRow: {},
}); });
//
const loadData = () => { const loadData = () => {
state.loading = true; state.loading = true;
GetEntityList(state.query) GetMemberList(state.query)
.then((res) => { .then((res) => {
if (res.code === 200) { if (res.code === 200) {
const { current, size, total, records } = res.data; const { current, size, total, records } = res.data;
@ -233,60 +172,56 @@ const loadData = () => {
state.loading = false; state.loading = false;
}); });
}; };
loadData(); loadData();
// //
const loadGridOptions = async () => {
try {
const res = await GetGridList(); //
if (res.code === 200) {
state.options.column.find((item) => item.prop === 'gridId').dicData = res.data.records;
}
} catch (error) {
app.$message.error('获取网格列表失败');
}
};
loadGridOptions();
const currentChange = (current) => { const currentChange = (current) => {
state.query.current = current; // state.query.current = current;
loadData(); // loadData();
}; };
//
const sizeChange = (size) => { const sizeChange = (size) => {
state.query.size = size; // state.query.size = size;
loadData(); // loadData();
}; };
//
const searchChange = (params, done) => { const searchChange = (params, done) => {
if (done) done(); // if (done) done();
state.query = params; // state.query = params;
state.query.current = 1; // state.query.current = 1;
loadData(); // loadData();
}; };
//
const refreshChange = () => { const refreshChange = () => {
loadData(); loadData();
app.$message.success('刷新成功'); app.$message.success('刷新成功');
}; };
//
const selectionChange = (rows) => { const selectionChange = (rows) => {
state.selection = rows; state.selection = rows;
}; };
//
const rowView = (row) => { const rowView = (row) => {
crudRef.value.rowView(row); crudRef.value.rowView(row);
}; };
const setCity = (row) => { const rowEdit = (row) => {
if (!isEmpty(row.cities)) { crudRef.value.rowEdit(row);
row.provinceCode = row?.cities[0] ?? null;
row.cityCode = row?.cities[1] ?? null;
row.gridAreaCode = row?.cities[2] ?? null;
row.townCode = row?.cities[3] ?? null;
row.village = row?.cities[4] ?? null;
// row.village = row?.cities.join(',');
}
}; };
//
const rowSave = (row, done, loading) => { const rowSave = (row, done, loading) => {
setCity(row); AddMember(row)
AddEntity(row)
.then((res) => { .then((res) => {
if (res.code === 200) { if (res.code === 200) {
app.$message.success('添加成功!'); app.$message.success('添加成功!');
@ -294,23 +229,12 @@ const rowSave = (row, done, loading) => {
loadData(); loadData();
} }
}) })
.catch((err) => { .catch((err) => app.$message.error(err.msg))
app.$message.error(err.msg); .finally(() => loading());
})
.finally(() => {
loading();
});
}; };
//
const rowEdit = (row) => {
const village = !isEmpty(row.village) ? row.village : [];
row.cities = compact([row.provinceCode, row.cityCode, row.gridAreaCode ?? '', row.townCode ?? '', ...village]);
crudRef.value.rowEdit(row);
};
const rowUpdate = (row, index, done, loading) => { const rowUpdate = (row, index, done, loading) => {
setCity(row); UpdateMember(row)
UpdateEntity(row)
.then((res) => { .then((res) => {
if (res.code === 200) { if (res.code === 200) {
app.$message.success('更新成功!'); app.$message.success('更新成功!');
@ -318,56 +242,48 @@ const rowUpdate = (row, index, done, loading) => {
loadData(); loadData();
} }
}) })
.catch((err) => { .catch((err) => app.$message.error(err.msg))
app.$message.error(err.msg); .finally(() => loading());
})
.finally(() => {
loading();
});
}; };
//
const rowDel = (row, index, done) => { const rowDel = (row, index, done) => {
if (isEmpty(row)) return; if (isEmpty(row)) return;
app app
.$confirm(`删除后信息将不可查看,确认要删除吗?`, '确定删除', { .$confirm(`确认删除该网格员吗?`, '提示', {
confirmButtonText: '确定', confirmButtonText: '确定',
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning', type: 'warning',
}) })
.then(() => { .then(() => {
DeleteEntity({ id: row.id }) DeleteMember(row.id) // 👈 id
.then((res) => { .then((res) => {
if (res.code === 200) { if (res.code === 200) {
app.$message.success('删除成功!'); app.$message.success('删除成功!');
loadData(); loadData();
done?.(); // 使 Table inline
} }
}) })
.catch((err) => { .catch((err) => app.$message.error(err.msg || '删除失败'));
app.$message.error(err.msg);
});
}) })
.catch(() => {}); .catch(() => {});
}; };
//
const onExport = () => { const onExport = () => {
if (isEmpty(state.data)) { if (isEmpty(state.data)) {
app.$message.error('当前暂时没有可供导出的数据!'); app.$message.error('当前暂时没有可供导出的数据!');
return; return;
} }
state.loading = true; state.loading = true;
const fileName = '网格明细表';
ExportEntity(state.query) //
const { current, size, ...query } = state.query;
ExportMember(query)
.then((res) => { .then((res) => {
if (res.status === 200) { downloadFile(res, '网格员明细表.xlsx', 'blob');
downloadFile(res.data, `${fileName}.xlsx`, 'blob'); app.$message.success('导出成功!');
app.$message.success('导出成功!');
}
})
.catch((err) => {
app.$message.error('导出失败!');
}) })
.catch(() => app.$message.error('导出失败!'))
.finally(() => { .finally(() => {
state.loading = false; state.loading = false;
}); });

View File

@ -33,11 +33,27 @@ import { CRUD_OPTIONS } from '@/config';
import Mock from 'mockjs'; import Mock from 'mockjs';
const res = Mock.mock({ const res = Mock.mock({
'data|20': [ 'data|2': [
{ {
id: '@increment(100000)', id: '@increment(100000)',
name: '@ctitle(5,10)', name: '小麦',
shop: '@ctitle(10,30)', shop: '万好芽种公司',
buyTime: '@datetime("yyyy-MM-dd HH:mm:ss")',
avalibleTime: '@datetime("yyyy-MM-dd HH:mm:ss")',
createdTime: '@datetime("yyyy-MM-dd HH:mm:ss")',
},
{
id: '@increment(100000)',
name: '玉米',
shop: '万好芽种公司',
buyTime: '@datetime("yyyy-MM-dd HH:mm:ss")',
avalibleTime: '@datetime("yyyy-MM-dd HH:mm:ss")',
createdTime: '@datetime("yyyy-MM-dd HH:mm:ss")',
},
{
id: '@increment(100000)',
name: '南瓜',
shop: '丰隆种源专卖点',
buyTime: '@datetime("yyyy-MM-dd HH:mm:ss")', buyTime: '@datetime("yyyy-MM-dd HH:mm:ss")',
avalibleTime: '@datetime("yyyy-MM-dd HH:mm:ss")', avalibleTime: '@datetime("yyyy-MM-dd HH:mm:ss")',
createdTime: '@datetime("yyyy-MM-dd HH:mm:ss")', createdTime: '@datetime("yyyy-MM-dd HH:mm:ss")',
@ -153,7 +169,7 @@ const loadData = async () => {
await sleep(500); await sleep(500);
state.data = res.data; state.data = res.data;
state.page = { state.page = {
total: 20, total: 6,
currentPage: 1, currentPage: 1,
pageSize: 10, pageSize: 10,
}; };

View File

@ -9,7 +9,7 @@
<el-card class="search-card" shadow="hover"> <el-card class="search-card" shadow="hover">
<div class="search-card-item"> <div class="search-card-item">
<span class="icon"><img :src="getAssetsFile('images/trace/search-1.png')" /></span> <span class="icon"><img :src="getAssetsFile('images/trace/search-1.png')" /></span>
<span class="text">植档案管理</span> <span class="text">植档案管理</span>
</div> </div>
</el-card> </el-card>
<div class="search-card-connector"></div> <div class="search-card-connector"></div>

View File

@ -235,7 +235,7 @@ const loadData = async () => {
await sleep(500); await sleep(500);
state.rankList = [ state.rankList = [
{ {
name: '个人', name: '农户',
num: 1000, num: 1000,
icon: '1', icon: '1',
}, },
@ -244,16 +244,16 @@ const loadData = async () => {
num: 1000, num: 1000,
icon: '2', icon: '2',
}, },
{ // {
name: '农业企业', // name: '',
num: 1000, // num: 1000,
icon: '3', // icon: '3',
}, // },
{ // {
name: '种植企业', // name: '',
num: 1000, // num: 1000,
icon: '4', // icon: '4',
}, // },
]; ];
state.data = mockData( state.data = mockData(
{ {

View File

@ -9,7 +9,7 @@
<el-card class="search-card" shadow="hover"> <el-card class="search-card" shadow="hover">
<div class="search-card-item"> <div class="search-card-item">
<span class="icon"><img :src="getAssetsFile('images/trace/search-1.png')" /></span> <span class="icon"><img :src="getAssetsFile('images/trace/search-1.png')" /></span>
<span class="text">植档案管理</span> <span class="text">植档案管理</span>
</div> </div>
</el-card> </el-card>
<div class="search-card-connector"></div> <div class="search-card-connector"></div>