添加基础数据

wechat
ihzero 2023-09-13 05:50:39 +08:00
parent e1e4dcce03
commit a8d7b6de00
15 changed files with 1500 additions and 192 deletions

View File

@ -18,11 +18,13 @@
v-for="(item, i) in columsList"
:key="i"
>
<u-cell-item
:title="item.title"
:value="item.value"
:arrow="false"
></u-cell-item>
<slot :name="item.dataIndex" :data="item">
<u-cell-item
:title="item.title"
:value="item.value.toString()"
:arrow="false"
></u-cell-item>
</slot>
</view>
</view>
</scroll-view>

View File

@ -48,6 +48,7 @@ export default {
data() {
return {
show: false,
isFirstLoad: true,
options: [],
}
},
@ -103,7 +104,9 @@ export default {
this.$emit('options-change', this.getOptions)
},
handleConfirm(e) {
if (!e.length) return
const { value } = e[0]
if (value == null) return
this.$emit('change', value)
this.$emit('input', value)
},
@ -111,5 +114,13 @@ export default {
return typeof fn === 'function'
},
},
watch: {
params: {
handler() {
!this.isFirstLoad && this.fetch()
},
deep: true,
},
},
}
</script>

View File

@ -0,0 +1,84 @@
<template>
<view class="w-full">
<view @click="show = true">
<u-input
class="w-full !pointer-events-none"
:placeholder="placeholder"
:value="status"
type="select"
/>
</view>
<u-picker
@confirm="handleConfirm"
mode="time"
v-model="show"
:params="{ year: true }"
></u-picker>
</view>
</template>
<script>
import { omit } from 'lodash-es'
export default {
props: {
value: {
type: [Array, Object, String, Number],
},
params: {
type: Object,
default: () => ({}),
},
labelField: {
type: String,
default: 'label',
},
valueField: {
type: String,
default: 'value',
},
placeholder: {
type: String,
default: '请选择',
},
},
data() {
return {
show: false,
isFirstLoad: true,
status: '',
}
},
computed: {},
created() {
this.fetch()
},
methods: {
async fetch() {},
emitChange() {
this.$emit('options-change', this.getOptions)
},
handleConfirm(e) {
let str = ''
Object.keys(e).forEach((key) => {
str += e[key]
})
this.status = str
this.$emit('change', str)
this.$emit('input', str)
},
isFunction(fn) {
return typeof fn === 'function'
},
},
watch: {
value: {
handler(e) {
this.status = e
},
deep: true,
immediate: true,
},
},
}
</script>

View File

@ -3,6 +3,7 @@
</template>
<script>
import ApiSelect from './ApiSelect.vue'
import Select from './Select.vue'
import Calendar from './Calendar.vue'
import Input from './Input.vue'
import { upperFirst, kebabCase } from 'lodash-es'
@ -30,6 +31,7 @@ export default {
},
components: {
ApiSelect,
Select,
Calendar,
Input,
},

View File

@ -1,3 +1,107 @@
<template>
<u-dropdown-item title="se"></u-dropdown-item>
</template>
<u-dropdown-item
:title="label"
v-model="status"
@change="handleChange"
:options="getOptions"
></u-dropdown-item>
</template>
<script>
import { omit } from 'lodash-es'
export default {
props: {
options: {
type: Array,
default: () => [],
},
label: {
type: String,
default: '',
},
value: {
type: [Array, Object, String, Number],
},
params: {
type: Object,
default: () => ({}),
},
labelField: {
type: String,
default: 'label',
},
valueField: {
type: String,
default: 'value',
},
},
computed: {
status: {
get() {
return this.value
},
set(val) {
this.$emit('change', val)
this.$emit('input', val)
},
},
getOptions() {
const { labelField, valueField } = this
return this.options.reduce((prev, next) => {
if (next) {
const value = next[valueField]
prev.push({
...omit(next, [labelField, valueField]),
label: next[labelField],
value: value,
})
}
return prev
}, [])
},
},
data() {
return {
emitData: null,
isFirstLoad: true,
}
},
created() {
this.fetch()
},
methods: {
async fetch() {
const data = this.options
try {
this.isFirstLoad = false
if (Array.isArray(data)) {
this.options = data
this.emitChange()
return
}
this.emitChange()
} catch (error) {
console.warn(error)
}
},
emitChange() {
this.$emit('options-change', this.getOptions)
},
handleChange(e) {
const args = this.getOptions.filter((item) => item.value == e)
this.emitData = args
},
isFunction(fn) {
return typeof fn === 'function'
},
},
watch: {
params: {
handler() {
//
!this.isFirstLoad && this.fetch()
},
deep: true,
},
},
}
</script>

View File

