提交 394deec8 作者: 宇宙超人

样式修改

上级 9d7d2c68
...@@ -2,8 +2,8 @@ import { otherHttp } from '/@/utils/http/axios' ...@@ -2,8 +2,8 @@ import { otherHttp } from '/@/utils/http/axios'
enum Api { enum Api {
zoneList = '/online/cgform/api/getData/01fd687ecb164aea914e92047e144d66', // 功能菜单数据 zoneList = '/online/cgform/api/getData/01fd687ecb164aea914e92047e144d66', // 功能菜单数据
farmsList = '/farms/list', // 农场列表 farmsList = '/farm/list', // 农场列表
farmsAdd = '/farms/add', // 添加农场 farmsAdd = '/farm/add', // 添加农场
agricultureModelsList = '/online/cgform/api/getData/7b2983df6ddf416aba68db8b0ab234ab', // 农业模型数据 agricultureModelsList = '/online/cgform/api/getData/7b2983df6ddf416aba68db8b0ab234ab', // 农业模型数据
baseManagementList = '/online/cgform/api/getData/e4e4e6c901254b60b1e7a005097999ec', // 基地管理数据 baseManagementList = '/online/cgform/api/getData/e4e4e6c901254b60b1e7a005097999ec', // 基地管理数据
commonToolsList = '/online/cgform/api/getData/3a7fbb877f304b7d83935caa454859c4', // 常用工具数据 commonToolsList = '/online/cgform/api/getData/3a7fbb877f304b7d83935caa454859c4', // 常用工具数据
...@@ -109,7 +109,7 @@ export function getFarmbaseList(params: any = {}) { ...@@ -109,7 +109,7 @@ export function getFarmbaseList(params: any = {}) {
} }
export function AllFarms(params = {}) { export function AllFarms(params = {}) {
return otherHttp.get({ return otherHttp.get({
url: '/farms/getAllFarms', url: '/farm/getAllFarms',
params, params,
}) })
} }
...@@ -156,7 +156,27 @@ export function farmsAdd(params = {}) { ...@@ -156,7 +156,27 @@ export function farmsAdd(params = {}) {
params, params,
}) })
} }
/**
* @param params
* @description: 编辑农场
* @returns
*/
export function farmsEdit(params = {}) {
return otherHttp.post({
url: '/farm/edit',
params,
})
}
/**
* @param params 请求参数
* @description: id查询农场
*/
export function farmsGet(params = {}) {
return otherHttp.get({
url: '/farm/queryById',
params,
})
}
/** /**
* @param params 请求参数 * @param params 请求参数
* @description: 农业模型数据 * @description: 农业模型数据
......
...@@ -592,25 +592,10 @@ ...@@ -592,25 +592,10 @@
{ {
"path": "pages/nongchang/detail/index", "path": "pages/nongchang/detail/index",
"style": { "style": {
"navigationBarTitleText": "农场", "navigationStyle": "custom",
"enablePullDownRefresh": false, "backgroundColorTop": "#5DB66F",
"navigationBarBackgroundColor": "#5DB66F",
"navigationBarTextStyle": "white",
"backgroundColorBottom": "#F2F2F2", "backgroundColorBottom": "#F2F2F2",
"app-plus": { "enablePullDownRefresh": false
"titleNView": {
"titleAlign": "left",
"buttons": [
{
"text": "+ 添加基地",
"fontSrc": "/static/uni.ttf",
"color": "#fff",
"fontSize": "26rpx",
"width": "auto"
}
]
}
}
} }
}, },
// === AI 聊天助手 === // === AI 聊天助手 ===
......
<script setup lang="ts"> <script setup lang="ts">
import { reactive, ref } from 'vue' import { reactive, toRefs } from 'vue'
import { onLoad } from '@dcloudio/uni-app' import { onShow } from '@dcloudio/uni-app'
import { areaTree } from '@/utils/areaData' import { useUserStore } from '@/store/modules/user'
import { useUserStore } from '@/store/modules/user' import { useGlobSetting } from '/@/hooks/setting'
import { useGlobSetting } from '/@/hooks/setting' import * as NongchangAPI from '@/api/model/nongchang'
import { useDictStore } from '@/store/modules/dict' import { areaTree } from '@/utils/areaData'
import * as NongchangAPI from '@/api/model/nongchang' import { useDictStore } from '@/store/modules/dict'
import { useFarmStore } from '@/store/modules/farm' import { useFarmStore } from '@/store/modules/farm'
const dictStore = useDictStore()
const userStore = useUserStore()
const globSetting = useGlobSetting()
const farmStore = useFarmStore()
onLoad((pageOptions) => {
// 页面加载时的初始化操作
const farmInfo = farmStore.getFarm
if (farmInfo) {
pageData.form.farmId = farmInfo.id
}
pageData.form.farmId = pageOptions.farmId
})
const dictStore = useDictStore() onShow(() => {
// 表单引用 // 数据字典赋值
const formRef = ref() initDict()
const loading = ref(false) pageData.form.userId = userStore.getUserInfo.id
const show = reactive({ })
address: false,
farmType: false, const pageData = reactive({
}) loading: false,
const options = reactive({ show: {
address: areaTree, growCrops: false,
farmType: [], },
}) options: {
// 表单数据 address: [],
const formData = reactive({ mainProducts: [],
growCrops: [],
},
form: {
id: '',
userId: '',
farmId: '', farmId: '',
baseName: '', baseName: '',
baseType: '',
baseTypeText: '',
scale: '', scale: '',
provinceName: '',
cityName: '',
districtName: '',
detailedAddress: '',
province: '',
managerName: '', managerName: '',
contactPhone: '', contactPhone: '',
idCard: '', growCrops: '',
plantedCrops: '', growCropsText: '',
operationYears: '',
baseImages: [],
identityProveUrl: [], // 身份证明(身份证/营业执照图片)
landProveUrl: [], // 土地证明(土地证/国有土地使用证)
productionProveUrl: [], // 生产证明(生产许可证/种养许可证)
qualityCertificateUrl: [], // 质量证明(质量认证证书)
otherMaterialUrl: [], // 其他证明(其他证明)
})
// 表单验证规则
const rules = {
baseName: [
{ required: true, message: '请输入基地名称', trigger: 'blur' },
{ min: 2, max: 50, message: '基地名称长度在2-50个字符之间', trigger: 'blur' },
],
baseType: [{ required: true, message: '请选择基地类型', trigger: 'change' }],
scale: [
{
validator: (rule: any, value: any, callback: any) => {
if (!value || value === '') {
callback(new Error('请输入规模'))
} else if (!/^[1-9]\d*$/.test(value.toString())) {
callback(new Error('规模必须为正整数'))
} else {
callback()
}
}, },
trigger: ['blur', 'change'], rules: [
{
name: 'baseName',
rule: ['required'],
msg: ['请输入基地名称'],
}, },
],
province: [
{ {
required: true, name: 'scale',
message: '请获取地址信息', rule: ['required'],
trigger: 'change', msg: ['请输入面积'],
// validator: () => formData.provinceName && formData.cityName && formData.districtName
}, },
],
detailedAddress: [
{ required: true, message: '请输入详细地址', trigger: 'blur' },
{ min: 5, max: 200, message: '详细地址长度在5-200个字符之间', trigger: 'blur' },
],
managerName: [
{ required: true, message: '请输入负责人姓名', trigger: 'blur' },
{ pattern: /^[\u4E00-\u9FA5]{2,10}$/, message: '姓名必须为2-10个汉字', trigger: 'blur' },
],
contactPhone: [
{ required: true, message: '请输入联系电话', trigger: 'blur' },
{ pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号码', trigger: 'blur' },
],
idCard: [
{ required: true, message: '请输入身份证号', trigger: 'blur' },
{ {
pattern: /^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/, name: 'managerName',
message: '请输入正确的身份证号码', rule: ['required'],
trigger: 'blur', msg: ['请输入负责人'],
}, },
],
plantedCrops: [
{ required: true, message: '请输入种植作物', trigger: 'blur' },
{ min: 2, max: 100, message: '种植作物长度在2-100个字符之间', trigger: 'blur' },
],
operationYears: [
{ {
validator: (rule: any, value: any, callback: any) => { name: 'contactPhone',
if (value && !/^[1-9]\d*$/.test(value.toString())) { rule: ['required'],
callback(new Error('经营年限必须为正整数')) msg: ['请输入联系电话'],
} else {
callback()
}
}, },
message: '经营年限必须为正整数', {
trigger: ['blur', 'change'], name: 'growCrops',
rule: ['required'],
msg: ['请选择种植作物'],
}, },
], ],
identityProveUrl: [{ required: true, message: '请上传身份证明', trigger: 'change', type: 'array' }], })
landProveUrl: [{ required: true, message: '请上传场地证明', trigger: 'change', type: 'array' }],
productionProveUrl: [{ required: true, message: '请上传生产证明', trigger: 'change', type: 'array' }],
}
function handleChangeFarmType(e) {
formData.baseType = e.value
formData.baseTypeText = e.text
show.farmType = false
}
function handleChangeAddress(e) {
formData.province = e.result
formData.provinceName = e.text[0]
formData.cityName = e.text[1]
formData.districtName = e.text[2]
show.address = false
}
const userStore = useUserStore()
const globSetting = useGlobSetting()
const toastRef = ref()
// 文件上传
function afterRead(event, key) {
// 获取上传的文件列表
const files = event.file
// 如果没有文件,直接返回
if (!files || files.length === 0) {
return
}
// 记录成功上传的数量
let successCount = 0
const totalCount = files.length
// 遍历所有文件进行上传
files.forEach((file) => {
uni.uploadFile({
url: `${globSetting.apiUrl + globSetting.urlPrefix}/sys/common/upload`, // 直接使用上传接口URL
filePath: file.url,
name: 'file',
formData: {
biz: 'temp',
},
header: {
'X-Access-Token': userStore.getToken,
},
success: (res) => {
if (res.statusCode === 200) {
const data = JSON.parse(res.data)
if (data.code === 200 || data.code === 0) {
successCount++
formData[key].push(data.message)
// 所有文件上传完成
if (successCount === totalCount) {
toastRef.value.show({
type: 'success',
text: `成功上传${successCount}张图片`,
})
}
}
}
},
fail: () => {
toastRef.value.show({
type: 'error',
text: '部分图片上传失败',
})
},
})
})
}
// 删除图片
function deletePic(event: any, key) {
formData[key].splice(event.index, 1)
}
// 提交表单
async function submitForm() {
try {
// 先进行表单验证
const valid = await formRef.value.validate()
if (!valid) {
return
}
loading.value = true
// 准备提交数据
const submitData = { ...formData }
// 将数组字段转换为逗号分隔的字符串 function initDict() {
const arrayFields = [ pageData.options.address = areaTree
'baseImages', pageData.options.growCrops = dictStore.getDictList.crops_type.map((item) => {
'identityProveUrl',
'landProveUrl',
'productionProveUrl',
'qualityCertificateUrl',
'otherMaterialUrl',
]
arrayFields.forEach((field) => {
if (Array.isArray(submitData[field])) {
submitData[field] = submitData[field].filter((item) => item?.trim()).join(',')
}
})
// 根据是否有ID决定调用编辑还是新增接口
const apiCall = submitData.id ? NongchangAPI.editFarmbase : NongchangAPI.addFarmbase
try {
await apiCall(submitData)
uni.showToast({
title: '提交成功',
icon: 'success',
duration: 1500,
})
// 延迟返回上一页
setTimeout(() => {
uni.navigateBack()
}, 1500)
} catch (error) {
console.error('API调用失败:', error)
uni.showToast({
title: error.message || '提交失败,请重试',
icon: 'none',
duration: 2000,
})
} finally {
loading.value = false
}
} catch (error) {
console.log('表单验证失败:', error)
loading.value = false
uni.showToast({
title: '请完善表单信息',
icon: 'none',
duration: 2000,
})
}
}
const farmStore = useFarmStore()
onLoad((pageOptions) => {
// 页面加载时的初始化操作
const farmInfo = farmStore.getFarm
if (farmInfo) {
formData.farmId = farmInfo.id
}
formData.farmId = pageOptions.farmId
console.log('pageOptions', pageOptions)
// 修复:修改页面上定义的 options 对象中的 farmType
options.farmType = dictStore.getDictList.farm_type.map((item) => {
return { return {
value: item.value, value: item.value,
text: item.text, text: item.text,
} }
}) })
if (pageOptions.id) { }
NongchangAPI.getFarmbaseInfoById({ id: pageOptions.id }).then((res) => { function handleChangeGrowCrops(e) {
if (res) { pageData.form.growCrops = e.value
// 将 res 中的数据赋值到 formData 中,key 保持一致 pageData.form.growCropsText = e.text
Object.keys(res).forEach((key) => { pageData.show.growCrops = false
if (key in formData) { }
// 如果是数组类型的字段且返回的是字符串,需要转换为数组 const toastRef = ref()
if (
[ const formRef = ref()
'baseImages', function submit() {
'identityProveUrl', formRef.value.validator(pageData.form, pageData.rules, true).then((res) => {
'landProveUrl', if (res.isPassed) {
'productionProveUrl', pageData.loading = true
'qualityCertificateUrl', // 根据是否有ID决定调用编辑还是新增接口
'otherMaterialUrl', const apiCall = pageData.form.id ? NongchangAPI.editFarmbase : NongchangAPI.addFarmbase
].includes(key) && apiCall(pageData.form)
typeof res[key] === 'string' .then(() => {
) { toastRef.value.show({
formData[key] = res[key].split(',').filter((item) => item.trim() !== '') type: 'success',
} else { text: '添加基地成功',
formData[key] = res[key]
}
}
}) })
formData.id = res.id
formData.province = res.provinceName + res.cityName + res.districtName
// 根据 res.baseType 的值从 options.farmType 中查找对应的文本
if (res.baseType && options.farmType.length > 0) {
const foundItem = options.farmType.find((item: any) => item.value === res.baseType)
if (foundItem) {
formData.baseTypeText = foundItem.text
}
}
// 数据赋值完成后,延迟触发表单验证更新
setTimeout(() => { setTimeout(() => {
if (formRef.value) { uni.navigateBack()
// 逐个验证可能存在问题的字段 }, 800)
formRef.value.validateField('scale') // uni.switchTab({
formRef.value.validateField('operationYears') // url: '/pages/mine/index',
// 重新验证整个表单 // })
formRef.value.validate() })
} .finally(() => {
}, 200) pageData.loading = false
}
}) })
} }
}) })
}
</script> </script>
<template> <template>
<view class="container"> <view class="page">
<u-form :model="formData" :rules="rules" ref="formRef" label-width="160rpx"> <view class="page-container">
<!-- 基地基本信息 --> <fui-form ref="formRef">
<view class="section-title">基地基本信息</view> <!-- 第一组表单 -->
<view class="form-card">
<u-form-item label="基地名称" prop="baseName" required> <fui-input
<u-input v-model="formData.baseName" placeholder="请输入基地名称" border="bottom" /> required
</u-form-item> label="基地名称"
labelSize="28"
<u-form-item label="基地类型" prop="baseType" required class="clickable" @click="show.farmType = true"> size="28"
<view class="address-display"> :labelWeight="400"
<text :class="{ 'placeholder-text': !formData.baseTypeText }"> labelWidth="auto"
{{ formData.baseTypeText || '请选择基地类型' }} placeholder="请输入基地名称"
v-model="pageData.form.baseName"
/>
<fui-input
required
number
label="面积"
labelSize="28"
size="28"
:labelWeight="400"
labelWidth="auto"
placeholder="请输入基地面积"
v-model="pageData.form.scale"
>
<view class="fontsize_28"></view>
</fui-input>
<fui-input
required
labelSize="28"
size="28"
:labelWeight="400"
labelWidth="auto"
label="负责人"
placeholder="请输入联系人名称"
v-model="pageData.form.managerName"
/>
<fui-input
required
type="number"
labelSize="28"
size="28"
:labelWeight="400"
labelWidth="auto"
label="负责人电话"
placeholder="请输入负责人电话"
v-model="pageData.form.contactPhone"
/>
<fui-form-item
required
asterisk
label="种植作物"
labelSize="28"
:labelWeight="400"
labelWidth="auto"
>
<view class="time-input" @click="pageData.show.growCrops = true">
<text class="select-text" :class="{ placeholder: !pageData.form.growCropsText }">
{{ pageData.form.growCropsText || '请选择种植作物' }}
</text> </text>
</view> </view>
</u-form-item> </fui-form-item>
<u-form-item label="规模" prop="scale" required>
<u-input v-model="formData.scale" placeholder="请输入规模(亩)" border="bottom" type="number">
<template #suffix>
<text class="suffix-text"></text>
</template>
</u-input>
</u-form-item>
<!-- 地址信息 -->
<view class="section-title">地址信息</view>
<u-form-item label="省市区" prop="province" required class="clickable" @click="show.address = true">
<view class="address-display">
<text :class="{ 'placeholder-text': !formData.province }">
{{ formData.province || '请选择省市区' }}
</text>
</view> </view>
</u-form-item>
<u-form-item label="详细地址" prop="detailedAddress" required>
<u-input v-model="formData.detailedAddress" placeholder="请输入详细地址" border="bottom" />
</u-form-item>
<!-- 负责人信息 --> <view class="submit-btn-box">
<view class="section-title">负责人信息</view> <fui-button text="添加农场" bold radius="96rpx" @click="submit" />
<u-form-item label="负责人姓名" prop="managerName" required>
<u-input v-model="formData.managerName" placeholder="请输入负责人姓名" border="bottom" />
</u-form-item>
<u-form-item label="联系电话" prop="contactPhone" required>
<u-input v-model="formData.contactPhone" placeholder="请输入联系电话" border="bottom" type="number" />
</u-form-item>
<u-form-item label="身份证号" prop="idCard" required>
<u-input v-model="formData.idCard" placeholder="请输入身份证号" border="bottom" />
</u-form-item>
<!-- 经营信息 -->
<view class="section-title">经营信息</view>
<u-form-item label="种植作物" prop="plantedCrops" required>
<u-input v-model="formData.plantedCrops" placeholder="请输入种植作物,多个用逗号分隔" border="bottom" />
</u-form-item>
<u-form-item label="经营年限" prop="operationYears" required>
<u-input v-model="formData.operationYears" placeholder="请输入经营年限" border="bottom" type="number">
<template #suffix>
<text class="suffix-text"></text>
</template>
</u-input>
</u-form-item>
<!-- 基地图片 -->
<view class="section-title">认证材料</view>
<u-form-item label="基地图片" prop="baseImages">
<u-upload
:fileList="formData.baseImages"
@after-read="(e) => afterRead(e, 'baseImages')"
@delete="(e) => deletePic(e, 'baseImages')"
name="1"
multiple
:maxCount="5"
:previewFullImage="true"
/>
</u-form-item>
<u-form-item label="身份证明" prop="identityProveUrl" required>
<div>
<u-upload
:fileList="formData.identityProveUrl"
@after-read="(e) => afterRead(e, 'identityProveUrl')"
@delete="(e) => deletePic(e, 'identityProveUrl')"
name="identityProveUrl"
multiple
:maxCount="2"
:previewFullImage="true"
/>
<div><i>身份证/营业执照图片</i></div>
</div>
</u-form-item>
<u-form-item label="场地证明" prop="landProveUrl" required>
<div>
<u-upload
:fileList="formData.landProveUrl"
@after-read="(e) => afterRead(e, 'landProveUrl')"
@delete="(e) => deletePic(e, 'landProveUrl')"
name="landProveUrl"
multiple
:maxCount="2"
:previewFullImage="true"
/>
<div><i>土地合同/场地照片</i></div>
</div>
</u-form-item>
<u-form-item label="生产证明" prop="productionProveUrl" required>
<div>
<u-upload
:fileList="formData.productionProveUrl"
@after-read="(e) => afterRead(e, 'productionProveUrl')"
@delete="(e) => deletePic(e, 'productionProveUrl')"
name="productionProveUrl"
multiple
:maxCount="2"
:previewFullImage="true"
/>
<div><i>现场作业照片/产品照片</i></div>
</div>
</u-form-item>
<u-form-item label="质量证书">
<div>
<u-upload
:fileList="formData.qualityCertificateUrl"
@after-read="(e) => afterRead(e, 'qualityCertificateUrl')"
@delete="(e) => deletePic(e, 'qualityCertificateUrl')"
name="qualityCertificateUrl"
multiple
:maxCount="2"
:previewFullImage="true"
/>
<div><i>质量认证证书</i></div>
</div>
</u-form-item>
<u-form-item label="其他材料">
<div>
<u-upload
:fileList="formData.otherMaterialUrl"
@after-read="(e) => afterRead(e, 'otherMaterialUrl')"
@delete="(e) => deletePic(e, 'otherMaterialUrl')"
name="otherMaterialUrl"
multiple
:maxCount="2"
:previewFullImage="true"
/>
<div><i>其他补充材料</i></div>
</div>
</u-form-item>
<!-- 提交按钮 -->
<view class="submit-btn-container">
<u-button type="primary" @click="submitForm" :loading="loading">提交</u-button>
</view> </view>
</u-form> </fui-form>
<fui-picker </view>
:show="show.address"
:options="options.address"
:linkage="true"
:layer="3"
@change="handleChangeAddress"
@cancel="show.address = false"
/>
<fui-picker <fui-picker
:show="show.farmType" :show="pageData.show.growCrops"
:layer="1" :layer="1"
:linkage="true" :linkage="true"
:options="options.farmType" :options="pageData.options.growCrops"
@change="handleChangeFarmType" @change="handleChangeGrowCrops"
@cancel="show.farmType = false" @cancel="pageData.show.growCrops = false"
/> />
<fui-toast ref="toastRef" />
<fui-loading isFixed v-if="pageData.loading" backgroundColor="rgba(0, 0, 0, 0.4)" />
</view> </view>
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>
.container { .page {
padding: 30rpx; background: #e8f5e9;
background-color: #f8f9fa;
min-height: 100vh; min-height: 100vh;
} }
.section-title { .page-container {
font-size: 32rpx; padding: 28rpx;
font-weight: 600; }
color: #333;
margin: 40rpx 0 20rpx 0;
padding-left: 20rpx;
border-left: 6rpx solid #5db66f;
}
.address-display {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12rpx 18rpx;
background-color: transparent;
border-bottom: 2rpx solid #e4e7ed;
border-radius: 0;
cursor: pointer;
width: 100%;
text {
flex: 1;
font-size: 28rpx;
color: #333;
}
.placeholder-text {
color: #c0c4cc;
}
}
.suffix-text { .form-card {
color: #909399; background-color: #ffffff;
margin-left: 10rpx; border-radius: 20rpx;
} margin-bottom: 20rpx;
.submit-btn-container {
margin: 60rpx 0;
::v-deep .u-button {
height: 88rpx;
border-radius: 44rpx;
font-size: 32rpx;
background-color: #5db66f;
border-color: #5db66f;
}
}
// uview-plus 表单样式调整
::v-deep .u-form-item {
margin-bottom: 40rpx;
.u-form-item__body {
padding: 0; padding: 0;
align-items: flex-start; overflow: hidden;
} box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
}
.u-form-item__body__left__content__label { .upload-title {
padding: 28rpx;
font-size: 28rpx; font-size: 28rpx;
color: #333; color: #333333;
font-weight: 500; font-weight: 400;
width: 160rpx; }
flex-shrink: 0;
text-align: right; .upload-content {
padding-right: 20rpx; padding: 0 32rpx 32rpx;
line-height: 80rpx; }
}
.submit-btn-box {
.u-form-item__body__right { padding: 32rpx 0;
flex: 1; }
min-width: 0;
} :deep(.fui-button) {
} border-color: #ff9800 !important;
background: #ff9800 !important;
::v-deep .u-form-item__body__left__content__required { }
position: static;
padding-right: 10rpx; :deep(.fui-input__wrap),
} :deep(.fui-textarea__wrap) {
padding: 28rpx 32rpx;
// 输入框样式优化 - 只保留下面的线 // border-bottom: 1px solid #e5e5e5;
::v-deep .u-input { }
.u-input__content {
padding: 0; :deep(.fui-input__label),
:deep(.fui-textarea__label) {
.u-input__content__field-wrapper { font-size: 28rpx;
border: none; color: #333333;
// border-bottom: 2rpx solid #e4e7ed; min-width: 160rpx;
border-radius: 0; font-weight: 400;
}
.u-input__content__field-wrapper__field { :deep(.fui-input__self),
:deep(.fui-textarea__self) {
font-size: 28rpx; font-size: 28rpx;
// padding: 20rpx 0; color: #333333;
height: auto; }
// min-height: 80rpx;
}
.u-input__content__field-wrapper__placeholder { :deep(.fui-input__placeholder),
color: #c0c4cc; :deep(.fui-textarea__placeholder) {
color: #d0d0d0;
font-size: 28rpx; font-size: 28rpx;
} }
}
.form-card :deep(.fui-input__wrap:last-child),
.form-card :deep(.fui-textarea__wrap:last-child) {
border-bottom: none;
}
::v-deep .uni-input-placeholder {
font-size: 28rpx !important;
color: #999999 !important;
}
:deep(.uni-textarea-placeholder) {
font-size: 28rpx !important;
color: #999999 !important;
}
:deep(.fui-button) {
width: 690rpx;
border-color: #5db66f !important;
background: #5db66f !important;
}
// 移除fui-form的默认样式
:deep(.fui-form) {
background: transparent;
}
:deep(.fui-form__item) {
background: transparent;
border: none;
margin-bottom: 0;
padding: 0;
}
:deep(.fui-input__border-bottom) {
right: 32rpx !important;
}
.form-item-block {
padding: 24rpx 12rpx;
// border-bottom: 1px solid #e5e5e5;
&.u-input--focus { &:last-child {
.u-input__content__field-wrapper { border-bottom: none;
border-bottom-color: #5db66f;
}
}
}
} }
}
// 上传组件样式调整 .form-item-label {
::v-deep .u-upload { font-size: 28rpx;
margin-top: 10rpx; color: #333333;
font-weight: 400;
margin-bottom: 20rpx;
.u-upload__wrap { &.required::before {
padding: 0; content: '*';
} color: #ff4d4f;
margin-right: 8rpx;
} }
}
// 选择器输入框样式 .block-textarea {
::v-deep .u-input--readonly { width: 100%;
.u-input__content__field-wrapper { padding: 0rpx 12rpx !important;
background-color: transparent; }
.u-input__content__field-wrapper__field { .block-upload {
color: #333; width: 100%;
} padding: 0 20rpx;
:deep(.uni-file-picker__container) {
background-color: #fff !important;
border: unset !important;
border-radius: 16rpx;
min-height: 200rpx;
display: flex;
justify-content: left !important;
} }
}
.select-text {
font-size: 28rpx;
color: #333333;
padding: 0 20rpx;
&.placeholder {
color: #999999;
} }
}
// 表单项点击区域样式 .fui-input-wrapper {
::v-deep .u-form-item {
&.clickable {
cursor: pointer; cursor: pointer;
}
.u-form-item__body__right {
position: relative;
&:after {
content: '';
position: absolute;
top: 0;
left: -20rpx;
right: -20rpx;
bottom: 0;
}
}
}
}
</style> </style>
...@@ -108,6 +108,7 @@ function createPopupHTML(employment) { ...@@ -108,6 +108,7 @@ function createPopupHTML(employment) {
if (!employment) return '' if (!employment) return ''
const distance = getDistanceText(employment) const distance = getDistanceText(employment)
const stars = getStarsHTML(employment)
console.log('employment', employment) console.log('employment', employment)
return ` return `
<div style=" <div style="
...@@ -163,9 +164,8 @@ function createPopupHTML(employment) { ...@@ -163,9 +164,8 @@ function createPopupHTML(employment) {
<div style="display: flex; align-items: center; justify-content: space-between;"> <div style="display: flex; align-items: center; justify-content: space-between;">
<div style="display: flex; align-items: center; gap: 4px;"> <div style="display: flex; align-items: center; gap: 4px;">
<span style="color: #FF9800; font-size: 16px;">★★★★</span> ${stars.html}
<span style="color: #E0E0E0; font-size: 16px;">★</span> <span style="font-size: 13px; color: #666666; margin-left: 4px;">${stars.rating}</span>
<span style="font-size: 13px; color: #666666; margin-left: 4px;">4</span>
</div> </div>
<a href="#" onclick="window.navigateToDetail('${employment.id}'); return false;" style=" <a href="#" onclick="window.navigateToDetail('${employment.id}'); return false;" style="
display: inline-block; display: inline-block;
...@@ -403,6 +403,28 @@ function getDistanceText(employment) { ...@@ -403,6 +403,28 @@ function getDistanceText(employment) {
} }
return `${distance.toFixed(1)}km` return `${distance.toFixed(1)}km`
} }
// 生成星级HTML
function getStarsHTML(employment) {
// 获取紧急程度,默认为0
const urgentdegree = Number(employment.urgentdegree) || 0
// 确保评级在0-5之间
const rating = Math.max(0, Math.min(5, urgentdegree))
let html = ''
for (let i = 1; i <= 5; i++) {
if (i <= rating) {
html += '<span style="color: #FF9800; font-size: 16px;">★</span>'
} else {
html += '<span style="color: #E0E0E0; font-size: 16px;">★</span>'
}
}
return {
html,
rating
}
}
// 发布用工 // 发布用工
function handlePublish() { function handlePublish() {
Navigate.to('/pages/linghuoyonggong/form') Navigate.to('/pages/linghuoyonggong/form')
......
<script setup lang="ts"> <script setup lang="ts">
import { reactive, toRefs } from 'vue' import { reactive, toRefs } from 'vue'
import { onShow } from '@dcloudio/uni-app' import { onShow } from '@dcloudio/uni-app'
import { useUserStore } from '@/store/modules/user' import { useUserStore } from '@/store/modules/user'
import { useGlobSetting } from '/@/hooks/setting' import { useGlobSetting } from '/@/hooks/setting'
import * as NongchangAPI from '@/api/model/nongchang' import * as NongchangAPI from '@/api/model/nongchang'
import { areaTree } from '@/utils/areaData' import { areaTree } from '@/utils/areaData'
import { useDictStore } from '@/store/modules/dict' import { useDictStore } from '@/store/modules/dict'
const dictStore = useDictStore() const dictStore = useDictStore()
const userStore = useUserStore() const userStore = useUserStore()
const globSetting = useGlobSetting() const globSetting = useGlobSetting()
onLoad((pageOptions) => {
onShow(() => { if (pageOptions.id) {
uni.setNavigationBarTitle({
title: '编辑农场',
})
pageData.form.id = pageOptions.id;
NongchangAPI.farmsGet({ id: pageOptions.id }).then((res) => {
// 将 res 中的数据赋值到 formData 中,key 保持一致
Object.keys(res).forEach((key) => {
if (key in pageData.form) {
pageData.form[key] = res[key]
}
})
pageData.form.provinceText = res.provinceName + '/' + res.cityName + '/' + res.districtName
// 编辑模式下,如果已有示例图片,需要设置到上传组件中
if (res.coverImage) {
nextTick(() => {
// 设置上传组件的初始文件
const uploadComponent = uploadRef.value
if (uploadComponent) {
uploadComponent.clearFiles()
// 构造文件对象格式,适配uni-file-picker的数据结构
const fileItem = {
url: res.coverImage,
name: res.coverImage.split('/').pop() || 'image.jpg',
extname: res.coverImage.split('.').pop() || 'jpg'
}
uploadComponent.files.push(fileItem)
}
})
}
// 编辑模式下,根据字典值获取对应的文本
// 延迟执行,确保字典数据已加载完成
nextTick(() => {
if (res.farmType) {
const farmTypeItem = pageData.options.farmType.find(item => item.value == res.farmType)
if (farmTypeItem) {
pageData.form.farmTypeText = farmTypeItem.text
}
}
if (res.growCrops) {
const growCropsItem = pageData.options.mainProducts.find(item => item.value == res.growCrops)
if (growCropsItem) {
pageData.form.growCropsText = growCropsItem.text
}
}
})
})
}
})
onShow(() => {
// 数据字典赋值 // 数据字典赋值
initDict() initDict()
pageData.form.userId = userStore.getUserInfo.id pageData.form.userId = userStore.getUserInfo.id
}) })
const pageData = reactive({ const pageData = reactive({
loading: false, loading: false,
show: { show: {
address: false, address: false,
...@@ -30,23 +82,22 @@ ...@@ -30,23 +82,22 @@
farmType: [], farmType: [],
}, },
form: { form: {
id:'',
userId: '', userId: '',
farmName: '', farmName: '',
title: '',
farmType: '', farmType: '',
farmTypeText: '', farmTypeText: '',
contactPhone: '', growCrops: '',
contactPerson: '', growCropsText: '',
description: '', totalArea: '',
address: '', farmProfiles: '',
owner: '',
ownerPhone: '',
provinceText: '',
provinceName: '', provinceName: '',
cityName: '', cityName: '',
districtName: '', districtName: '',
addressDetail: '', addressDetail: '',
mainBusiness: '',
mainProducts: '',
mainProductsText: '',
totalArea: '',
coverImage: '', coverImage: '',
}, },
rules: [ rules: [
...@@ -56,61 +107,49 @@ ...@@ -56,61 +107,49 @@
msg: ['请输入农场名称'], msg: ['请输入农场名称'],
}, },
{ {
name: 'title',
rule: ['required'],
msg: ['请输入农场类型'],
},
{
name: 'farmType', name: 'farmType',
rule: ['required'], rule: ['required'],
msg: ['请选择农场类型'], msg: ['请选择农场类型'],
}, },
{ {
name: 'contactPhone', name: 'growCrops',
rule: ['required'], rule: ['required'],
msg: ['请输入联系电话'], msg: ['请选择种植物种'],
}, },
{ {
name: 'contactPerson', name: 'totalArea',
rule: ['required'], rule: ['required'],
msg: ['请输入联系人'], msg: ['请输入总面积'],
}, },
{ {
name: 'description', name: 'farmProfiles',
rule: ['required'], rule: ['required'],
msg: ['请输入农场简介'], msg: ['请输入农场简介'],
}, },
{ {
name: 'address', name: 'owner',
rule: ['required'], rule: ['required'],
msg: ['请选择农场地址'], msg: ['请输入农场主姓名'],
}, },
{ {
name: 'addressDetail', name: 'ownerPhone',
rule: ['required'], rule: ['required'],
msg: ['请填写详细地址'], msg: ['请输入农场主电话'],
},
{
name: 'mainBusiness',
rule: ['required'],
msg: ['请填写主要业务'],
}, },
{ {
name: 'mainProducts', name: 'provinceName',
rule: ['required'], rule: ['required'],
msg: ['请选择主要产品'], msg: ['请选择归属省份'],
}, },
{ {
name: 'totalArea', name: 'addressDetail',
rule: ['required'], rule: ['required'],
msg: ['请输入农场面积'], msg: ['请填写详细地址'],
}, },
], ],
}) })
const { show, options, form } = toRefs(pageData)
function initDict() { function initDict() {
pageData.options.address = areaTree pageData.options.address = areaTree
pageData.options.mainProducts = dictStore.getDictList.main_business.map((item) => { pageData.options.mainProducts = dictStore.getDictList.main_business.map((item) => {
return { return {
...@@ -124,28 +163,28 @@ ...@@ -124,28 +163,28 @@
text: item.text, text: item.text,
} }
}) })
} }
function handleChangeFarmType(e) { function handleChangeFarmType(e) {
pageData.form.farmType = e.value pageData.form.farmType = e.value
pageData.form.farmTypeText = e.text pageData.form.farmTypeText = e.text
pageData.show.farmType = false pageData.show.farmType = false
} }
function handleChangeMainProducts(e) { function handleChangeGrowCrops(e) {
pageData.form.mainProducts = e.value pageData.form.growCrops = e.value
pageData.form.mainProductsText = e.text pageData.form.growCropsText = e.text
pageData.show.mainProducts = false pageData.show.mainProducts = false
} }
function handleChangeAddress(e) { function handleChangeAddress(e) {
pageData.form.address = e.text.join('/')
pageData.form.provinceName = e.text[0] pageData.form.provinceName = e.text[0]
pageData.form.cityName = e.text[1] pageData.form.cityName = e.text[1]
pageData.form.districtName = e.text[2] pageData.form.districtName = e.text[2]
pageData.form.provinceText = e.text[0] + '/' + e.text[1] + '/' + e.text[2]
pageData.show.address = false pageData.show.address = false
} }
const toastRef = ref() const toastRef = ref()
const uploadRef = ref() const uploadRef = ref()
// 文件上传 // 文件上传
function handleUpload(file) { function handleUpload(file) {
pageData.loading = true pageData.loading = true
uni.uploadFile({ uni.uploadFile({
url: `${globSetting.apiUrl + globSetting.urlPrefix}/sys/common/upload`, // 直接使用上传接口URL url: `${globSetting.apiUrl + globSetting.urlPrefix}/sys/common/upload`, // 直接使用上传接口URL
...@@ -181,63 +220,196 @@ ...@@ -181,63 +220,196 @@
pageData.loading = false pageData.loading = false
}, },
}) })
} }
// 文件删除 // 文件删除
function handleDelete(file) { function handleDelete(file) {
uploadRef.value.clearFiles() uploadRef.value.clearFiles()
pageData.form.coverImage = null pageData.form.coverImage = null
} }
const formRef = ref() const formRef = ref()
function submit() { function submit() {
formRef.value.validator(pageData.form, pageData.rules, true).then((res) => { formRef.value.validator(pageData.form, pageData.rules, true).then((res) => {
if (res.isPassed) { if (res.isPassed) {
pageData.loading = true pageData.loading = true
NongchangAPI.farmsAdd(pageData.form) const apiCall = pageData.form.id ? NongchangAPI.farmsEdit : NongchangAPI.farmsAdd
apiCall(pageData.form)
.then(() => { .then(() => {
toastRef.value.show({ toastRef.value.show({
type: 'success', type: 'success',
text: '添加农场成功', text: pageData.form.id ? '保存修改成功' : '添加农场成功',
})
uni.switchTab({
url: '/pages/mine/index',
}) })
setTimeout(() => {
uni.navigateBack()
}, 500);
}) })
.finally(() => { .finally(() => {
pageData.loading = false pageData.loading = false
}) })
} }
}) })
} }
</script> </script>
<template> <template>
<view class="page">
<view class="page-container">
<fui-form ref="formRef"> <fui-form ref="formRef">
<fui-input required label="农场名称" placeholder="请输入农场名称" v-model="form.farmName" /> <!-- 第一组表单 -->
<fui-input required label="农场标语" placeholder="请输入农场标语" v-model="form.title" /> <view class="form-card">
<fui-input
required
label="农场名称"
labelSize="28"
size="28"
:labelWeight="400"
labelWidth="auto"
placeholder="请输入农场名称"
v-model="pageData.form.farmName"
/>
<fui-form-item
required
asterisk
label="农场类型"
labelSize="28"
:labelWeight="400"
labelWidth="auto"
>
<view class="time-input" @click="pageData.show.farmType = true">
<text class="select-text" :class="{ placeholder: !pageData.form.farmTypeText }">
{{ pageData.form.farmTypeText || '请选择农场类型' }}
</text>
</view>
</fui-form-item>
<!-- <view class="fui-input-wrapper" @click="pageData.show.farmType = true">
<fui-input <fui-input
required required
readonly
label="农场类型" label="农场类型"
placeholder="请选择农场类型" placeholder="请选择农场类型"
v-model="form.farmTypeText" v-model="pageData.form.farmTypeText"
@click="show.farmType = true" labelSize="28"
:labelWeight="400"
labelWidth="auto"
/>
</view> -->
<fui-input
required
labelSize="28"
size="28"
:labelWeight="400"
labelWidth="auto"
label="农场主姓名"
placeholder="请输入农场主姓名"
v-model="pageData.form.owner"
/>
<fui-input
required
type="number"
labelSize="28"
size="28"
:labelWeight="400"
labelWidth="auto"
label="农场主电话"
placeholder="请输入农场主电话"
v-model="pageData.form.ownerPhone"
/>
<!-- 农场简介换行显示 -->
<view class="form-item-block">
<view class="form-item-label required">农场简介</view>
<fui-textarea
height="100rpx"
size="28"
:borderTop="false"
:borderBottom="false"
placeholder="请输入农场简介"
v-model="pageData.form.farmProfiles"
class="block-textarea"
/>
</view>
</view>
<!-- 第二组表单 -->
<view class="form-card">
<fui-form-item
required
asterisk
label="归属省份"
labelSize="28"
:labelWeight="400"
labelWidth="auto"
>
<view class="time-input" @click="pageData.show.address = true">
<text class="select-text" :class="{ placeholder: !pageData.form.provinceText }">
{{ pageData.form.provinceText || '请选择归属省份' }}
</text>
</view>
</fui-form-item>
<!-- <view class="fui-input-wrapper" @click="pageData.show.address = true">
<fui-input
required
readonly
labelWidth="auto"
labelSize="28"
:labelWeight="400"
label="归属省份"
placeholder="请选择归属省份"
:value="pageData.form.provinceText"
/> />
<fui-input required label="联系人" placeholder="请输入联系人" v-model="form.contactPerson" /> </view> -->
<fui-input required label="联系电话" placeholder="请输入联系电话" v-model="form.contactPhone" />
<fui-textarea required label="农场描述" placeholder="请输入农场描述" v-model="pageData.form.description" />
<fui-input required label="地区" placeholder="请选择地区" v-model="form.address" @click="show.address = true" />
<fui-input required label="详细地址" placeholder="请输入详细地址" v-model="form.addressDetail" />
<fui-input required label="主营业务" borderTop placeholder="请输入主营业务" v-model="form.mainBusiness" />
<fui-input <fui-input
required required
label="主要产品" labelWidth="auto"
borderTop labelSize="28"
placeholder="请选择主要产品" :labelWeight="400"
v-model="form.mainProductsText" size="28"
@click="show.mainProducts = true" label="详细地址"
placeholder="请输入详细地址"
v-model="pageData.form.addressDetail"
/> />
<fui-input required label="总面积(亩)" borderTop placeholder="请输入总面积" v-model="form.totalArea" /> <fui-form-item
<view class="bg-white" style="padding: 0.875rem 0.35rem"> required
<view class="mb-1 flex justify-start"> 封面图片 </view> asterisk
label="种植物种"
labelSize="28"
:labelWeight="400"
labelWidth="auto"
>
<view class="time-input" @click="pageData.show.mainProducts = true">
<text class="select-text" :class="{ placeholder: !pageData.form.growCropsText }">
{{ pageData.form.growCropsText || '请选择种植物种' }}
</text>
</view>
</fui-form-item>
<!-- <view class="fui-input-wrapper" @click="pageData.show.mainProducts = true">
<fui-input
required
readonly
labelWidth="auto"
labelSize="28"
:labelWeight="400"
label="种植物种"
placeholder="请选择种植物种"
v-model="pageData.form.growCropsText"
/>
</view> -->
<fui-input
required
size="28"
labelWidth="auto"
labelSize="28"
:labelWeight="400"
label="总面积 (亩)"
placeholder="请输入总面积"
v-model="pageData.form.totalArea"
/>
</view>
<!-- 第三组表单 - 图片上传 -->
<view class="form-card">
<!-- 上传图片换行显示 -->
<view class="form-item-block">
<view class="form-item-label required">示例图片</view>
<view class="block-upload">
<uni-file-picker <uni-file-picker
ref="uploadRef" ref="uploadRef"
limit="1" limit="1"
...@@ -246,43 +418,192 @@ ...@@ -246,43 +418,192 @@
@delete="handleDelete" @delete="handleDelete"
/> />
</view> </view>
<view class="fui-btn__box bg-white p-4"> </view>
<fui-button text="添加农场" bold radius="96rpx" @click="submit" /> </view>
<view class="submit-btn-box">
<fui-button :text="pageData.form.id ? '保存修改' : '添加基地'" bold radius="96rpx" @click="submit" />
</view> </view>
</fui-form> </fui-form>
</view>
<fui-picker <fui-picker
:show="show.farmType" :show="pageData.show.farmType"
:layer="1" :layer="1"
:linkage="true" :linkage="true"
:options="options.farmType" :options="pageData.options.farmType"
@change="handleChangeFarmType" @change="handleChangeFarmType"
@cancel="show.farmType = false" @cancel="pageData.show.farmType = false"
/> />
<fui-picker <fui-picker
:show="show.mainProducts" :show="pageData.show.mainProducts"
:layer="1" :layer="1"
:linkage="true" :linkage="true"
:options="options.mainProducts" :options="pageData.options.mainProducts"
@change="handleChangeMainProducts" @change="handleChangeGrowCrops"
@cancel="show.mainProducts = false" @cancel="pageData.show.mainProducts = false"
/> />
<fui-picker <fui-picker
:show="show.address" :show="pageData.show.address"
:options="options.address" :options="pageData.options.address"
:linkage="true" :linkage="true"
:layer="3" :layer="3"
@change="handleChangeAddress" @change="handleChangeAddress"
@cancel="show.address = false" @cancel="pageData.show.address = false"
/> />
<fui-toast ref="toastRef" /> <fui-toast ref="toastRef" />
<fui-loading isFixed v-if="pageData.loading" backgroundColor="rgba(0, 0, 0, 0.4)" /> <fui-loading isFixed v-if="pageData.loading" backgroundColor="rgba(0, 0, 0, 0.4)" />
</view>
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>
:deep(.fui-button) { .page {
background: #e8f5e9;
min-height: 100vh;
}
.page-container {
padding: 28rpx;
}
.form-card {
background-color: #ffffff;
border-radius: 20rpx;
margin-bottom: 20rpx;
padding: 0;
overflow: hidden;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
}
.upload-title {
padding: 28rpx;
font-size: 28rpx;
color: #333333;
font-weight: 400;
}
.upload-content {
padding: 0 32rpx 32rpx;
}
.submit-btn-box {
padding: 32rpx 0;
}
:deep(.fui-button) {
border-color: #ff9800 !important; border-color: #ff9800 !important;
background: #ff9800 !important; background: #ff9800 !important;
}
:deep(.fui-input__wrap),
:deep(.fui-textarea__wrap) {
padding: 28rpx 32rpx;
// border-bottom: 1px solid #e5e5e5;
}
:deep(.fui-input__label),
:deep(.fui-textarea__label) {
font-size: 28rpx;
color: #333333;
min-width: 160rpx;
font-weight: 400;
}
:deep(.fui-input__self),
:deep(.fui-textarea__self) {
font-size: 28rpx;
color: #333333;
}
:deep(.fui-input__placeholder),
:deep(.fui-textarea__placeholder) {
color: #d0d0d0;
font-size: 28rpx;
}
.form-card :deep(.fui-input__wrap:last-child),
.form-card :deep(.fui-textarea__wrap:last-child) {
border-bottom: none;
}
::v-deep .uni-input-placeholder {
font-size: 28rpx !important;
color: #999999 !important;
}
:deep(.uni-textarea-placeholder) {
font-size: 28rpx !important;
color: #999999 !important;
}
:deep(.fui-button) {
width: 690rpx;
border-color: #5db66f !important;
background: #5db66f !important;
}
// 移除fui-form的默认样式
:deep(.fui-form) {
background: transparent;
}
:deep(.fui-form__item) {
background: transparent;
border: none;
margin-bottom: 0;
padding: 0;
}
:deep(.fui-input__border-bottom) {
right: 32rpx !important;
}
.form-item-block {
padding: 24rpx 12rpx;
// border-bottom: 1px solid #e5e5e5;
&:last-child {
border-bottom: none;
}
}
.form-item-label {
font-size: 28rpx;
color: #333333;
font-weight: 400;
margin-bottom: 20rpx;
&.required::before {
content: '*';
color: #ff4d4f;
margin-right: 8rpx;
}
}
.block-textarea {
width: 100%;
padding: 0rpx 12rpx !important;
}
.block-upload {
width: 100%;
padding: 0 20rpx;
:deep(.uni-file-picker__container) {
background-color: #fff !important;
border: unset !important;
border-radius: 16rpx;
min-height: 200rpx;
display: flex;
justify-content: left !important;
}
}
.select-text {
font-size: 28rpx;
color: #333333;
padding: 0 20rpx;
&.placeholder {
color: #999999;
} }
}
.fui-input-wrapper {
cursor: pointer;
}
</style> </style>
<!-- 农场详情 --> <!-- 农场详情 -->
<script setup lang="ts"> <script setup lang="ts">
import * as turf from '@turf/turf' import * as turf from '@turf/turf'
import type { Page } from './config' import type { Page } from './config'
import PlayWidget from './components/PlayWidget.vue' import PlayWidget from './components/PlayWidget.vue'
import Navigate from '@/utils/page/navigate' import Navigate from '@/utils/page/navigate'
import { import {
addDefaultGeoJSONSource, addDefaultGeoJSONSource,
addDefaultSplotLayer, addDefaultSplotLayer,
addDefaultSymbolLayer, addDefaultSymbolLayer,
useMapbox, useMapbox,
} from '@/components/Map/Mapbox/hook' } from '@/components/Map/Mapbox/hook'
import type { ToolBoxButtonHandleEvent } from '@/components/Map/Widgets/ToolBox' import type { ToolBoxButtonHandleEvent } from '@/components/Map/Widgets/ToolBox'
import { ToolBoxWidget, useToolBoxWidget } from '@/components/Map/Widgets/ToolBox' import { ToolBoxWidget, useToolBoxWidget } from '@/components/Map/Widgets/ToolBox'
import * as NongchangAPI from '@/api/model/nongchang' import * as NongchangAPI from '@/api/model/nongchang'
import * as farmbaseApi from '@/api/model/farmbase' import * as farmbaseApi from '@/api/model/farmbase'
// 页面参数 // 页面参数
const page = reactive<Page>({ const page = reactive<Page>({
id: 'example-mapbox', id: 'example-mapbox',
init: false, init: false,
requests: 0, requests: 0,
latest: null, latest: null,
query: {}, query: {},
}) })
onShow(() => {
const model = reactive({ getFarmbaseInfoList()
})
const model = reactive({
id: '', id: '',
name: '', name: '',
lonlat: '', lonlat: '',
...@@ -58,9 +60,8 @@ ...@@ -58,9 +60,8 @@
farmbaseInfo: {}, farmbaseInfo: {},
farmbaseInfoList: [], farmbaseInfoList: [],
deviceTypeCount: [], deviceTypeCount: [],
}) })
async function getFarmbaseInfoList() {
async function getFarmbaseInfoList() {
farmbaseApi farmbaseApi
.list({ .list({
farmId: model.id, farmId: model.id,
...@@ -73,23 +74,23 @@ ...@@ -73,23 +74,23 @@
getFarmbaseInfoById(records[0].id) getFarmbaseInfoById(records[0].id)
} }
}) })
} }
async function getFarmbaseInfoById(id) { async function getFarmbaseInfoById(id) {
farmbaseApi.getFarmbaseInfoById({ id }).then((res) => { farmbaseApi.getFarmbaseInfoById({ id }).then((res) => {
model.farmbaseInfo = res model.farmbaseInfo = res
getDeviceTypeCount() getDeviceTypeCount()
}) })
} }
async function getDeviceTypeCount() { async function getDeviceTypeCount() {
farmbaseApi.getDeviceTypeCount({ farmId: model.id, farmBaseId: model.farmbaseInfo?.id }).then((res) => { farmbaseApi.getDeviceTypeCount({ farmId: model.id, farmBaseId: model.farmbaseInfo?.id }).then((res) => {
model.deviceTypeCount = res model.deviceTypeCount = res
}) })
} }
// 地图组件 // 地图组件
const [registerMap, map] = useMapbox({ const [registerMap, map] = useMapbox({
style: { zoom: 15 }, style: { zoom: 15 },
onLoaded: async (data) => { onLoaded: async (data) => {
console.log('✨✨✨ Map Loaded', data) console.log('✨✨✨ Map Loaded', data)
...@@ -234,10 +235,10 @@ ...@@ -234,10 +235,10 @@
onSourceRequestErrorHandle: () => { onSourceRequestErrorHandle: () => {
Message.hideLoading() Message.hideLoading()
}, },
}) })
// 左侧工具栏小部件 // 左侧工具栏小部件
const [registerToolBoxWidget] = useToolBoxWidget({ const [registerToolBoxWidget] = useToolBoxWidget({
show: true, show: true,
expand: true, expand: true,
showExpandButton: false, showExpandButton: false,
...@@ -315,20 +316,59 @@ ...@@ -315,20 +316,59 @@
], ],
}, },
], ],
})
// 自定义导航栏回调函数
function onBackClick() {
uni.navigateBack({
delta: 1,
}) })
}
onNavigationBarButtonTap((e) => { function onTitleIconClick() {
Navigate.to(`/pages/nongchang/create-nongchang-form?id=${model.id}`)
}
function onAddBaseClick() {
// 点击添加基地按钮的回调函数
Navigate.to(`/pages/jidiguanli/add?farmId=${model.id}`)
}
// 保留原有的导航栏按钮点击回调(如果有需要的话)
onNavigationBarButtonTap((e) => {
console.log(e)
if (e.index === 0) { if (e.index === 0) {
Navigate.to(`/pages/jidiguanli/add?farmId=${model.id}`) Navigate.to(`/pages/jidiguanli/add?farmId=${model.id}`)
} }
}) })
</script> </script>
<template> <template>
<view class="page bg-white"> <view class="page bg-white">
<!-- 自定义导航栏 -->
<view class="custom-navbar">
<view class="navbar-content">
<view class="navbar-left" @click="onBackClick">
<fui-icon name="arrowleft" color="#FFF" size="44"></fui-icon>
</view>
<view class="navbar-center">
<text class="navbar-title">{{ model.name || '农场' }}</text>
<view class="navbar-icon" @click="onTitleIconClick">
<image class="title-icon" src="/static/images/nongchang/farm-title-icon.png" />
</view>
</view>
<view class="navbar-right">
<text class="add-base-btn" @click="onAddBaseClick">+ 添加基地</text>
</view>
</view>
</view>
<!-- 为自定义导航栏预留空间 -->
<view class="navbar-placeholder"></view>
<!-- 地图组件 --> <!-- 地图组件 -->
<!-- <view class="h-730 overflow-hidden map-box"> --> <!-- <view class="h-730 overflow-hidden map-box"> -->
<view class="h-810 overflow-hidden map-box"> <view class="h-730 overflow-hidden map-box">
<!-- 地图组件 --> <!-- 地图组件 -->
<Mapbox @register="registerMap" /> <Mapbox @register="registerMap" />
</view> </view>
...@@ -351,8 +391,9 @@ ...@@ -351,8 +391,9 @@
</view> </view>
</view> </view>
<view class="card !top-810"> <view class="card !top-730">
<view class="w-full absolute top--70rpx"> <view class="w-full absolute top--70rpx">
<view style="background: #e6f5e8">
<view class="box-1"> <view class="box-1">
<view class="relative w-full flex flex-row"> <view class="relative w-full flex flex-row">
<view class="box-1-left" <view class="box-1-left"
...@@ -418,7 +459,9 @@ ...@@ -418,7 +459,9 @@
<view class="box-3-info-item justify-between"> <view class="box-3-info-item justify-between">
<view class="box-3-info-item-text-box"> <view class="box-3-info-item-text-box">
<text class="box-3-info-item-text1">种植: </text> <text class="box-3-info-item-text1">种植: </text>
<text class="box-3-info-item-text2">{{ model.farmbaseInfo.plantedCrops }}</text> <text class="box-3-info-item-text2">{{
model.farmbaseInfo.growCrops_dictText
}}</text>
</view> </view>
<view class="box-3-info-item-text-box"> <view class="box-3-info-item-text-box">
<text class="box-3-info-item-text1">预计产量: </text> <text class="box-3-info-item-text1">预计产量: </text>
...@@ -440,10 +483,16 @@ ...@@ -440,10 +483,16 @@
<view class="box-4"> <view class="box-4">
<view class="box-4-title"> <view class="box-4-title">
<view class="box-4-title-text1"><text>基地设备</text></view> <view class="box-4-title-text1"><text>基地设备</text></view>
<navigator url="/pages/device/device" class="box-4-title-text2"><text>+ 添加设备</text></navigator> <navigator url="/pages/device/device" class="box-4-title-text2"
><text>+ 添加设备</text></navigator
>
</view> </view>
<view class="box-4-device"> <view class="box-4-device">
<view class="box-4-device-item" v-for="(device, index) in model.deviceTypeCount" :key="index"> <view
class="box-4-device-item"
v-for="(device, index) in model.deviceTypeCount"
:key="index"
>
<view class="box-4-item-icon"> <view class="box-4-item-icon">
<image class="box-4-item-icon-image" src="/static/images/nongchang/jiankong.png" /> <image class="box-4-item-icon-image" src="/static/images/nongchang/jiankong.png" />
</view> </view>
...@@ -457,17 +506,129 @@ ...@@ -457,17 +506,129 @@
</view> </view>
</view> </view>
</view> </view>
</view>
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>
// //
page { page {
background-color: #e6f5e8; background-color: #e6f5e8;
} }
.page { .page {
position: relative; position: relative;
min-height: 100vh;
background-color: #e6f5e8; background-color: #e6f5e8;
// 自定义导航栏样式
.custom-navbar {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 999;
background-color: #5db66f;
padding-top: var(--status-bar-height, 44rpx);
.navbar-content {
height: 88rpx;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 20rpx;
.navbar-left {
width: 120rpx;
display: flex;
justify-content: flex-start;
.back-icon {
width: 60rpx;
height: 60rpx;
display: flex;
align-items: center;
justify-content: center;
color: #fff;
font-size: 36rpx;
font-weight: bold;
border-radius: 50%;
background-color: rgba(255, 255, 255, 0.2);
&:active {
background-color: rgba(255, 255, 255, 0.3);
transform: scale(0.95);
}
}
}
.navbar-center {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
position: relative;
.navbar-title {
color: #fff;
font-size: 32rpx;
font-weight: 600;
// margin-right: 10rpx;
}
.navbar-icon {
display: flex;
align-items: center;
justify-content: center;
// margin-left: 8rpx;
// padding: 8rpx;
border-radius: 50%;
// background-color: rgba(255, 255, 255, 0.2);
transition: all 0.3s ease;
.title-icon {
width: 32rpx;
height: 32rpx;
}
&:active {
background-color: rgba(255, 255, 255, 0.3);
transform: scale(0.9);
}
&:hover {
background-color: rgba(255, 255, 255, 0.25);
}
}
}
.navbar-right {
width: 180rpx;
display: flex;
justify-content: flex-end;
.add-base-btn {
color: #fff;
font-size: 26rpx;
padding: 12rpx 20rpx;
transition: all 0.3s ease;
&:active {
background-color: rgba(255, 255, 255, 0.3);
transform: scale(0.95);
}
&:hover {
background-color: rgba(255, 255, 255, 0.25);
}
}
}
}
}
// 导航栏占位空间
.navbar-placeholder {
height: calc(88rpx + var(--status-bar-height, 44rpx));
}
.map-box { .map-box {
// #ifdef APP-PLUS // #ifdef APP-PLUS
position: relative; position: relative;
...@@ -766,5 +927,5 @@ ...@@ -766,5 +927,5 @@
} }
} }
} }
} }
</style> </style>
...@@ -11,7 +11,8 @@ const PROXY_LIST: [[string, string]?] = [ ...@@ -11,7 +11,8 @@ const PROXY_LIST: [[string, string]?] = [
// [`http://192.168.0.100:18100`, `https://oss.beta.app.yiring.com`], // [`http://192.168.0.100:18100`, `https://oss.beta.app.yiring.com`],
// 开发环境(预览) // 开发环境(预览)
[`http://192.168.0.156:18100`, `http://111.22.182.169:49091`], // [`http://192.168.0.156:18100`, `http://111.22.182.169:49091`],
[`http://192.168.0.156:18100`, `http://36.133.16.81:42111`],
] ]
/** /**
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论