feat: 项目初始化

This commit is contained in:
tianyongbao
2025-10-11 22:48:19 +08:00
parent 3a51eed514
commit 7e10c62cf9
87 changed files with 46791 additions and 36 deletions

601
src/home/updatePond.vue Normal file
View File

@@ -0,0 +1,601 @@
<template>
<view class="updatePond">
<scroll-view :scroll-y="true" :style="{ height: '100%' }">
<view class="body">
<nut-form ref="updateRef" :rules="rule" :model-value="formData">
<nut-form-item label="鱼塘名称" prop="pondName">
<nut-input
clearable
:cursor="formData.pondName.length"
input-align="right"
v-model="formData.pondName"
type="text"
:max-length="20"
placeholder="请输入鱼塘名称"
/>
</nut-form-item>
<nut-form-item label="养殖品种" prop="fishKindIds">
<view
@click="showFish = true"
:style="{
width: '100%',
minHeight: '60px',
justifyContent: ' flex-end',
}"
:class="fishListInfo ? 'c_222 view_f' : 'c_757575 view_f'"
>
<nut-ellipsis
direction="end"
:content="fishListInfo ? fishListInfo : '请选择养殖品种'"
:rows="3"
expand-text="展开"
collapse-text="收起"
:style="{ float: 'right' }"
></nut-ellipsis>
<Right color="#979797" />
</view>
</nut-form-item>
<nut-form-item label="密度" prop="density">
<nut-input
type="digit"
clearable
:cursor="String(formData.density).length"
input-align="right"
v-model="formData.density"
placeholder="请输入密度"
>
<template #right>
<text class="c_888">/</text>
</template>
</nut-input>
</nut-form-item>
<nut-form-item label="鱼塘面积" prop="area">
<nut-input
type="digit"
clearable
input-align="right"
:cursor="String(formData.area).length"
v-model="formData.area"
placeholder="请输入鱼塘面积"
>
<template #right>
<text class="c_888"></text>
</template>
</nut-input>
</nut-form-item>
<nut-form-item label="投苗日期" prop="placeTime">
<nut-input
clearable
input-align="right"
v-model="formData.placeTime"
type="text"
readonly
@click="show = true"
placeholder="请选择投苗日期"
>
<template #right>
<Right color="#979797" />
</template>
</nut-input>
</nut-form-item>
</nut-form>
<nut-config-provider :theme-vars="themeVars">
<nut-cell-group>
<nut-cell title="塘口设备" is-link @click="bandDevice">
<template #desc>
<text class="c_17B4B2">选择设备</text>
</template>
</nut-cell>
<nut-cell
v-for="item in detectorList"
:key="item.id"
:style="{
padding: 'var(--nut-cell-padding, 26rpx 32rpx) !important',
}"
>
<template #title>
<span class="font_30 c_222">{{ item.deviceName }}</span>
</template>
<template #icon>
<IconFont :name="rongjieyang" />
</template>
</nut-cell>
<nut-collapse v-for="item in controlList" :key="item.id">
<nut-collapse-item :name="item.id">
<template #title>
<view class="view_f">
<IconFont
:name="kongzhiqi"
:style="{
margin: 'var(--nut-cell-default-icon-margin, 0 8rpx 0 0rpx)',
}"
/>
<text class="font_30 c_222">{{ item.deviceName }}</text>
</view>
</template>
<nut-cell-group>
<nut-cell v-for="i in item.listSwitch" :key="i.id">
<template #title>
<span class="font_30 c_222">{{ i.switchName }}</span>
</template>
<template #icon>
<IconFont :name="kaiguan" />
</template>
</nut-cell>
</nut-cell-group>
</nut-collapse-item>
</nut-collapse>
</nut-cell-group>
</nut-config-provider>
<nut-button
block
shape="square"
type="primary"
size="large"
:style="{
fontWeight: 'bold',
fontSize: '14px !important',
borderRadius: '10px',
}"
@click="save"
:loading="isLoading"
>保存</nut-button
>
<nut-button
block
shape="square"
size="large"
color="#E22323"
plain
:style="{
fontWeight: 'bold',
fontSize: '14px !important',
borderRadius: '10px',
marginTop: '20rpx',
}"
:loading="d_isLoading"
@click="delPond"
v-if="Uid == rootuserid"
>删除塘口</nut-button
>
</view>
</scroll-view>
<!-- 日期选择器 -->
<nut-popup v-model:visible="show" position="bottom">
<nut-date-picker
v-model="val"
:min-date="min"
:max-date="max"
:three-dimensional="false"
@confirm="confirm"
@cancel="cancelDate"
></nut-date-picker>
</nut-popup>
<!-- 鱼类选择器 -->
<nut-popup v-model:visible="showFish" position="bottom" :style="{ height: '50%' }">
<Fish
@cancel="cancel"
@confirm="submit"
:fishIds="formData.fishKindIds"
:style="{ marginBottom: '20px' }"
/>
</nut-popup>
<!-- 绑定设备弹框 -->
<nut-dialog v-model:visible="bandDevShow" text-align="left" no-footer>
<view class="d_body" :style="{ paddingBottom: '0px' }">
<nut-row>
<nut-col :span="24">
<view class="d_title">选择设备</view>
</nut-col>
<nut-col :span="24">
<nut-divider class="divider" />
</nut-col>
<nut-col :span="24">
<next-tree
ref="qiantree"
:selectParent="false"
labelKey="deviceName"
valueKey="id"
:multiple="true"
:treeData="deviceList"
@confirm="onconfirm"
childrenKey="listSwitch"
border
@cancel="oncancel"
showChild
/>
</nut-col>
</nut-row>
</view>
</nut-dialog>
<!-- 弹出层提示 -->
<nut-dialog :content="msg" v-model:visible="showRes" no-footer>
<view :style="{ height: '100%' }">
<view class="d_body">
<nut-row>
<nut-col :span="24" class="d_title" :style="{ textAlign: 'center' }">
请选择鱼塘!
</nut-col>
</nut-row>
</view>
<view class="d_btn" :style="{ position: 'absolute' }">
<nut-row>
<nut-col :span="24" :style="{ border: '1px solid #eee', color: '#15BBC5' }">
<nut-button type="primary" shape="square" block @click="goHome"
>确定</nut-button
>
</nut-col>
</nut-row>
</view>
</view>
</nut-dialog>
<!-- 弹出层提示 -->
<nut-toast :msg="state.msg" v-model:visible="state.show" :type="state.type" />
</view>
</template>
<script setup lang="ts" name="UpdatePond">
import { UpdateFormType } from "./types";
import Fish from "@/components/other/fish";
import { PondUpdate, pondBaseInfo, pondDeviceInfo, PondDel } from "@/api/pond";
import { allDeviceList, bandDeviceToPond } from "@/api/device";
import { formatDate, sortByField } from "@/utils/tools";
import Taro from "@tarojs/taro";
import { IconFont, Right } from "@nutui/icons-vue-taro";
import nextTree from "@/components/tree/index";
import { stateType } from "@/utils/types";
import { imgUrl } from "@/utils/imgUrl";
definePageConfig({
navigationBarTitleText: "塘口设置",
});
const store: any = inject("store");
const kaiguan = `${imgUrl}kaiguan.png`;
const rongjieyang = `${imgUrl}rongjieyang.png`;
const kongzhiqi = `${imgUrl}kongzhiqi.png`;
// 塘口id
const instance: any = Taro.getCurrentInstance();
const id = instance.router.params.id;
const themeVars = ref({
// cellPadding: '5px 16px',
collapseItemPadding: "5px 16px",
cellBoxShadow: "0px",
collapseWrapperContentPadding: "0px 10px",
});
const formData: UpdateFormType = reactive({
id: undefined,
pondName: "",
fishKindIds: [],
area: 0,
density: 0,
placeTime: null,
});
const rule = reactive({
pondName: [{ required: true, message: "请输入鱼塘名称" }],
fishKindIds: [{ required: true, message: "请选择养殖品种", validator: kindValidator }],
});
const updateRef: any = ref(null);
const showRes = ref<boolean>(false);
const msg = ref<string>("设置成功");
/** 日期弹框相关 */
const show = ref<boolean>(false);
const min = new Date(2000, 0, 1);
const max = new Date(2100, 0, 1);
const val = ref(new Date());
const showFish = ref<boolean>(false);
const isLoading = ref<boolean>(false);
const d_isLoading = ref<boolean>(false);
const fishListInfo = ref("");
const detectorList = ref([]);
const controlList = ref([]);
const bandDevShow = ref(false);
const bandDeviceList = ref<any[]>([]);
// 设备列表
const deviceList = ref<any[]>([]);
const state: stateType = reactive({
msg: "",
type: "text",
center: true,
show: false,
});
const Uid = Taro.getStorageSync("UserId");
const rootuserid = ref(store.getRootUserId);
/** -----------------method start----------------- */
Taro.useDidShow(() => {
info();
getDeviceList();
getDevicesList();
});
// 校验
function kindValidator(val) {
if (val.length > 0) {
return Promise.resolve();
} else {
return Promise.reject("请选择养殖品种");
}
}
// 取消选择鱼类
function cancel() {
showFish.value = false;
// fishListInfo.value = "";
// formData.fishKindIds = [];
}
// 确定选择鱼类
function submit(e) {
showFish.value = false;
formData.fishKindIds = e ? e.res : [];
fishListInfo.value = e ? e.fishInfo : "";
}
// 确定日期
function confirm(e) {
const s = e.selectedValue;
formData.placeTime = s[0] + "-" + s[1] + "-" + s[2];
val.value = new Date(s[0], s[1] - 1 > 0 ? s[1] - 1 : 0, s[2]);
show.value = false;
}
// 保存
function save() {
updateRef.value?.validate().then(({ valid, errors }) => {
if (valid) {
if (formData.id) {
const data = {
id: formData.id,
pondName: formData.pondName,
fishKindIds: formData.fishKindIds,
area: formData.area,
density: formData.density,
placeTime: formData.placeTime ? formData.placeTime : null,
};
isLoading.value = true;
PondUpdate(data)
.then((res: any) => {
if (res.statusCode == 200) {
state.show = true;
state.msg = "保存成功";
}
})
.finally(() => {
isLoading.value = false;
});
}
} else {
console.warn("error:", errors);
}
});
}
// 查看鱼塘详情
function info() {
if (!id) {
// 错误提示
msg.value = "请选择鱼塘";
showRes.value = true;
return;
}
pondBaseInfo({ id }).then((res: any) => {
if (res.statusCode == 200) {
formData.id = res.data.id;
formData.pondName = res.data.pondName;
formData.fishKindIds = res.data.fishKindIds;
formData.area = res.data.area;
formData.density = res.data.density;
// 鱼类列表格式化
const fishArray: any = [];
const fishNames: any = [];
res.data.listFish.forEach((item: any) => {
fishArray.push(String(item.id));
fishNames.push(String(item.fishName));
});
formData.fishKindIds = fishArray;
fishListInfo.value = fishNames.length > 0 ? fishNames.join("") : "";
// 时间日期格式化
val.value = new Date(res.data.placeTime);
formData.placeTime = res.data.placeTime ? formatDate(val.value) : "";
}
});
}
// 返回首页
function goHome() {
Taro.switchTab({
url: "/pages/main/home",
});
}
// 弹出绑定设备列表
function bandDevice() {
if (detectorList.value.length == 0 && controlList.value.length == 0) {
state.show = true;
state.msg = "请先添加设备";
} else {
bandDevShow.value = true;
}
}
// 获取塘口下的设备列表
function getDeviceList() {
// 查询塘口下设备列表
pondDeviceInfo({ id }).then((res: any) => {
if (res.statusCode == 200) {
detectorList.value = res.data.listDetector;
controlList.value = res.data.listController;
}
});
}
// 设备列表
function getDevicesList() {
allDeviceList({ type: 1 }).then((res: any) => {
if (res.statusCode == 200) {
res.data.forEach((r: any) => {
r.open = true;
r.disabled = false;
r.checked = false;
// 判断是否在当前选中的港口id
if (r.pondInfo) {
if (id == r.pondInfo.id) {
r.checked = true;
} else {
r.disabled = true;
}
}
if (r.deviceType == 2) {
r.id = undefined;
// r.id = r.deviceName;
}
if (r.listSwitch && r.listSwitch.length > 0) {
r.listSwitch.forEach((rr) => {
rr.deviceName = rr.switchName;
rr.disabled = false;
rr.checked = false;
// 判断是否在当前选中的港口id
if (rr.pondInfo) {
if (id == rr.pondInfo.id) {
rr.checked = true;
} else {
rr.disabled = true;
}
}
});
}
});
const ids: any = [];
res.data.forEach((device, i) => {
if (device.deviceType === 2 && device.isOxygenUsed) {
ids.push(i);
}
});
if (ids.length > 0) {
ids.forEach((i) => {
let newDevice = { ...res.data[i], deviceType: 1, listSwitch: [] }; // 修改deviceType并清空listSwitch
newDevice.id = newDevice.kzId;
res.data.push(newDevice);
});
}
res.data.forEach((r) => {
r.open = true;
r.disabled = false;
r.checked = false;
// 判断是否在当前选中的港口id
if (r.pondInfo) {
if (id == r.pondInfo.id) {
r.checked = true;
} else {
r.disabled = true;
}
}
});
res.data.sort(sortByField("deviceType", true));
deviceList.value = res.data;
}
});
}
// 取消绑定设备选择
function oncancel() {
bandDevShow.value = false;
}
// 确定选择绑定的设备
function onconfirm(list) {
bandDeviceList.value = list.list;
const listDetectorId: any = [];
const listSwitchId: any = [];
list.list.forEach((res) => {
if (res.source.deviceType) {
if (res.source.id) {
listDetectorId.push(res.source.id);
}
} else {
listSwitchId.push(res.source.id);
}
});
// 确定提示框
Taro.showModal({
title: "提示",
content: "确认绑定选中的设备?",
success: function (res) {
if (res.confirm) {
const data = {
pondId: id,
listDetectorId,
listSwitchId,
};
bandDeviceToPond(data)
.then((res) => {
if (res.statusCode == 200) {
state.show = true;
state.msg = "绑定成功";
getDeviceList();
}
})
.finally(() => {
bandDevShow.value = false;
});
} else if (res.cancel) {
bandDevShow.value = false;
}
},
});
}
// 删除塘口
function delPond() {
let msg = "确认删除塘口?";
let title = "提示";
if (detectorList.value.length == 0 && controlList.value.length == 0) {
msg = "确认删除塘口?";
} else {
title = "提示!!!";
msg = "塘口存在设备,确认要删除塘口?";
}
Taro.showModal({
title: title,
content: msg,
success: function (res) {
if (res.confirm) {
d_isLoading.value = true;
PondDel({ id })
.then((res) => {
if (res.statusCode == 200) {
state.show = true;
state.msg = "删除成功";
// 返回首页
Taro.switchTab({
url: "/pages/main/home",
});
}
})
.finally(() => {
d_isLoading.value = false;
});
} else if (res.cancel) {
console.log("用户点击取消");
}
},
});
}
// 取消日期选择
function cancelDate() {
formData.placeTime = null;
show.value = false;
}
/** -----------------method end------------------- */
</script>
<style lang="scss">
.updatePond {
width: 100%;
height: 100%;
background-image: url("https://www.yuceyun.cn/wechat/bg.jpg");
background-color: #e5ebed;
background-repeat: no-repeat;
background-size: 100% 100%;
position: fixed;
margin: 0;
.body {
padding: 20px;
}
.nut-dialog {
padding: 0;
}
.nut-dialog__content {
margin: 0;
max-height: 100%;
}
}
</style>