@ -0,0 +1,122 @@
<template>
<view class="w-full">
<view @click="show = true">
<u-input
class="w-full !pointer-events-none"
:placeholder="placeholder"
:value="showText"
type="select"
/>
</view>
<u-select
@confirm="handleConfirm"
:default-value="defaultValue"
v-model="show"
:list="getOptions"
></u-select>
</view>
</template>
<script>
import { omit } from 'lodash-es'
export default {
props: {
options: {
type: Array,
default: () => [],
},
value: {
type: [Array, Object, String, Number],
},
params: {
type: Object,
default: () => ({}),
},
labelField: {
type: String,
default: 'label',
},
valueField: {
type: String,
default: 'value',
},
placeholder: {
type: String,
default: '请选择',
},
},
data() {
return {
show: false,
isFirstLoad: true,
}
},
computed: {
currentOption() {
const item = this.getOptions.find((e) => e.value == this.value)
return item ?? {}
},
showText() {
return this.currentOption?.label ?? this.value
},
defaultValue() {
const index = this.getOptions.findIndex((e) => e.value == this.value)
return [index > -1 ? index : 0]
},
getOptions() {
const { labelField, valueField } = this
return this.options.reduce((prev, next) => {
if (next) {
const value = next[valueField]
prev.push({
...omit(next, [labelField, valueField]),
label: next[labelField],
value: value,
})
}
return prev
}, [])
},
},
created() {
this.fetch()
},
methods: {
async fetch() {
const data = this.options
try {
this.isFirstLoad = false
if (Array.isArray(data)) {
this.options = data
this.emitChange()
return
}
this.emitChange()
} catch (error) {
console.warn(error)
}
},
emitChange() {
this.$emit('options-change', this.getOptions)
},
handleConfirm(e) {
if (!e.length) return
const { value } = e[0]
if (value == null) return
this.$emit('change', value)
this.$emit('input', value)
},
isFunction(fn) {
return typeof fn === 'function'
},
},
watch: {
params: {
handler() {
!this.isFirstLoad && this.fetch()
},
deep: true,
},
},
}
</script>

View File

