Merge branch 'temp' of https://gitea.peidikeji.cn/zhouhui/lcny-vue3-antd-admin into temp
commit
282a5f38e8
|
|
@ -33,6 +33,7 @@
|
||||||
"gen:icon": "esno ./build/generate/icon/index.ts"
|
"gen:icon": "esno ./build/generate/icon/index.ts"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@amap/amap-jsapi-loader": "^1.0.1",
|
||||||
"@ant-design/colors": "^6.0.0",
|
"@ant-design/colors": "^6.0.0",
|
||||||
"@ant-design/icons-vue": "^6.1.0",
|
"@ant-design/icons-vue": "^6.1.0",
|
||||||
"@iconify/iconify": "^2.2.1",
|
"@iconify/iconify": "^2.2.1",
|
||||||
|
|
|
||||||
|
|
@ -149,6 +149,20 @@ export function getAgriculturalBasic(mode: ErrorMessageMode = 'modal') {
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @description:镇街数据
|
||||||
|
*/
|
||||||
|
export function getTownAgriculturalBasic(params, mode: ErrorMessageMode = 'modal') {
|
||||||
|
return defHttp.get(
|
||||||
|
{
|
||||||
|
url: '/api/agricultural-basic',
|
||||||
|
params,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
errorMessageMode: mode,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* @description:新增管理员
|
* @description:新增管理员
|
||||||
*/
|
*/
|
||||||
|
|
@ -230,3 +244,87 @@ export function editPassword(id: string, data, mode: ErrorMessageMode = 'modal')
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description:获取农作物
|
||||||
|
*/
|
||||||
|
export function getCrops(data, mode: ErrorMessageMode = 'modal') {
|
||||||
|
return defHttp.get(
|
||||||
|
{
|
||||||
|
url: `/api/crops`,
|
||||||
|
data,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
errorMessageMode: mode,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description:新增区域数据
|
||||||
|
*/
|
||||||
|
export function addaGriculturalBasic(data, mode: ErrorMessageMode = 'modal') {
|
||||||
|
return defHttp.post(
|
||||||
|
{
|
||||||
|
url: `/api/agricultural-basic`,
|
||||||
|
data,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
errorMessageMode: mode,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @description:修改区域数据
|
||||||
|
*/
|
||||||
|
export function editGriculturalBasic(id: string, data, mode: ErrorMessageMode = 'modal') {
|
||||||
|
return defHttp.put(
|
||||||
|
{
|
||||||
|
url: `/api/agricultural-basic/${id}`,
|
||||||
|
data,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
errorMessageMode: mode,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @description:删除区域数据
|
||||||
|
*/
|
||||||
|
export function deleteGriculturalBasic(id: string, mode: ErrorMessageMode = 'modal') {
|
||||||
|
return defHttp.delete(
|
||||||
|
{
|
||||||
|
url: `/api/agricultural-basic/${id}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
errorMessageMode: mode,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @description:详情区域数据
|
||||||
|
*/
|
||||||
|
export function GriculturalBasicInfo(id: string, mode: ErrorMessageMode = 'modal') {
|
||||||
|
return defHttp.get(
|
||||||
|
{
|
||||||
|
url: `/api/agricultural-basic/${id}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
errorMessageMode: mode,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @description:查看农作物产量
|
||||||
|
*/
|
||||||
|
export function getCropYields(params, mode: ErrorMessageMode = 'modal') {
|
||||||
|
return defHttp.get(
|
||||||
|
{
|
||||||
|
url: `/api/crop-yields`,
|
||||||
|
params,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
errorMessageMode: mode,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import type { AppRouteModule } from '/@/router/types';
|
import type { AppRouteModule } from '/@/router/types'
|
||||||
import { LAYOUT } from '/@/router/constant';
|
import { LAYOUT } from '/@/router/constant'
|
||||||
const main: AppRouteModule = {
|
const main: AppRouteModule = {
|
||||||
path: '/base',
|
path: '/base',
|
||||||
name: 'Base',
|
name: 'Base',
|
||||||
|
|
@ -20,13 +20,21 @@ const main: AppRouteModule = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'industrial-structure',
|
path: 'base-data',
|
||||||
name: 'BaseIndustrialStructure',
|
name: 'BaseData',
|
||||||
component: () => import('/@/views/base/industrial-structure/index.vue'),
|
component: () => import('/@/views/base/base-data/index.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
title: '农业产业结构',
|
title: '全市基地数据',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
// {
|
||||||
|
// path: 'industrial-structure',
|
||||||
|
// name: 'BaseIndustrialStructure',
|
||||||
|
// component: () => import('/@/views/base/industrial-structure/index.vue'),
|
||||||
|
// meta: {
|
||||||
|
// title: '农业产业结构',
|
||||||
|
// },
|
||||||
|
// },
|
||||||
{
|
{
|
||||||
path: 'ranking-list',
|
path: 'ranking-list',
|
||||||
name: 'BaseRankingList',
|
name: 'BaseRankingList',
|
||||||
|
|
@ -52,6 +60,6 @@ const main: AppRouteModule = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
}
|
||||||
|
|
||||||
export default main;
|
export default main
|
||||||
|
|
|
||||||
|
|
@ -90,3 +90,13 @@ export const withInstall = <T>(component: T, alias?: string) => {
|
||||||
}
|
}
|
||||||
return component as T & Plugin
|
return component as T & Plugin
|
||||||
}
|
}
|
||||||
|
export function formatDataByObject(obj) {
|
||||||
|
const arr: any[] = []
|
||||||
|
Object.keys(obj).forEach((e) => {
|
||||||
|
arr.push({
|
||||||
|
label: obj[e],
|
||||||
|
value: e,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,77 @@
|
||||||
|
<template>
|
||||||
|
<BasicDrawer
|
||||||
|
v-bind="$attrs"
|
||||||
|
@register="registerDrawer"
|
||||||
|
showFooter
|
||||||
|
:title="getTitle"
|
||||||
|
width="1000px"
|
||||||
|
@ok="handleSubmit"
|
||||||
|
>
|
||||||
|
<BasicForm @register="registerForm"> </BasicForm>
|
||||||
|
<Map v-model:modelValue="mapInfo" />
|
||||||
|
</BasicDrawer>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref, computed, unref, watch } from 'vue'
|
||||||
|
import { BasicForm, useForm } from '/@/components/Form/index'
|
||||||
|
import { accountFormSchema } from './base.data'
|
||||||
|
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer'
|
||||||
|
import Map from './map.vue'
|
||||||
|
import { addaGriculturalBasic, editGriculturalBasic } from '/@/api/sys/user'
|
||||||
|
const mapInfo = ref({
|
||||||
|
address: '',
|
||||||
|
latitude: '',
|
||||||
|
longitude: '',
|
||||||
|
})
|
||||||
|
const emits = defineEmits(['success', 'register'])
|
||||||
|
const isUpdate = ref(false)
|
||||||
|
const getTitle = computed(() => (!isUpdate.value ? '新增基地' : '编辑基地'))
|
||||||
|
const [registerForm, { resetFields, setFieldsValue, validate }] = useForm({
|
||||||
|
labelWidth: 90,
|
||||||
|
baseColProps: { span: 24 },
|
||||||
|
schemas: accountFormSchema,
|
||||||
|
showActionButtonGroup: false,
|
||||||
|
})
|
||||||
|
const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
|
||||||
|
resetFields()
|
||||||
|
setDrawerProps({ confirmLoading: false })
|
||||||
|
isUpdate.value = data?.isUpdate
|
||||||
|
if (unref(isUpdate)) {
|
||||||
|
mapInfo.value = {
|
||||||
|
address: data.address,
|
||||||
|
latitude: data.address_lat,
|
||||||
|
longitude: data.address_lng,
|
||||||
|
}
|
||||||
|
setFieldsValue({
|
||||||
|
...data,
|
||||||
|
crops_ids: data.crops.map((e) => e.id),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
watch(mapInfo, (newValue) => {
|
||||||
|
setFieldsValue({
|
||||||
|
address: newValue?.address,
|
||||||
|
address_lat: newValue?.latitude,
|
||||||
|
address_lng: newValue.longitude,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
const handleSubmit = async () => {
|
||||||
|
try {
|
||||||
|
const values = await validate()
|
||||||
|
values.type = 1
|
||||||
|
setDrawerProps({ confirmLoading: true })
|
||||||
|
if (values.id) {
|
||||||
|
// 修改
|
||||||
|
await editGriculturalBasic(values.id, values)
|
||||||
|
} else {
|
||||||
|
// 新增
|
||||||
|
await addaGriculturalBasic(values)
|
||||||
|
}
|
||||||
|
closeDrawer()
|
||||||
|
emits('success')
|
||||||
|
} finally {
|
||||||
|
setDrawerProps({ confirmLoading: false })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,132 @@
|
||||||
|
import { BasicColumn } from '/@/components/Table'
|
||||||
|
import { FormSchema } from '/@/components/Table'
|
||||||
|
import { getCrops } from '/@/api/sys/user'
|
||||||
|
export const columns: BasicColumn[] = [
|
||||||
|
{
|
||||||
|
title: '基地名称',
|
||||||
|
dataIndex: 'name',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '基地负责人',
|
||||||
|
dataIndex: 'person',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '基地农作物',
|
||||||
|
dataIndex: 'crops',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '基地经度',
|
||||||
|
dataIndex: 'address_lat',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '基地纬度',
|
||||||
|
dataIndex: 'address_lng',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '基地地址',
|
||||||
|
dataIndex: 'address',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '基地面积',
|
||||||
|
dataIndex: 'areas',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '基地就业人数',
|
||||||
|
dataIndex: 'workforce',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '基地描述',
|
||||||
|
dataIndex: 'description',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
width: 180,
|
||||||
|
title: '操作',
|
||||||
|
dataIndex: 'action',
|
||||||
|
align: 'center',
|
||||||
|
fixed: undefined,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
export const searchFormSchema: FormSchema[] = []
|
||||||
|
|
||||||
|
export const accountFormSchema: FormSchema[] = [
|
||||||
|
{
|
||||||
|
field: 'id',
|
||||||
|
label: '基地ID',
|
||||||
|
required: false,
|
||||||
|
dynamicDisabled: true,
|
||||||
|
component: 'Input',
|
||||||
|
ifShow: ({ values }) => {
|
||||||
|
return !!values.id
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'name',
|
||||||
|
label: '基地名称',
|
||||||
|
required: true,
|
||||||
|
component: 'Input',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'address',
|
||||||
|
label: '基地地址',
|
||||||
|
required: true,
|
||||||
|
component: 'Input',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'person',
|
||||||
|
label: '基地负责人',
|
||||||
|
required: true,
|
||||||
|
component: 'Input',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'areas',
|
||||||
|
label: '基地面积',
|
||||||
|
required: true,
|
||||||
|
component: 'Input',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'workforce',
|
||||||
|
label: '基地人数',
|
||||||
|
required: true,
|
||||||
|
component: 'Input',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'crops_ids',
|
||||||
|
label: '基地农作物',
|
||||||
|
required: true,
|
||||||
|
component: 'ApiSelect',
|
||||||
|
componentProps: {
|
||||||
|
api: async () => {
|
||||||
|
const res = await getCrops({ type: 'all', crop_type: 1 })
|
||||||
|
return res.map((e) => {
|
||||||
|
return {
|
||||||
|
...e,
|
||||||
|
disabled: e.is_end === 1,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
labelField: 'name',
|
||||||
|
valueField: 'id',
|
||||||
|
mode: 'multiple',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
field: 'description',
|
||||||
|
label: '基地介绍',
|
||||||
|
required: false,
|
||||||
|
component: 'InputTextArea',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'address_lat',
|
||||||
|
label: '基地经度',
|
||||||
|
required: false,
|
||||||
|
component: 'Input',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'address_lng',
|
||||||
|
label: '基地纬度',
|
||||||
|
required: false,
|
||||||
|
component: 'Input',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
@ -0,0 +1,86 @@
|
||||||
|
<template>
|
||||||
|
<div class="pt-20px">
|
||||||
|
<BasicTable @register="registerTable">
|
||||||
|
<template #toolbar>
|
||||||
|
<a-button type="primary" @click="handleCreate"> 新增基地 </a-button>
|
||||||
|
</template>
|
||||||
|
<template #bodyCell="{ column, record }">
|
||||||
|
<template v-if="column.key === 'action'">
|
||||||
|
<div class="flex items-center justify-center">
|
||||||
|
<TableAction
|
||||||
|
:actions="[
|
||||||
|
{ label: '编辑', onClick: handleEdit.bind(null, record) },
|
||||||
|
{
|
||||||
|
label: '删除',
|
||||||
|
popConfirm: {
|
||||||
|
title: '是否确认删除',
|
||||||
|
placement: 'topRight',
|
||||||
|
confirm: handleDelete.bind(null, record),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template v-if="column.key === 'crops'">
|
||||||
|
<Button
|
||||||
|
class="mx-2px"
|
||||||
|
v-for="(item, index) in record['crops']"
|
||||||
|
:key="index"
|
||||||
|
type="link"
|
||||||
|
>{{ item.name }}</Button
|
||||||
|
>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</BasicTable>
|
||||||
|
<BaseDrawer @register="registerDrawer" @success="handleSuccess" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { BasicTable, useTable, TableAction } from '/@/components/Table'
|
||||||
|
import { deleteGriculturalBasic, getTownAgriculturalBasic } from '/@/api/sys/user'
|
||||||
|
import { message } from 'ant-design-vue'
|
||||||
|
import { useDrawer } from '/@/components/Drawer'
|
||||||
|
import BaseDrawer from './BaseDrawer.vue'
|
||||||
|
import { Button } from 'ant-design-vue'
|
||||||
|
import { columns, searchFormSchema } from './base.data'
|
||||||
|
const [registerDrawer, { openDrawer }] = useDrawer()
|
||||||
|
const [registerTable, { reload }] = useTable({
|
||||||
|
title: '基地列表',
|
||||||
|
api: async (e) => {
|
||||||
|
const res = await getTownAgriculturalBasic({ type: 1, ...e })
|
||||||
|
return res
|
||||||
|
},
|
||||||
|
rowKey: 'id',
|
||||||
|
columns,
|
||||||
|
formConfig: {
|
||||||
|
labelWidth: 120,
|
||||||
|
schemas: searchFormSchema,
|
||||||
|
},
|
||||||
|
useSearchForm: false,
|
||||||
|
showTableSetting: true,
|
||||||
|
bordered: true,
|
||||||
|
showIndexColumn: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
const handleSuccess = () => {
|
||||||
|
message.success('操作成功')
|
||||||
|
reload()
|
||||||
|
}
|
||||||
|
const handleCreate = () => {
|
||||||
|
openDrawer(true, {
|
||||||
|
isUpdate: false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const handleEdit = (record: Recordable) => {
|
||||||
|
openDrawer(true, {
|
||||||
|
...record,
|
||||||
|
isUpdate: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const handleDelete = async (record: Recordable) => {
|
||||||
|
await deleteGriculturalBasic(record.id)
|
||||||
|
message.success('删除成功')
|
||||||
|
reload()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,115 @@
|
||||||
|
<template>
|
||||||
|
<div class="map-wrapper">
|
||||||
|
<div id="mapcontainer"></div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { shallowRef, computed, onMounted, ref, watch, nextTick } from 'vue'
|
||||||
|
import AMapLoader from '@amap/amap-jsapi-loader'
|
||||||
|
import { cloneWith } from 'lodash'
|
||||||
|
window._AMapSecurityConfig = {
|
||||||
|
securityJsCode: 'c18396f675a1469441ec75a190c70ee7',
|
||||||
|
}
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: {
|
||||||
|
type: Object,
|
||||||
|
default() {
|
||||||
|
return {}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
const emit = defineEmits(['update:modelValue'])
|
||||||
|
const map = shallowRef(null)
|
||||||
|
// 地点
|
||||||
|
const location = computed({
|
||||||
|
get() {
|
||||||
|
return props.modelValue
|
||||||
|
},
|
||||||
|
set(val) {
|
||||||
|
emit('update:modelValue', val)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
watch(location, (val) => {
|
||||||
|
if (val.longitude && val.latitude) {
|
||||||
|
nextTick(() => {
|
||||||
|
drawMarker(val.longitude, val.latitude)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
let placeSearch, AMapObj, marker, geocoder
|
||||||
|
function initMap() {
|
||||||
|
AMapLoader.load({
|
||||||
|
key: '98a4438e9a1e86bc285783f68656f7b5', // 申请好的Web端Key,首次调用 load 时必填
|
||||||
|
version: '2.0',
|
||||||
|
}).then((AMap) => {
|
||||||
|
AMapObj = AMap
|
||||||
|
map.value = new AMap.Map('mapcontainer', {
|
||||||
|
center: [104.739928, 29.484215], //中心点坐标
|
||||||
|
zoom: 5, //级别
|
||||||
|
})
|
||||||
|
// 添加点击事件
|
||||||
|
map.value.on('click', onMapClick)
|
||||||
|
if (location?.value?.longitude) {
|
||||||
|
drawMarker(location?.value?.longitude, location?.value?.latitude)
|
||||||
|
}
|
||||||
|
AMap.plugin(
|
||||||
|
['AMap.ToolBar', 'AMap.Scale', 'AMap.Geolocation', 'AMap.PlaceSearch', 'AMap.Geocoder'],
|
||||||
|
|
||||||
|
() => {
|
||||||
|
geocoder = new AMap.Geocoder({
|
||||||
|
city: '全国',
|
||||||
|
})
|
||||||
|
},
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
onMounted(() => {
|
||||||
|
initMap()
|
||||||
|
})
|
||||||
|
|
||||||
|
// 点击地图
|
||||||
|
function onMapClick(e) {
|
||||||
|
const { lng, lat } = e.lnglat
|
||||||
|
drawMarker(lng, lat)
|
||||||
|
// 逆地理编码
|
||||||
|
geocoder.getAddress([lng, lat], (status, result) => {
|
||||||
|
if (status === 'complete' && result.info === 'OK') {
|
||||||
|
const { addressComponent, formattedAddress } = result.regeocode
|
||||||
|
let { city, province, district } = addressComponent
|
||||||
|
if (!city) {
|
||||||
|
// 直辖市
|
||||||
|
city = province
|
||||||
|
}
|
||||||
|
location.value = {
|
||||||
|
longitude: lng,
|
||||||
|
latitude: lat,
|
||||||
|
address: formattedAddress,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 绘制地点marker
|
||||||
|
function drawMarker(longitude, latitude) {
|
||||||
|
if (marker) {
|
||||||
|
marker.setMap(null)
|
||||||
|
}
|
||||||
|
marker = new AMapObj.Marker({
|
||||||
|
position: new AMapObj.LngLat(longitude, latitude),
|
||||||
|
anchor: 'bottom-center',
|
||||||
|
})
|
||||||
|
map.value.add(marker)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.map-wrapper {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: 400px;
|
||||||
|
#mapcontainer {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,55 @@
|
||||||
|
<template>
|
||||||
|
<BasicDrawer
|
||||||
|
v-bind="$attrs"
|
||||||
|
@register="registerDrawer"
|
||||||
|
showFooter
|
||||||
|
:title="getTitle"
|
||||||
|
width="500px"
|
||||||
|
@ok="handleSubmit"
|
||||||
|
>
|
||||||
|
<BasicForm @register="registerForm"> </BasicForm>
|
||||||
|
</BasicDrawer>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref, computed, unref } from 'vue'
|
||||||
|
import { BasicForm, useForm } from '/@/components/Form/index'
|
||||||
|
import { accountFormSchema } from './city.data'
|
||||||
|
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer'
|
||||||
|
import { addaGriculturalBasic, editGriculturalBasic } from '/@/api/sys/user'
|
||||||
|
const emits = defineEmits(['success', 'register'])
|
||||||
|
const isUpdate = ref(false)
|
||||||
|
const getTitle = computed(() => (!isUpdate.value ? '新增街镇' : '编辑街镇'))
|
||||||
|
const [registerForm, { resetFields, setFieldsValue, validate }] = useForm({
|
||||||
|
labelWidth: 120,
|
||||||
|
baseColProps: { span: 24 },
|
||||||
|
schemas: accountFormSchema,
|
||||||
|
showActionButtonGroup: false,
|
||||||
|
})
|
||||||
|
const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
|
||||||
|
resetFields()
|
||||||
|
setDrawerProps({ confirmLoading: false })
|
||||||
|
isUpdate.value = data?.isUpdate
|
||||||
|
if (unref(isUpdate)) {
|
||||||
|
setFieldsValue({
|
||||||
|
...data,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const handleSubmit = async () => {
|
||||||
|
try {
|
||||||
|
const values = await validate()
|
||||||
|
values.type = 2
|
||||||
|
if (values.id) {
|
||||||
|
// 修改
|
||||||
|
await editGriculturalBasic(values.id, values)
|
||||||
|
} else {
|
||||||
|
// 新增
|
||||||
|
await addaGriculturalBasic(values)
|
||||||
|
}
|
||||||
|
closeDrawer()
|
||||||
|
emits('success')
|
||||||
|
} finally {
|
||||||
|
setDrawerProps({ confirmLoading: false })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,127 @@
|
||||||
|
import { BasicColumn } from '/@/components/Table'
|
||||||
|
import { FormSchema } from '/@/components/Table'
|
||||||
|
// import { getCrops } from '/@/api/sys/user'
|
||||||
|
export const columns: BasicColumn[] = [
|
||||||
|
{
|
||||||
|
title: '街镇名称',
|
||||||
|
dataIndex: 'name',
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// title: '农作物',
|
||||||
|
// dataIndex: 'cultivated',
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// title: '街镇经度',
|
||||||
|
// dataIndex: 'address_lat',
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// title: '街镇纬度',
|
||||||
|
// dataIndex: 'address_lng',
|
||||||
|
// },
|
||||||
|
{
|
||||||
|
title: '街镇地址',
|
||||||
|
dataIndex: 'address',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '街镇面积',
|
||||||
|
dataIndex: 'areas',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '街镇就业人数',
|
||||||
|
dataIndex: 'workforce',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '街镇描述',
|
||||||
|
dataIndex: 'description',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
width: 180,
|
||||||
|
title: '操作',
|
||||||
|
dataIndex: 'action',
|
||||||
|
align: 'center',
|
||||||
|
fixed: undefined,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
export const searchFormSchema: FormSchema[] = []
|
||||||
|
|
||||||
|
export const accountFormSchema: FormSchema[] = [
|
||||||
|
{
|
||||||
|
field: 'id',
|
||||||
|
label: '街镇ID',
|
||||||
|
required: false,
|
||||||
|
dynamicDisabled: true,
|
||||||
|
component: 'Input',
|
||||||
|
ifShow: ({ values }) => {
|
||||||
|
return !!values.id
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'name',
|
||||||
|
label: '街镇名称',
|
||||||
|
required: true,
|
||||||
|
component: 'Input',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'address',
|
||||||
|
label: '街镇地址',
|
||||||
|
required: true,
|
||||||
|
component: 'Input',
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// field: 'person',
|
||||||
|
// label: '街镇负责人',
|
||||||
|
// required: true,
|
||||||
|
// component: 'Input',
|
||||||
|
// },
|
||||||
|
{
|
||||||
|
field: 'areas',
|
||||||
|
label: '街镇面积',
|
||||||
|
required: true,
|
||||||
|
component: 'Input',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'workforce',
|
||||||
|
label: '街镇人数',
|
||||||
|
required: true,
|
||||||
|
component: 'Input',
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// field: 'crops_ids',
|
||||||
|
// label: '街镇农作物',
|
||||||
|
// required: true,
|
||||||
|
// component: 'ApiSelect',
|
||||||
|
// componentProps: {
|
||||||
|
// api: async () => {
|
||||||
|
// const res = await getCrops({ type: 'all', crop_type: 2 })
|
||||||
|
// return res.map((e) => {
|
||||||
|
// return {
|
||||||
|
// ...e,
|
||||||
|
// disabled: e.is_end === 1,
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// },
|
||||||
|
// labelField: 'name',
|
||||||
|
// valueField: 'id',
|
||||||
|
// mode: 'multiple',
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// field: 'address_lat',
|
||||||
|
// label: '街镇经度',
|
||||||
|
// required: false,
|
||||||
|
// component: 'Input',
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// field: 'address_lng',
|
||||||
|
// label: '街镇纬度',
|
||||||
|
// required: false,
|
||||||
|
// component: 'Input',
|
||||||
|
// },
|
||||||
|
{
|
||||||
|
field: 'description',
|
||||||
|
label: '街镇介绍',
|
||||||
|
required: false,
|
||||||
|
component: 'InputTextArea',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="pl-10px mb-10px">
|
<div class="pl-10px mb-10px">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<SvgIcon :name="data.icon" :size="16" color="transparent" />
|
<SvgIcon name="city" :size="16" color="transparent" />
|
||||||
<div class="text-[#828fa2] text-14px ml-4px">{{ data.title }}</div>
|
<div class="text-[#828fa2] text-14px ml-4px">{{ data.name }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-6px">
|
<div class="mt-6px">
|
||||||
<span class="text-28px font-bold">{{ data.value }}</span>
|
<span class="text-28px font-bold">{{ data.value }}</span>
|
||||||
|
|
@ -12,14 +12,14 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { SvgIcon } from '/@/components/Icon/index';
|
import { SvgIcon } from '/@/components/Icon/index'
|
||||||
defineProps({
|
defineProps({
|
||||||
loading: Boolean,
|
loading: Boolean,
|
||||||
data: {
|
data: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => {},
|
default: () => {},
|
||||||
},
|
},
|
||||||
});
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped></style>
|
||||||
|
|
|
||||||
|
|
@ -1,78 +1,60 @@
|
||||||
<template>
|
<template>
|
||||||
<PageWrapper>
|
<PageWrapper>
|
||||||
<a-card title="全市数据统计">
|
<a-card title="全市数据统计">
|
||||||
<template #extra>
|
<!-- <template #extra>
|
||||||
<a-button size="small">编辑</a-button>
|
<a-button size="small">编辑</a-button>
|
||||||
</template>
|
</template> -->
|
||||||
<a-card-grid class="!md:w-1/3 !xl:w-1/7 !w-full">
|
<a-card-grid
|
||||||
<CountItem :data="{ title: '幅员面积', icon: 'city', unit: '平方公里', value: 794.41 }" />
|
class="!md:w-1/3 !xl:w-1/7 !w-full"
|
||||||
</a-card-grid>
|
v-for="(item, index) in CityDate"
|
||||||
<a-card-grid class="!md:w-1/3 !xl:w-1/7 !w-full">
|
:key="index"
|
||||||
<CountItem :data="{ title: '镇街', icon: 'city', unit: '个', value: 13 }" />
|
>
|
||||||
</a-card-grid>
|
<CountItem :data="item" />
|
||||||
<a-card-grid class="!md:w-1/3 !xl:w-1/7 !w-full">
|
|
||||||
<CountItem :data="{ title: '水产品产量', icon: 'city', unit: '万吨', value: 3.72 }" />
|
|
||||||
</a-card-grid>
|
|
||||||
<a-card-grid class="!md:w-1/3 !xl:w-1/7 !w-full">
|
|
||||||
<CountItem :data="{ title: '粮食产量', icon: 'city', unit: '万吨', value: 33.28 }" />
|
|
||||||
</a-card-grid>
|
|
||||||
<a-card-grid class="!md:w-1/3 !xl:w-1/7 !w-full">
|
|
||||||
<CountItem :data="{ title: '人口', icon: 'city', unit: '万人', value: 77.94 }" />
|
|
||||||
</a-card-grid>
|
|
||||||
<a-card-grid class="!md:w-1/3 !xl:w-1/7 !w-full">
|
|
||||||
<CountItem :data="{ title: '耕地总面积', icon: 'city', unit: '万亩', value: 59.66 }" />
|
|
||||||
</a-card-grid>
|
|
||||||
<a-card-grid class="!md:w-1/3 !xl:w-1/7 !w-full">
|
|
||||||
<CountItem :data="{ title: '生猪年出栏', icon: 'city', unit: '万头', value: 42.01 }" />
|
|
||||||
</a-card-grid>
|
</a-card-grid>
|
||||||
</a-card>
|
</a-card>
|
||||||
|
|
||||||
<a-card title="基地数据" class="!mt-4">
|
<div class="mt-20px">
|
||||||
<template #extra>
|
<BasicTable @register="registerTable">
|
||||||
<a-button size="small">新增</a-button>
|
<template #toolbar>
|
||||||
|
<!-- <a-button type="primary" @click="handleCreate"> 新增 </a-button> -->
|
||||||
</template>
|
</template>
|
||||||
<BasicTable @register="registerTable" />
|
<template #bodyCell="{ column, record }">
|
||||||
</a-card>
|
<template v-if="column.key === 'action'">
|
||||||
|
<div class="flex items-center justify-center">
|
||||||
|
<TableAction
|
||||||
|
:actions="[
|
||||||
|
{ label: '编辑', onClick: handleEdit.bind(null, record) },
|
||||||
|
// {
|
||||||
|
// label: '删除',
|
||||||
|
// popConfirm: {
|
||||||
|
// title: '是否确认删除',
|
||||||
|
// placement: 'topRight',
|
||||||
|
// confirm: handleDelete.bind(null, record),
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
]"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</BasicTable>
|
||||||
|
</div>
|
||||||
|
<DeviceDrawer @register="registerDrawer" @success="handleSuccess" />
|
||||||
</PageWrapper>
|
</PageWrapper>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { PageWrapper } from '/@/components/Page';
|
import { PageWrapper } from '/@/components/Page'
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent, onMounted, ref } from 'vue'
|
||||||
import { Card } from 'ant-design-vue';
|
import { Card } from 'ant-design-vue'
|
||||||
import CountItem from './components/CountItem.vue';
|
import CountItem from './components/CountItem.vue'
|
||||||
|
import DeviceDrawer from './DeviceDrawer.vue'
|
||||||
import { BasicTable, useTable, BasicColumn } from '/@/components/Table';
|
import { getCitydataStatistics } from '/@/api/sys/other'
|
||||||
const columns: BasicColumn[] = [
|
import { getTownAgriculturalBasic, deleteGriculturalBasic } from '/@/api/sys/user'
|
||||||
{
|
import { columns } from './city.data'
|
||||||
title: '基地名称',
|
import { BasicTable, useTable, TableAction } from '/@/components/Table'
|
||||||
dataIndex: 'roleName',
|
import { useDrawer } from '/@/components/Drawer'
|
||||||
},
|
import { message } from 'ant-design-vue'
|
||||||
{
|
|
||||||
title: '基地农作物',
|
|
||||||
dataIndex: 'roleValue',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '负责人',
|
|
||||||
dataIndex: 'orderNo',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '经度',
|
|
||||||
dataIndex: 'createTime',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '纬度',
|
|
||||||
dataIndex: 'remark1',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '基地面积',
|
|
||||||
dataIndex: 'remark2',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '就业人数',
|
|
||||||
dataIndex: 'remark3',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
[Card.name]: Card,
|
[Card.name]: Card,
|
||||||
|
|
@ -80,28 +62,58 @@
|
||||||
CountItem,
|
CountItem,
|
||||||
PageWrapper,
|
PageWrapper,
|
||||||
BasicTable,
|
BasicTable,
|
||||||
|
TableAction,
|
||||||
|
DeviceDrawer,
|
||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
|
const CityDate = ref([])
|
||||||
|
const [registerDrawer, { openDrawer }] = useDrawer()
|
||||||
const [registerTable, { reload }] = useTable({
|
const [registerTable, { reload }] = useTable({
|
||||||
// api: getRoleListByPage,
|
api: async () => {
|
||||||
|
const res = await getTownAgriculturalBasic({ type: 2 })
|
||||||
|
return res
|
||||||
|
},
|
||||||
columns,
|
columns,
|
||||||
useSearchForm: false,
|
useSearchForm: false,
|
||||||
showTableSetting: false,
|
showTableSetting: false,
|
||||||
bordered: true,
|
bordered: true,
|
||||||
showIndexColumn: false,
|
showIndexColumn: false,
|
||||||
actionColumn: {
|
})
|
||||||
width: 80,
|
const handleCreate = () => {
|
||||||
title: '操作',
|
openDrawer(true, {
|
||||||
dataIndex: 'action',
|
isUpdate: false,
|
||||||
slots: { customRender: 'action' },
|
})
|
||||||
fixed: undefined,
|
}
|
||||||
},
|
const handleEdit = (record: Recordable) => {
|
||||||
});
|
openDrawer(true, {
|
||||||
|
...record,
|
||||||
|
isUpdate: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const handleDelete = async (record: Recordable) => {
|
||||||
|
await deleteGriculturalBasic(record.id)
|
||||||
|
message.success('删除成功')
|
||||||
|
reload()
|
||||||
|
}
|
||||||
|
const handleSuccess = () => {
|
||||||
|
message.success('操作成功')
|
||||||
|
reload()
|
||||||
|
}
|
||||||
|
onMounted(async () => {
|
||||||
|
let res = await getCitydataStatistics()
|
||||||
|
CityDate.value = res
|
||||||
|
})
|
||||||
return {
|
return {
|
||||||
|
CityDate,
|
||||||
registerTable,
|
registerTable,
|
||||||
};
|
handleCreate,
|
||||||
|
handleEdit,
|
||||||
|
handleDelete,
|
||||||
|
registerDrawer,
|
||||||
|
handleSuccess,
|
||||||
|
}
|
||||||
},
|
},
|
||||||
});
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,9 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { Card } from 'ant-design-vue';
|
import { Card } from 'ant-design-vue'
|
||||||
import { Ref, ref, watch } from 'vue';
|
import { Ref, ref, watch } from 'vue'
|
||||||
import { useECharts } from '/@/hooks/web/useECharts';
|
import { useECharts } from '/@/hooks/web/useECharts'
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
loading: Boolean,
|
loading: Boolean,
|
||||||
width: {
|
width: {
|
||||||
|
|
@ -19,14 +19,14 @@
|
||||||
type: String as PropType<string>,
|
type: String as PropType<string>,
|
||||||
default: '300px',
|
default: '300px',
|
||||||
},
|
},
|
||||||
});
|
})
|
||||||
const chartRef = ref<HTMLDivElement | null>(null);
|
const chartRef = ref<HTMLDivElement | null>(null)
|
||||||
const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
|
const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>)
|
||||||
watch(
|
watch(
|
||||||
() => props.loading,
|
() => props.loading,
|
||||||
() => {
|
() => {
|
||||||
if (props.loading) {
|
if (props.loading) {
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
setOptions({
|
setOptions({
|
||||||
tooltip: {
|
tooltip: {
|
||||||
|
|
@ -71,12 +71,12 @@
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
immediate: true,
|
immediate: true,
|
||||||
},
|
},
|
||||||
);
|
)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,80 @@
|
||||||
|
<template>
|
||||||
|
<BasicDrawer
|
||||||
|
v-bind="$attrs"
|
||||||
|
@register="registerDrawer"
|
||||||
|
showFooter
|
||||||
|
:title="getTitle"
|
||||||
|
width="500px"
|
||||||
|
@ok="handleSubmit"
|
||||||
|
>
|
||||||
|
<BasicForm @register="registerForm"> </BasicForm>
|
||||||
|
</BasicDrawer>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref, computed, unref } from 'vue'
|
||||||
|
import { BasicForm, useForm } from '/@/components/Form/index'
|
||||||
|
import { accountFormSchema } from './ranking.data'
|
||||||
|
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer'
|
||||||
|
import { defaultsDeep } from 'lodash-es'
|
||||||
|
import { createDevice, getDeviceTypes, updateDevice } from '/@/api/sys/other'
|
||||||
|
const emits = defineEmits(['success', 'register'])
|
||||||
|
const isUpdate = ref(false)
|
||||||
|
const getTitle = computed(() => (!isUpdate.value ? '新增设备' : '编辑设备'))
|
||||||
|
const [registerForm, { resetFields, setFieldsValue, validate }] = useForm({
|
||||||
|
labelWidth: 120,
|
||||||
|
baseColProps: { span: 24 },
|
||||||
|
schemas: accountFormSchema,
|
||||||
|
showActionButtonGroup: false,
|
||||||
|
})
|
||||||
|
const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
|
||||||
|
resetFields()
|
||||||
|
setDrawerProps({ confirmLoading: false })
|
||||||
|
isUpdate.value = data?.isUpdate
|
||||||
|
if (unref(isUpdate)) {
|
||||||
|
const obj = Object.assign({}, { ...data, ...data?.extends })
|
||||||
|
const deviceTypes = await getDeviceTypes()
|
||||||
|
await setFieldsValue({
|
||||||
|
...obj,
|
||||||
|
agricultural_base_id: obj.base_id,
|
||||||
|
type: formatDataByObject(deviceTypes).find((e) => e.label == obj.type)?.value,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const formatDataByObject = (obj) => {
|
||||||
|
const arr: any[] = []
|
||||||
|
Object.keys(obj).forEach((e) => {
|
||||||
|
arr.push({
|
||||||
|
label: obj[e],
|
||||||
|
value: e,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
const setValue = (keys: any, value: any) => {
|
||||||
|
const object = {}
|
||||||
|
var last = keys.pop()
|
||||||
|
keys.reduce((o, k) => (o[k] = o[k] || {}), object)[last] = value
|
||||||
|
return object
|
||||||
|
}
|
||||||
|
const handleSubmit = async () => {
|
||||||
|
try {
|
||||||
|
const values = await validate()
|
||||||
|
let params = {}
|
||||||
|
for (const key in values) {
|
||||||
|
params = defaultsDeep({}, params, setValue(key.split('.'), values[key]))
|
||||||
|
}
|
||||||
|
setDrawerProps({ confirmLoading: true })
|
||||||
|
if (values.id) {
|
||||||
|
// 修改
|
||||||
|
await updateDevice(values.id, params)
|
||||||
|
} else {
|
||||||
|
// 新增
|
||||||
|
await createDevice(params)
|
||||||
|
}
|
||||||
|
closeDrawer()
|
||||||
|
emits('success')
|
||||||
|
} finally {
|
||||||
|
setDrawerProps({ confirmLoading: false })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
@ -1,160 +1,78 @@
|
||||||
<template>
|
<template>
|
||||||
<PageWrapper>
|
<div>
|
||||||
<a-card>
|
<BasicTable @register="registerTable">
|
||||||
<a-tabs :animated="false">
|
<template #toolbar>
|
||||||
<template v-for="item in achieveList" :key="item.key">
|
<a-button type="primary" @click="handleCreate"> 新增 </a-button>
|
||||||
<a-tab-pane>
|
|
||||||
<template #tab>
|
|
||||||
<span> {{ item.name }}</span>
|
|
||||||
</template>
|
</template>
|
||||||
</a-tab-pane>
|
<template #bodyCell="{ column, record }">
|
||||||
</template>
|
<template v-if="column.key === 'action'">
|
||||||
</a-tabs>
|
<div class="flex items-center justify-center">
|
||||||
<div class="flex justify-between">
|
<TableAction
|
||||||
<ADatePicker
|
:actions="[
|
||||||
mode="year"
|
{ label: '编辑', onClick: handleEdit.bind(null, record) },
|
||||||
v-model:value="yearValue"
|
{
|
||||||
format="YYYY"
|
label: '删除',
|
||||||
:open="yearShow"
|
popConfirm: {
|
||||||
@openChange="handleOpenChange"
|
title: '是否确认删除',
|
||||||
@panelChange="handlePanelChange"
|
placement: 'topRight',
|
||||||
valueFormat="YYYY"
|
confirm: handleDelete.bind(null, record),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]"
|
||||||
/>
|
/>
|
||||||
<a-button>新增</a-button>
|
|
||||||
</div>
|
</div>
|
||||||
<BasicTable class="p0 mt-4" @register="registerTable" />
|
|
||||||
</a-card>
|
|
||||||
</PageWrapper>
|
|
||||||
</template>
|
</template>
|
||||||
|
</template>
|
||||||
<script lang="ts">
|
</BasicTable>
|
||||||
import { defineComponent, ref } from 'vue'
|
<DeviceDrawer @register="registerDrawer" @success="handleSuccess" />
|
||||||
import { Tabs, Card, DatePicker, Button } from 'ant-design-vue'
|
</div>
|
||||||
import { PageWrapper } from '/@/components/Page'
|
</template>
|
||||||
import { BasicTable, useTable, BasicColumn } from '/@/components/Table'
|
<script lang="ts" setup>
|
||||||
// import { Moment } from 'moment';
|
import { BasicTable, useTable, TableAction } from '/@/components/Table'
|
||||||
export interface TabItem {
|
import { getCropYields } from '/@/api/sys/user'
|
||||||
key: string
|
import { message } from 'ant-design-vue'
|
||||||
name: string
|
import { useDrawer } from '/@/components/Drawer'
|
||||||
}
|
import DeviceDrawer from './RankingDrawer.vue'
|
||||||
const achieveList: TabItem[] = [
|
import { columns, searchFormSchema } from './ranking.data'
|
||||||
{
|
const [registerDrawer, { openDrawer }] = useDrawer()
|
||||||
key: '1',
|
|
||||||
name: '水稻',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: '2',
|
|
||||||
name: '耙耙柑',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: '3',
|
|
||||||
name: '活草鱼',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: '4',
|
|
||||||
name: '生猪',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: '5',
|
|
||||||
name: '稻虾',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: '6',
|
|
||||||
name: '乌鱼',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: '7',
|
|
||||||
name: '鲈鱼',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: '8',
|
|
||||||
name: '爱媛',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
const columns: BasicColumn[] = [
|
|
||||||
{
|
|
||||||
title: '基地',
|
|
||||||
dataIndex: 'roleName',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '时间',
|
|
||||||
dataIndex: 'roleValue',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '录入时间',
|
|
||||||
dataIndex: 'orderNo',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '录入人员',
|
|
||||||
dataIndex: 'createTime',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '总产量(斤)',
|
|
||||||
dataIndex: 'createTime2',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '种养殖面积(亩)',
|
|
||||||
dataIndex: 'createTime3',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '产值(元)',
|
|
||||||
dataIndex: 'createTime4',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
export default defineComponent({
|
|
||||||
components: {
|
|
||||||
[Tabs.name]: Tabs,
|
|
||||||
[Tabs.TabPane.name]: Tabs.TabPane,
|
|
||||||
[Card.name]: Card,
|
|
||||||
[DatePicker.name]: DatePicker,
|
|
||||||
[Button.name]: Button,
|
|
||||||
PageWrapper,
|
|
||||||
BasicTable,
|
|
||||||
},
|
|
||||||
setup() {
|
|
||||||
const yearShow = ref<boolean>(false)
|
|
||||||
const yearValue = ref()
|
|
||||||
|
|
||||||
const [registerTable, { reload }] = useTable({
|
const [registerTable, { reload }] = useTable({
|
||||||
// api: getRoleListByPage,
|
title: '产量列表',
|
||||||
|
api: async (e) => {
|
||||||
|
console.log(e)
|
||||||
|
const res = await getCropYields(e)
|
||||||
|
console.log(res)
|
||||||
|
return res.list
|
||||||
|
},
|
||||||
|
rowKey: 'id',
|
||||||
columns,
|
columns,
|
||||||
useSearchForm: false,
|
formConfig: {
|
||||||
showTableSetting: false,
|
labelWidth: 120,
|
||||||
|
schemas: searchFormSchema,
|
||||||
|
},
|
||||||
|
useSearchForm: true,
|
||||||
|
showTableSetting: true,
|
||||||
bordered: true,
|
bordered: true,
|
||||||
showIndexColumn: false,
|
showIndexColumn: true,
|
||||||
actionColumn: {
|
|
||||||
width: 80,
|
|
||||||
title: '操作',
|
|
||||||
dataIndex: 'action',
|
|
||||||
slots: { customRender: 'action' },
|
|
||||||
fixed: undefined,
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const handleOpenChange = (open: boolean) => {
|
const handleSuccess = () => {
|
||||||
yearShow.value = open
|
message.success('操作成功')
|
||||||
|
reload()
|
||||||
}
|
}
|
||||||
const handlePanelChange = (e) => {
|
const handleCreate = () => {
|
||||||
yearShow.value = false
|
openDrawer(true, {
|
||||||
yearValue.value = e
|
id: false,
|
||||||
console.log(e.format('YYYY'))
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
yearShow,
|
|
||||||
yearValue,
|
|
||||||
achieveList,
|
|
||||||
registerTable,
|
|
||||||
handleOpenChange,
|
|
||||||
handlePanelChange,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
const handleEdit = (record: Recordable) => {
|
||||||
|
openDrawer(true, {
|
||||||
|
...record,
|
||||||
|
isUpdate: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const handleDelete = async (record: Recordable) => {
|
||||||
|
// await deleteDevice(record.id)
|
||||||
|
message.success('删除成功')
|
||||||
|
reload()
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less">
|
|
||||||
.p0 {
|
|
||||||
.ant-table-wrapper {
|
|
||||||
padding: 0 !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,160 @@
|
||||||
|
<template>
|
||||||
|
<PageWrapper>
|
||||||
|
<a-card>
|
||||||
|
<a-tabs :animated="false">
|
||||||
|
<template v-for="item in achieveList" :key="item.key">
|
||||||
|
<a-tab-pane>
|
||||||
|
<template #tab>
|
||||||
|
<span> {{ item.name }}</span>
|
||||||
|
</template>
|
||||||
|
</a-tab-pane>
|
||||||
|
</template>
|
||||||
|
</a-tabs>
|
||||||
|
<div class="flex justify-between">
|
||||||
|
<ADatePicker
|
||||||
|
mode="year"
|
||||||
|
v-model:value="yearValue"
|
||||||
|
format="YYYY"
|
||||||
|
:open="yearShow"
|
||||||
|
@openChange="handleOpenChange"
|
||||||
|
@panelChange="handlePanelChange"
|
||||||
|
valueFormat="YYYY"
|
||||||
|
/>
|
||||||
|
<a-button>新增</a-button>
|
||||||
|
</div>
|
||||||
|
<BasicTable class="p0 mt-4" @register="registerTable" />
|
||||||
|
</a-card>
|
||||||
|
</PageWrapper>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent, ref } from 'vue'
|
||||||
|
import { Tabs, Card, DatePicker, Button } from 'ant-design-vue'
|
||||||
|
import { PageWrapper } from '/@/components/Page'
|
||||||
|
import { BasicTable, useTable, BasicColumn } from '/@/components/Table'
|
||||||
|
// import { Moment } from 'moment';
|
||||||
|
export interface TabItem {
|
||||||
|
key: string
|
||||||
|
name: string
|
||||||
|
}
|
||||||
|
const achieveList: TabItem[] = [
|
||||||
|
{
|
||||||
|
key: '1',
|
||||||
|
name: '水稻',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: '2',
|
||||||
|
name: '耙耙柑',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: '3',
|
||||||
|
name: '活草鱼',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: '4',
|
||||||
|
name: '生猪',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: '5',
|
||||||
|
name: '稻虾',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: '6',
|
||||||
|
name: '乌鱼',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: '7',
|
||||||
|
name: '鲈鱼',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: '8',
|
||||||
|
name: '爱媛',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
const columns: BasicColumn[] = [
|
||||||
|
{
|
||||||
|
title: '基地',
|
||||||
|
dataIndex: 'roleName',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '时间',
|
||||||
|
dataIndex: 'roleValue',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '录入时间',
|
||||||
|
dataIndex: 'orderNo',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '录入人员',
|
||||||
|
dataIndex: 'createTime',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '总产量(斤)',
|
||||||
|
dataIndex: 'createTime2',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '种养殖面积(亩)',
|
||||||
|
dataIndex: 'createTime3',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '产值(元)',
|
||||||
|
dataIndex: 'createTime4',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
export default defineComponent({
|
||||||
|
components: {
|
||||||
|
[Tabs.name]: Tabs,
|
||||||
|
[Tabs.TabPane.name]: Tabs.TabPane,
|
||||||
|
[Card.name]: Card,
|
||||||
|
[DatePicker.name]: DatePicker,
|
||||||
|
[Button.name]: Button,
|
||||||
|
PageWrapper,
|
||||||
|
BasicTable,
|
||||||
|
},
|
||||||
|
setup() {
|
||||||
|
const yearShow = ref<boolean>(false)
|
||||||
|
const yearValue = ref()
|
||||||
|
|
||||||
|
const [registerTable, { reload }] = useTable({
|
||||||
|
// api: getRoleListByPage,
|
||||||
|
columns,
|
||||||
|
useSearchForm: false,
|
||||||
|
showTableSetting: false,
|
||||||
|
bordered: true,
|
||||||
|
showIndexColumn: false,
|
||||||
|
actionColumn: {
|
||||||
|
width: 80,
|
||||||
|
title: '操作',
|
||||||
|
dataIndex: 'action',
|
||||||
|
slots: { customRender: 'action' },
|
||||||
|
fixed: undefined,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const handleOpenChange = (open: boolean) => {
|
||||||
|
yearShow.value = open
|
||||||
|
}
|
||||||
|
const handlePanelChange = (e) => {
|
||||||
|
yearShow.value = false
|
||||||
|
yearValue.value = e
|
||||||
|
console.log(e.format('YYYY'))
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
yearShow,
|
||||||
|
yearValue,
|
||||||
|
achieveList,
|
||||||
|
registerTable,
|
||||||
|
handleOpenChange,
|
||||||
|
handlePanelChange,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less">
|
||||||
|
.p0 {
|
||||||
|
.ant-table-wrapper {
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,171 @@
|
||||||
|
import { BasicColumn } from '/@/components/Table'
|
||||||
|
import { FormSchema } from '/@/components/Table'
|
||||||
|
import { getAgriculturalBasic } from '/@/api/sys/user'
|
||||||
|
import { getDeviceTypes } from '/@/api/sys/other'
|
||||||
|
import { h } from 'vue'
|
||||||
|
import { Tag } from 'ant-design-vue'
|
||||||
|
function formatDataByObject(obj): any[] {
|
||||||
|
const arr: any[] = []
|
||||||
|
Object.keys(obj).forEach((e) => {
|
||||||
|
arr.push({
|
||||||
|
label: obj[e],
|
||||||
|
value: e,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
export const columns: BasicColumn[] = [
|
||||||
|
{
|
||||||
|
title: '类型',
|
||||||
|
dataIndex: 'type',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '设备编号',
|
||||||
|
dataIndex: 'sn',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '基地',
|
||||||
|
dataIndex: 'base_name',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '监控点',
|
||||||
|
dataIndex: 'monitoring_point',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '状态',
|
||||||
|
dataIndex: 'status',
|
||||||
|
customRender: ({ record }) => {
|
||||||
|
const status = record.status
|
||||||
|
// 状态: 0 禁用, 1 在线, 2 离线, 3 故障
|
||||||
|
const list = [
|
||||||
|
{
|
||||||
|
value: 0,
|
||||||
|
color: 'red',
|
||||||
|
label: '禁用',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 1,
|
||||||
|
color: 'green',
|
||||||
|
label: '在线',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 2,
|
||||||
|
color: 'pink',
|
||||||
|
label: '离线',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 3,
|
||||||
|
color: 'orange',
|
||||||
|
label: '故障',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
const item = list.find((e) => e.value === status)
|
||||||
|
const color = item?.color ?? 'red'
|
||||||
|
const text = item?.label ?? status
|
||||||
|
return h(Tag, { color: color }, () => text)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
width: 180,
|
||||||
|
title: '操作',
|
||||||
|
dataIndex: 'action',
|
||||||
|
align: 'center',
|
||||||
|
fixed: undefined,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
export const searchFormSchema: FormSchema[] = [
|
||||||
|
{
|
||||||
|
field: 'year',
|
||||||
|
label: '年份',
|
||||||
|
component: 'ApiSelect',
|
||||||
|
componentProps: {
|
||||||
|
api: getAgriculturalBasic,
|
||||||
|
labelField: 'name',
|
||||||
|
valueField: 'id',
|
||||||
|
},
|
||||||
|
colProps: { span: 6 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'crop',
|
||||||
|
label: '农作物',
|
||||||
|
component: 'ApiSelect',
|
||||||
|
componentProps: {
|
||||||
|
api: async () => {
|
||||||
|
const res = await getDeviceTypes()
|
||||||
|
return formatDataByObject(res)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
colProps: { span: 6 },
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
export const accountFormSchema: FormSchema[] = [
|
||||||
|
{
|
||||||
|
field: 'id',
|
||||||
|
label: 'ID',
|
||||||
|
required: false,
|
||||||
|
dynamicDisabled: true,
|
||||||
|
component: 'Input',
|
||||||
|
ifShow: ({ values }) => {
|
||||||
|
return !!values.id
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'time_year',
|
||||||
|
label: '年份',
|
||||||
|
required: true,
|
||||||
|
component: 'DatePicker',
|
||||||
|
componentProps: {
|
||||||
|
mode: 'year',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'quarter',
|
||||||
|
label: '季度',
|
||||||
|
required: true,
|
||||||
|
component: 'Input',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'crop_id',
|
||||||
|
label: '农作物',
|
||||||
|
required: true,
|
||||||
|
component: 'ApiSelect',
|
||||||
|
componentProps: {
|
||||||
|
api: async () => {
|
||||||
|
const res = await getDeviceTypes()
|
||||||
|
return formatDataByObject(res)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'base_id',
|
||||||
|
label: '区域',
|
||||||
|
required: true,
|
||||||
|
component: 'ApiSelect',
|
||||||
|
componentProps: {
|
||||||
|
api: async () => {
|
||||||
|
const res = await getDeviceTypes()
|
||||||
|
return formatDataByObject(res)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'yield',
|
||||||
|
label: '产量',
|
||||||
|
required: true,
|
||||||
|
component: 'Input',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'cultivated',
|
||||||
|
label: '种养殖面积',
|
||||||
|
required: true,
|
||||||
|
component: 'Input',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'output',
|
||||||
|
label: '产值',
|
||||||
|
required: true,
|
||||||
|
component: 'Input',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
@ -2,6 +2,11 @@
|
||||||
# yarn lockfile v1
|
# yarn lockfile v1
|
||||||
|
|
||||||
|
|
||||||
|
"@amap/amap-jsapi-loader@^1.0.1":
|
||||||
|
version "1.0.1"
|
||||||
|
resolved "https://registry.npmmirror.com/@amap/amap-jsapi-loader/-/amap-jsapi-loader-1.0.1.tgz#9ec4b4d5d2467eac451f6c852e35db69e9f9f0c0"
|
||||||
|
integrity sha512-nPyLKt7Ow/ThHLkSvn2etQlUzqxmTVgK7bIgwdBRTg2HK5668oN7xVxkaiRe3YZEzGzfV2XgH5Jmu2T73ljejw==
|
||||||
|
|
||||||
"@ampproject/remapping@^2.1.0":
|
"@ampproject/remapping@^2.1.0":
|
||||||
version "2.2.0"
|
version "2.2.0"
|
||||||
resolved "https://registry.npmmirror.com/@ampproject/remapping/-/remapping-2.2.0.tgz#56c133824780de3174aed5ab6834f3026790154d"
|
resolved "https://registry.npmmirror.com/@ampproject/remapping/-/remapping-2.2.0.tgz#56c133824780de3174aed5ab6834f3026790154d"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue