feat:生长监控-饲养记录-投喂体验

This commit is contained in:
changxu02 2024-10-30 16:39:05 +08:00
parent c8fef96c13
commit 17083622b7
6 changed files with 414 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 444 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 353 B

View File

@ -0,0 +1,361 @@
import HeaderNation from "../components/HeaderNation";
import StatusBar from "../components/StatusBar";
import OuterFrame from "../components/OuterFrame";
import { APP_FULL_HEIGHT } from "../config";
import { View, ScrollView, Text, Picker, Image, Textarea } from "@tarojs/components";
import { useState, useEffect } from "react";
import NormalIcon from "./assets/normal.png";
import CheckedIcon from "./assets/checked.png";
import useStore from "../storage";
import Taro, { getCurrentInstance } from "@tarojs/taro";
import { getFarmDefineTree, getFodder, postCreatePlan, getBatchCode } from "../api/agricultureActivity";
import { cropGrowPage } from "../api/monitor";
// 从Date对象中获取年月日 不足两位前面补0
const getYearMonthDay = (timer) => {
const year = timer.getFullYear();
const month = (timer.getMonth() + 1) > 9 ? timer.getMonth() + 1 : '0' + (timer.getMonth() + 1);
const day = timer.getDate() > 9 ? timer.getDate() : '0' + timer.getDate();
return `${year}-${month}-${day}`;
}
export default function AgricultureActivity() {
// 获取组件的路由对象 获取传入组件的参数 重渲染不会导致navigateTo传来的参数丢失
const router = getCurrentInstance().router;
const plotId = router && router.params.plotId; // 在生长监控界面选择的地块ID
const plotList = useStore((store:any) => store.plotList); // 地块列表
// 设置当前选中的地块下标为在生长监控界面选择的地块
let curPlotIdx: number = 0;
if (plotId) {
for (let i = 0; i < plotList.length; ++i) {
if (plotList[i].plotId === plotId) {
curPlotIdx = i;
break;
}
}
}
// 地块 or 蟹塘 下标
const [curPlot, setCurPlot] = useState(curPlotIdx);
// 农事类型 or 农事阶段
const [curType, setCurType] = useState(0); // 当前农事类型下标
const [types, setTypes] = useState<any[]>([]); // 农事类型数组
// 获取农事类型 根据storage中的CREATOR的值进行筛选
const getTypes = async () => {
const res = await getFarmDefineTree({ parentId: 0, status: 1 });
if (!res || !res.data || !Array.isArray(res.data)) return;
const creator = Taro.getStorageSync("CREATOR");
const tmpList = res.data.filter(ele => ele.creator === creator);
console.log("农事类型: ", tmpList);
// 投喂饲料ID为21
let tmp = tmpList.findIndex(ele => ele.id === 21);
setCurType(tmp === -1 ? 0 : tmp);
setTypes(tmpList);
}
useEffect(() => {
getTypes();
console.log("地块列表: ", plotList);
}, []);
// 操作类型 下标和数组
const [curOperation, setCurOperation] = useState(0);
const operations = ["机械作业", "人工作业"];
// 开始时间 YYYY-MM-DD
const date = new Date();
const curDate = getYearMonthDay(date);
const [startDate, setStartDate] = useState(curDate);
// 投入品 下标和数组
const [curFodder, setCurFodder] = useState(0);
const [fodder, setFodder] = useState<any[]>([]);
const [curGrowth, setCurGrowth] = useState<any>();
// 根据生长期名称获取投入品列表
const getFodderList = async (growthPeriod?: string) => {
const res = await getFodder({ growthPeriod });
const list = res.data;
if (!list || !Array.isArray(list)) {
return [];
} else {
return list;
}
}
// 获取所有投入品
const getAllFodder = async () => {
// 获取当前地块的当前生命周期
// 目前获取当前生命周期的方式是生长期的第一个
const { data } = await cropGrowPage({ belongPlot: plotList[curPlot].plotId });
const { list } = data;
console.log("生长期: ", list);
if (!list || !Array.isArray(list)) return;
const curPeriod = list[0];
let feedList: any[] = [];
// 当前生长期有值 就查当前生长期的投入品
if (curPeriod) {
feedList = await getFodderList(curPeriod.growth);
}
// 当前生长期没值 或者 上面查出的投入品列表为空 则查询所有生长期的投入品
if (!curPeriod || feedList.length === 0) {
feedList = await getFodderList();
}
console.log("投入品: ", feedList);
setFodder(feedList);
setCurGrowth(curPeriod);
}
// 负责人
const [person, setPerson] = useState({ name: "", id: undefined });
// 批次码
const [batchCode, setBatchCode] = useState();
const getBatchCodeByPlotId = async () => {
const res = await getBatchCode({ belongPlot: plotList[curPlot].plotId });
console.log("批次码列表: ", res);
if (!res || !res.data || !Array.isArray(res.data.list) || res.data.list.length === 0) {
setBatchCode(undefined);
} else {
setBatchCode(res.data.list[0].batchCode);
}
}
// 地块切换时 重新获取投喂农资 负责人 批次码
useEffect(() => {
getAllFodder();
setPerson({ name: plotList[curPlot].contact, id: undefined });
getBatchCodeByPlotId();
}, [curPlot]);
// 备注
const [remark, setRemark] = useState("");
// 提交表单
const handleClickSubmit = async (e: any) => {
e.stopPropagation();
// 计划名称 饲料投喂-投入品名称-投入品数量(投入品单位)
let curPlanName = types[curType].defineName;
const item = fodder[curFodder];
curPlanName = curPlanName + "-" + item.name + "-" + item.standard + "(" + item.unit + ")";
// 创建表单对象 开始时间 等于 结束时间
const data = {
planName: curPlanName,
belongPark: plotList[curPlot].parkId,
parkName: curGrowth ? curGrowth.parkName : undefined,
belongPlot: plotList[curPlot].plotId,
plotName: plotList[curPlot].name,
cropId: curGrowth ? curGrowth.cropId : undefined,
cropName: curGrowth ? curGrowth.cropName : undefined,
cropType: curGrowth ? curGrowth.cropType : undefined,
planState: "0",
personId: undefined, // 目前没有联系人ID
personName: person.name,
startTime: new Date(`${startDate}T00:00:00`).getTime(),
endTime: new Date(`${startDate}T23:59:59`).getTime(),
planArea: undefined,
area: undefined,
finishArea: undefined,
farmDefineType: types[curType].id, // 饲料投喂阶段的ID
batchCode: batchCode,
planDesc: curPlanName,
remark: remark,
modeOperation: curOperation,
createTime: new Date().getTime(),
taskPublisher: Taro.getStorageSync("USER_ID")
}
try {
console.log("表单数据: ", data);
const res = await postCreatePlan(data);
console.log("添加结果: ", res);
Taro.showToast({
title: "添加成功",
icon:'success',
duration: 500,
});
let timer = setInterval(() => {
Taro.navigateBack();
clearInterval(timer);
}, 500);
} catch (e) {
console.log("提交表单出错: ", e);
}
}
return (
<OuterFrame>
<StatusBar />
<HeaderNation title="农事活动" />
<View style={{ height: APP_FULL_HEIGHT, backgroundColor: "#F5F5F5" }}>
<ScrollView
style={{ height: APP_FULL_HEIGHT - 89 }}
scrollY
type="nested"
className="text-[28px] text-[#333]"
>
<View className="bg-white rounded-[16px] w-[710px] h-[441px] ml-[20px] mt-[22px] px-[25px] flex flex-col justify-evenly">
<View className="flex justify-between pl-[28px] pr-[14px]">
<View><Text className="text-[#FF663F]">*</Text></View>
<Picker
mode="selector"
range={ plotList }
rangeKey="name"
value={ curPlot }
onChange={(event) => {
setCurPlot(Number(event.detail.value));
}}
>
<View className="text-[#666]">
{ plotList[curPlot].name }<Text className="ml-[13px] text-[#B3B3B3]">{">"}</Text>
</View>
</Picker>
</View>
<View className="w-full px-[25px] h-[1px] bg-[#E6E6E6]"></View>
<View className="flex justify-between pl-[28px] pr-[14px]">
<View><Text className="text-[#FF663F]">*</Text></View>
<Picker
mode="selector"
range={ types }
rangeKey="defineName"
value={ curType }
onChange={(event) => {
const idx = Number(event.detail.value);
// 投喂饲料才能被设置 21是投喂饲料的id
if (21 === types[idx].id) {
setCurType(idx);
}
}}
>
<View className="text-[#666]">
{ (types.length !== 0) && types[curType].defineName }
<Text className="ml-[13px] text-[#B3B3B3]">{">"}</Text>
</View>
</Picker>
</View>
<View className="w-full px-[25px] h-[1px] bg-[#E6E6E6]"></View>
<View className="flex justify-between pl-[28px] pr-[14px]">
<View></View>
<Picker
mode="selector"
range={ operations }
value={ curOperation }
onChange={(event) => {
setCurOperation(Number(event.detail.value));
}}
>
<View className="text-[#666]">
{ operations[curOperation] }<Text className="ml-[13px] text-[#B3B3B3]">{">"}</Text>
</View>
</Picker>
</View>
<View className="w-full px-[25px] h-[1px] bg-[#E6E6E6]"></View>
<View className="flex justify-between pl-[28px] pr-[14px]">
<View><Text className="text-[#FF663F]">*</Text></View>
<Picker
mode="date"
value={ startDate }
start={ curDate }
onChange={(event) => {
setStartDate(event.detail.value);
}}
>
<View className="text-[#666]">
{ startDate }<Text className="ml-[13px] text-[#B3B3B3]">{">"}</Text>
</View>
</Picker>
</View>
</View>
{
(types.length > 0 && types[curType].id === 21) && (
<View className="bg-white rounded-[16px] w-[710px] h-[422px] ml-[20px] mt-[22px]">
<View className="h-[90px] flex items-center">
<View className="ml-[34px] w-[6px] h-[22px] bg-[#5EC45F]"></View>
<View className="ml-[13px] text-[#1E1E1E]"></View>
</View>
<View className="w-full h-[1px] bg-[#E6E6E6]"></View>
<ScrollView scrollY type="nested" className="w-[660px] h-[331px] mx-[25px]">
{
fodder.length > 0 && fodder.map((item, index) => (
<>
<View
className="h-[110px] pl-[28px] pr-[14px] flex justify-between items-center"
onClick={(e) => {
e.stopPropagation();
setCurFodder(index);
}}
>
<View>{ item.name }</View>
<View className="text-[#999] flex items-center">
{
index !== curFodder && (
<>
<View className="mr-[43px]">{ item.standard }{ item.unit }</View>
<Image src={ NormalIcon } mode="aspectFit" style={{ height: 15, width: 15 }}/>
</>
)
}
{
index === curFodder && (
<>
<View className="mr-[43px] text-[#333]">{ item.standard }{ item.unit }</View>
<Image src={ CheckedIcon } mode="aspectFit" style={{ height: 15, width: 15 }}/>
</>
)
}
</View>
</View>
<View className="h-[1px] bg-[#E6E6E6]"></View>
</>
))
}
</ScrollView>
</View>
)
}
<View className="bg-white rounded-[16px] w-[710px] h-[460px] ml-[20px] mt-[22px] px-[25px]">
<View className="h-[109px] pl-[28px] pr-[13px] flex justify-between items-center">
<View><Text className="text-[#FF663F]">*</Text></View>
<View>{ person.name }</View>
</View>
<View className="w-full h-[1px] bg-[#E6E6E6]"></View>
<View className="h-[105px] pl-[28px] flex items-center">
<View></View>
</View>
<View className="h-[200px] flex justify-center items-center">
<Textarea
style={{ width: 320, height: 100 }}
className="rounded-[16px] bg-[#F7F7F7] py-[23px] px-[30px]"
value={ remark }
placeholder="请输入备注"
maxlength={ -1 }
onInput={(event) => {
setRemark(event.detail.value);
}}
/>
</View>
</View>
{/* 上面设置mb-[60px]会出现margin塌陷问题 用下面的区域代替 */}
<View className="w-full h-[60px] bg-[#F5F5F5]"></View>
</ScrollView>
<View className="w-full h-[90px] flex justify-center items-center">
<View
className="w-[600px] h-[90px] leading-[90px] text-white text-center bg-[#5EC45F] rounded-[45px]"
onClick={(e) => handleClickSubmit(e) }
>
</View>
</View>
</View>
</OuterFrame>
);
}

View File

@ -0,0 +1,37 @@
import { request } from "./index";
// 查询农事类型(农事阶段)
export const getFarmDefineTree = async (params) => {
return request({
url: 'wechat/v1/farm-record/farm-define/tree',
method: 'GET',
params
});
}
// 查询投喂饲料
export const getFodder = async (params) => {
return request({
url: 'wechat/v1/feed-strategy/get-input-products',
method: 'GET',
params
});
}
// 新增农事计划
export const postCreatePlan = async (data) => {
return request({
url: "wechat/v1/farm-record/farm-plan/create",
method: "POST",
data
});
}
// 根据地块ID查询批次码
export const getBatchCode = async (params) => {
return request({
url: "wechat/v1/farm-record/crop-base/batch-code",
method: "GET",
params
});
}

View File

@ -40,6 +40,12 @@ export default defineAppConfig({
"inviteFriends/index",
"orderDetail/index"
]
},
{
root: "agricultureActivity/",
pages: [
"index"
]
}
],
window: {

View File

@ -109,6 +109,16 @@ const FeedRecoord = ({ belongPlot }) => {
</View>
)) : <NoData />
}
<View className="flex justify-center items-center h-[90px] w-full mt-[40px]">
<View
className="w-[600px] h-[90px] rounded-[45px] bg-[#5EC45F] text-white text-[32px] leading-[90px] text-center"
onClick={() => {
Taro.navigateTo({ url: `/agricultureActivity/index?plotId=${ belongPlot }` });
}}
>
</View>
</View>
</View>
)
}