@ -229,6 +229,38 @@
"enablePullDownRefresh": false,
"navigationStyle":"custom"
}
},{
"path" : "pages/crop/town-crop",
"style" :
{
"navigationBarTitleText": "城镇农作物",
"enablePullDownRefresh": false,
"navigationStyle":"custom"
}
},{
"path" : "pages/crop/basics-crop",
"style" :
{
"navigationBarTitleText": "基地农作物",
"enablePullDownRefresh": false,
"navigationStyle":"custom"
}
},{
"path" : "pages/yield/town-yield",
"style" :
{
"navigationBarTitleText": "城镇产量",
"enablePullDownRefresh": false,
"navigationStyle":"custom"
}
},{
"path" : "pages/yield/basics-yield",
"style" :
{
"navigationBarTitleText": "基地产量",
"enablePullDownRefresh": false,
"navigationStyle":"custom"
}
}
],
"globalStyle": {

View File

@ -166,9 +166,9 @@ export default {
const params = { ...this.form, type: 1 }
if (this.isEdit) {
this.onUpdate(params)
await this.onUpdate(params)
} else {
this.onCreate(params)
await this.onCreate(params)
}
this.$emit('confirm')
},
@ -206,7 +206,6 @@ export default {
watch: {
data: {
handler(val) {
console.log(val)
if (val) {
this.setDefaultForm(val)
}

View File

@ -0,0 +1,237 @@
<template>
<view>
<Appbar title="基地农作物">
<template #right>
<view class="text-white mr-20px" @click="handleCreate"></view>
</template>
</Appbar>
<u-sticky>
<view class="bg-white">
<SearchForm
:schemas="searchFormSchema"
@submit="handleSubmit"
></SearchForm>
</view>
</u-sticky>
<mescroll-body
@init="mescrollInit"
@up="upCallback"
:up="upOption"
:down="downOption"
>
<view>
<u-swipe-action
v-for="(item, i) in dataList"
:show="item.show"
:index="i"
:key="item.id"
class="my-20rpx mx-30rpx rounded-md overflow-hidden"
:options="options"
@click="handleClick"
@content-click="handleContentClick"
>
<view>
<view class="bg-white p-20rpx">
<view>名称{{ item.name }} </view>
<view class="flex">
<view class="flex-1">单位{{ item.unit }}</view>
<view class="flex-1"
>是否是结点{{ item.is_end ? '是' : '否' }}</view
>
</view>
</view>
</view>
</u-swipe-action>
</view>
</mescroll-body>
<!-- 详情 -->
<BaseTablePopup
v-model="baseShow"
:colums="baseTableColums"
:data="currentData"
@onEdit="handleEdit"
@onDel="handleDel"
>
<!-- <template #extends="{ data }">
<view
class="flex justify-between w-full px-30rpx py-20rpx"
v-for="(item, i) in data.value"
:key="i"
>
<view> 名称{{ item.name }}</view>
<view> 单位{{ item.unit }}</view>
</view>
</template> -->
</BaseTablePopup>
<!-- 编辑 -->
<cuPopup v-model="formShow" :title="currentData ? '编辑农作物' : '新增农作物'">
<BasicsEdit
@cancel="formShow = false"
@confirm="handleEditConfirm"
:data="currentData"
:crop_type="1"
></BasicsEdit>
</cuPopup>
</view>
</template>
<script>
import Appbar from '@/components/Appbar'
import SearchForm from '@/components/search-form'
import { http } from '@/api/index.js'
import MescrollMixin from '@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js'
import cuPopup from '@/components/cu-popup/index.vue'
import BaseTablePopup from '@/components/base-table/popup.vue'
import BasicsEdit from './components/basics-edit.vue'
const baseTableColums = [
{
title: '名称',
dataIndex: 'name',
},
{
title: '单位',
dataIndex: 'unit',
},
{
title: '是否是结点',
dataIndex: 'is_end',
format: (text) => {
return text == 1 ? '是' : '否'
},
},
// {
// title: '',
// dataIndex: 'extends',
// },
]
export default {
mixins: [MescrollMixin],
components: {
SearchForm,
Appbar,
cuPopup,
BaseTablePopup,
BasicsEdit,
},
data() {
return {
baseTableColums,
currentData: null,
filterParmas: {},
downOption: {
use: false,
},
upOption: {
auto: false,
page: {
size: 20,
},
},
dataList: [],
options: [
{
text: '编辑',
opt: 'edit',
style: {
backgroundColor: '#007aff',
},
},
{
text: '删除',
opt: 'delete',
style: {
backgroundColor: '#dd524d',
},
},
],
formShow: false,
baseShow: false,
searchFormSchema: [
{
field: 'name',
label: '名称',
component: 'Input',
componentProps: {
placeholder: '请输入名称',
},
},
],
}
},
methods: {
handleSubmit(e) {
this.filterParmas = e
this.mescroll.resetUpScroll()
},
upCallback({ num, size }) {
this.getData({
...this.filterParmas,
page: num,
per_page: size,
type: 'all',
crop_type: 1,
})
},
async getData(e) {
try {
const { data } = await http.get(`/api/crops`, {
params: e,
})
if (e.page == 1) this.dataList = []
const { data: list, meta } = data
this.dataList = this.dataList.concat(
list.map((e) => Object.assign({ show: false }, e))
)
this.mescroll.endByPage(list.length, meta.total)
} catch (error) {
this.mescroll.endErr()
}
},
handleClick(index1, index) {
const { opt } = this.options[index]
const item = this.dataList[index1]
this.currentData = item
if (opt == 'edit') {
this.handleEdit(item)
} else if (opt == 'delete') {
this.handleDel(item)
}
},
handleContentClick(e) {
this.currentData = this.dataList[e]
this.baseShow = true
},
handleEdit(item) {
this.currentData = item
this.formShow = true
this.baseShow = false
},
async handleDel(item) {
uni.showModal({
title: '提示',
content: '是否确定删除?',
success: async (res) => {
if (res.confirm) {
try {
await this.$http.delete(`/api/crops/${item.id}`)
this.mescroll.resetUpScroll()
this.baseShow = false
} catch ({ data }) {
this.$u.toast(data.message)
}
}
},
})
},
async handleCreate() {
this.currentData = null
this.formShow = true
this.baseShow = false
},
handleEditConfirm() {
this.mescroll.resetUpScroll()
this.formShow = false
},
},
}
</script>

View File

@ -7,59 +7,63 @@
<u-form-item label="ID" v-if="form.id">
<u-input disabled v-model="form.id"></u-input>
</u-form-item>
<u-form-item label="外部链接">
<u-switch v-model="form.is_blank"></u-switch>
</u-form-item>
<u-form-item label="外部链接" v-if="form.is_blank">
<u-input v-model="form.blank_url" placeholder="请输入"></u-input>
</u-form-item>
<u-form-item label="农业类型">
<u-form-item label="产业">
<ApiSelect
v-model="form.industry_key"
v-bind="industrySelectOption"
v-model="form.category_id"
v-bind="categorySelectOption"
></ApiSelect>
</u-form-item>
<u-form-item label="基地名称">
<u-input v-model="form.name" placeholder="请输入"></u-input>
<u-form-item label="名称">
<u-input v-model="form.name"></u-input>
</u-form-item>
<u-form-item label="排序">
<u-input v-model="form.sort" placeholder="请输入"></u-input>
</u-form-item>
<u-form-item label="基地负责人">
<u-input v-model="form.person" placeholder="请输入"></u-input>
</u-form-item>
<u-form-item label="基地面积">
<u-input v-model="form.areas" placeholder="请输入"></u-input>
</u-form-item>
<u-form-item label="种养殖面积">
<u-input v-model="form.cultivated" placeholder="请输入"></u-input>
</u-form-item>
<u-form-item label="基地人数">
<u-input v-model="form.workforce" placeholder="请输入"></u-input>
</u-form-item>
<u-form-item label="城镇">
<u-form-item label="上级">
<ApiSelect
v-model="form.parent_id"
v-bind="parentSelectOption"
@options-change="handleParentChange"
></ApiSelect>
</u-form-item>
<u-form-item label="基地农作物">
<ApiCheckbox
v-model="form.crops_ids"
v-bind="cropsSelectOption"
></ApiCheckbox>
<u-form-item label="单位">
<u-input v-model="form.unit"></u-input>
</u-form-item>
<u-form-item label="基地地址">
<u-input v-model="form.address"></u-input>
<u-form-item label="是否是结点">
<u-switch v-model="form.is_end"></u-switch>
</u-form-item>
<u-form-item label="基地介绍">
<u-input type="textarea" v-model="form.description"></u-input>
</u-form-item>
<u-form-item label="基地经度">
<u-input v-model="form.address_lng"></u-input>
</u-form-item>
<u-form-item label="基地纬度">
<u-input v-model="form.address_lat"></u-input>
<u-form-item v-if="form.is_end" label="">
<view>
<view
class="w-full flex my-10rpx"
v-for="(arr, j) in form.extends"
:key="j"
>
<view class="flex-1 mr-20rpx">
<u-input
:clearable="false"
border
v-model="arr.name"
placeholder="请输入名称"
/>
</view>
<view class="flex-1 flex items-center">
<u-input
:clearable="false"
border
v-model="arr.unit"
placeholder="请输入单位"
/>
</view>
<view v-if="j == 0" class="px-10rpx">
<u-icon @click="addDomain()" name="plus" size="34"></u-icon>
</view>
<view class="px-10rpx" v-else>
<u-icon
@click="removeDomain(j)"
name="minus"
size="34"
></u-icon>
</view>
</view>
</view>
</u-form-item>
</u-form>
</scroll-view>
@ -77,41 +81,22 @@
import { http } from '@/api/index.js'
import ApiSelect from '@/components/search-form/components/ApiSelect1.vue'
import ApiCheckbox from '@/components/search-form/components/ApiCheckbox.vue'
const industrySelectOption = {
const categorySelectOption = {
api: async (e) => {
const { data } = await http.get('/api/keywords-industry', {
const { data } = await http.get('/api/keywords-crops-cate', {
params: e,
})
return data.data
},
labelField: 'name',
valueField: 'key',
valueField: 'id',
}
const parentSelectOption = {
api: async (e) => {
const { data } = await http.get('/api/agricultural-basic', {
params: {
type: 2,
},
})
console.log(data)
return data.data
},
labelField: 'name',
valueField: 'id',
}
const cropsSelectOption = {
api: async (e) => {
const { data } = await http.get('/api/crops', {
params: { type: 'all', crop_type: 1 },
})
console.log(data)
return data.data.map((e) => {
return {
...e,
disabled: e.is_end === 0,
}
params: e,
})
return data.data.filter(({ is_end }) => is_end != 1)
},
labelField: 'name',
valueField: 'id',
@ -123,6 +108,10 @@ export default {
type: Object,
default: () => {},
},
crop_type: {
type: Number,
default: 2,
},
},
components: {
ApiSelect,
@ -132,50 +121,66 @@ export default {
isEdit() {
return !!this.data
},
parentSelectOption() {
return {
...parentSelectOption,
params: {
type: 'all',
crop_type: this.crop_type,
category: this.form.category_id,
},
}
},
},
data() {
return {
industrySelectOption,
parentSelectOption,
cropsSelectOption,
categorySelectOption,
form: {
id: '',
is_blank: false,
blank_url: '',
industry_key: '',
category_id: '',
name: '',
sort: 0,
person: '',
areas: '',
cultivated: '',
workforce: '',
parent_id: '',
crops_ids: [],
address: '',
description: '',
address_lng: '',
address_lat: '',
unit: '',
is_end: false,
extends: [
{
name: '',
unit: '',
},
],
},
}
},
methods: {
addDomain() {
this.form.extends.push({
name: '',
unit: '',
})
},
removeDomain(index) {
this.form.extends.splice(index, 1)
},
handleParentChange(e) {
// this.form.parent_id = ''
},
handleCancel() {
this.$emit('cancel')
},
async handleSubmit() {
const params = { ...this.form, type: 1 }
const params = { ...this.form, crop_type: this.crop_type }
if (this.isEdit) {
this.onUpdate(params)
await this.onUpdate(params)
} else {
this.onCreate(params)
await this.onCreate(params)
}
this.$emit('confirm')
},
async onUpdate(params) {
try {
await this.$http.put(`/api/agricultural-basic/${params.id}`, params)
await this.$http.put(`/api/crops/${params.id}`, params)
this.$u.toast('操作成功')
} catch ({ data }) {
data && this.$u.toast(data?.message)
@ -184,23 +189,28 @@ export default {
async onCreate(params) {
try {
await this.$http.post('/api/agricultural-basic', params)
await this.$http.post('/api/crops', params)
this.$u.toast('操作成功')
} catch ({ data }) {
data && this.$u.toast(data?.message)
}
},
setDefaultForm(data) {
Object.keys(data).forEach((key) => {
const value = data[key]
if (key == 'blank_url') {
this.form.is_blank = data[key] ? true : false
} else if (key == 'crops') {
this.form.crops_ids = value.map((e) => e.id)
async setDefaultForm(e) {
const { data } = await this.$http.get(`/api/crops/${e.id}`)
const { data: resData } = data
Object.keys(e).forEach((key) => {
let value = e[key]
if (key == 'is_end') value = value == 1
if (key == 'extends') {
if (value.length == 0) value = [{ name: '', unit: '' }]
}
if (this.form[key] !== undefined) this.form[key] = value
})
this.form.category_id = resData?.category?.id
this.form.parent_id = resData?.parent_id > 0 ? resData?.parent_id : null
},
},
watch: {

View File

@ -1,6 +1,6 @@
<template>
<view>
<Appbar title="基地数据">
<Appbar title="城镇农作物">
<template #right>
<view class="text-white mr-20px" @click="handleCreate"></view>
</template>
@ -32,21 +32,12 @@
>
<view>
<view class="bg-white p-20rpx">
<view>基地名称{{ item.name }} </view>
<view>农业类型{{ item.industry_label }}</view>
<view class="my-12rpx">
<u-line></u-line>
</view>
<view class="grid grid-cols-3">
<view class="text-center">基地面积</view>
<view class="text-center">种养殖面积</view>
<view class="text-center">就业人数</view>
</view>
<view class="grid grid-cols-3">
<view class="text-center">{{ item.areas }}</view>
<view class="text-center">{{ item.cultivated }}</view>
<view class="text-center">{{ item.workforce }}</view>
<view>名称{{ item.name }} </view>
<view class="flex">
<view class="flex-1">单位{{ item.unit }}</view>
<view class="flex-1"
>是否是结点{{ item.is_end ? '是' : '否' }}</view
>
</view>
</view>
</view>
@ -61,9 +52,20 @@
:data="currentData"
@onEdit="handleEdit"
@onDel="handleDel"
></BaseTablePopup>
>
<!-- <template #extends="{ data }">
<view
class="flex justify-between w-full px-30rpx py-20rpx"
v-for="(item, i) in data.value"
:key="i"
>
<view> 名称{{ item.name }}</view>
<view> 单位{{ item.unit }}</view>
</view>
</template> -->
</BaseTablePopup>
<!-- 编辑 -->
<cuPopup v-model="formShow" :title="currentData ? '编辑基地' : '新增基地'">
<cuPopup v-model="formShow" :title="currentData ? '编辑农作物' : '新增农作物'">
<BasicsEdit
@cancel="formShow = false"
@confirm="handleEditConfirm"
@ -82,63 +84,24 @@ import BaseTablePopup from '@/components/base-table/popup.vue'
import BasicsEdit from './components/basics-edit.vue'
const baseTableColums = [
{
title: '基地名称',
title: '名称',
dataIndex: 'name',
},
{
title: '农业类型',
dataIndex: 'industry_label',
title: '单位',
dataIndex: 'unit',
},
{
title: '是否外部链接',
dataIndex: 'is_blank',
title: '是否是结点',
dataIndex: 'is_end',
format: (text) => {
return text ? '是' : '否'
return text == 1 ? '是' : '否'
},
},
{
title: '排序',
dataIndex: 'sort',
},
{
title: '基地负责人',
dataIndex: 'person',
},
{
title: '基地农作物',
dataIndex: 'crops',
format: (arr) => {
return arr?.map((e) => e.name).join(',') ?? ''
},
},
{
title: '基地经度',
dataIndex: 'address_lng',
},
{
title: '基地纬度',
dataIndex: 'address_lat',
},
{
title: '基地地址',
dataIndex: 'address',
},
{
title: '基地面积',
dataIndex: 'areas',
},
{
title: '种养殖面积',
dataIndex: 'cultivated',
},
{
title: '基地就业人数',
dataIndex: 'workforce',
},
{
title: '基地描述',
dataIndex: 'description',
},
// {
// title: '',
// dataIndex: 'extends',
// },
]
export default {
mixins: [MescrollMixin],
@ -191,23 +154,6 @@ export default {
placeholder: '请输入名称',
},
},
{
field: 'type',
label: '农业类型',
component: 'ApiSelect',
componentProps: ({ formActionType }) => {
return {
api: async (e) => {
const { data } = await http.get('/api/keywords-industry', {
params: e,
})
return data.data
},
labelField: 'name',
valueField: 'id',
}
},
},
],
}
},
@ -221,12 +167,13 @@ export default {
...this.filterParmas,
page: num,
per_page: size,
type: 1,
type: 'all',
crop_type: 2,
})
},
async getData(e) {
try {
const { data } = await http.get(`/api/agricultural-basic`, {
const { data } = await http.get(`/api/crops`, {
params: e,
})
if (e.page == 1) this.dataList = []
@ -265,7 +212,7 @@ export default {
success: async (res) => {
if (res.confirm) {
try {
await this.$http.delete(`/api/agricultural-basic/${item.id}`)
await this.$http.delete(`/api/crops/${item.id}`)
this.mescroll.resetUpScroll()
this.baseShow = false
} catch ({ data }) {

View File

@ -100,9 +100,11 @@ export default {
children: [
{
label: '城镇农作物',
url: '/pages/crop/town-crop',
},
{
label: '基地农作物',
url: '/pages/crop/basics-crop',
},
],
},
@ -112,9 +114,11 @@ export default {
children: [
{
label: '城镇产量',
url: '/pages/yield/town-yield',
},
{
label: '基地产量',
url: '/pages/yield/basics-yield',
},
],
},

View File

@ -0,0 +1,281 @@
<template>
<view>
<Appbar title="基地产量">
<template #right>
<view class="text-white mr-20px" @click="handleCreate"></view>
</template>
</Appbar>
<u-sticky>
<view class="bg-white">
<SearchForm
:schemas="searchFormSchema"
@submit="handleSubmit"
></SearchForm>
</view>
</u-sticky>
<mescroll-body
@init="mescrollInit"
@up="upCallback"
:up="upOption"
:down="downOption"
>
<view>
<u-swipe-action
v-for="(item, i) in dataList"
:show="item.show"
:index="i"
:key="item.id"
class="my-20rpx mx-30rpx rounded-md overflow-hidden"
:options="options"
@click="handleClick"
@content-click="handleContentClick"
>
<view>
<view class="bg-white p-20rpx">
<view>街镇名称{{ item.base_name }} </view>
<view>农作物名称{{ item.crop_name }}</view>
<view class="my-12rpx">
<u-line></u-line>
</view>
<view class="grid grid-cols-3">
<view class="text-center">产量</view>
<view class="text-center">产值</view>
<view class="text-center">耕种面积</view>
</view>
<view class="grid grid-cols-3">
<view class="text-center">{{ item.yield }}</view>
<view class="text-center">{{ item.output }}</view>
<view class="text-center">{{ item.cultivated }}</view>
</view>
</view>
</view>
</u-swipe-action>
</view>
</mescroll-body>
<!-- 详情 -->
<BaseTablePopup
v-model="baseShow"
:colums="baseTableColums"
:data="currentData"
@onEdit="handleEdit"
@onDel="handleDel"
></BaseTablePopup>
<!-- 编辑 -->
<cuPopup v-model="formShow" :title="currentData ? '编辑产量' : '新增产量'">
<BasicsEdit
:type="1"
@cancel="formShow = false"
@confirm="handleEditConfirm"
:data="currentData"
></BasicsEdit>
</cuPopup>
</view>
</template>
<script>
import Appbar from '@/components/Appbar'
import SearchForm from '@/components/search-form'
import { http } from '@/api/index.js'
import MescrollMixin from '@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js'
import cuPopup from '@/components/cu-popup/index.vue'
import BaseTablePopup from '@/components/base-table/popup.vue'
import BasicsEdit from './components/basics-edit.vue'
const baseTableColums = [
{
title: '街镇名称',
dataIndex: 'base_name',
},
{
title: '农作物名称',
dataIndex: 'crop_name',
},
{
title: '年份',
dataIndex: 'time_year',
format: (text) => {
return text + '年'
},
},
{
title: '季度',
dataIndex: 'quarter',
format: (e) => {
const map = {
1: '第一季度',
2: '第二季度',
3: '第三季度',
4: '第四季度',
}
return map[e]
},
},
{
title: '产量',
dataIndex: 'yield',
},
{
title: '产值',
dataIndex: 'output',
},
{
title: '耕种面积',
dataIndex: 'cultivated',
},
]
export default {
mixins: [MescrollMixin],
components: {
SearchForm,
Appbar,
cuPopup,
BaseTablePopup,
BasicsEdit,
},
data() {
return {
baseTableColums,
currentData: null,
filterParmas: {},
downOption: {
use: false,
},
upOption: {
auto: false,
page: {
size: 20,
},
},
dataList: [],
options: [
{
text: '编辑',
opt: 'edit',
style: {
backgroundColor: '#007aff',
},
},
{
text: '删除',
opt: 'delete',
style: {
backgroundColor: '#dd524d',
},
},
],
formShow: false,
baseShow: false,
searchFormSchema: [
{
field: 'quarter',
label: '季度',
component: 'Select',
componentProps: {
options: [
{ label: '第一季度', value: '1' },
{ label: '第二季度', value: '2' },
{ label: '第三季度', value: '3' },
{ label: '第四季度', value: '4' },
],
},
},
{
field: 'type',
label: '农作物',
component: 'ApiSelect',
componentProps: ({ formActionType }) => {
return {
api: async (e) => {
const { data } = await http.get('/api/crops', {
params: e,
})
return data.data
},
labelField: 'name',
valueField: 'id',
params: {
type: 'all',
crop_type: 1,
},
}
},
},
],
}
},
methods: {
handleSubmit(e) {
this.filterParmas = e
this.mescroll.resetUpScroll()
},
upCallback({ num, size }) {
this.getData({
...this.filterParmas,
page: num,
per_page: size,
type: 1,
})
},
async getData(e) {
try {
const { data } = await http.get(`/api/crop-yields`, {
params: e,
})
if (e.page == 1) this.dataList = []
const { data: list, meta } = data
this.dataList = this.dataList.concat(
list.map((e) => Object.assign({ show: false }, e))
)
this.mescroll.endByPage(list.length, meta.total)
} catch (error) {
this.mescroll.endErr()
}
},
handleClick(index1, index) {
const { opt } = this.options[index]
const item = this.dataList[index1]
this.currentData = item
if (opt == 'edit') {
this.handleEdit(item)
} else if (opt == 'delete') {
this.handleDel(item)
}
},
handleContentClick(e) {
this.currentData = this.dataList[e]
this.baseShow = true
},
handleEdit(item) {
this.currentData = item
this.formShow = true
this.baseShow = false
},
async handleDel(item) {
uni.showModal({
title: '提示',
content: '是否确定删除?',
success: async (res) => {
if (res.confirm) {
try {
await this.$http.delete(`/api/crop-yields/${item.id}`)
this.mescroll.resetUpScroll()
this.baseShow = false
} catch ({ data }) {
this.$u.toast(data.message)
}
}
},
})
},
async handleCreate() {
this.currentData = null
this.formShow = true
this.baseShow = false
},
handleEditConfirm() {
this.mescroll.resetUpScroll()
this.formShow = false
},
},
}
</script>

View File

@ -0,0 +1,193 @@
<template>
<view class="p-20rpx h-full overflow-hidden flex flex-col">
<view class="flex-1 relative">
<view class="absolute top-0 left-0 w-full h-full">
<scroll-view scroll-y="true" class="h-full">
<u-form ref="uForm" :model="form" class="cu-form" label-width="200">
<u-form-item label="ID" v-if="form.id">
<u-input disabled v-model="form.id"></u-input>
</u-form-item>
<u-form-item label="农作物">
<ApiSelect
v-model="form.crop_id"
v-bind="cropSelectOption"
></ApiSelect>
</u-form-item>
<u-form-item label="区域">
<ApiSelect
v-model="form.base_id"
v-bind="baseSelectOption"
></ApiSelect>
</u-form-item>
<u-form-item label="年份">
<Picker v-model="form.time_year"></Picker>
</u-form-item>
<u-form-item label="季度">
<Select v-model="form.quarter" v-bind="quarterOption"></Select>
</u-form-item>
<u-form-item label="产量">
<u-input v-model="form.yield"></u-input>
</u-form-item>
<u-form-item label="产值">
<u-input v-model="form.output"></u-input>
</u-form-item>
<u-form-item label="耕种面积">
<u-input v-model="form.cultivated"></u-input>
</u-form-item>
</u-form>
</scroll-view>
</view>
</view>
<view class="grid grid-cols-2 gap-x-20rpx">
<u-button class="mt-20rpx" round @click="handleCancel"> </u-button>
<u-button class="mt-20rpx" type="primary" round @click="handleSubmit">
保存
</u-button>
</view>
</view>
</template>
<script>
import { http } from '@/api/index.js'
import ApiSelect from '@/components/search-form/components/ApiSelect1.vue'
import ApiCheckbox from '@/components/search-form/components/ApiCheckbox.vue'
import Select from '@/components/search-form/components/Select1.vue'
import Picker from '@/components/search-form/components/Picker.vue'
const quarterOption = {
options: [
{ label: '第一季度', value: '1' },
{ label: '第二季度', value: '2' },
{ label: '第三季度', value: '3' },
{ label: '第四季度', value: '4' },
],
}
export default {
props: {
data: {
type: Object,
default: () => {},
},
type:{
type: Number,
default: 1,
}
},
components: {
ApiSelect,
ApiCheckbox,
Select,
Picker,
},
computed: {
isEdit() {
return !!this.data
},
cropSelectOption() {
return {
api: async (e) => {
const { data } = await http.get('/api/crops', {
params: e,
})
return data.data
},
labelField: 'name',
valueField: 'id',
params: {
type: 'all',
// crop_type: this.type,
},
}
},
baseSelectOption() {
return {
api: async (e) => {
const { data } = await http.get('/api/agricultural-basic', {
params: e,
})
return data.data
},
labelField: 'name',
valueField: 'id',
params: {
// type: this.type,
page: 1,
per_page: 99999,
},
}
},
},
data() {
return {
quarterOption,
form: {
id: '',
crop_id: '',
base_id: '',
time_year: '',
quarter: '',
yield: '',
output: '',
cultivated: '',
},
}
},
methods: {
handleCancel() {
this.$emit('cancel')
},
async handleSubmit() {
const params = { ...this.form, type: 2 }
if (this.isEdit) {
await this.onUpdate(params)
} else {
await this.onCreate(params)
}
this.$emit('confirm')
},
async onUpdate(params) {
try {
await this.$http.put(`/api/crop-yields/${params.id}`, params)
this.$u.toast('操作成功')
} catch ({ data }) {
data && this.$u.toast(data?.message)
}
},
async onCreate(params) {
try {
await this.$http.post('/api/crop-yields', params)
this.$u.toast('操作成功')
} catch ({ data }) {
data && this.$u.toast(data?.message)
}
},
async setDefaultForm(e) {
if (!e.id) return
try {
const { data } = await this.$http.get(`/api/crop-yields/${e.id}`)
const { data: resData } = data
Object.keys(resData).forEach((key) => {
const value = resData[key]
if (this.form[key] !== undefined) this.form[key] = value
})
} catch (error) {}
},
},
watch: {
data: {
handler(val) {
if (val) {
this.setDefaultForm(val)
}
},
immediate: true,
deep: true,
},
},
}
</script>

View File

@ -0,0 +1,280 @@
<template>
<view>
<Appbar title="城镇产量">
<template #right>
<view class="text-white mr-20px" @click="handleCreate"></view>
</template>
</Appbar>
<u-sticky>
<view class="bg-white">
<SearchForm
:schemas="searchFormSchema"
@submit="handleSubmit"
></SearchForm>
</view>
</u-sticky>
<mescroll-body
@init="mescrollInit"
@up="upCallback"
:up="upOption"
:down="downOption"
>
<view>
<u-swipe-action
v-for="(item, i) in dataList"
:show="item.show"
:index="i"
:key="item.id"
class="my-20rpx mx-30rpx rounded-md overflow-hidden"
:options="options"
@click="handleClick"
@content-click="handleContentClick"
>
<view>
<view class="bg-white p-20rpx">
<view>街镇名称{{ item.base_name }} </view>
<view>农作物名称{{ item.crop_name }}</view>
<view class="my-12rpx">
<u-line></u-line>
</view>
<view class="grid grid-cols-3">
<view class="text-center">产量</view>
<view class="text-center">产值</view>
<view class="text-center">耕种面积</view>
</view>
<view class="grid grid-cols-3">
<view class="text-center">{{ item.yield }}</view>
<view class="text-center">{{ item.output }}</view>
<view class="text-center">{{ item.cultivated }}</view>
</view>
</view>
</view>
</u-swipe-action>
</view>
</mescroll-body>
<!-- 详情 -->
<BaseTablePopup
v-model="baseShow"
:colums="baseTableColums"
:data="currentData"
@onEdit="handleEdit"
@onDel="handleDel"
></BaseTablePopup>
<!-- 编辑 -->
<cuPopup v-model="formShow" :title="currentData ? '编辑产量' : '新增产量'">
<BasicsEdit
@cancel="formShow = false"
@confirm="handleEditConfirm"
:data="currentData"
></BasicsEdit>
</cuPopup>
</view>
</template>
<script>
import Appbar from '@/components/Appbar'
import SearchForm from '@/components/search-form'
import { http } from '@/api/index.js'
import MescrollMixin from '@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js'
import cuPopup from '@/components/cu-popup/index.vue'
import BaseTablePopup from '@/components/base-table/popup.vue'
import BasicsEdit from './components/basics-edit.vue'
const baseTableColums = [
{
title: '街镇名称',
dataIndex: 'base_name',
},
{
title: '农作物名称',
dataIndex: 'crop_name',
},
{
title: '年份',
dataIndex: 'time_year',
format: (text) => {
return text + '年'
},
},
{
title: '季度',
dataIndex: 'quarter',
format: (e) => {
const map = {
1: '第一季度',
2: '第二季度',
3: '第三季度',
4: '第四季度',
}
return map[e]
},
},
{
title: '产量',
dataIndex: 'yield',
},
{
title: '产值',
dataIndex: 'output',
},
{
title: '耕种面积',
dataIndex: 'cultivated',
},
]
export default {
mixins: [MescrollMixin],
components: {
SearchForm,
Appbar,
cuPopup,
BaseTablePopup,
BasicsEdit,
},
data() {
return {
baseTableColums,
currentData: null,
filterParmas: {},
downOption: {
use: false,
},
upOption: {
auto: false,
page: {
size: 20,
},
},
dataList: [],
options: [
{
text: '编辑',
opt: 'edit',
style: {
backgroundColor: '#007aff',
},
},
{
text: '删除',
opt: 'delete',
style: {
backgroundColor: '#dd524d',
},
},
],
formShow: false,
baseShow: false,
searchFormSchema: [
{
field: 'quarter',
label: '季度',
component: 'Select',
componentProps: {
options: [
{ label: '第一季度', value: '1' },
{ label: '第二季度', value: '2' },
{ label: '第三季度', value: '3' },
{ label: '第四季度', value: '4' },
],
},
},
{
field: 'type',
label: '农作物',
component: 'ApiSelect',
componentProps: ({ formActionType }) => {
return {
api: async (e) => {
const { data } = await http.get('/api/crops', {
params: e,
})
return data.data
},
labelField: 'name',
valueField: 'id',
params: {
type: 'all',
crop_type: 2,
},
}
},
},
],
}
},
methods: {
handleSubmit(e) {
this.filterParmas = e
this.mescroll.resetUpScroll()
},
upCallback({ num, size }) {
this.getData({
...this.filterParmas,
page: num,
per_page: size,
type: 2,
})
},
async getData(e) {
try {
const { data } = await http.get(`/api/crop-yields`, {
params: e,
})
if (e.page == 1) this.dataList = []
const { data: list, meta } = data
this.dataList = this.dataList.concat(
list.map((e) => Object.assign({ show: false }, e))
)
this.mescroll.endByPage(list.length, meta.total)
} catch (error) {
this.mescroll.endErr()
}
},
handleClick(index1, index) {
const { opt } = this.options[index]
const item = this.dataList[index1]
this.currentData = item
if (opt == 'edit') {
this.handleEdit(item)
} else if (opt == 'delete') {
this.handleDel(item)
}
},
handleContentClick(e) {
this.currentData = this.dataList[e]
this.baseShow = true
},
handleEdit(item) {
this.currentData = item
this.formShow = true
this.baseShow = false
},
async handleDel(item) {
uni.showModal({
title: '提示',
content: '是否确定删除?',
success: async (res) => {
if (res.confirm) {
try {
await this.$http.delete(`/api/crop-yields/${item.id}`)
this.mescroll.resetUpScroll()
this.baseShow = false
} catch ({ data }) {
this.$u.toast(data.message)
}
}
},
})
},
async handleCreate() {
this.currentData = null
this.formShow = true
this.baseShow = false
},
handleEditConfirm() {
this.mescroll.resetUpScroll()
this.formShow = false
},
},
}
</script>