提交 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 dictStore = useDictStore()
// 表单引用 const userStore = useUserStore()
const formRef = ref() const globSetting = useGlobSetting()
const loading = ref(false) const farmStore = useFarmStore()
const show = reactive({ onLoad((pageOptions) => {
address: false, // 页面加载时的初始化操作
farmType: false, const farmInfo = farmStore.getFarm
}) if (farmInfo) {
const options = reactive({ pageData.form.farmId = farmInfo.id
address: areaTree, }
farmType: [], pageData.form.farmId = pageOptions.farmId
}) })
// 表单数据
const formData = reactive({ onShow(() => {
// 数据字典赋值
initDict()
pageData.form.userId = userStore.getUserInfo.id
})
const pageData = reactive({
loading: false,
show: {
growCrops: false,
},
options: {
address: [],
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: [], rules: [
identityProveUrl: [], // 身份证明(身份证/营业执照图片) {
landProveUrl: [], // 土地证明(土地证/国有土地使用证) name: 'baseName',
productionProveUrl: [], // 生产证明(生产许可证/种养许可证) rule: ['required'],
qualityCertificateUrl: [], // 质量证明(质量认证证书) msg: ['请输入基地名称'],
otherMaterialUrl: [], // 其他证明(其他证明) },
}) {
name: 'scale',
// 表单验证规则 rule: ['required'],
const rules = { msg: ['请输入面积'],
baseName: [ },
{ required: true, message: '请输入基地名称', trigger: 'blur' }, {
{ min: 2, max: 50, message: '基地名称长度在2-50个字符之间', trigger: 'blur' }, name: 'managerName',
], rule: ['required'],
baseType: [{ required: true, message: '请选择基地类型', trigger: 'change' }], msg: ['请输入负责人'],
scale: [ },
{ {
validator: (rule: any, value: any, callback: any) => { name: 'contactPhone',
if (!value || value === '') { rule: ['required'],
callback(new Error('请输入规模')) msg: ['请输入联系电话'],
} else if (!/^[1-9]\d*$/.test(value.toString())) { },
callback(new Error('规模必须为正整数')) {
} else { name: 'growCrops',
callback() rule: ['required'],
} msg: ['请选择种植作物'],
}, },
trigger: ['blur', 'change'], ],
}, })
],
province: [ function initDict() {
{ pageData.options.address = areaTree
required: true, pageData.options.growCrops = dictStore.getDictList.crops_type.map((item) => {
message: '请获取地址信息', return {
trigger: 'change', value: item.value,
// validator: () => formData.provinceName && formData.cityName && formData.districtName text: item.text,
},
],
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]$/,
message: '请输入正确的身份证号码',
trigger: 'blur',
},
],
plantedCrops: [
{ required: true, message: '请输入种植作物', trigger: 'blur' },
{ min: 2, max: 100, message: '种植作物长度在2-100个字符之间', trigger: 'blur' },
],
operationYears: [
{
validator: (rule: any, value: any, callback: any) => {
if (value && !/^[1-9]\d*$/.test(value.toString())) {
callback(new Error('经营年限必须为正整数'))
} else {
callback()
}
},
message: '经营年限必须为正整数',
trigger: ['blur', 'change'],
},
],
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 function handleChangeGrowCrops(e) {
const totalCount = files.length pageData.form.growCrops = e.value
pageData.form.growCropsText = e.text
// 遍历所有文件进行上传 pageData.show.growCrops = false
files.forEach((file) => { }
uni.uploadFile({ const toastRef = ref()
url: `${globSetting.apiUrl + globSetting.urlPrefix}/sys/common/upload`, // 直接使用上传接口URL
filePath: file.url, const formRef = ref()
name: 'file', function submit() {
formData: { formRef.value.validator(pageData.form, pageData.rules, true).then((res) => {
biz: 'temp', if (res.isPassed) {
}, pageData.loading = true
header: { // 根据是否有ID决定调用编辑还是新增接口
'X-Access-Token': userStore.getToken, const apiCall = pageData.form.id ? NongchangAPI.editFarmbase : NongchangAPI.addFarmbase
}, apiCall(pageData.form)
success: (res) => { .then(() => {
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({ toastRef.value.show({
type: 'error', type: 'success',
text: '部分图片上传失败', text: '添加基地成功',
}) })
}, setTimeout(() => {
}) uni.navigateBack()
}) }, 800)
} // uni.switchTab({
// 删除图片 // url: '/pages/mine/index',
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 }
// 将数组字段转换为逗号分隔的字符串
const arrayFields = [
'baseImages',
'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,
}) })
.finally(() => {
// 延迟返回上一页 pageData.loading = false
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 {
value: item.value,
text: item.text,
}
})
if (pageOptions.id) {
NongchangAPI.getFarmbaseInfoById({ id: pageOptions.id }).then((res) => {
if (res) {
// 将 res 中的数据赋值到 formData 中,key 保持一致
Object.keys(res).forEach((key) => {
if (key in formData) {
// 如果是数组类型的字段且返回的是字符串,需要转换为数组
if (
[
'baseImages',
'identityProveUrl',
'landProveUrl',
'productionProveUrl',
'qualityCertificateUrl',
'otherMaterialUrl',
].includes(key) &&
typeof res[key] === 'string'
) {
formData[key] = res[key].split(',').filter((item) => item.trim() !== '')
} else {
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(() => {
if (formRef.value) {
// 逐个验证可能存在问题的字段
formRef.value.validateField('scale')
formRef.value.validateField('operationYears')
// 重新验证整个表单
formRef.value.validate()
}
}, 200)
}
})
} }
}) })
}
</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="请输入基地名称"
</text> 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>
</view>
</fui-form-item>
</view> </view>
</u-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="submit-btn-box">
<view class="section-title">地址信息</view> <fui-button text="添加农场" bold radius="96rpx" @click="submit" />
<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> </fui-form>
</view>
<u-form-item label="详细地址" prop="detailedAddress" required>
<u-input v-model="formData.detailedAddress" placeholder="请输入详细地址" border="bottom" />
</u-form-item>
<!-- 负责人信息 -->
<view class="section-title">负责人信息</view>
<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>
</u-form>
<fui-picker <fui-picker
:show="show.address" :show="pageData.show.growCrops"
:options="options.address"
:linkage="true"
:layer="3"
@change="handleChangeAddress"
@cancel="show.address = false"
/>
<fui-picker
:show="show.farmType"
: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; }
.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;
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;
} }
}
.section-title {
font-size: 32rpx; .form-item-label {
font-weight: 600; font-size: 28rpx;
color: #333; color: #333333;
margin: 40rpx 0 20rpx 0; font-weight: 400;
padding-left: 20rpx; margin-bottom: 20rpx;
border-left: 6rpx solid #5db66f;
&.required::before {
content: '*';
color: #ff4d4f;
margin-right: 8rpx;
} }
}
.address-display {
.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; display: flex;
justify-content: space-between; justify-content: left !important;
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 {
color: #909399;
margin-left: 10rpx;
} }
}
.submit-btn-container { .select-text {
margin: 60rpx 0; font-size: 28rpx;
color: #333333;
::v-deep .u-button { padding: 0 20rpx;
height: 88rpx; &.placeholder {
border-radius: 44rpx; color: #999999;
font-size: 32rpx;
background-color: #5db66f;
border-color: #5db66f;
}
} }
}
// uview-plus 表单样式调整 .fui-input-wrapper {
::v-deep .u-form-item { cursor: pointer;
margin-bottom: 40rpx; }
.u-form-item__body {
padding: 0;
align-items: flex-start;
}
.u-form-item__body__left__content__label {
font-size: 28rpx;
color: #333;
font-weight: 500;
width: 160rpx;
flex-shrink: 0;
text-align: right;
padding-right: 20rpx;
line-height: 80rpx;
}
.u-form-item__body__right {
flex: 1;
min-width: 0;
}
}
::v-deep .u-form-item__body__left__content__required {
position: static;
padding-right: 10rpx;
}
// 输入框样式优化 - 只保留下面的线
::v-deep .u-input {
.u-input__content {
padding: 0;
.u-input__content__field-wrapper {
border: none;
// border-bottom: 2rpx solid #e4e7ed;
border-radius: 0;
.u-input__content__field-wrapper__field {
font-size: 28rpx;
// padding: 20rpx 0;
height: auto;
// min-height: 80rpx;
}
.u-input__content__field-wrapper__placeholder {
color: #c0c4cc;
font-size: 28rpx;
}
}
&.u-input--focus {
.u-input__content__field-wrapper {
border-bottom-color: #5db66f;
}
}
}
}
// 上传组件样式调整
::v-deep .u-upload {
margin-top: 10rpx;
.u-upload__wrap {
padding: 0;
}
}
// 选择器输入框样式
::v-deep .u-input--readonly {
.u-input__content__field-wrapper {
background-color: transparent;
.u-input__content__field-wrapper__field {
color: #333;
}
}
}
// 表单项点击区域样式
::v-deep .u-form-item {
&.clickable {
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({
initDict() title: '编辑农场',
pageData.form.userId = userStore.getUserInfo.id
})
const pageData = reactive({
loading: false,
show: {
address: false,
mainProducts: false,
farmType: false,
},
options: {
address: [],
mainProducts: [],
farmType: [],
},
form: {
userId: '',
farmName: '',
title: '',
farmType: '',
farmTypeText: '',
contactPhone: '',
contactPerson: '',
description: '',
address: '',
provinceName: '',
cityName: '',
districtName: '',
addressDetail: '',
mainBusiness: '',
mainProducts: '',
mainProductsText: '',
totalArea: '',
coverImage: '',
},
rules: [
{
name: 'farmName',
rule: ['required'],
msg: ['请输入农场名称'],
},
{
name: 'title',
rule: ['required'],
msg: ['请输入农场类型'],
},
{
name: 'farmType',
rule: ['required'],
msg: ['请选择农场类型'],
},
{
name: 'contactPhone',
rule: ['required'],
msg: ['请输入联系电话'],
},
{
name: 'contactPerson',
rule: ['required'],
msg: ['请输入联系人'],
},
{
name: 'description',
rule: ['required'],
msg: ['请输入农场简介'],
},
{
name: 'address',
rule: ['required'],
msg: ['请选择农场地址'],
},
{
name: 'addressDetail',
rule: ['required'],
msg: ['请填写详细地址'],
},
{
name: 'mainBusiness',
rule: ['required'],
msg: ['请填写主要业务'],
},
{
name: 'mainProducts',
rule: ['required'],
msg: ['请选择主要产品'],
},
{
name: 'totalArea',
rule: ['required'],
msg: ['请输入农场面积'],
},
],
})
const { show, options, form } = toRefs(pageData)
function initDict() {
pageData.options.address = areaTree
pageData.options.mainProducts = dictStore.getDictList.main_business.map((item) => {
return {
value: item.value,
text: item.text,
}
}) })
pageData.options.farmType = dictStore.getDictList.farm_type.map((item) => { pageData.form.id = pageOptions.id;
return { NongchangAPI.farmsGet({ id: pageOptions.id }).then((res) => {
value: item.value, // 将 res 中的数据赋值到 formData 中,key 保持一致
text: item.text, 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)
}
})
} }
})
} // 编辑模式下,根据字典值获取对应的文本
function handleChangeFarmType(e) { // 延迟执行,确保字典数据已加载完成
pageData.form.farmType = e.value nextTick(() => {
pageData.form.farmTypeText = e.text if (res.farmType) {
pageData.show.farmType = false const farmTypeItem = pageData.options.farmType.find(item => item.value == res.farmType)
} if (farmTypeItem) {
function handleChangeMainProducts(e) { pageData.form.farmTypeText = farmTypeItem.text
pageData.form.mainProducts = e.value
pageData.form.mainProductsText = e.text
pageData.show.mainProducts = false
}
function handleChangeAddress(e) {
pageData.form.address = e.text.join('/')
pageData.form.provinceName = e.text[0]
pageData.form.cityName = e.text[1]
pageData.form.districtName = e.text[2]
pageData.show.address = false
}
const toastRef = ref()
const uploadRef = ref()
// 文件上传
function handleUpload(file) {
pageData.loading = true
uni.uploadFile({
url: `${globSetting.apiUrl + globSetting.urlPrefix}/sys/common/upload`, // 直接使用上传接口URL
filePath: file.tempFiles[0].path,
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) {
toastRef.value.show({
type: 'success',
text: '上传成功',
})
pageData.form.coverImage = data.message // 保存返回的图片信息
} }
} }
},
fail: (err) => { if (res.growCrops) {
toastRef.value.show({ const growCropsItem = pageData.options.mainProducts.find(item => item.value == res.growCrops)
type: 'error', if (growCropsItem) {
text: '上传失败', pageData.form.growCropsText = growCropsItem.text
}) }
uploadRef.value.clearFiles() }
pageData.form.coverImage = null })
},
complete: () => {
pageData.loading = false
},
}) })
} }
// 文件删除 })
function handleDelete(file) { onShow(() => {
uploadRef.value.clearFiles() // 数据字典赋值
pageData.form.coverImage = null initDict()
} pageData.form.userId = userStore.getUserInfo.id
const formRef = ref() })
function submit() {
formRef.value.validator(pageData.form, pageData.rules, true).then((res) => { const pageData = reactive({
if (res.isPassed) { loading: false,
pageData.loading = true show: {
NongchangAPI.farmsAdd(pageData.form) address: false,
.then(() => { mainProducts: false,
toastRef.value.show({ farmType: false,
type: 'success', },
text: '添加农场成功', options: {
}) address: [],
uni.switchTab({ mainProducts: [],
url: '/pages/mine/index', farmType: [],
}) },
}) form: {
.finally(() => { id:'',
pageData.loading = false userId: '',
farmName: '',
farmType: '',
farmTypeText: '',
growCrops: '',
growCropsText: '',
totalArea: '',
farmProfiles: '',
owner: '',
ownerPhone: '',
provinceText: '',
provinceName: '',
cityName: '',
districtName: '',
addressDetail: '',
coverImage: '',
},
rules: [
{
name: 'farmName',
rule: ['required'],
msg: ['请输入农场名称'],
},
{
name: 'farmType',
rule: ['required'],
msg: ['请选择农场类型'],
},
{
name: 'growCrops',
rule: ['required'],
msg: ['请选择种植物种'],
},
{
name: 'totalArea',
rule: ['required'],
msg: ['请输入总面积'],
},
{
name: 'farmProfiles',
rule: ['required'],
msg: ['请输入农场简介'],
},
{
name: 'owner',
rule: ['required'],
msg: ['请输入农场主姓名'],
},
{
name: 'ownerPhone',
rule: ['required'],
msg: ['请输入农场主电话'],
},
{
name: 'provinceName',
rule: ['required'],
msg: ['请选择归属省份'],
},
{
name: 'addressDetail',
rule: ['required'],
msg: ['请填写详细地址'],
},
],
})
function initDict() {
pageData.options.address = areaTree
pageData.options.mainProducts = dictStore.getDictList.main_business.map((item) => {
return {
value: item.value,
text: item.text,
}
})
pageData.options.farmType = dictStore.getDictList.farm_type.map((item) => {
return {
value: item.value,
text: item.text,
}
})
}
function handleChangeFarmType(e) {
pageData.form.farmType = e.value
pageData.form.farmTypeText = e.text
pageData.show.farmType = false
}
function handleChangeGrowCrops(e) {
pageData.form.growCrops = e.value
pageData.form.growCropsText = e.text
pageData.show.mainProducts = false
}
function handleChangeAddress(e) {
pageData.form.provinceName = e.text[0]
pageData.form.cityName = e.text[1]
pageData.form.districtName = e.text[2]
pageData.form.provinceText = e.text[0] + '/' + e.text[1] + '/' + e.text[2]
pageData.show.address = false
}
const toastRef = ref()
const uploadRef = ref()
// 文件上传
function handleUpload(file) {
pageData.loading = true
uni.uploadFile({
url: `${globSetting.apiUrl + globSetting.urlPrefix}/sys/common/upload`, // 直接使用上传接口URL
filePath: file.tempFiles[0].path,
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) {
toastRef.value.show({
type: 'success',
text: '上传成功',
}) })
pageData.form.coverImage = data.message // 保存返回的图片信息
}
} }
}) },
} fail: (err) => {
toastRef.value.show({
type: 'error',
text: '上传失败',
})
uploadRef.value.clearFiles()
pageData.form.coverImage = null
},
complete: () => {
pageData.loading = false
},
})
}
// 文件删除
function handleDelete(file) {
uploadRef.value.clearFiles()
pageData.form.coverImage = null
}
const formRef = ref()
function submit() {
formRef.value.validator(pageData.form, pageData.rules, true).then((res) => {
if (res.isPassed) {
pageData.loading = true
const apiCall = pageData.form.id ? NongchangAPI.farmsEdit : NongchangAPI.farmsAdd
apiCall(pageData.form)
.then(() => {
toastRef.value.show({
type: 'success',
text: pageData.form.id ? '保存修改成功' : '添加农场成功',
})
setTimeout(() => {
uni.navigateBack()
}, 500);
})
.finally(() => {
pageData.loading = false
})
}
})
}
</script> </script>
<template> <template>
<fui-form ref="formRef"> <view class="page">
<fui-input required label="农场名称" placeholder="请输入农场名称" v-model="form.farmName" /> <view class="page-container">
<fui-input required label="农场标语" placeholder="请输入农场标语" v-model="form.title" /> <fui-form ref="formRef">
<fui-input <!-- 第一组表单 -->
required <view class="form-card">
label="农场类型" <fui-input
placeholder="请选择农场类型" required
v-model="form.farmTypeText" label="农场名称"
@click="show.farmType = true" labelSize="28"
/> size="28"
<fui-input required label="联系人" placeholder="请输入联系人" v-model="form.contactPerson" /> :labelWeight="400"
<fui-input required label="联系电话" placeholder="请输入联系电话" v-model="form.contactPhone" /> labelWidth="auto"
<fui-textarea required label="农场描述" placeholder="请输入农场描述" v-model="pageData.form.description" /> placeholder="请输入农场名称"
<fui-input required label="地区" placeholder="请选择地区" v-model="form.address" @click="show.address = true" /> v-model="pageData.form.farmName"
<fui-input required label="详细地址" placeholder="请输入详细地址" v-model="form.addressDetail" /> />
<fui-input required label="主营业务" borderTop placeholder="请输入主营业务" v-model="form.mainBusiness" /> <fui-form-item
<fui-input required
required asterisk
label="主要产品" label="农场类型"
borderTop labelSize="28"
placeholder="请选择主要产品" :labelWeight="400"
v-model="form.mainProductsText" labelWidth="auto"
@click="show.mainProducts = true" >
/> <view class="time-input" @click="pageData.show.farmType = true">
<fui-input required label="总面积(亩)" borderTop placeholder="请输入总面积" v-model="form.totalArea" /> <text class="select-text" :class="{ placeholder: !pageData.form.farmTypeText }">
<view class="bg-white" style="padding: 0.875rem 0.35rem"> {{ pageData.form.farmTypeText || '请选择农场类型' }}
<view class="mb-1 flex justify-start"> 封面图片 </view> </text>
<uni-file-picker </view>
ref="uploadRef" </fui-form-item>
limit="1" <!-- <view class="fui-input-wrapper" @click="pageData.show.farmType = true">
:auto-upload="false" <fui-input
@select="handleUpload" required
@delete="handleDelete" readonly
/> label="农场类型"
</view> placeholder="请选择农场类型"
<view class="fui-btn__box bg-white p-4"> v-model="pageData.form.farmTypeText"
<fui-button text="添加农场" bold radius="96rpx" @click="submit" /> 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"
/>
</view> -->
<fui-input
required
labelWidth="auto"
labelSize="28"
:labelWeight="400"
size="28"
label="详细地址"
placeholder="请输入详细地址"
v-model="pageData.form.addressDetail"
/>
<fui-form-item
required
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
ref="uploadRef"
limit="1"
:auto-upload="false"
@select="handleUpload"
@delete="handleDelete"
/>
</view>
</view>
</view>
<view class="submit-btn-box">
<fui-button :text="pageData.form.id ? '保存修改' : '添加基地'" bold radius="96rpx" @click="submit" />
</view>
</fui-form>
</view> </view>
</fui-form>
<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 {
border-color: #ff9800 !important; background: #e8f5e9;
background: #ff9800 !important; 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;
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()
id: '', })
name: '', const model = reactive({
lonlat: '', id: '',
address: '', name: '',
description: '', lonlat: '',
// 地块、位置信息 GeoJSON address: '',
plots: [], description: '',
// 设备信息 // 地块、位置信息 GeoJSON
devices: [], plots: [],
// 设备信息
// 天气信息 devices: [],
weather: {
live: { // 天气信息
tem: '12°', weather: {
live: {
tem: '12°',
phenomena: '',
wind: '',
humidity: '',
},
forecast: [
{
phenomena: '', phenomena: '',
wind: '', date: '',
humidity: '', maxTem: '',
minTem: '',
}, },
forecast: [ ],
{ },
phenomena: '', // 预报日期
date: '', forecasts: ['29日', '30日', '1日', '2日', '3日'],
maxTem: '', clicked: 0,
minTem: '', farmbaseInfo: {},
}, farmbaseInfoList: [],
], deviceTypeCount: [],
}, })
// 预报日期 async function getFarmbaseInfoList() {
forecasts: ['29日', '30日', '1日', '2日', '3日'], farmbaseApi
clicked: 0, .list({
farmbaseInfo: {}, farmId: model.id,
farmbaseInfoList: [], })
deviceTypeCount: [], .then((res) => {
const { records } = res
model.farmbaseInfoList = records
if (records.length > 0) {
getFarmbaseInfoById(records[0].id)
}
})
}
async function getFarmbaseInfoById(id) {
farmbaseApi.getFarmbaseInfoById({ id }).then((res) => {
model.farmbaseInfo = res
getDeviceTypeCount()
}) })
}
async function getFarmbaseInfoList() { async function getDeviceTypeCount() {
farmbaseApi farmbaseApi.getDeviceTypeCount({ farmId: model.id, farmBaseId: model.farmbaseInfo?.id }).then((res) => {
.list({ model.deviceTypeCount = res
farmId: model.id, })
}) }
.then((res) => {
const { records } = res // 地图组件
model.farmbaseInfoList = records const [registerMap, map] = useMapbox({
style: { zoom: 15 },
if (records.length > 0) { onLoaded: async (data) => {
getFarmbaseInfoById(records[0].id) console.log('✨✨✨ Map Loaded', data)
}
}) // 查询农场数据
} const res = await NongchangAPI.farmsList()
console.log('农场列表', res.records)
// 获取第一个农场信息
const item = res.records?.[0]
model.id = item.id
model.name = item.farmName
model.description = item.description
if (item.longitude && item.latitude) {
model.lonlat = `${item.longitude},${item.latitude}`
} else {
// 模拟位置数据
model.lonlat = '111.024108, 29.554847'
Message.toast('未设置农场坐标位置,已使用模拟位置数据')
}
async function getFarmbaseInfoById(id) { // 设置页面标题
farmbaseApi.getFarmbaseInfoById({ id }).then((res) => { uni.setNavigationBarTitle({
model.farmbaseInfo = res title: item.farmName,
getDeviceTypeCount()
}) })
} // 设置地图中心点
map.flyTo({
async function getDeviceTypeCount() { center: model.lonlat.split(',').map(Number) as [number, number],
farmbaseApi.getDeviceTypeCount({ farmId: model.id, farmBaseId: model.farmbaseInfo?.id }).then((res) => { duration: 0,
model.deviceTypeCount = res
}) })
}
// 地图组件
const [registerMap, map] = useMapbox({
style: { zoom: 15 },
onLoaded: async (data) => {
console.log('✨✨✨ Map Loaded', data)
// 查询农场数据
const res = await NongchangAPI.farmsList()
console.log('农场列表', res.records)
// 获取第一个农场信息
const item = res.records?.[0]
model.id = item.id
model.name = item.farmName
model.description = item.description
if (item.longitude && item.latitude) {
model.lonlat = `${item.longitude},${item.latitude}`
} else {
// 模拟位置数据
model.lonlat = '111.024108, 29.554847'
Message.toast('未设置农场坐标位置,已使用模拟位置数据')
}
// 设置页面标题 // 渲染地块数据
uni.setNavigationBarTitle({ model.plots = [
title: item.farmName, turf.polygon(
}) [
// 设置地图中心点
map.flyTo({
center: model.lonlat.split(',').map(Number) as [number, number],
duration: 0,
})
// 渲染地块数据
model.plots = [
turf.polygon(
[ [
[ [111.0235, 29.5562],
[111.0235, 29.5562], [111.0255, 29.5562],
[111.0255, 29.5562], [111.0255, 29.5558],
[111.0255, 29.5558], [111.0235, 29.5558],
[111.0235, 29.5558], [111.0235, 29.5562],
[111.0235, 29.5562],
],
], ],
{ ],
color: 'yellow', {
name: '基地 A', color: 'yellow',
popup: `{{name}}`, name: '基地 A',
}, popup: `{{name}}`,
), },
turf.polygon( ),
turf.polygon(
[
[ [
[ [111.0225, 29.5565],
[111.0225, 29.5565], [111.0238, 29.5568],
[111.0238, 29.5568], [111.023, 29.5555],
[111.023, 29.5555], [111.022, 29.5558],
[111.022, 29.5558], [111.0225, 29.5565],
[111.0225, 29.5565],
],
], ],
{ ],
color: 'red', {
name: '基地 B', color: 'red',
popup: `{{name}}`, name: '基地 B',
}, popup: `{{name}}`,
), },
turf.polygon( ),
turf.polygon(
[
[ [
[ [111.0258, 29.555],
[111.0258, 29.555], [111.0262, 29.5542],
[111.0262, 29.5542], [111.0252, 29.554],
[111.0252, 29.554], [111.0258, 29.555],
[111.0258, 29.555],
],
], ],
{ ],
color: 'blue', {
name: '基地 C', color: 'blue',
popup: `{{name}}`, name: '基地 C',
},
),
]
addDefaultGeoJSONSource(map, `${page.id}-plot`, model.plots)
addDefaultSplotLayer(map, `${page.id}-plot`, {
paint: {
'fill-opacity': 0.2,
'fill-outline-color': ['get', 'color'],
},
})
map.addLayer({
type: 'line',
id: `${page.id}-plot-line`,
source: `${page.id}-plot`,
layout: {
'line-join': 'round',
'line-cap': 'round',
},
paint: {
'line-color': ['get', 'color'],
'line-width': 2,
},
})
// 渲染设备数据
model.devices = [
turf.point([111.024108, 29.554847], {
name: '设备1',
description: '设备1描述',
icon: 'GD',
popup: `{{name}}`,
}),
turf.point([111.023139, 29.55539], {
name: '设备2',
description: '设备2描述',
icon: 'JCD',
popup: `{{name}}`,
}),
turf.point([111.024989, 29.555435], {
name: '设备3',
description: '设备3描述',
icon: 'BZ',
popup: `{{name}}`, popup: `{{name}}`,
}),
]
addDefaultGeoJSONSource(map, `${page.id}-symbol`, model.devices)
addDefaultSymbolLayer(map, `${page.id}-symbol`, {
layout: {
'text-field': '',
'icon-image': ['get', 'icon'],
'icon-size': 1,
}, },
}) ),
]
addDefaultGeoJSONSource(map, `${page.id}-plot`, model.plots)
addDefaultSplotLayer(map, `${page.id}-plot`, {
paint: {
'fill-opacity': 0.2,
'fill-outline-color': ['get', 'color'],
},
})
map.addLayer({
type: 'line',
id: `${page.id}-plot-line`,
source: `${page.id}-plot`,
layout: {
'line-join': 'round',
'line-cap': 'round',
},
paint: {
'line-color': ['get', 'color'],
'line-width': 2,
},
})
// 查询农场信息 // 渲染设备数据
getFarmbaseInfoList() model.devices = [
}, turf.point([111.024108, 29.554847], {
onSourceRequestHandle: () => { name: '设备1',
page.requests-- description: '设备1描述',
if (page.requests === 0) { icon: 'GD',
Message.hideLoading() popup: `{{name}}`,
} }),
}, turf.point([111.023139, 29.55539], {
onSourceRequestErrorHandle: () => { name: '设备2',
Message.hideLoading() description: '设备2描述',
}, icon: 'JCD',
}) popup: `{{name}}`,
}),
turf.point([111.024989, 29.555435], {
name: '设备3',
description: '设备3描述',
icon: 'BZ',
popup: `{{name}}`,
}),
]
addDefaultGeoJSONSource(map, `${page.id}-symbol`, model.devices)
addDefaultSymbolLayer(map, `${page.id}-symbol`, {
layout: {
'text-field': '',
'icon-image': ['get', 'icon'],
'icon-size': 1,
},
})
// 左侧工具栏小部件 // 查询农场信息
const [registerToolBoxWidget] = useToolBoxWidget({ getFarmbaseInfoList()
show: true, },
expand: true, onSourceRequestHandle: () => {
showExpandButton: false, page.requests--
top: -90, if (page.requests === 0) {
tools: [ Message.hideLoading()
{ }
key: 'action', },
align: 'top', onSourceRequestErrorHandle: () => {
buttons: [ Message.hideLoading()
{ },
name: '设备', })
color: '#75c849',
icon: '/static/images/codefun/device.active.png', // 左侧工具栏小部件
type: 'toggle', const [registerToolBoxWidget] = useToolBoxWidget({
handle: (e: ToolBoxButtonHandleEvent) => { show: true,
// 切换显示设备数据地图渲染 expand: true,
const active = e.button.icon === '/static/images/codefun/device.active.png' showExpandButton: false,
if (active) { top: -90,
e.button.color = '#666666' tools: [
e.button.icon = '/static/images/codefun/device.png' {
map.setLayoutProperty(`${page.id}-symbol`, 'visibility', 'none') key: 'action',
} else { align: 'top',
e.button.color = '#75c849' buttons: [
e.button.icon = '/static/images/codefun/device.active.png' {
map.setLayoutProperty(`${page.id}-symbol`, 'visibility', 'visible') name: '设备',
} color: '#75c849',
}, icon: '/static/images/codefun/device.active.png',
type: 'toggle',
handle: (e: ToolBoxButtonHandleEvent) => {
// 切换显示设备数据地图渲染
const active = e.button.icon === '/static/images/codefun/device.active.png'
if (active) {
e.button.color = '#666666'
e.button.icon = '/static/images/codefun/device.png'
map.setLayoutProperty(`${page.id}-symbol`, 'visibility', 'none')
} else {
e.button.color = '#75c849'
e.button.icon = '/static/images/codefun/device.active.png'
map.setLayoutProperty(`${page.id}-symbol`, 'visibility', 'visible')
}
}, },
], },
}, ],
{ },
key: 'action', {
align: 'top', key: 'action',
buttons: [ align: 'top',
{ buttons: [
name: '降雨', {
icon: '/static/images/codefun/rain.png', name: '降雨',
type: 'button', icon: '/static/images/codefun/rain.png',
handle: () => { type: 'button',
Message.toast('暂无降雨数据') handle: () => {
}, Message.toast('暂无降雨数据')
}, },
{ },
name: '温度', {
icon: '/static/images/codefun/temp.png', name: '温度',
type: 'button', icon: '/static/images/codefun/temp.png',
handle: () => { type: 'button',
Message.toast('暂无温度数据') handle: () => {
}, Message.toast('暂无温度数据')
}, },
{ },
name: '强对流', {
icon: '/static/images/codefun/severe.png', name: '强对流',
type: 'button', icon: '/static/images/codefun/severe.png',
handle: () => { type: 'button',
Message.toast('暂无强对流数据') handle: () => {
}, Message.toast('暂无强对流数据')
}, },
{ },
name: '大风', {
icon: '/static/images/codefun/wind.png', name: '大风',
type: 'button', icon: '/static/images/codefun/wind.png',
handle: () => { type: 'button',
Message.toast('暂无大风数据') handle: () => {
}, Message.toast('暂无大风数据')
}, },
{ },
name: '其他', {
icon: '/static/images/codefun/other.png', name: '其他',
type: 'button', icon: '/static/images/codefun/other.png',
handle: () => { type: 'button',
Message.alert('敬请期待~', '温馨提醒') handle: () => {
}, Message.alert('敬请期待~', '温馨提醒')
}, },
], },
}, ],
], },
}) ],
})
onNavigationBarButtonTap((e) => { // 自定义导航栏回调函数
if (e.index === 0) { function onBackClick() {
Navigate.to(`/pages/jidiguanli/add?farmId=${model.id}`) uni.navigateBack({
} delta: 1,
}) })
}
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) {
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,105 +391,115 @@ ...@@ -351,105 +391,115 @@
</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 class="box-1"> <view style="background: #e6f5e8">
<view class="relative w-full flex flex-row"> <view class="box-1">
<view class="box-1-left" <view class="relative w-full flex flex-row">
><image class="image_1" src="/static/images/nongchang/play.png" <view class="box-1-left"
/></view> ><image class="image_1" src="/static/images/nongchang/play.png"
<view class="box-1-right"> /></view>
<view class="box-1-right-top"> <view class="box-1-right">
<view class="text_1">预报</view> <view class="box-1-right-top">
<view class="text_1">预报</view>
</view>
<view class="box-1-right-bottom"
><text
v-for="(forecast, index) in model.forecasts"
:class="model.clicked === index ? 'active' : ''"
:key="index"
>{{ forecast }}</text
></view
>
</view> </view>
<view class="box-1-right-bottom"
><text
v-for="(forecast, index) in model.forecasts"
:class="model.clicked === index ? 'active' : ''"
:key="index"
>{{ forecast }}</text
></view
>
</view>
</view>
</view>
<view class="box-2">
<view class="box-2-left">
<view class="box-2-left-top">
<text class="box-2-left-top-text1">12°</text>
<text class="box-2-left-top-text2">多云</text>
</view>
<view class="box-2-left-bottom">
<text class="box-2-left-bottom-text1">北风2级 | 湿度62%</text>
</view> </view>
</view> </view>
<view class="box-2-right"> <view class="box-2">
<view class="box-2-right-item"> <view class="box-2-left">
<text class="box-2-right-text1">15°-19°</text> <view class="box-2-left-top">
<text class="box-2-right-text2">今天 阴</text> <text class="box-2-left-top-text1">12°</text>
</view> <text class="box-2-left-top-text2">多云</text>
<view class="box-2-right-interval" /> </view>
<view class="box-2-right-item"> <view class="box-2-left-bottom">
<text class="box-2-right-text1">17°-21°</text> <text class="box-2-left-bottom-text1">北风2级 | 湿度62%</text>
<text class="box-2-right-text2">明天 多云</text> </view>
</view> </view>
</view> <view class="box-2-right">
</view> <view class="box-2-right-item">
<view class="box-3"> <text class="box-2-right-text1">15°-19°</text>
<view class="box-3-tags"> <text class="box-2-right-text2">今天 阴</text>
<view </view>
class="box-3-tags-item" <view class="box-2-right-interval" />
:class="model.farmbaseInfo.id === farmbase.id ? 'box-3-tags-item-active' : ''" <view class="box-2-right-item">
v-for="farmbase in model.farmbaseInfoList" <text class="box-2-right-text1">17°-21°</text>
:key="farmbase.id" <text class="box-2-right-text2">明天 多云</text>
>
<view @click="getFarmbaseInfoById(farmbase.id)">
<text>{{ farmbase.baseName }}</text>
</view> </view>
</view> </view>
</view> </view>
<view class="box-3-info"> <view class="box-3">
<view class="box-3-info-item"> <view class="box-3-tags">
<view class="box-3-info-item-text-box"> <view
<text class="box-3-info-item-text1">总面积: </text> class="box-3-tags-item"
<text class="box-3-info-item-text2">{{ model.farmbaseInfo.scale }}</text> :class="model.farmbaseInfo.id === farmbase.id ? 'box-3-tags-item-active' : ''"
v-for="farmbase in model.farmbaseInfoList"
:key="farmbase.id"
>
<view @click="getFarmbaseInfoById(farmbase.id)">
<text>{{ farmbase.baseName }}</text>
</view>
</view> </view>
</view> </view>
<view class="box-3-info-item justify-between"> <view class="box-3-info">
<view class="box-3-info-item-text-box"> <view class="box-3-info-item">
<text class="box-3-info-item-text1">种植: </text> <view class="box-3-info-item-text-box">
<text class="box-3-info-item-text2">{{ model.farmbaseInfo.plantedCrops }}</text> <text class="box-3-info-item-text1">总面积: </text>
<text class="box-3-info-item-text2">{{ model.farmbaseInfo.scale }}</text>
</view>
</view> </view>
<view class="box-3-info-item-text-box"> <view class="box-3-info-item justify-between">
<text class="box-3-info-item-text1">预计产量: </text> <view class="box-3-info-item-text-box">
<text class="box-3-info-item-text2" /> <text class="box-3-info-item-text1">种植: </text>
<text class="box-3-info-item-text2">{{
model.farmbaseInfo.growCrops_dictText
}}</text>
</view>
<view class="box-3-info-item-text-box">
<text class="box-3-info-item-text1">预计产量: </text>
<text class="box-3-info-item-text2" />
</view>
</view> </view>
</view> <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.managerName }}</text>
<text class="box-3-info-item-text2">{{ model.farmbaseInfo.managerName }}</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> <text class="box-3-info-item-text2">{{ model.farmbaseInfo.contactPhone }}</text>
<text class="box-3-info-item-text2">{{ model.farmbaseInfo.contactPhone }}</text> </view>
</view> </view>
</view> </view>
</view> </view>
</view> <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"
<navigator url="/pages/device/device" class="box-4-title-text2"><text>+ 添加设备</text></navigator> ><text>+ 添加设备</text></navigator
</view> >
<view class="box-4-device"> </view>
<view class="box-4-device-item" v-for="(device, index) in model.deviceTypeCount" :key="index"> <view class="box-4-device">
<view class="box-4-item-icon"> <view
<image class="box-4-item-icon-image" src="/static/images/nongchang/jiankong.png" /> class="box-4-device-item"
</view> v-for="(device, index) in model.deviceTypeCount"
<view class="box-4-item-content"> :key="index"
<text class="box-4-item-text1">{{ device.deviceName }}</text> >
<text class="box-4-item-text2">{{ device.deviceCount }}</text> <view class="box-4-item-icon">
<image class="box-4-item-icon-image" src="/static/images/nongchang/jiankong.png" />
</view>
<view class="box-4-item-content">
<text class="box-4-item-text1">{{ device.deviceName }}</text>
<text class="box-4-item-text2">{{ device.deviceCount }}</text>
</view>
</view> </view>
</view> </view>
</view> </view>
...@@ -460,311 +510,422 @@ ...@@ -460,311 +510,422 @@
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>
// //
page { page {
background-color: #e6f5e8; background-color: #e6f5e8;
} }
.page { .page {
position: relative; position: relative;
background-color: #e6f5e8; min-height: 100vh;
background-color: #e6f5e8;
.map-box {
// #ifdef APP-PLUS // 自定义导航栏样式
position: relative; .custom-navbar {
top: 0; position: fixed;
// #endif top: 0;
// #ifdef H5 left: 0;
position: relative; right: 0;
top: 0; z-index: 999;
// #endif 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;
.card { .back-icon {
width: 100%; width: 60rpx;
background-color: #e6f5e8; height: 60rpx;
position: absolute; display: flex;
font-weight: 400; align-items: center;
font-family: '思源黑体'; 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);
}
}
}
.box-1 { .navbar-center {
width: 95%; flex: 1;
height: 80rpx;
background-color: #fff;
margin: 20rpx;
border-radius: 18rpx;
display: flex; display: flex;
flex-direction: row; align-items: center;
justify-content: center;
position: relative;
.navbar-title {
color: #fff;
font-size: 32rpx;
font-weight: 600;
// margin-right: 10rpx;
}
.box-1-left { .navbar-icon {
width: 50rpx;
height: 100%;
margin-left: 20rpx;
display: flex; display: flex;
align-items: center; 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;
}
.image_1 { &:active {
width: 50rpx; background-color: rgba(255, 255, 255, 0.3);
height: 50rpx; transform: scale(0.9);
}
&:hover {
background-color: rgba(255, 255, 255, 0.25);
} }
} }
}
.box-1-right { .navbar-right {
width: calc(100% - 80rpx); width: 180rpx;
height: 100%; display: flex;
margin-left: 20rpx; justify-content: flex-end;
display: flex;
flex-direction: column;
.box-1-right-top { .add-base-btn {
// height: 50%; color: #fff;
background-image: url('/static/images/nongchang/yubaobeijing.png'); font-size: 26rpx;
background-size: 100% 100%; padding: 12rpx 20rpx;
background-repeat: no-repeat; transition: all 0.3s ease;
.text_1 { &:active {
font-size: 25rpx; background-color: rgba(255, 255, 255, 0.3);
color: #5db66f; transform: scale(0.95);
text-align: center;
}
} }
.box-1-right-bottom { &:hover {
// height: 50%; background-color: rgba(255, 255, 255, 0.25);
display: flex;
flex-direction: row;
justify-content: space-around;
color: #999999;
font-size: 24rpx;
.active {
color: #cccccc;
}
} }
} }
} }
}
}
// 导航栏占位空间
.navbar-placeholder {
height: calc(88rpx + var(--status-bar-height, 44rpx));
}
.box-2 { .map-box {
width: 95%; // #ifdef APP-PLUS
height: 150rpx; position: relative;
margin: 20rpx; top: 0;
// #endif
// #ifdef H5
position: relative;
top: 0;
// #endif
}
.card {
width: 100%;
background-color: #e6f5e8;
position: absolute;
font-weight: 400;
font-family: '思源黑体';
.box-1 {
width: 95%;
height: 80rpx;
background-color: #fff;
margin: 20rpx;
border-radius: 18rpx;
display: flex;
flex-direction: row;
.box-1-left {
width: 50rpx;
height: 100%;
margin-left: 20rpx;
display: flex; display: flex;
flex-direction: row; align-items: center;
.box-2-left { .image_1 {
width: 35%; width: 50rpx;
display: flex; height: 50rpx;
flex-direction: column; }
justify-content: space-around; }
padding: 10rpx;
margin-right: 20rpx;
background-color: #fff;
border-radius: 18rpx;
line-height: 100%;
.box-2-left-top { .box-1-right {
display: flex; width: calc(100% - 80rpx);
flex-direction: row; height: 100%;
justify-content: space-around; margin-left: 20rpx;
.box-2-left-top-text1 { display: flex;
font-size: 50rpx; flex-direction: column;
font-weight: bold;
color: #333333;
}
.box-2-left-top-text2 { .box-1-right-top {
font-size: 32rpx; // height: 50%;
color: #555555; background-image: url('/static/images/nongchang/yubaobeijing.png');
} background-size: 100% 100%;
} background-repeat: no-repeat;
.box-2-left-bottom { .text_1 {
display: flex; font-size: 25rpx;
flex-direction: row; color: #5db66f;
justify-content: space-around; text-align: center;
line-height: 100%;
.box-2-left-bottom-text1 {
font-size: 24rpx;
color: #555555;
}
} }
} }
.box-2-right { .box-1-right-bottom {
width: 62%; // height: 50%;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: space-around; justify-content: space-around;
margin-right: 20rpx; color: #999999;
background-color: #fff; font-size: 24rpx;
border-radius: 18rpx;
line-height: 100%;
.box-2-right-item { .active {
width: 50%; color: #cccccc;
display: flex;
flex-direction: column;
justify-content: space-around;
text-align: center;
.box-2-right-text1 {
font-size: 42rpx;
font-weight: bold;
color: #333333;
}
.box-2-right-text2 {
font-size: 24rpx;
color: #555555;
}
}
.box-2-right-interval {
width: 1px;
height: 80%;
margin: auto;
background-color: #eeeeee;
} }
} }
} }
}
.box-3 { .box-2 {
width: 95%; width: 95%;
height: 280rpx; height: 150rpx;
margin: 20rpx; margin: 20rpx;
padding: 0 20rpx; display: flex;
background-color: #fff; flex-direction: row;
border-radius: 18rpx;
.box-2-left {
width: 35%;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: space-around; justify-content: space-around;
padding: 10rpx;
margin-right: 20rpx;
background-color: #fff;
border-radius: 18rpx;
line-height: 100%;
.box-3-tags { .box-2-left-top {
width: 100%;
height: 70rpx;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
font-size: 28rpx; justify-content: space-around;
.box-2-left-top-text1 {
font-size: 50rpx;
font-weight: bold;
color: #333333;
}
.box-3-tags-item { .box-2-left-top-text2 {
width: 31%; font-size: 32rpx;
height: 100%; color: #555555;
margin-right: 20rpx;
text-align: center;
line-height: 70rpx;
border-radius: 48rpx;
background-color: rgba($color: #5db66f, $alpha: 0.1);
color: #5db66f;
font-weight: 300;
} }
}
.box-3-tags-item-active { .box-2-left-bottom {
background-color: #5db66f !important; display: flex;
color: #fff !important; flex-direction: row;
justify-content: space-around;
line-height: 100%;
.box-2-left-bottom-text1 {
font-size: 24rpx;
color: #555555;
} }
} }
}
.box-3-info { .box-2-right {
width: 100%; width: 62%;
height: calc(100% - 120rpx); display: flex;
flex-direction: row;
justify-content: space-around;
margin-right: 20rpx;
background-color: #fff;
border-radius: 18rpx;
line-height: 100%;
.box-2-right-item {
width: 50%;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: space-around; justify-content: space-around;
text-align: center;
.box-2-right-text1 {
font-size: 42rpx;
font-weight: bold;
color: #333333;
}
.box-3-info-item { .box-2-right-text2 {
display: flex; font-size: 24rpx;
flex-direction: row; color: #555555;
}
}
.box-2-right-interval {
width: 1px;
height: 80%;
margin: auto;
background-color: #eeeeee;
}
}
}
.box-3-info-item-text-box { .box-3 {
width: 50%; width: 95%;
height: 280rpx;
margin: 20rpx;
padding: 0 20rpx;
background-color: #fff;
border-radius: 18rpx;
display: flex;
flex-direction: column;
justify-content: space-around;
.box-3-tags {
width: 100%;
height: 70rpx;
display: flex;
flex-direction: row;
font-size: 28rpx;
.box-3-info-item-text1 { .box-3-tags-item {
font-size: 26rpx; width: 31%;
color: #999999; height: 100%;
margin-right: 10rpx; margin-right: 20rpx;
} text-align: center;
line-height: 70rpx;
border-radius: 48rpx;
background-color: rgba($color: #5db66f, $alpha: 0.1);
color: #5db66f;
font-weight: 300;
}
.box-3-info-item-text2 { .box-3-tags-item-active {
font-size: 30rpx; background-color: #5db66f !important;
color: #333333; color: #fff !important;
}
}
}
} }
} }
.box-4 { .box-3-info {
width: 95%; width: 100%;
margin: 30rpx 20rpx 0 20rpx; height: calc(100% - 120rpx);
border-radius: 18rpx; display: flex;
flex-direction: column;
justify-content: space-around;
.box-4-title { .box-3-info-item {
width: 100%;
height: 50rpx;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: space-between;
.box-4-title-text1 { .box-3-info-item-text-box {
font-size: 30rpx; width: 50%;
color: #333333;
font-weight: bold;
}
.box-4-title-text2 { .box-3-info-item-text1 {
font-size: 28rpx; font-size: 26rpx;
color: #5db66f; color: #999999;
margin-right: 10rpx;
}
.box-3-info-item-text2 {
font-size: 30rpx;
color: #333333;
}
} }
} }
}
}
.box-4 {
width: 95%;
margin: 30rpx 20rpx 0 20rpx;
border-radius: 18rpx;
.box-4-title {
width: 100%;
height: 50rpx;
display: flex;
flex-direction: row;
justify-content: space-between;
.box-4-title-text1 {
font-size: 30rpx;
color: #333333;
font-weight: bold;
}
.box-4-title-text2 {
font-size: 28rpx;
color: #5db66f;
}
}
.box-4-device { .box-4-device {
width: 100%; width: 100%;
height: calc(100% - 50rpx); height: calc(100% - 50rpx);
margin-top: 10rpx; margin-top: 10rpx;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
.box-4-device-item {
width: 49%;
height: 48%;
display: flex; display: flex;
flex-wrap: wrap; flex-direction: row;
justify-content: space-between; border-radius: 24rpx;
background-color: #fff;
margin-bottom: 10rpx;
.box-4-device-item { .box-4-item-icon {
width: 49%; width: 80rpx;
height: 48%; height: 100%;
margin: 0 25rpx;
display: flex; display: flex;
flex-direction: row; align-items: center;
border-radius: 24rpx;
background-color: #fff;
margin-bottom: 10rpx;
.box-4-item-icon {
width: 80rpx;
height: 100%;
margin: 0 25rpx;
display: flex;
align-items: center;
.box-4-item-icon-image {
width: 100%;
height: 80rpx;
}
}
.box-4-item-content { .box-4-item-icon-image {
width: 100%; width: 100%;
height: 100%; height: 80rpx;
display: flex; }
justify-content: center; }
flex-direction: column;
.box-4-item-content {
.box-4-item-text1 { width: 100%;
font-size: 30rpx; height: 100%;
color: #333333; display: flex;
} justify-content: center;
flex-direction: column;
.box-4-item-text2 {
font-size: 26rpx; .box-4-item-text1 {
color: #5db66f; font-size: 30rpx;
} color: #333333;
}
.box-4-item-text2 {
font-size: 26rpx;
color: #5db66f;
} }
} }
} }
} }
} }
} }
}
</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 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论