Merge branch 'dev' of http://192.168.18.88:8077/sznyb/daimp-front into dev
This commit is contained in:
commit
1700a7ab42
@ -23,6 +23,7 @@
|
||||
"axios": "^1.6.5",
|
||||
"dayjs": "^1.11.11",
|
||||
"echarts": "^5.6.0",
|
||||
"echarts-gl": "^2.0.9",
|
||||
"element-plus": "^2.7.3",
|
||||
"file-saver": "^2.0.5",
|
||||
"js-base64": "^3.7.7",
|
||||
|
@ -35,23 +35,7 @@ export default {
|
||||
const chartRef = ref(null);
|
||||
const { setOptions, getInstance, resize } = useEcharts(chartRef);
|
||||
const option = reactive({
|
||||
tooltip: {
|
||||
formatter: '{b} ({c})',
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'pie',
|
||||
radius: '72%',
|
||||
center: ['50%', '55%'],
|
||||
data: [],
|
||||
labelLine: { show: true },
|
||||
label: {
|
||||
show: true,
|
||||
formatter: '{b} \n ({d}%)',
|
||||
color: '#B1B9D3',
|
||||
},
|
||||
},
|
||||
],
|
||||
series: [],
|
||||
});
|
||||
|
||||
watchEffect(() => {
|
||||
@ -72,8 +56,7 @@ export default {
|
||||
if (props.option) {
|
||||
Object.assign(option, cloneDeep(props.option));
|
||||
}
|
||||
// option.series[0].data = props.chartData;
|
||||
option.series[0].data = props.chartData;
|
||||
option.series = props.chartData;
|
||||
setOptions(option);
|
||||
resize();
|
||||
getInstance()?.off('click', onClick);
|
||||
|
39
main/src/components/custom-iframe/index.vue
Normal file
39
main/src/components/custom-iframe/index.vue
Normal file
@ -0,0 +1,39 @@
|
||||
<template>
|
||||
<iframe v-if="state.url" :src="state.url" frameborder="0" width="100%" height="100%" @load="onLoad"></iframe>
|
||||
</template>
|
||||
|
||||
<script setup name="custom-iframe">
|
||||
import { reactive, watch } from 'vue';
|
||||
import { isExternal } from '@/utils/validate';
|
||||
|
||||
const props = defineProps({
|
||||
url: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['on-load']);
|
||||
|
||||
const state = reactive({
|
||||
url: '',
|
||||
loaded: false,
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.url,
|
||||
(val) => {
|
||||
if (isExternal(val)) {
|
||||
state.url = val;
|
||||
}
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
}
|
||||
);
|
||||
|
||||
const onLoad = () => {
|
||||
state.loaded = true;
|
||||
emit('on-load', state.loaded);
|
||||
};
|
||||
</script>
|
@ -2,14 +2,18 @@
|
||||
<div :class="`custom-table-tree ${shadow ? 'custom-table-tree__shadow' : ''}`">
|
||||
<div v-if="title" class="title">{{ title }}</div>
|
||||
<el-tree
|
||||
node-key="id"
|
||||
:data="data"
|
||||
:node-key="option.nodeKey"
|
||||
:show-checkbox="option.showCheckbox"
|
||||
:default-expanded-keys="option.defaultExpandedKeys"
|
||||
:default-checked-keys="option.defaultCheckedKeys"
|
||||
:props="option.defaultProps"
|
||||
:props="option.props ?? option.defaultProps"
|
||||
@node-click="handleNodeClick"
|
||||
/>
|
||||
>
|
||||
<template #default="{ data: rows }">
|
||||
<slot :data="rows"></slot>
|
||||
</template>
|
||||
</el-tree>
|
||||
</div>
|
||||
</template>
|
||||
<script setup name="custom-table-tree">
|
||||
@ -21,7 +25,9 @@ const props = defineProps({
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {
|
||||
nodeKey: 'id',
|
||||
showCheckbox: false,
|
||||
props: {},
|
||||
defaultProps: {
|
||||
children: 'children',
|
||||
label: 'label',
|
||||
@ -34,8 +40,8 @@ const props = defineProps({
|
||||
});
|
||||
const emit = defineEmits(['node-click']);
|
||||
|
||||
const handleNodeClick = (data) => {
|
||||
emit('node-click', data);
|
||||
const handleNodeClick = (data, node) => {
|
||||
emit('node-click', data, node);
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
|
@ -1,4 +1,5 @@
|
||||
import SvgIcon from './svg-icon';
|
||||
import CustomIframe from './custom-iframe';
|
||||
import CustomTableOperate from './custom-table-operate';
|
||||
import CustomTableTree from './custom-table-tree';
|
||||
import CustomCarouselPicture from './custom-carousel-picture';
|
||||
@ -16,6 +17,7 @@ import CustomEchartPie3d from './custom-echart-pie-3d';
|
||||
|
||||
export {
|
||||
SvgIcon,
|
||||
CustomIframe,
|
||||
CustomTableOperate,
|
||||
CustomTableTree,
|
||||
CustomCarouselPicture,
|
||||
|
@ -1,7 +1,7 @@
|
||||
import * as echarts from 'echarts/core';
|
||||
|
||||
import { BarChart, LineChart, PieChart, MapChart, PictorialBarChart, RadarChart, GraphChart } from 'echarts/charts';
|
||||
|
||||
import 'echarts-gl';
|
||||
import {
|
||||
TitleComponent,
|
||||
TooltipComponent,
|
||||
|
@ -45,7 +45,7 @@ export function isHttp(url) {
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
export function isExternal(path) {
|
||||
return /^(https?:|mailto:|tel:)/.test(path);
|
||||
return /^(http?:|https?:|mailto:|tel:)/.test(path);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1628,6 +1628,11 @@ class-utils@^0.3.5:
|
||||
isobject "^3.0.0"
|
||||
static-extend "^0.1.1"
|
||||
|
||||
claygl@^1.2.1:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.npmmirror.com/claygl/-/claygl-1.3.0.tgz#7a6e2903210519ac358848f5d78070ed211685f3"
|
||||
integrity sha512-+gGtJjT6SSHD2l2yC3MCubW/sCV40tZuSs5opdtn79vFSGUgp/lH139RNEQ6Jy078/L0aV8odCw8RSrUcMfLaQ==
|
||||
|
||||
clean-css@^5.2.2:
|
||||
version "5.3.3"
|
||||
resolved "https://registry.npmmirror.com/clean-css/-/clean-css-5.3.3.tgz#b330653cd3bd6b75009cc25c714cae7b93351ccd"
|
||||
@ -2177,6 +2182,14 @@ dunder-proto@^1.0.0, dunder-proto@^1.0.1:
|
||||
es-errors "^1.3.0"
|
||||
gopd "^1.2.0"
|
||||
|
||||
echarts-gl@^2.0.9:
|
||||
version "2.0.9"
|
||||
resolved "https://registry.npmmirror.com/echarts-gl/-/echarts-gl-2.0.9.tgz#ee228a6c7520a6fb7bbb71ea94394f3637ade033"
|
||||
integrity sha512-oKeMdkkkpJGWOzjgZUsF41DOh6cMsyrGGXimbjK2l6Xeq/dBQu4ShG2w2Dzrs/1bD27b2pLTGSaUzouY191gzA==
|
||||
dependencies:
|
||||
claygl "^1.2.1"
|
||||
zrender "^5.1.1"
|
||||
|
||||
echarts@^5.6.0:
|
||||
version "5.6.0"
|
||||
resolved "https://registry.npmmirror.com/echarts/-/echarts-5.6.0.tgz#2377874dca9fb50f104051c3553544752da3c9d6"
|
||||
@ -7095,7 +7108,7 @@ yocto-queue@^0.1.0:
|
||||
resolved "https://registry.npmmirror.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
|
||||
integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
|
||||
|
||||
zrender@5.6.1:
|
||||
zrender@5.6.1, zrender@^5.1.1:
|
||||
version "5.6.1"
|
||||
resolved "https://registry.npmmirror.com/zrender/-/zrender-5.6.1.tgz#e08d57ecf4acac708c4fcb7481eb201df7f10a6b"
|
||||
integrity sha512-OFXkDJKcrlx5su2XbzJvj/34Q3m6PvyCZkVPHGYpcCJ52ek4U/ymZyfuV1nKE23AyBJ51E/6Yr0mhZ7xGTO4ag==
|
||||
|
@ -1,4 +1,4 @@
|
||||
import request from '@/utils/request';
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 登录方法
|
||||
export function login(username, password, code, uuid) {
|
||||
@ -10,7 +10,7 @@ export function login(username, password, code, uuid) {
|
||||
},
|
||||
method: 'post',
|
||||
data: { username, password, code, uuid },
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
// 注册方法
|
||||
@ -22,7 +22,7 @@ export function register(data) {
|
||||
},
|
||||
method: 'post',
|
||||
data: data,
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
// 刷新方法
|
||||
@ -30,7 +30,7 @@ export function refreshToken() {
|
||||
return request({
|
||||
url: '/auth/refresh',
|
||||
method: 'post',
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
// 获取用户详细信息
|
||||
@ -38,7 +38,7 @@ export function getInfo() {
|
||||
return request({
|
||||
url: '/system/user/getInfo',
|
||||
method: 'get',
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
// 退出方法
|
||||
@ -46,7 +46,7 @@ export function logout() {
|
||||
return request({
|
||||
url: '/auth/logout',
|
||||
method: 'delete',
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
// 获取验证码
|
||||
@ -58,5 +58,5 @@ export function getCodeImg() {
|
||||
},
|
||||
method: 'get',
|
||||
timeout: 20000,
|
||||
});
|
||||
})
|
||||
}
|
||||
|
@ -7,14 +7,13 @@ const TokenKey = 'Admin-Token';
|
||||
const ExpiresInKey = 'Admin-Expires-In';
|
||||
|
||||
export function getToken() {
|
||||
return true
|
||||
// let token = Cookies.get(TokenKey);
|
||||
// if (undefined === token || null == token || 'null' === token) {
|
||||
// token = getQueryString('Authorization');
|
||||
// if (null != token || 'null' !== token) Cookies.set(TokenKey, token);
|
||||
// }
|
||||
// if (undefined === token || null == token || 'null' === token) token = false;
|
||||
// return token;
|
||||
let token = Cookies.get(TokenKey);
|
||||
if (undefined === token || null == token || 'null' === token) {
|
||||
token = getQueryString('Authorization');
|
||||
if (null != token || 'null' !== token) Cookies.set(TokenKey, token);
|
||||
}
|
||||
if (undefined === token || null == token || 'null' === token) token = false;
|
||||
return token;
|
||||
}
|
||||
|
||||
export function setToken(token) {
|
||||
|
@ -28,7 +28,7 @@ service.interceptors.request.use(
|
||||
// 是否需要防止数据重复提交
|
||||
const isRepeatSubmit = (config.headers || {}).repeatSubmit === false;
|
||||
if (getToken() && !isToken) {
|
||||
config.headers['Authorization'] = 'Bearer ' + getToken(); // 让每个请求携带自定义token 请根据实际情况自行修改
|
||||
config.headers['Authorization'] = getToken(); // 让每个请求携带自定义token 请根据实际情况自行修改
|
||||
}
|
||||
// get请求映射params参数
|
||||
if (config.method === 'get' && config.params) {
|
||||
|
@ -18,7 +18,7 @@ module.exports = {
|
||||
// 部署生产环境和开发环境下的URL。
|
||||
// 默认情况下,Vue CLI 会假设你的应用是被部署在一个域名的根路径上
|
||||
// 例如 https://www.ruoyi.vip/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.ruoyi.vip/admin/,则设置 baseUrl 为 /admin/。
|
||||
publicPath: `/sub-admin/`,
|
||||
publicPath: './',
|
||||
// 在npm run build 或 yarn build 时 ,生成文件的目录名称(要和baseUrl的生产环境路径一致)(默认dist)
|
||||
outputDir: 'dist',
|
||||
// 用于放置生成的静态资源 (js、css、img、fonts) 的;(项目打包之后,静态资源会放在这个文件夹下)
|
||||
@ -68,7 +68,7 @@ module.exports = {
|
||||
libraryTarget: 'umd', // 把微应用打包成 umd 库格式
|
||||
jsonpFunction: `${name}`,
|
||||
filename: `[name].[hash].js`,
|
||||
chunkFilename: `[name].[hash].js`
|
||||
chunkFilename: `[name].[hash].js`,
|
||||
},
|
||||
plugins: [
|
||||
new CompressionPlugin({
|
||||
|
@ -44,35 +44,25 @@ export function delPlanCrop(params) {
|
||||
|
||||
//种植产物对应的种植阶段相关
|
||||
// #region
|
||||
// export function getPlanStage(params = {}) {
|
||||
// return request('land-resource/baseInfo/planTypePage', {
|
||||
// method: 'GET',
|
||||
// params,
|
||||
// });
|
||||
// }
|
||||
export function getPlanStage(params = {}) {
|
||||
return request('land-resource/baseInfo/stageTypePage', {
|
||||
method: 'GET',
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
||||
// export function upPlanStage(data = {}) {
|
||||
// return request('land-resource/baseInfo/planTypeEdit', {
|
||||
// method: 'PUT',
|
||||
// data,
|
||||
// });
|
||||
// }
|
||||
export function upPlanStage(data = {}) {
|
||||
return request('land-resource/baseInfo/stageTypeEdit', {
|
||||
method: 'PUT',
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
// export function exportPlanStage(params = {}) {
|
||||
// return request('/land-resource/baseInfo/planTypeExport', {
|
||||
// method: 'GET',
|
||||
// params,
|
||||
// responseType: 'blob',
|
||||
// });
|
||||
// }
|
||||
|
||||
// export function delPlanStage(params) {
|
||||
// return request('land-resource/baseInfo/planTypeDelete/' + params.id, {
|
||||
// method: 'DELETE',
|
||||
// });
|
||||
// }
|
||||
|
||||
// #endregion
|
||||
export function delPlanStage(params) {
|
||||
return request('land-resource/baseInfo/stageTypeDelete/' + params.id, {
|
||||
method: 'DELETE',
|
||||
});
|
||||
}
|
||||
|
||||
export function savePlanStage(data) {
|
||||
return request('land-resource/baseInfo/stageTypeSave', {
|
||||
@ -81,6 +71,14 @@ export function savePlanStage(data) {
|
||||
});
|
||||
}
|
||||
|
||||
export function getWorkPage(params = {}) {
|
||||
return request('land-resource/planManage/workPage', {
|
||||
method: 'GET',
|
||||
params,
|
||||
});
|
||||
}
|
||||
// #endregion
|
||||
|
||||
/* ------ 土壤类型 ------ */
|
||||
// #region
|
||||
|
||||
|
@ -99,6 +99,13 @@ export function delPlan(params) {
|
||||
});
|
||||
}
|
||||
|
||||
export function getPlanHistory(params = {}) {
|
||||
return request('land-resource/planManage/historyPlanPage', {
|
||||
method: 'GET',
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
||||
//种植阶段相关
|
||||
export function getPlantingStage(params = {}) {
|
||||
return request('land-resource/planManage/pageStage', {
|
||||
|
@ -3,14 +3,14 @@
|
||||
* @Author: zenghua.wang
|
||||
* @Date: 2023-06-20 14:29:45
|
||||
* @LastEditors: zenghua.wang
|
||||
* @LastEditTime: 2025-02-13 16:02:18
|
||||
* @LastEditTime: 2025-03-20 14:04:09
|
||||
-->
|
||||
<template>
|
||||
<el-breadcrumb class="layout-breadcrumb" separator="/">
|
||||
<transition-group name="breadcrumb">
|
||||
<el-breadcrumb-item v-if="matched[0].meta.title !== '首页'" key="home" :to="{ path: '/' }">
|
||||
<el-breadcrumb-item v-if="matched[0].meta.title !== '政务服务'" key="home" :to="{ path: '/' }">
|
||||
<div class="layout-breadcrumb-item">
|
||||
<span class="layout-breadcrumb-title">首页</span>
|
||||
<span class="layout-breadcrumb-title">政务服务</span>
|
||||
</div>
|
||||
</el-breadcrumb-item>
|
||||
<el-breadcrumb-item v-for="(item, index) in matched" :key="item.name">
|
||||
|
@ -3,7 +3,7 @@
|
||||
* @Author: zenghua.wang
|
||||
* @Date: 2023-06-20 11:48:41
|
||||
* @LastEditors: zenghua.wang
|
||||
* @LastEditTime: 2025-03-12 11:10:12
|
||||
* @LastEditTime: 2025-03-20 14:40:44
|
||||
*/
|
||||
import { createRouter, createWebHistory } from 'vue-router';
|
||||
import Layout from '@/layouts/index.vue';
|
||||
|
@ -0,0 +1,326 @@
|
||||
<template>
|
||||
<div style="margin-top: 16px">
|
||||
<!-- <el-dialog v-model="isShowVal" title="种植阶段详情" width="1000" center @closed="stageClose"> -->
|
||||
<el-text class="mx-1" size="large">种植阶段详情</el-text>
|
||||
<div style="margin-top: 16px">
|
||||
<avue-crud
|
||||
ref="stateCrudRef"
|
||||
v-model="stageState.form"
|
||||
v-model:search="stageState.query"
|
||||
v-model:page="stageState.pageData"
|
||||
:table-loading="stageState.loading"
|
||||
:data="stageState.data"
|
||||
:option="stageState.options"
|
||||
@refresh-change="stageRefresh"
|
||||
@search-reset="stageSearch"
|
||||
@search-change="stageSearch"
|
||||
@selection-change="stageSelection"
|
||||
@current-change="stageCurrent"
|
||||
@size-change="stageSize"
|
||||
@row-del="stageRowDel"
|
||||
@row-save="stageRowSave"
|
||||
@row-update="stageRowUpdate"
|
||||
>
|
||||
<template #menu-left>
|
||||
<el-button type="primary" icon="Plus" @click="onStateAdd">新增</el-button>
|
||||
</template>
|
||||
|
||||
<template #stage="{ row }">
|
||||
<el-tag size="small">{{ stageObj[row.stage] }}</el-tag>
|
||||
</template>
|
||||
|
||||
<template #cropId="{ row }">
|
||||
{{ row.cropName }}
|
||||
</template>
|
||||
|
||||
<template #menu="scope">
|
||||
<custom-table-operate :actions="stageState.options.actions" :data="scope" />
|
||||
</template>
|
||||
</avue-crud>
|
||||
<!-- </el-dialog> -->
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { onMounted, reactive, ref, watch } from 'vue';
|
||||
import { useApp } from '@/hooks';
|
||||
import { CRUD_OPTIONS } from '@/config';
|
||||
import { useUserStore } from '@/store/modules/user';
|
||||
import { getPlanStage, savePlanStage, upPlanStage, delPlanStage } from '@/apis/baseInfo.js';
|
||||
import { isEmpty, imageToBase64, getAssetsFile, downloadFile } from '@/utils';
|
||||
|
||||
const props = defineProps({
|
||||
isShow: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
rowOriginal: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {};
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['close']);
|
||||
|
||||
const { VITE_APP_BASE_API } = import.meta.env;
|
||||
const app = useApp();
|
||||
const UserStore = useUserStore();
|
||||
const stateCrudRef = ref(null);
|
||||
const stageOptions = reactive([
|
||||
{ value: '0', label: '苗期' },
|
||||
{ value: '1', label: '花果期' },
|
||||
{ value: '2', label: '采收期' },
|
||||
]);
|
||||
|
||||
const workOptions = reactive([
|
||||
{ label: '作业计划1', value: '000001' },
|
||||
{ label: '作业计划2', value: '000002' },
|
||||
]);
|
||||
|
||||
const stageObj = reactive({
|
||||
0: '苗期',
|
||||
1: '花果期',
|
||||
2: '采收期',
|
||||
});
|
||||
|
||||
const isShowVal = ref(false);
|
||||
let currentRow = reactive({});
|
||||
|
||||
const loadList = () => {
|
||||
if (isShowVal.value) {
|
||||
console.info('loadList', props);
|
||||
getStageList();
|
||||
}
|
||||
};
|
||||
onMounted(() => {
|
||||
isShowVal.value = props.isShow;
|
||||
currentRow = props.rowOriginal;
|
||||
loadList();
|
||||
// console.info('onMounted', props);
|
||||
});
|
||||
watch(
|
||||
() => (props.isShow, props.rowOriginal),
|
||||
() => {
|
||||
isShowVal.value = props.isShow;
|
||||
currentRow = props.rowOriginal;
|
||||
console.info('watch', props);
|
||||
loadList();
|
||||
},
|
||||
{ deep: true, immediate: true }
|
||||
);
|
||||
let stageState = reactive({
|
||||
loading: false,
|
||||
query: {
|
||||
current: 1,
|
||||
size: 10,
|
||||
stage: null,
|
||||
},
|
||||
form: {},
|
||||
options: {
|
||||
...CRUD_OPTIONS,
|
||||
addBtn: false,
|
||||
selection: false,
|
||||
column: [
|
||||
{
|
||||
label: '种植产物',
|
||||
prop: 'cropId',
|
||||
type: 'select',
|
||||
remote: false,
|
||||
width: '160px',
|
||||
showOverflowTooltip: true,
|
||||
props: {
|
||||
label: 'crop',
|
||||
value: 'id',
|
||||
},
|
||||
dicHeaders: {
|
||||
authorization: UserStore.token,
|
||||
},
|
||||
dicUrl: `${VITE_APP_BASE_API}/land-resource/baseInfo/planTypePage?current=1&size=999`,
|
||||
dicFormatter: (res) => res.data.records ?? [],
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: '请选择',
|
||||
trigger: 'blur',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: '所属阶段',
|
||||
prop: 'stage',
|
||||
type: 'select',
|
||||
search: true,
|
||||
dicData: stageOptions,
|
||||
rules: {
|
||||
required: true,
|
||||
message: '请选择',
|
||||
trigger: 'blur',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '作业类型',
|
||||
prop: 'workType',
|
||||
// type: 'select',
|
||||
search: false,
|
||||
// dicData: workOptions,
|
||||
rules: { required: true, message: '请选择', trigger: 'blur' },
|
||||
},
|
||||
{
|
||||
label: '作业时间(多少天后)',
|
||||
prop: 'workTime',
|
||||
rules: { required: true, message: '请输入', trigger: 'blur' },
|
||||
props: {
|
||||
type: 'Number',
|
||||
},
|
||||
addDisplay: true,
|
||||
editDisplay: true,
|
||||
},
|
||||
],
|
||||
actions: [
|
||||
{
|
||||
name: '编辑',
|
||||
icon: 'edit',
|
||||
event: ({ row }) => stageRowEdit(row),
|
||||
},
|
||||
{
|
||||
type: 'danger',
|
||||
name: '删除',
|
||||
icon: 'delete',
|
||||
event: ({ row }) => stageRowDel(row),
|
||||
},
|
||||
],
|
||||
},
|
||||
pageData: {
|
||||
total: 0,
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
},
|
||||
data: [],
|
||||
currentRow: {},
|
||||
});
|
||||
|
||||
async function getStageList() {
|
||||
if (!currentRow.id) {
|
||||
return app.$message.success('请选择种植产物');
|
||||
}
|
||||
stageState.loading = true;
|
||||
getPlanStage({ ...stageState.query, cropId: currentRow.id })
|
||||
.then((res) => {
|
||||
if (res.code === 200) {
|
||||
const { current, size, total, records } = res.data;
|
||||
stageState.data = records || [];
|
||||
stageState.pageData = {
|
||||
currentPage: current || 1,
|
||||
pageSize: size || 10,
|
||||
total: total,
|
||||
};
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
app.$message.error(err.msg);
|
||||
stageState.data = [];
|
||||
})
|
||||
.finally(() => {
|
||||
stageState.loading = false;
|
||||
});
|
||||
}
|
||||
|
||||
const stageSearch = (params, done) => {
|
||||
if (done) done();
|
||||
stageState.query = params;
|
||||
stageState.query.current = 1;
|
||||
getStageList();
|
||||
};
|
||||
|
||||
const stageSelection = (rows) => {
|
||||
stageState.selection = rows;
|
||||
};
|
||||
|
||||
const stageCurrent = (current) => {
|
||||
stageState.query.current = current;
|
||||
getStageList();
|
||||
};
|
||||
|
||||
const stageSize = (size) => {
|
||||
stageState.query.size = size;
|
||||
getStageList();
|
||||
};
|
||||
|
||||
const stageRowDel = (row, index, done) => {
|
||||
if (isEmpty(row)) return;
|
||||
app
|
||||
.$confirm(`删除后信息将不可查看,确认要删除吗?`, '确定删除', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
})
|
||||
.then(() => {
|
||||
console.info('删除');
|
||||
delPlanStage({ id: row.id })
|
||||
.then((res) => {
|
||||
if (res.code === 200) {
|
||||
app.$message.success('删除成功!');
|
||||
getStageList();
|
||||
done();
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
app.$message.error(err.msg);
|
||||
});
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
const stageRowEdit = (row) => {
|
||||
stateCrudRef.value.rowEdit(row);
|
||||
};
|
||||
|
||||
const onStateAdd = () => {
|
||||
if (!currentRow.id) {
|
||||
app.$message.error('请选择种植产物');
|
||||
return;
|
||||
}
|
||||
stateCrudRef.value.rowAdd();
|
||||
};
|
||||
|
||||
const stageRowSave = (row, done, loading) => {
|
||||
console.info('stageRowSave', row);
|
||||
savePlanStage({ ...row })
|
||||
.then((res) => {
|
||||
if (res.code === 200) {
|
||||
app.$message.success('添加成功!');
|
||||
done();
|
||||
getStageList();
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
app.$message.error(err.msg);
|
||||
})
|
||||
.finally(() => {
|
||||
loading();
|
||||
});
|
||||
};
|
||||
|
||||
const stageRowUpdate = (row, index, done, loading) => {
|
||||
console.info('stageRowUpdate');
|
||||
upPlanStage(row)
|
||||
.then((res) => {
|
||||
if (res.code === 200) {
|
||||
app.$message.success('更新成功!');
|
||||
done();
|
||||
getStageList();
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
app.$message.error(err.msg);
|
||||
})
|
||||
.finally(() => {
|
||||
loading();
|
||||
});
|
||||
};
|
||||
const stageClose = () => {
|
||||
isShowVal.value = false;
|
||||
emit('close');
|
||||
};
|
||||
</script>
|
@ -33,39 +33,8 @@
|
||||
</template>
|
||||
</avue-crud>
|
||||
|
||||
<stageList :is-show="stageShow" :row-original="state.currentRow" @close="stageHide"></stageList>
|
||||
<el-text class="mx-1" size="large">种植阶段详情</el-text>
|
||||
<div style="margin-top: 16px">
|
||||
<avue-crud
|
||||
ref="stateCrudRef"
|
||||
v-model="stageState.form"
|
||||
v-model:search="stageState.query"
|
||||
v-model:page="stageState.pageData"
|
||||
:table-loading="stageState.loading"
|
||||
:data="stageState.data"
|
||||
:option="stageState.options"
|
||||
@refresh-change="stageRefresh"
|
||||
@search-reset="stageSearch"
|
||||
@search-change="stageSearch"
|
||||
@selection-change="stageSelection"
|
||||
@current-change="stageCurrent"
|
||||
@size-change="stageSize"
|
||||
@row-del="stageRowDel"
|
||||
@row-save="stageRowSave"
|
||||
@row-update="stageRowUpdate"
|
||||
>
|
||||
<template #menu-left>
|
||||
<el-button type="primary" icon="Plus" @click="onStateAdd">新增</el-button>
|
||||
</template>
|
||||
|
||||
<template #stage="{ row }">
|
||||
<el-tag size="small">{{ stageObj[row.stage] }}</el-tag>
|
||||
</template>
|
||||
|
||||
<template #menu="scope">
|
||||
<custom-table-operate :actions="stageState.options.actions" :data="scope" />
|
||||
</template>
|
||||
</avue-crud>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
@ -75,7 +44,8 @@ import { CRUD_OPTIONS } from '@/config';
|
||||
import { isEmpty, downloadFile } from '@/utils';
|
||||
import { useUserStore } from '@/store/modules/user';
|
||||
import { compact } from 'lodash';
|
||||
import { getPlanCrop, savePlanCrop, upPlanCrop, exportPlanCrop, delPlanCrop } from '@/apis/baseInfo';
|
||||
import { getPlanCrop, savePlanCrop, upPlanCrop, exportPlanCrop, delPlanCrop, getPlanStage } from '@/apis/baseInfo';
|
||||
import stageList from '../dictCrop/component/stage.vue';
|
||||
|
||||
const { VITE_APP_BASE_API } = import.meta.env;
|
||||
const app = useApp();
|
||||
@ -83,21 +53,7 @@ const UserStore = useUserStore();
|
||||
const crudRef = ref(null);
|
||||
const stateCrudRef = ref(null);
|
||||
|
||||
const stageOptions = reactive([
|
||||
{ value: '0', label: '苗期' },
|
||||
{ value: '1', label: '花果期' },
|
||||
{ value: '2', label: '采收期' },
|
||||
]);
|
||||
|
||||
const stageObj = reactive({
|
||||
0: '苗期',
|
||||
1: '花果期',
|
||||
2: '采收期',
|
||||
});
|
||||
const workOptions = reactive([
|
||||
{ planName: '作业计划1', id: '000001' },
|
||||
{ planName: '作业计划2', id: '000002' },
|
||||
]);
|
||||
let stageShow = ref(false);
|
||||
const state = reactive({
|
||||
loading: false,
|
||||
query: {
|
||||
@ -134,19 +90,19 @@ const state = reactive({
|
||||
trigger: 'blur',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '种植时间',
|
||||
prop: 'planDate',
|
||||
type: 'date',
|
||||
format: 'YYYY-MM-DD',
|
||||
valueFormat: 'YYYY-MM-DD',
|
||||
width: 160,
|
||||
rules: {
|
||||
required: true,
|
||||
message: '请选择作业日期',
|
||||
trigger: 'blur',
|
||||
},
|
||||
},
|
||||
// {
|
||||
// label: '种植时间',
|
||||
// prop: 'planDate',
|
||||
// type: 'date',
|
||||
// format: 'YYYY-MM-DD',
|
||||
// valueFormat: 'YYYY-MM-DD',
|
||||
// width: 160,
|
||||
// rules: {
|
||||
// required: true,
|
||||
// message: '请选择作业日期',
|
||||
// trigger: 'blur',
|
||||
// },
|
||||
// },
|
||||
{
|
||||
label: '状态',
|
||||
prop: 'status',
|
||||
@ -191,68 +147,6 @@ const state = reactive({
|
||||
currentRow: {},
|
||||
});
|
||||
|
||||
const stageState = reactive({
|
||||
loading: false,
|
||||
query: {
|
||||
current: 1,
|
||||
size: 10,
|
||||
},
|
||||
form: {},
|
||||
options: {
|
||||
...CRUD_OPTIONS,
|
||||
addBtn: false,
|
||||
selection: false,
|
||||
column: [
|
||||
{
|
||||
label: '所属阶段',
|
||||
prop: 'stage',
|
||||
type: 'select',
|
||||
search: true,
|
||||
dicData: stageOptions,
|
||||
rules: {
|
||||
required: true,
|
||||
message: '请选择',
|
||||
trigger: 'blur',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '作业计划',
|
||||
prop: 'workId',
|
||||
type: 'select',
|
||||
search: true,
|
||||
dicData: workOptions,
|
||||
rules: {
|
||||
required: true,
|
||||
message: '请选择',
|
||||
trigger: 'blur',
|
||||
},
|
||||
},
|
||||
{ label: '作业时间', prop: 'coordinate', disabled: true, addDisplay: false, editDisplay: false },
|
||||
{ label: '结束时间', prop: 'createTime', disabled: true, addDisplay: false, editDisplay: false },
|
||||
],
|
||||
actions: [
|
||||
{
|
||||
name: '编辑',
|
||||
icon: 'edit',
|
||||
event: ({ row }) => stageRowEdit(row),
|
||||
},
|
||||
{
|
||||
type: 'danger',
|
||||
name: '删除',
|
||||
icon: 'delete',
|
||||
event: ({ row }) => stageRowDel(row),
|
||||
},
|
||||
],
|
||||
},
|
||||
pageData: {
|
||||
total: 0,
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
},
|
||||
data: [],
|
||||
currentRow: {},
|
||||
});
|
||||
|
||||
// 加载
|
||||
const loadData = () => {
|
||||
state.loading = true;
|
||||
@ -380,13 +274,6 @@ const rowUpdate = (row, index, done, loading) => {
|
||||
});
|
||||
};
|
||||
|
||||
//种植阶段相关
|
||||
// 刷新
|
||||
const stageRefresh = () => {
|
||||
// loadData();
|
||||
app.$message.success('刷新成功');
|
||||
};
|
||||
|
||||
const rowStatus = (row) => {
|
||||
console.info('操作状态');
|
||||
let parmer = {
|
||||
@ -433,126 +320,10 @@ const rowDel = (row, index, done) => {
|
||||
|
||||
const rowClick = (row) => {
|
||||
state.currentRow = { ...row };
|
||||
stageShow.value = true;
|
||||
console.info('rowClick', state.currentRow);
|
||||
getStageList();
|
||||
};
|
||||
async function getStageList() {
|
||||
// stageState.loading = true;
|
||||
// getPlantingStage({ ...stageState.query, planId: state.currentRow.id })
|
||||
// .then((res) => {
|
||||
// if (res.code === 200) {
|
||||
// const { current, size, total, records } = res.data;
|
||||
// stageState.data = records || [];
|
||||
// stageState.pageData = {
|
||||
// currentPage: current || 1,
|
||||
// pageSize: size || 10,
|
||||
// total: total,
|
||||
// };
|
||||
// }
|
||||
// })
|
||||
// .catch((err) => {
|
||||
// app.$message.error(err.msg);
|
||||
// stageState.data = [];
|
||||
// })
|
||||
// .finally(() => {
|
||||
// stageState.loading = false;
|
||||
// });
|
||||
}
|
||||
|
||||
const stageSearch = (params, done) => {
|
||||
if (done) done();
|
||||
stageState.query = params;
|
||||
stageState.query.current = 1;
|
||||
getStageList();
|
||||
};
|
||||
|
||||
const stageSelection = (rows) => {
|
||||
stageState.selection = rows;
|
||||
};
|
||||
|
||||
const stageCurrent = (current) => {
|
||||
stageState.query.current = current;
|
||||
getStageList();
|
||||
};
|
||||
|
||||
const stageSize = (size) => {
|
||||
stageState.query.size = size;
|
||||
getStageList();
|
||||
};
|
||||
|
||||
const stageRowDel = (row, index, done) => {
|
||||
if (isEmpty(row)) return;
|
||||
app
|
||||
.$confirm(`删除后信息将不可查看,确认要删除吗?`, '确定删除', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
})
|
||||
.then(() => {
|
||||
console.info('删除');
|
||||
// delPlantingStage({ id: row.id })
|
||||
// .then((res) => {
|
||||
// if (res.code === 200) {
|
||||
// app.$message.success('删除成功!');
|
||||
// getStageList();
|
||||
// done();
|
||||
// }
|
||||
// })
|
||||
// .catch((err) => {
|
||||
// app.$message.error(err.msg);
|
||||
// });
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
const stageRowEdit = (row) => {
|
||||
stateCrudRef.value.rowEdit(row);
|
||||
};
|
||||
|
||||
const onStateAdd = () => {
|
||||
if (!state.currentRow.id) {
|
||||
app.$message.error('请选择种植产物');
|
||||
return;
|
||||
}
|
||||
// stageInfoData.landName = state.currentRow.landName || '';
|
||||
// stageInfoData.crop = state.currentRow.crop || '';
|
||||
// stageInfoVisible.value = true;
|
||||
stateCrudRef.value.rowAdd();
|
||||
};
|
||||
|
||||
const stageRowSave = (row, done, loading) => {
|
||||
row.planId = state.currentRow.planId;
|
||||
console.info('stageRowSave', row);
|
||||
// savePlantingStage({ ...row })
|
||||
// .then((res) => {
|
||||
// if (res.code === 200) {
|
||||
// app.$message.success('添加成功!');
|
||||
// done();
|
||||
// getStageList();
|
||||
// }
|
||||
// })
|
||||
// .catch((err) => {
|
||||
// app.$message.error(err.msg);
|
||||
// })
|
||||
// .finally(() => {
|
||||
// loading();
|
||||
// });
|
||||
};
|
||||
|
||||
const stageRowUpdate = (row, index, done, loading) => {
|
||||
console.info('stageRowUpdate');
|
||||
// editPlantingStage(row)
|
||||
// .then((res) => {
|
||||
// if (res.code === 200) {
|
||||
// app.$message.success('更新成功!');
|
||||
// done();
|
||||
// getStageList();
|
||||
// }
|
||||
// })
|
||||
// .catch((err) => {
|
||||
// app.$message.error(err.msg);
|
||||
// })
|
||||
// .finally(() => {
|
||||
// loading();
|
||||
// });
|
||||
const stageHide = () => {
|
||||
stageShow.value = false;
|
||||
};
|
||||
</script>
|
||||
|
@ -3,13 +3,14 @@
|
||||
<div>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="4">
|
||||
<el-tree
|
||||
<!-- <el-tree
|
||||
style="max-width: 600px"
|
||||
:data="typeTree"
|
||||
node-key="areaCode"
|
||||
:props="{ children: 'areaChildVOS', label: 'areaName' }"
|
||||
@node-click="handleNodeClick"
|
||||
/>
|
||||
/> -->
|
||||
<custom-table-tree title="行政区域" :data="typeTree" :option="treeOption" @node-click="handleNodeClick" />
|
||||
</el-col>
|
||||
<el-col :span="20">
|
||||
<avue-crud
|
||||
@ -126,35 +127,13 @@ const state = reactive({
|
||||
currentRow: {},
|
||||
});
|
||||
|
||||
let typeTree = ref([
|
||||
// {
|
||||
// label: '耿马县',
|
||||
// id: '0',
|
||||
// level: '0',
|
||||
// children: [
|
||||
// {
|
||||
// label: '镇1',
|
||||
// level: '1',
|
||||
// id: '01',
|
||||
// children: [
|
||||
// { label: '村1', children: [], id: '0101', pId: '01', level: '2' },
|
||||
// { label: '村2', children: [], id: '0102', pId: '01', level: '2' },
|
||||
// ],
|
||||
// pId: '0',
|
||||
// },
|
||||
// { label: '镇2', level: '1', children: [], id: '02', pId: '0' },
|
||||
// ],
|
||||
// },
|
||||
// {
|
||||
// label: '县1',
|
||||
// id: '1',
|
||||
// level: '0',
|
||||
// children: [{ label: '镇1', children: [], id: '11', pId: '10', level: '1' }],
|
||||
// },
|
||||
]);
|
||||
let townOptions = reactive([]);
|
||||
|
||||
let infoData = reactive({
|
||||
const typeTree = ref([]);
|
||||
const treeOption = ref({
|
||||
nodeKey: 'areaCode',
|
||||
props: { children: 'areaChildVOS', label: 'areaName' },
|
||||
});
|
||||
const townOptions = reactive([]);
|
||||
const infoData = reactive({
|
||||
countyId: '',
|
||||
townId: '',
|
||||
name: '',
|
||||
|
@ -1,3 +0,0 @@
|
||||
<template>
|
||||
<div>开发中</div>
|
||||
</template>
|
@ -0,0 +1,259 @@
|
||||
<template>
|
||||
<div style="margin-top: 16px">
|
||||
<el-dialog v-model="isShowVal" title="规划记录" width="1000" center @closed="stageClose">
|
||||
<avue-crud
|
||||
ref="listRef"
|
||||
v-model="stageState.form"
|
||||
v-model:search="stageState.query"
|
||||
v-model:page="stageState.pageData"
|
||||
:table-loading="stageState.loading"
|
||||
:data="stageState.data"
|
||||
:option="stageState.options"
|
||||
@refresh-change="stageRefresh"
|
||||
@search-reset="stageSearch"
|
||||
@search-change="stageSearch"
|
||||
@selection-change="stageSelection"
|
||||
@current-change="stageCurrent"
|
||||
@size-change="stageSize"
|
||||
@row-del="stageRowDel"
|
||||
@row-save="stageRowSave"
|
||||
@row-update="stageRowUpdate"
|
||||
>
|
||||
<template #menu-left>
|
||||
<!-- <el-button type="primary" icon="Plus" @click="onStateAdd">新增</el-button> -->
|
||||
</template>
|
||||
|
||||
<template #planId="{ row }">
|
||||
{{ row.planName }}
|
||||
</template>
|
||||
|
||||
<template #menu="scope">
|
||||
<custom-table-operate :actions="stageState.options.actions" :data="scope" />
|
||||
</template>
|
||||
</avue-crud>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { onMounted, reactive, ref, watch } from 'vue';
|
||||
import { useApp } from '@/hooks';
|
||||
import { CRUD_OPTIONS } from '@/config';
|
||||
import { useUserStore } from '@/store/modules/user';
|
||||
import { getPlantingStage, savePlantingStage, editPlantingStage, delPlantingStage, getPlanHistory } from '@/apis/land.js';
|
||||
import { isEmpty, imageToBase64, getAssetsFile, downloadFile } from '@/utils';
|
||||
|
||||
const props = defineProps({
|
||||
isShow: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
rowOriginal: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {};
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['close']);
|
||||
|
||||
const { VITE_APP_BASE_API } = import.meta.env;
|
||||
const app = useApp();
|
||||
const UserStore = useUserStore();
|
||||
const listRef = ref(null);
|
||||
const stageOptions = reactive([
|
||||
{ value: '0', label: '苗期' },
|
||||
{ value: '1', label: '花果期' },
|
||||
{ value: '2', label: '采收期' },
|
||||
]);
|
||||
|
||||
const workOptions = reactive([
|
||||
{ label: '作业计划1', value: '000001' },
|
||||
{ label: '作业计划2', value: '000002' },
|
||||
]);
|
||||
|
||||
const stageObj = reactive({
|
||||
0: '苗期',
|
||||
1: '花果期',
|
||||
2: '采收期',
|
||||
});
|
||||
|
||||
const isShowVal = ref(false);
|
||||
let currentRow = reactive({});
|
||||
|
||||
const loadList = () => {
|
||||
if (isShowVal.value) {
|
||||
console.info('loadList', props);
|
||||
getList();
|
||||
}
|
||||
};
|
||||
onMounted(() => {
|
||||
isShowVal.value = props.isShow;
|
||||
currentRow = props.rowOriginal;
|
||||
loadList();
|
||||
// console.info('onMounted', props);
|
||||
});
|
||||
watch(
|
||||
() => (props.isShow, props.rowOriginal),
|
||||
() => {
|
||||
isShowVal.value = props.isShow;
|
||||
currentRow = props.rowOriginal;
|
||||
console.info('watch', props);
|
||||
loadList();
|
||||
},
|
||||
{ deep: true, immediate: true }
|
||||
);
|
||||
const stageState = reactive({
|
||||
loading: false,
|
||||
query: {
|
||||
current: 1,
|
||||
size: 10,
|
||||
},
|
||||
form: {},
|
||||
options: {
|
||||
...CRUD_OPTIONS,
|
||||
addBtn: false,
|
||||
selection: false,
|
||||
column: [
|
||||
{
|
||||
label: '年度计划',
|
||||
prop: 'planId',
|
||||
type: 'select',
|
||||
remote: false,
|
||||
width: '160px',
|
||||
showOverflowTooltip: true,
|
||||
props: {
|
||||
label: 'planName',
|
||||
value: 'id',
|
||||
},
|
||||
dicHeaders: {
|
||||
authorization: UserStore.token,
|
||||
},
|
||||
dicUrl: `${VITE_APP_BASE_API}/land-resource/annualManage/page`,
|
||||
dicFormatter: (res) => res.data.records ?? [],
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: '请选择',
|
||||
trigger: 'blur',
|
||||
},
|
||||
],
|
||||
},
|
||||
{ label: '供应商', prop: 'seedSupplier', addDisplay: false, editDisplay: true },
|
||||
{ label: '种植日期', prop: 'planDate', addDisplay: true, editDisplay: true },
|
||||
{ label: '种植产物', prop: 'crop', addDisplay: false, editDisplay: false },
|
||||
],
|
||||
actions: [
|
||||
{
|
||||
name: '编辑',
|
||||
icon: 'edit',
|
||||
event: ({ row }) => stageRowEdit(row),
|
||||
},
|
||||
],
|
||||
},
|
||||
pageData: {
|
||||
total: 0,
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
},
|
||||
data: [],
|
||||
currentRow: {},
|
||||
});
|
||||
|
||||
async function getList() {
|
||||
stageState.loading = true;
|
||||
getPlanHistory({ ...stageState.query, landId: currentRow.landId })
|
||||
.then((res) => {
|
||||
if (res.code === 200) {
|
||||
const { current, size, total, records } = res.data;
|
||||
stageState.data = records || [];
|
||||
stageState.pageData = {
|
||||
currentPage: current || 1,
|
||||
pageSize: size || 10,
|
||||
total: total,
|
||||
};
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
app.$message.error(err.msg);
|
||||
stageState.data = [];
|
||||
})
|
||||
.finally(() => {
|
||||
stageState.loading = false;
|
||||
});
|
||||
}
|
||||
|
||||
const stageSearch = (params, done) => {
|
||||
if (done) done();
|
||||
stageState.query = params;
|
||||
stageState.query.current = 1;
|
||||
getList();
|
||||
};
|
||||
|
||||
const stageSelection = (rows) => {
|
||||
stageState.selection = rows;
|
||||
};
|
||||
|
||||
const stageCurrent = (current) => {
|
||||
stageState.query.current = current;
|
||||
getList();
|
||||
};
|
||||
|
||||
const stageSize = (size) => {
|
||||
stageState.query.size = size;
|
||||
getList();
|
||||
};
|
||||
|
||||
const stageRowEdit = (row) => {
|
||||
listRef.value.rowEdit(row);
|
||||
};
|
||||
|
||||
const onStateAdd = () => {
|
||||
if (!currentRow.landId) {
|
||||
app.$message.error('请选择种植规划');
|
||||
return;
|
||||
}
|
||||
listRef.value.rowAdd();
|
||||
};
|
||||
|
||||
const stageRowSave = (row, done, loading) => {
|
||||
row.landId = currentRow.landId;
|
||||
console.info('stageRowSave', row);
|
||||
savePlantingStage({ ...row })
|
||||
.then((res) => {
|
||||
if (res.code === 200) {
|
||||
app.$message.success('添加成功!');
|
||||
done();
|
||||
getList();
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
app.$message.error(err.msg);
|
||||
})
|
||||
.finally(() => {
|
||||
loading();
|
||||
});
|
||||
};
|
||||
|
||||
const stageRowUpdate = (row, index, done, loading) => {
|
||||
console.info('stageRowUpdate');
|
||||
editPlantingStage(row)
|
||||
.then((res) => {
|
||||
if (res.code === 200) {
|
||||
app.$message.success('更新成功!');
|
||||
done();
|
||||
getList();
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
app.$message.error(err.msg);
|
||||
})
|
||||
.finally(() => {
|
||||
loading();
|
||||
});
|
||||
};
|
||||
const stageClose = () => {
|
||||
isShowVal.value = false;
|
||||
emit('close');
|
||||
};
|
||||
</script>
|
@ -78,12 +78,17 @@ const stageObj = reactive({
|
||||
2: '采收期',
|
||||
});
|
||||
|
||||
const handleWorkChange = async (value, form, done) => {
|
||||
stageState.form.workTime = value.item?.workTime || '';
|
||||
};
|
||||
|
||||
const isShowVal = ref(false);
|
||||
let currentRow = reactive({});
|
||||
|
||||
const loadList = () => {
|
||||
if (isShowVal.value) {
|
||||
console.info('loadList', props);
|
||||
getStageList();
|
||||
}
|
||||
};
|
||||
onMounted(() => {
|
||||
@ -107,13 +112,37 @@ const stageState = reactive({
|
||||
query: {
|
||||
current: 1,
|
||||
size: 10,
|
||||
stage: null,
|
||||
},
|
||||
form: {},
|
||||
options: {
|
||||
...CRUD_OPTIONS,
|
||||
addBtn: false,
|
||||
selection: false,
|
||||
group: [
|
||||
{ label: '所属阶段', prop: 'stage' },
|
||||
{ label: '作业类型', prop: 'workType' },
|
||||
{ label: '作业时间', prop: 'operationDate' },
|
||||
],
|
||||
column: [
|
||||
// {
|
||||
// label: '种植产物',
|
||||
// prop: 'cropId',
|
||||
// type: 'select',
|
||||
// remote: false,
|
||||
// width: '160px',
|
||||
// showOverflowTooltip: true,
|
||||
// props: {
|
||||
// label: 'crop',
|
||||
// value: 'id',
|
||||
// },
|
||||
// dicHeaders: {
|
||||
// authorization: UserStore.token,
|
||||
// },
|
||||
// dicUrl: `${VITE_APP_BASE_API}/land-resource/baseInfo/planTypePage?current=1&size=999`,
|
||||
// dicFormatter: (res) => res.data.records ?? [],
|
||||
// rules: [{ required: true, message: '请选择', trigger: 'blur' }],
|
||||
// },
|
||||
{
|
||||
label: '所属阶段',
|
||||
prop: 'stage',
|
||||
@ -127,19 +156,42 @@ const stageState = reactive({
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '作业计划',
|
||||
label: '作业类型',
|
||||
prop: 'workId',
|
||||
type: 'select',
|
||||
search: true,
|
||||
dicData: workOptions,
|
||||
rules: {
|
||||
required: true,
|
||||
message: '请选择',
|
||||
trigger: 'blur',
|
||||
search: false,
|
||||
remote: false,
|
||||
width: '160px',
|
||||
showOverflowTooltip: true,
|
||||
props: {
|
||||
label: 'workType',
|
||||
value: 'id',
|
||||
},
|
||||
dicHeaders: {
|
||||
authorization: UserStore.token,
|
||||
},
|
||||
dicUrl: `${VITE_APP_BASE_API}/land-resource/planManage/workPage?current=1&size=999`,
|
||||
dicFormatter: (res) => res.data.records ?? [],
|
||||
rules: { required: true, message: '请选择', trigger: 'blur' },
|
||||
change: handleWorkChange,
|
||||
},
|
||||
{
|
||||
label: '作业时间(多少天后)',
|
||||
prop: 'workTime',
|
||||
rules: { required: true, message: '请输入', trigger: 'blur' },
|
||||
props: {
|
||||
type: 'Number',
|
||||
},
|
||||
addDisabled: true,
|
||||
editDisplay: false,
|
||||
viewDisplay: false,
|
||||
},
|
||||
{
|
||||
label: '作业时间',
|
||||
prop: 'operationDate',
|
||||
editDisplay: false,
|
||||
addDisplay: false,
|
||||
},
|
||||
{ label: '作业时间', prop: 'coordinate', addDisplay: false, editDisplay: false },
|
||||
{ label: '结束时间', prop: 'createTime', addDisplay: false, editDisplay: false },
|
||||
],
|
||||
actions: [
|
||||
{
|
||||
@ -166,7 +218,7 @@ const stageState = reactive({
|
||||
|
||||
async function getStageList() {
|
||||
stageState.loading = true;
|
||||
getPlantingStage({ ...stageState.query, planId: currentRow.currentRow.id })
|
||||
getPlantingStage({ ...stageState.query, planId: currentRow.id })
|
||||
.then((res) => {
|
||||
if (res.code === 200) {
|
||||
const { current, size, total, records } = res.data;
|
||||
@ -245,7 +297,7 @@ const onStateAdd = () => {
|
||||
};
|
||||
|
||||
const stageRowSave = (row, done, loading) => {
|
||||
row.planId = currentRow.planId;
|
||||
row.planId = currentRow.id;
|
||||
console.info('stageRowSave', row);
|
||||
savePlantingStage({ ...row })
|
||||
.then((res) => {
|
@ -51,7 +51,8 @@
|
||||
</template>
|
||||
</avue-crud>
|
||||
|
||||
<stageList :is-show="stageShow" :row-original="stageRowVal" @close="stageHide"></stageList>
|
||||
<stageList :is-show="stageShow" :row-original="currentRowVal" @close="stageHide"></stageList>
|
||||
<historyList :is-show="historyShow" :row-original="currentRowVal" @close="historyHide"></historyList>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
@ -71,7 +72,8 @@ import {
|
||||
delPlantingStage,
|
||||
} from '@/apis/land.js';
|
||||
import { isEmpty, imageToBase64, getAssetsFile, downloadFile } from '@/utils';
|
||||
import stageList from '../../component/plantPlan/compoent/stage.vue';
|
||||
import stageList from '../../component/plantPlan/component/stage.vue';
|
||||
import historyList from '../../component/plantPlan/component/history.vue';
|
||||
|
||||
const { VITE_APP_BASE_API } = import.meta.env;
|
||||
const app = useApp();
|
||||
@ -90,7 +92,8 @@ const workOptions = reactive([
|
||||
]);
|
||||
|
||||
let stageShow = ref(false);
|
||||
let stageRowVal = reactive({});
|
||||
let currentRowVal = reactive({});
|
||||
let historyShow = ref(false);
|
||||
|
||||
const state = reactive({
|
||||
loading: false,
|
||||
@ -229,6 +232,11 @@ const state = reactive({
|
||||
icon: 'edit',
|
||||
event: ({ row }) => toStage(row),
|
||||
},
|
||||
{
|
||||
name: '规划记录',
|
||||
icon: 'Memo',
|
||||
event: ({ row }) => toHistory(row),
|
||||
},
|
||||
{
|
||||
type: 'danger',
|
||||
name: '删除',
|
||||
@ -409,9 +417,9 @@ const rowDel = (row, index, done) => {
|
||||
};
|
||||
|
||||
const toStage = (row) => {
|
||||
stageRowVal = row;
|
||||
currentRowVal = row;
|
||||
stageShow.value = true;
|
||||
console.info('toStage', stageRowVal);
|
||||
console.info('toStage', currentRowVal);
|
||||
};
|
||||
|
||||
//导入
|
||||
@ -467,4 +475,12 @@ const rowClick = (row) => {
|
||||
const stageHide = () => {
|
||||
stageShow.value = false;
|
||||
};
|
||||
|
||||
const toHistory = (row) => {
|
||||
currentRowVal = row;
|
||||
historyShow.value = true;
|
||||
};
|
||||
const historyHide = () => {
|
||||
historyShow.value = false;
|
||||
};
|
||||
</script>
|
||||
|
@ -91,31 +91,61 @@ const state = reactive({
|
||||
overHidden: true,
|
||||
},
|
||||
{
|
||||
label: '地块名',
|
||||
prop: 'p2',
|
||||
width: 200,
|
||||
type: 'cascader',
|
||||
// hide: true,
|
||||
// addDisplay: true,
|
||||
// editDisplay: true,
|
||||
// viewDisplay: false,
|
||||
// props: {
|
||||
// label: 'areaName',
|
||||
// value: 'areaCode',
|
||||
// children: 'areaChildVOS',
|
||||
// },
|
||||
// dicUrl: `${VITE_APP_BASE_API}/system/area/region?areaCode=530000`,
|
||||
// dicHeaders: {
|
||||
// authorization: UserStore.token,
|
||||
// },
|
||||
// dicFormatter: (res) => res.data ?? [],
|
||||
label: '基地分类',
|
||||
prop: 'type',
|
||||
type: 'select',
|
||||
dicData: [
|
||||
{
|
||||
label: '种植基地',
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
label: '养殖基地',
|
||||
value: 2,
|
||||
},
|
||||
],
|
||||
rules: {
|
||||
required: true,
|
||||
message: '请选择',
|
||||
message: '请输入',
|
||||
trigger: 'blur',
|
||||
},
|
||||
overHidden: true,
|
||||
},
|
||||
{
|
||||
label: '地块名',
|
||||
prop: 'landName',
|
||||
width: 200,
|
||||
formslot: true,
|
||||
rules: {
|
||||
required: true,
|
||||
message: '请输入',
|
||||
trigger: 'blur',
|
||||
},
|
||||
},
|
||||
// {
|
||||
// label: '地块名',
|
||||
// prop: 'p2',
|
||||
// width: 200,
|
||||
// type: 'select',
|
||||
// // addDisplay: true,
|
||||
// // editDisplay: true,
|
||||
// // viewDisplay: false,
|
||||
// // props: {
|
||||
// // label: 'areaName',
|
||||
// // value: 'areaCode',
|
||||
// // children: 'areaChildVOS',
|
||||
// // },
|
||||
// // dicUrl: `${VITE_APP_BASE_API}/system/area/region?areaCode=530000`,
|
||||
// // dicHeaders: {
|
||||
// // authorization: UserStore.token,
|
||||
// // },
|
||||
// // dicFormatter: (res) => res.data ?? [],
|
||||
// rules: {
|
||||
// required: true,
|
||||
// message: '请选择',
|
||||
// trigger: 'blur',
|
||||
// },
|
||||
// overHidden: true,
|
||||
// },
|
||||
{
|
||||
label: '区域位置',
|
||||
prop: 'p3',
|
||||
@ -136,26 +166,6 @@ const state = reactive({
|
||||
trigger: 'blur',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '基地分类',
|
||||
prop: 'type',
|
||||
type: 'select',
|
||||
dicData: [
|
||||
{
|
||||
label: '种植基地',
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
label: '养殖基地',
|
||||
value: 2,
|
||||
},
|
||||
],
|
||||
rules: {
|
||||
required: true,
|
||||
message: '请输入',
|
||||
trigger: 'blur',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '状态',
|
||||
prop: 'status',
|
||||
@ -273,8 +283,8 @@ const loadData = async () => {
|
||||
await sleep(500);
|
||||
state.data = mockData(
|
||||
{
|
||||
p1: '202501基地',
|
||||
p2: '耿马镇1号地块',
|
||||
p1: '耿马镇一号基地',
|
||||
p2: '耿马镇2025001号地块',
|
||||
p3: '耿马傣族佤族自治县/耿马镇',
|
||||
p4: '1000',
|
||||
p5: '张三',
|
||||
|
@ -3,7 +3,7 @@
|
||||
* @Author: zenghua.wang
|
||||
* @Date: 2022-09-18 21:24:29
|
||||
* @LastEditors: zenghua.wang
|
||||
* @LastEditTime: 2025-02-28 11:04:41
|
||||
* @LastEditTime: 2025-03-20 14:24:31
|
||||
*/
|
||||
|
||||
import { defineConfig, loadEnv } from 'vite';
|
||||
|
@ -21,6 +21,7 @@
|
||||
"@wangeditor/editor-for-vue": "^5.1.12",
|
||||
"axios": "^1.6.5",
|
||||
"echarts": "^5.6.0",
|
||||
"echarts-gl": "^2.0.9",
|
||||
"element-plus": "^2.7.2",
|
||||
"js-base64": "^3.7.6",
|
||||
"lodash": "^4.17.21",
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 75 KiB |
Binary file not shown.
After Width: | Height: | Size: 865 B |
Binary file not shown.
After Width: | Height: | Size: 1.8 KiB |
@ -80,7 +80,7 @@ const chartsData = reactive({
|
||||
},
|
||||
//图表大小位置限制
|
||||
grid: {
|
||||
x: '10%',
|
||||
x: '16%',
|
||||
x2: '5%',
|
||||
y: '15%',
|
||||
y2: '15%',
|
||||
|
@ -6,16 +6,17 @@
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from 'vue';
|
||||
const dataList = reactive([
|
||||
{ name: '打车费', val: 1230, itemStyle: { color: 'rgba(56, 136, 235, 1)' } },
|
||||
{ name: '住宿费', val: 300, itemStyle: { color: 'rgba(113, 70, 159, 1)' } },
|
||||
{ name: '办公费', val: 800, itemStyle: { color: 'rgba(237, 171, 87, 1)' } },
|
||||
{ name: '差旅费', val: 500, itemStyle: { color: 'rgba(231, 89, 77, 1)' } },
|
||||
{ name: '肉类', val: 1230, itemStyle: { color: 'rgba(56, 136, 235, 1)' } },
|
||||
{ name: '水果', val: 300, itemStyle: { color: 'rgba(113, 70, 159, 1)' } },
|
||||
{ name: '蔬菜', val: 800, itemStyle: { color: 'rgba(237, 171, 87, 1)' } },
|
||||
{ name: '水产', val: 500, itemStyle: { color: 'rgba(231, 89, 77, 1)' } },
|
||||
{ name: '谷物', val: 600, itemStyle: { color: 'rgba(231, 89, 77, 1)' } },
|
||||
]);
|
||||
const heightProportion = ref(0.3); // 柱状扇形的高度比例
|
||||
|
||||
// 生成扇形的曲面参数方程,用于 series-surface.parametricEquation
|
||||
// #region
|
||||
const getParametricEquation = (startRatio, endRatio, isSelected, isHovered, k, height) => {
|
||||
const getParametricEquation = (startRatio, endRatio, isSelected, isHovered, k, height, radiusScale) => {
|
||||
// 计算
|
||||
let midRatio = (startRatio + endRatio) / 3;
|
||||
|
||||
@ -54,22 +55,22 @@ const getParametricEquation = (startRatio, endRatio, isSelected, isHovered, k, h
|
||||
|
||||
x: function (u, v) {
|
||||
if (u < startRadian) {
|
||||
return offsetX + Math.cos(startRadian) * (1 + Math.cos(v) * k) * hoverRate;
|
||||
return offsetX + Math.cos(startRadian) * (1 + Math.cos(v) * k) * hoverRate * radiusScale;
|
||||
}
|
||||
if (u > endRadian) {
|
||||
return offsetX + Math.cos(endRadian) * (1 + Math.cos(v) * k) * hoverRate;
|
||||
return offsetX + Math.cos(endRadian) * (1 + Math.cos(v) * k) * hoverRate * radiusScale;
|
||||
}
|
||||
return offsetX + Math.cos(u) * (1 + Math.cos(v) * k) * hoverRate;
|
||||
return offsetX + Math.cos(u) * (1 + Math.cos(v) * k) * hoverRate * radiusScale;
|
||||
},
|
||||
|
||||
y: function (u, v) {
|
||||
if (u < startRadian) {
|
||||
return offsetY + Math.sin(startRadian) * (1 + Math.cos(v) * k) * hoverRate;
|
||||
return offsetY + Math.sin(startRadian) * (1 + Math.cos(v) * k) * hoverRate * radiusScale;
|
||||
}
|
||||
if (u > endRadian) {
|
||||
return offsetY + Math.sin(endRadian) * (1 + Math.cos(v) * k) * hoverRate;
|
||||
return offsetY + Math.sin(endRadian) * (1 + Math.cos(v) * k) * hoverRate * radiusScale;
|
||||
}
|
||||
return offsetY + Math.sin(u) * (1 + Math.cos(v) * k) * hoverRate;
|
||||
return offsetY + Math.sin(u) * (1 + Math.cos(v) * k) * hoverRate * radiusScale;
|
||||
},
|
||||
|
||||
z: function (u, v) {
|
||||
@ -86,7 +87,7 @@ const getParametricEquation = (startRatio, endRatio, isSelected, isHovered, k, h
|
||||
// #endregion
|
||||
|
||||
// 生成模拟 3D 饼图的配置项
|
||||
const getPie3D = (pieData, internalDiameterRatio) => {
|
||||
const getPie3D = (pieData, internalDiameterRatio, radiusScale = 1.8) => {
|
||||
let series = [];
|
||||
let sumValue = 0;
|
||||
let startValue = 0;
|
||||
@ -138,7 +139,8 @@ const getPie3D = (pieData, internalDiameterRatio) => {
|
||||
false,
|
||||
false,
|
||||
k,
|
||||
series[i].pieData.value
|
||||
series[i].pieData.value,
|
||||
radiusScale
|
||||
);
|
||||
|
||||
startValue = endValue;
|
||||
@ -148,8 +150,8 @@ const getPie3D = (pieData, internalDiameterRatio) => {
|
||||
const midRadian = (series[i].pieData.startRatio + series[i].pieData.endRatio) * Math.PI;
|
||||
// 计算扇区外缘顶部坐标(v=0时)
|
||||
const radius = 1 + k; // 外径公式
|
||||
const posX = Math.cos(midRadian) * radius;
|
||||
const posY = Math.sin(midRadian) * radius;
|
||||
const posX = Math.cos(midRadian) * radius * radiusScale;
|
||||
const posY = Math.sin(midRadian) * radius * radiusScale;
|
||||
// 获取该扇区实际高度
|
||||
const posZ = heightProportion.value * series[i].pieData.value;
|
||||
let flag = (midRadian >= 0 && midRadian <= Math.PI / 2) || (midRadian >= (3 * Math.PI) / 2 && midRadian <= Math.PI * 2) ? 1 : -1;
|
||||
@ -169,15 +171,15 @@ const getPie3D = (pieData, internalDiameterRatio) => {
|
||||
{
|
||||
type: 'scatter3D',
|
||||
label: {
|
||||
show: true,
|
||||
show: true, //设置label的显示和隐藏
|
||||
distance: 0,
|
||||
position: 'center',
|
||||
textStyle: {
|
||||
color: '#ffffff',
|
||||
backgroundColor: color,
|
||||
borderWidth: 2,
|
||||
fontSize: 14,
|
||||
padding: 10,
|
||||
fontSize: 8,
|
||||
padding: 4,
|
||||
borderRadius: 4,
|
||||
},
|
||||
formatter: '{b}',
|
||||
@ -241,8 +243,8 @@ const getPie3D = (pieData, internalDiameterRatio) => {
|
||||
},
|
||||
parametricEquation: {
|
||||
u: {
|
||||
min: 0.74, // 控制环的内径(92%半径)
|
||||
max: 0.75, // 外径(100%半径)
|
||||
min: 0.94, // 控制环的内径(92%半径)
|
||||
max: 0.95, // 外径(100%半径)
|
||||
step: 0.0001,
|
||||
},
|
||||
v: {
|
||||
@ -277,8 +279,8 @@ const getPie3D = (pieData, internalDiameterRatio) => {
|
||||
},
|
||||
parametricEquation: {
|
||||
u: {
|
||||
min: 0.54, // 控制环的内径(92%半径)
|
||||
max: 0.55, // 外径(100%半径)
|
||||
min: 0.94, // 控制环的内径(92%半径)
|
||||
max: 0.95, // 外径(100%半径)
|
||||
step: 0.0001,
|
||||
},
|
||||
v: {
|
||||
@ -309,7 +311,6 @@ dataList.forEach((item) => {
|
||||
|
||||
const chartsData = reactive({
|
||||
option: {
|
||||
backgroundColor: '#2d58e4',
|
||||
xAxis3D: {
|
||||
min: -1.5,
|
||||
max: 1.5,
|
||||
@ -325,7 +326,7 @@ const chartsData = reactive({
|
||||
grid3D: {
|
||||
show: false,
|
||||
boxHeight: 4,
|
||||
bottom: '50%',
|
||||
top: '10%',
|
||||
viewControl: {
|
||||
distance: 380,
|
||||
alpha: 25,
|
||||
|
@ -7,7 +7,7 @@
|
||||
<div class="left-charts-item">
|
||||
<customBack top-title="生产经营主体类别统计" :top-postion="'left'">
|
||||
<template #back>
|
||||
<!-- <entitiesCategoryCharts></entitiesCategoryCharts> -->
|
||||
<entitiesCategoryCharts></entitiesCategoryCharts>
|
||||
</template>
|
||||
</customBack>
|
||||
</div>
|
||||
|
@ -0,0 +1,131 @@
|
||||
<template>
|
||||
<div class="cases-alerts-warp">
|
||||
<div class="cases-alerts" :style="{ 'background-image': 'url(' + getAssetsFile('images/inputs/partbg1.png') + ')' }">
|
||||
<div class="cases-alerts-content">
|
||||
<div class="cases-alerts-item-pos">
|
||||
<template v-for="(n, index) in datalist" :key="index">
|
||||
<div class="cases-alerts-item">
|
||||
<div class="header" :style="{ 'background-image': 'url(' + getAssetsFile('images/inputs/partbg2.png') + ')' }">
|
||||
<div class="title">{{ n.title }}</div>
|
||||
</div>
|
||||
<div class="content">
|
||||
<template v-for="(m, mindex) in n.valStr" :key="mindex">
|
||||
<div class="content-item" :style="{ 'background-image': 'url(' + getAssetsFile('images/inputs/partbg3.png') + ')' }">
|
||||
<div class="num">{{ m }}</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from 'vue';
|
||||
import { isEmpty, getAssetsFile } from '@/utils';
|
||||
const datalist = reactive([
|
||||
{ title: '案件次数', val: 100 },
|
||||
{ title: '预警次数', val: 236 },
|
||||
]);
|
||||
|
||||
onMounted(() => {
|
||||
if (datalist.length && datalist.length > 0) {
|
||||
datalist.forEach((m) => {
|
||||
let valStr = '';
|
||||
|
||||
if (m.val < 1000 && m.val >= 100) {
|
||||
valStr = '0' + m.val;
|
||||
} else if (m.val < 100 && m.val >= 10) {
|
||||
valStr = '00' + m.val;
|
||||
} else if (m.val < 10) {
|
||||
valStr = '000' + m.val;
|
||||
} else {
|
||||
valStr = m.val.toFixed(0);
|
||||
}
|
||||
m.valStr = [...valStr];
|
||||
// console.info('valStr', m.valStr);
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
div {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.cases-alerts-warp {
|
||||
height: 100%;
|
||||
padding: 8px;
|
||||
.cases-alerts {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
.cases-alerts-content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0 20px;
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
.cases-alerts-item-pos {
|
||||
width: 100%;
|
||||
display: inline-flex;
|
||||
justify-content: space-around;
|
||||
}
|
||||
.cases-alerts-item {
|
||||
display: inline-block;
|
||||
width: calc((100% - 20px) / 2);
|
||||
.header,
|
||||
.content {
|
||||
display: inline-flex;
|
||||
width: 100%;
|
||||
}
|
||||
.header {
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
line-height: 32px;
|
||||
height: 32px;
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
.title {
|
||||
text-align: center;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
transform: skewX(-8deg);
|
||||
background: linear-gradient(to bottom, '#ff7e5f', '#548fff');
|
||||
-webkit-background-clip: text;
|
||||
color: #fff;
|
||||
letter-spacing: 8px;
|
||||
text-shadow: -6px 0 0 1px #add8f1;
|
||||
}
|
||||
}
|
||||
.content {
|
||||
justify-content: space-around;
|
||||
margin-top: 50%;
|
||||
.content-item {
|
||||
height: 36px;
|
||||
display: inline-block;
|
||||
width: calc((100% - 20px) / 4);
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
line-height: 36px;
|
||||
text-align: center;
|
||||
.num {
|
||||
text-align: center;
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
transform: skewX(-8deg);
|
||||
background: linear-gradient(to bottom, '#ff7e5f', '#548fff');
|
||||
-webkit-background-clip: text;
|
||||
color: #fff;
|
||||
text-shadow: -6px 0 0 1px #add8f1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -0,0 +1,171 @@
|
||||
<template>
|
||||
<div class="demo roll-list-land-plan" style="height: 90%">
|
||||
<!-- <div class="list-item-header item-warp" :style="{ flex: listKeys.length }">
|
||||
<template v-for="(h, indexh) in listKeys" :key="indexh">
|
||||
<div class="item-td" :style="{ width: 'calc(100% / ' + listKeys.length + ')' }">{{ listKeysHeader[h] }}</div>
|
||||
</template>
|
||||
</div> -->
|
||||
<vue3ScrollSeamless class="scroll-wrap" :class-options="classOptions" :data-list="datalist">
|
||||
<div v-for="(item, index) in datalist" :key="index" class="list-item">
|
||||
<div class="list-item-content">
|
||||
<div class="list-item-boday item-warp" :style="{ flex: listKeys.length }">
|
||||
<div class="item-content">
|
||||
<div class="label">{{ item.title }}</div>
|
||||
<div class="val">
|
||||
<!-- <el-progress :percentage="50" :show-text="false" :indeterminate="false" :stroke-width="12" color="#6cd1f9" :duration="8" /> -->
|
||||
<div class="progress-warp" :style="{ width: item.percent + 'px' }">
|
||||
<div class="progress"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</vue3ScrollSeamless>
|
||||
</div>
|
||||
<!-- </div> -->
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted, onUnmounted, computed, reactive } from 'vue';
|
||||
import { vue3ScrollSeamless } from 'vue3-scroll-seamless';
|
||||
const props = defineProps({
|
||||
// items: {
|
||||
// type: Array,
|
||||
// default: () => [],
|
||||
// },
|
||||
});
|
||||
|
||||
let list = reactive([
|
||||
{ title: '农药', value: 357 },
|
||||
{ title: '肥料', value: 159 },
|
||||
{ title: '种源', value: 516 },
|
||||
{ title: '兽药', value: 82 },
|
||||
{ title: '农机', value: 45 },
|
||||
]);
|
||||
|
||||
let datalist = computed(() => {
|
||||
return list.map((m) => {
|
||||
return { ...m, percent: parseInt(Number(m.value / max.value) * 200) };
|
||||
});
|
||||
});
|
||||
|
||||
let max = computed(() => {
|
||||
let valueList = new Set(list.map((item) => item.value));
|
||||
let sortValue = [...valueList].sort((a, b) => b - a) || [];
|
||||
// console.info('valueList', sortValue);
|
||||
return sortValue.length ? sortValue[0] : 0;
|
||||
});
|
||||
|
||||
const listKeys = reactive(['title', 'value']);
|
||||
const listKeysHeader = reactive({
|
||||
title: '分类',
|
||||
value: '数量',
|
||||
});
|
||||
|
||||
const classOptions = {
|
||||
singleHeight: 48,
|
||||
};
|
||||
onMounted(() => {});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.roll-list-land-plan {
|
||||
margin-top: 8px;
|
||||
::v-deep() {
|
||||
.el-progress-bar__outer {
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
.scroll-wrap {
|
||||
height: 90%;
|
||||
width: 100%;
|
||||
margin: 4px auto;
|
||||
overflow: hidden;
|
||||
}
|
||||
.list-item-header {
|
||||
background: #144482;
|
||||
font-size: 10px;
|
||||
width: 100%;
|
||||
.item-td {
|
||||
padding: 8px 6px;
|
||||
}
|
||||
}
|
||||
.list-item-boday {
|
||||
background: transparent;
|
||||
width: 100%;
|
||||
.item-td {
|
||||
padding: 4px 6px;
|
||||
&.td-title {
|
||||
color: #6cd1f9 !important;
|
||||
}
|
||||
&.zebra-b {
|
||||
background: #051225 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
.item-warp {
|
||||
display: inline-flex;
|
||||
justify-content: space-around;
|
||||
.item-td {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
}
|
||||
.item-content {
|
||||
width: 100%;
|
||||
display: inline-flex;
|
||||
justify-content: flex-start;
|
||||
margin: 8px 0;
|
||||
.label,
|
||||
.val {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.label {
|
||||
width: 50px;
|
||||
color: #fff;
|
||||
}
|
||||
.val {
|
||||
width: calc(100% - 50px);
|
||||
.progress-warp {
|
||||
.progress {
|
||||
height: 10px;
|
||||
border-radius: 6px;
|
||||
background: linear-gradient(90deg, #45bfe9 0%, #01589c 100%);
|
||||
animation: expandWidth 1s ease-in-out forwards;
|
||||
}
|
||||
|
||||
@keyframes expandWidth {
|
||||
from {
|
||||
width: 0;
|
||||
}
|
||||
to {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.list-item {
|
||||
// border-bottom: 1px dashed rgba(255, 255, 255, 0.2);
|
||||
line-height: 18px;
|
||||
|
||||
.list-item-content {
|
||||
display: inline-flex;
|
||||
width: 100%;
|
||||
justify-content: space-around;
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
}
|
||||
.demo {
|
||||
// display: flex;
|
||||
// align-items: center;
|
||||
// justify-content: center;
|
||||
// margin-top: 10px;
|
||||
}
|
||||
</style>
|
@ -6,7 +6,9 @@
|
||||
<el-col :span="6" class="left-charts">
|
||||
<div class="left-charts-item">
|
||||
<customBack top-title="投入品分类统计" :top-postion="'left'">
|
||||
<template #back> </template>
|
||||
<template #back>
|
||||
<inputsType></inputsType>
|
||||
</template>
|
||||
</customBack>
|
||||
</div>
|
||||
<div class="left-charts-item">
|
||||
@ -30,7 +32,9 @@
|
||||
<el-col :span="6" class="right-charts">
|
||||
<div class="right-charts-item">
|
||||
<customBack top-title="案件次数" :top-postion="'right'">
|
||||
<template #back> </template>
|
||||
<template #back>
|
||||
<casesAlerts></casesAlerts>
|
||||
</template>
|
||||
</customBack>
|
||||
</div>
|
||||
<div class="right-charts-item">
|
||||
@ -61,6 +65,8 @@ import inputsGmp from './components/inputsGmp.vue';
|
||||
import landbreedCharts from './components/landbreedCharts.vue';
|
||||
import monthlyuseCharts from './components/monthlyuseCharts.vue';
|
||||
import dealerDistributionCharts from './components/dealerDistributionCharts.vue';
|
||||
import casesAlerts from './components/casesAlerts.vue';
|
||||
import inputsType from './components/inputsType.vue';
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.data-home-index {
|
||||
|
@ -1,12 +1,12 @@
|
||||
<template>
|
||||
<div class="distribution-charts">
|
||||
<custom-echart-pie :chart-data="plantBreed.valData" height="100%" :option="plantBreed.option" />
|
||||
<custom-echart-pie :chart-data="chartsData.valData" height="100%" :option="chartsData.option" />
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from 'vue';
|
||||
|
||||
const plantBreed = reactive({
|
||||
const chartsData = reactive({
|
||||
option: {
|
||||
color: ['#3685fe', '#41b879', '#ffd500'],
|
||||
title: {
|
||||
@ -42,6 +42,9 @@ const plantBreed = reactive({
|
||||
itemStyle: {
|
||||
borderRadius: 5,
|
||||
},
|
||||
// animationDuration: 15000,
|
||||
// // 可选:设置动画缓动效果
|
||||
// animationEasing: 'elasticOut',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
@ -0,0 +1,65 @@
|
||||
<template>
|
||||
<div class="insect-pests-charts">
|
||||
<custom-echart-bar :chart-data="chartsData.valData" height="100%" :option="chartsData.option" />
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from 'vue';
|
||||
const chartsData = reactive({
|
||||
option: {
|
||||
grid: {
|
||||
left: '3%',
|
||||
right: '4%',
|
||||
bottom: '2%',
|
||||
top: '18%',
|
||||
containLabel: true,
|
||||
},
|
||||
title: {
|
||||
text: ' ',
|
||||
textStyle: {
|
||||
color: '#333',
|
||||
},
|
||||
},
|
||||
label: {
|
||||
color: '#333',
|
||||
},
|
||||
barStyle: {
|
||||
barWidth: 15,
|
||||
itemStyle: {
|
||||
borderRadius: [8, 8, 0, 0], // 设置柱子的圆角半径
|
||||
},
|
||||
color: {
|
||||
type: 'linear', // 线性渐变
|
||||
x: 0,
|
||||
y: 0,
|
||||
x2: 0,
|
||||
y2: 1,
|
||||
colorStops: [
|
||||
{ offset: 0, color: '#45bfe9' },
|
||||
{ offset: 1, color: '#01589c' },
|
||||
],
|
||||
global: false, // 默认为 false
|
||||
},
|
||||
},
|
||||
legend: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
valData: [
|
||||
{ value: 80, type: '经销商', name: '耿马镇' },
|
||||
{ value: 105, type: '经销商', name: '勐撒镇' },
|
||||
{ value: 100, type: '经销商', name: '勐永镇' },
|
||||
{ value: 125, type: '经销商', name: '孟定镇' },
|
||||
{ value: 217, type: '经销商', name: '勐简乡' },
|
||||
{ value: 200, type: '经销商', name: '贺派乡' },
|
||||
{ value: 155, type: '经销商', name: '四排山乡' },
|
||||
{ value: 80, type: '经销商', name: '芒洪乡' },
|
||||
{ value: 105, type: '经销商', name: '大兴乡' },
|
||||
],
|
||||
});
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.insect-pests-charts {
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,74 @@
|
||||
<template>
|
||||
<div class="plant-type-charts">
|
||||
<custom-echart-pie :chart-data="chartsData.valData" height="100%" :option="chartsData.option" />
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from 'vue';
|
||||
|
||||
const chartsData = reactive({
|
||||
option: {
|
||||
color: ['#3685fe', '#41b879', '#ffd500'],
|
||||
title: {
|
||||
text: ' ',
|
||||
textStyle: {
|
||||
color: '#333',
|
||||
},
|
||||
},
|
||||
legend: {
|
||||
data: ['甘蔗', '菠萝', '土豆', '番茄', '白菜', '其他'],
|
||||
right: '0', // 距离左侧10%的位置
|
||||
top: 'middle', // 垂直居中
|
||||
orient: 'vertical', // 图例垂直排列
|
||||
itemWidth: 15, // 图例标记的宽度
|
||||
itemHeight: 8, // 图例标记的高度
|
||||
textStyle: {
|
||||
fontSize: 10, // 图例文字的字体大小
|
||||
color: '#fff', // 图例文字的颜色
|
||||
},
|
||||
},
|
||||
label: {
|
||||
color: '#333',
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'pie',
|
||||
radius: [20, 80],
|
||||
roseType: 'area',
|
||||
center: ['40%', '50%'],
|
||||
label: {
|
||||
show: false,
|
||||
},
|
||||
itemStyle: {
|
||||
borderRadius: 5,
|
||||
},
|
||||
// animationDuration: 15000,
|
||||
// // 可选:设置动画缓动效果
|
||||
// animationEasing: 'elasticOut',
|
||||
},
|
||||
],
|
||||
},
|
||||
valData: [
|
||||
{ value: 205.6, name: '甘蔗' },
|
||||
{ value: 308.7, name: '菠萝' },
|
||||
{ value: 359.6, name: '土豆' },
|
||||
{ value: 452.6, name: '番茄' },
|
||||
{ value: 388.9, name: '白菜' },
|
||||
{ value: 512.5, name: '其他' },
|
||||
],
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
if (chartsData.valData && chartsData.valData.length) {
|
||||
chartsData.valData.forEach((m, index) => {
|
||||
let num = 100;
|
||||
m.value = (Number(m.value) + Math.random() + num).toFixed(2);
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.plant-type-charts {
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
@ -4,15 +4,53 @@
|
||||
<template #center>
|
||||
<el-row style="width: 100%; height: 100%">
|
||||
<el-col :span="6" class="left-charts">
|
||||
<div class="left-charts-item"></div>
|
||||
<div class="left-charts-item"></div>
|
||||
<div class="left-charts-item"></div>
|
||||
<div class="left-charts-item">
|
||||
<customBack top-title="智慧种植种类分析" :top-postion="'left'">
|
||||
<template #back>
|
||||
<plantTypeCharts></plantTypeCharts>
|
||||
</template>
|
||||
</customBack>
|
||||
</div>
|
||||
<div class="left-charts-item">
|
||||
<customBack top-title="昆虫害监测" :top-postion="'left'">
|
||||
<template #back></template>
|
||||
</customBack>
|
||||
</div>
|
||||
<div class="left-charts-item">
|
||||
<customBack top-title="病理害监测" :top-postion="'left'">
|
||||
<template #back></template>
|
||||
</customBack>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-row style="height: 60%">
|
||||
<el-col :span="24"> 1-1</el-col>
|
||||
</el-row>
|
||||
<el-row style="height: 40%">
|
||||
<el-col :span="12">
|
||||
<customBack top-title="水肥检测分析" :top-postion="'left'"> <template #back></template> </customBack>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<customBack top-title="智慧水肥灌溉" :top-postion="'right'"> <template #back></template> </customBack>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-col>
|
||||
<el-col :span="12"></el-col>
|
||||
<el-col :span="6" class="right-charts">
|
||||
<div class="right-charts-item"></div>
|
||||
<div class="right-charts-item"></div>
|
||||
<div class="right-charts-item"></div>
|
||||
<div class="right-charts-item">
|
||||
<customBack top-title="智慧监控 A区 QQI" :top-postion="'right'">
|
||||
<template #back></template>
|
||||
</customBack>
|
||||
</div>
|
||||
<div class="right-charts-item">
|
||||
<customBack top-title="种植产量分析" :top-postion="'right'">
|
||||
<template #back></template>
|
||||
</customBack>
|
||||
</div>
|
||||
<div class="right-charts-item">
|
||||
<customBack top-title="水质检测分析" :top-postion="'right'">
|
||||
<template #back></template>
|
||||
</customBack>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
@ -21,6 +59,8 @@
|
||||
</template>
|
||||
<script setup>
|
||||
import baseBg from '@/components/baseBg.vue';
|
||||
import customBack from '@/components/customBack.vue';
|
||||
import plantTypeCharts from './components/plantTypeCharts.vue';
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.data-home-index {
|
||||
|
@ -1601,6 +1601,11 @@ class-utils@^0.3.5:
|
||||
isobject "^3.0.0"
|
||||
static-extend "^0.1.1"
|
||||
|
||||
claygl@^1.2.1:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.npmmirror.com/claygl/-/claygl-1.3.0.tgz#7a6e2903210519ac358848f5d78070ed211685f3"
|
||||
integrity sha512-+gGtJjT6SSHD2l2yC3MCubW/sCV40tZuSs5opdtn79vFSGUgp/lH139RNEQ6Jy078/L0aV8odCw8RSrUcMfLaQ==
|
||||
|
||||
clone-regexp@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.npmmirror.com/clone-regexp/-/clone-regexp-1.0.1.tgz#051805cd33173375d82118fc0918606da39fd60f"
|
||||
@ -2086,6 +2091,14 @@ dunder-proto@^1.0.0, dunder-proto@^1.0.1:
|
||||
es-errors "^1.3.0"
|
||||
gopd "^1.2.0"
|
||||
|
||||
echarts-gl@^2.0.9:
|
||||
version "2.0.9"
|
||||
resolved "https://registry.npmmirror.com/echarts-gl/-/echarts-gl-2.0.9.tgz#ee228a6c7520a6fb7bbb71ea94394f3637ade033"
|
||||
integrity sha512-oKeMdkkkpJGWOzjgZUsF41DOh6cMsyrGGXimbjK2l6Xeq/dBQu4ShG2w2Dzrs/1bD27b2pLTGSaUzouY191gzA==
|
||||
dependencies:
|
||||
claygl "^1.2.1"
|
||||
zrender "^5.1.1"
|
||||
|
||||
echarts@^5.6.0:
|
||||
version "5.6.0"
|
||||
resolved "https://registry.npmmirror.com/echarts/-/echarts-5.6.0.tgz#2377874dca9fb50f104051c3553544752da3c9d6"
|
||||
@ -6686,7 +6699,7 @@ yocto-queue@^0.1.0:
|
||||
resolved "https://registry.npmmirror.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
|
||||
integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
|
||||
|
||||
zrender@5.6.1:
|
||||
zrender@5.6.1, zrender@^5.1.1:
|
||||
version "5.6.1"
|
||||
resolved "https://registry.npmmirror.com/zrender/-/zrender-5.6.1.tgz#e08d57ecf4acac708c4fcb7481eb201df7f10a6b"
|
||||
integrity sha512-OFXkDJKcrlx5su2XbzJvj/34Q3m6PvyCZkVPHGYpcCJ52ek4U/ymZyfuV1nKE23AyBJ51E/6Yr0mhZ7xGTO4ag==
|
||||
|
Loading…
x
Reference in New Issue
Block a user