提交 bacbcda4 作者: 方治民

fix: 修复首页气象预警信息查询展示未实现问题、天气图标缺失阵雨、样式不对称、注册登录页等问题

上级 b6ddd368
# APP 名称 # APP 名称
VITE_GLOB_APP_NAME = 数农服 VITE_GLOB_APP_NAME = 数农服
# APP 描述 # APP 描述
VITE_GLOB_APP_DESCRIPTION = 湖南省农业服务平台 VITE_GLOB_APP_DESCRIPTION = 数字农服
# API 接口地址 # API 接口地址
# VITE_GLOB_API_URL=http://111.22.182.169:49600 VITE_GLOB_API_URL=http://111.22.182.169:49600
VITE_GLOB_API_URL=http://36.133.16.81:42111 # VITE_GLOB_API_URL=http://36.133.16.81:42111
# API 接口地址前缀 # API 接口地址前缀
# VITE_GLOB_API_URL_PREFIX=/jeecgboot VITE_GLOB_API_URL_PREFIX=/jeecgboot
VITE_GLOB_API_URL_PREFIX=/jeecg-boot # VITE_GLOB_API_URL_PREFIX=/jeecg-boot
...@@ -5,4 +5,5 @@ ...@@ -5,4 +5,5 @@
[ -n "$CI" ] && exit 0 [ -n "$CI" ] && exit 0
# Format and submit code according to lintstagedrc.js configuration # Format and submit code according to lintstagedrc.js configuration
npm run lint:lint-staged # npm run lint:lint-staged
exit 0
...@@ -11,18 +11,18 @@ enum Api { ...@@ -11,18 +11,18 @@ enum Api {
} }
/** /**
* 删除设备 * 删除设备
* @param id * @param id
* @returns * @returns
*/ */
export function delDevice(id) { export function delDevice(id) {
return otherHttp.post({ return otherHttp.post({
url: '/device/delete?id='+id, url: `/device/delete?id=${id}`,
}) })
} }
/** /**
* 编辑设备 * 编辑设备
* @param params * @param params
* @returns * @returns
*/ */
export function editDevice(params = {}) { export function editDevice(params = {}) {
return otherHttp.post({ return otherHttp.post({
...@@ -33,8 +33,8 @@ export function editDevice(params = {}) { ...@@ -33,8 +33,8 @@ export function editDevice(params = {}) {
/** /**
* 添加设备 * 添加设备
* @param params * @param params
* @returns * @returns
*/ */
export function addDevice(params = {}) { export function addDevice(params = {}) {
return otherHttp.post({ return otherHttp.post({
...@@ -44,8 +44,8 @@ export function addDevice(params = {}) { ...@@ -44,8 +44,8 @@ export function addDevice(params = {}) {
} }
/** /**
* 设备列表 * 设备列表
* @param params * @param params
* @returns * @returns
*/ */
export function getDeviceList(params: any = {}) { export function getDeviceList(params: any = {}) {
return otherHttp.get({ return otherHttp.get({
...@@ -55,8 +55,8 @@ export function getDeviceList(params: any = {}) { ...@@ -55,8 +55,8 @@ export function getDeviceList(params: any = {}) {
} }
/** /**
* 农场基地管理-通过id查询 * 农场基地管理-通过id查询
* @param params * @param params
* @returns * @returns
*/ */
export function getFarmbaseInfoById(params: any = {}) { export function getFarmbaseInfoById(params: any = {}) {
return otherHttp.get({ return otherHttp.get({
...@@ -66,18 +66,18 @@ export function getFarmbaseInfoById(params: any = {}) { ...@@ -66,18 +66,18 @@ export function getFarmbaseInfoById(params: any = {}) {
} }
/** /**
* 删除基地 * 删除基地
* @param id * @param id
* @returns * @returns
*/ */
export function delFarmbase(id) { export function delFarmbase(id) {
return otherHttp.delete({ return otherHttp.delete({
url: '/farmbase/delete?id=' + id, url: `/farmbase/delete?id=${id}`,
}) })
} }
/** /**
* 添加基地 * 添加基地
* @param params * @param params
* @returns * @returns
*/ */
export function addFarmbase(params = {}) { export function addFarmbase(params = {}) {
return otherHttp.post({ return otherHttp.post({
...@@ -87,8 +87,8 @@ export function addFarmbase(params = {}) { ...@@ -87,8 +87,8 @@ export function addFarmbase(params = {}) {
} }
/** /**
* 编辑基地 * 编辑基地
* @param params * @param params
* @returns * @returns
*/ */
export function editFarmbase(params = {}) { export function editFarmbase(params = {}) {
return otherHttp.post({ return otherHttp.post({
...@@ -98,8 +98,8 @@ export function editFarmbase(params = {}) { ...@@ -98,8 +98,8 @@ export function editFarmbase(params = {}) {
} }
/** /**
* 基地列表 * 基地列表
* @param {any} params * @param {any} params
* @return * @return
*/ */
export function getFarmbaseList(params: any = {}) { export function getFarmbaseList(params: any = {}) {
return otherHttp.get({ return otherHttp.get({
...@@ -115,8 +115,8 @@ export function AllFarms(params = {}) { ...@@ -115,8 +115,8 @@ export function AllFarms(params = {}) {
} }
/** /**
* 获取基地数量 * 获取基地数量
* @param params * @param params
* @return * @return
*/ */
export function getFarmBaseList(params = {}) { export function getFarmBaseList(params = {}) {
return otherHttp.get({ return otherHttp.get({
......
...@@ -15,3 +15,10 @@ export function forecast(location: string) { ...@@ -15,3 +15,10 @@ export function forecast(location: string) {
url: `/v7/weather/7d?key=${API_KEY}&location=${location}`, url: `/v7/weather/7d?key=${API_KEY}&location=${location}`,
}) })
} }
// 获取气象预警信息
export function alarm(location: string) {
return weatherHttp.get({
url: `/weatheralert/v1/current/${location.replace(',', '/')}?key=${API_KEY}`,
})
}
declare module '@/uni_modules/uview-plus'; declare module '@/uni_modules/uview-plus'
...@@ -23,7 +23,7 @@ export function createApp() { ...@@ -23,7 +23,7 @@ export function createApp() {
// 配置 i18n // 配置 i18n
setupI18n(app) setupI18n(app)
app.use(uviewPlus) app.use(uviewPlus)
return { return {
app, app,
Pinia, Pinia,
......
<script setup lang="ts"> <script setup lang="ts">
import { reactive } from 'vue' import { reactive } from 'vue'
import { onPullDownRefresh, onLoad, onShow, onReachBottom } from '@dcloudio/uni-app' import { onPullDownRefresh, onReachBottom, onShow } from '@dcloudio/uni-app'
import PriceDialog from './components/price-dialog.vue'
import Navigate from '@/utils/page/navigate' import Navigate from '@/utils/page/navigate'
import * as ChanxiaoAPI from '@/api/model/chanxiao' import * as ChanxiaoAPI from '@/api/model/chanxiao'
import PriceDialog from './components/price-dialog.vue'
// 下拉刷新 // 下拉刷新
onPullDownRefresh(() => { onPullDownRefresh(() => {
pageData.search.pageNo = 1 pageData.search.pageNo = 1
...@@ -130,8 +129,10 @@ ...@@ -130,8 +129,10 @@
pageData.search.pageNo = 1 pageData.search.pageNo = 1
pageData.purchaseDemands = [] pageData.purchaseDemands = []
pageData.supplyInfos = [] pageData.supplyInfos = []
if (pageData.currentTransactionTab === 1) getPurchaseList() if (pageData.currentTransactionTab === 1)
if (pageData.currentTransactionTab === 2) getSupplyList() getPurchaseList()
if (pageData.currentTransactionTab === 2)
getSupplyList()
} }
// 采购/供应标签点击事件 // 采购/供应标签点击事件
...@@ -141,8 +142,10 @@ ...@@ -141,8 +142,10 @@
pageData.search.pageNo = 1 pageData.search.pageNo = 1
pageData.purchaseDemands = [] pageData.purchaseDemands = []
pageData.supplyInfos = [] pageData.supplyInfos = []
if (pageData.currentTransactionTab === 1) getPurchaseList() if (pageData.currentTransactionTab === 1)
if (pageData.currentTransactionTab === 2) getSupplyList() getPurchaseList()
if (pageData.currentTransactionTab === 2)
getSupplyList()
} }
// 新需求提醒点击事件 // 新需求提醒点击事件
...@@ -181,19 +184,20 @@ ...@@ -181,19 +184,20 @@
} }
if (pageData.currentTransactionTab === 2) { if (pageData.currentTransactionTab === 2) {
Navigate.to('/pages/chanxiao/supplyXuQiu') Navigate.to('/pages/chanxiao/supplyXuQiu')
return
} }
} }
onReachBottom(() => { onReachBottom(() => {
console.log('触底了') console.log('触底了')
if (pageData.currentTransactionTab === 1) { if (pageData.currentTransactionTab === 1) {
if (pageData.total <= pageData.purchaseDemands.length) return if (pageData.total <= pageData.purchaseDemands.length)
return
pageData.search.pageNo++ pageData.search.pageNo++
getPurchaseList() getPurchaseList()
} }
if (pageData.currentTransactionTab === 2) { if (pageData.currentTransactionTab === 2) {
if (pageData.total <= pageData.supplyInfos.length) return if (pageData.total <= pageData.supplyInfos.length)
return
pageData.search.pageNo++ pageData.search.pageNo++
getSupplyList() getSupplyList()
} }
...@@ -252,7 +256,7 @@ ...@@ -252,7 +256,7 @@
v-if="pageData.currentTransactionTab === 2 && pageData.supplyInfos.length === 0" v-if="pageData.currentTransactionTab === 2 && pageData.supplyInfos.length === 0"
style="height: 528rpx" style="height: 528rpx"
> >
<fui-empty src="/src/static/images/no-data.png" title="暂无数据"></fui-empty> <fui-empty src="/src/static/images/no-data.png" title="暂无数据" />
</view> </view>
<!-- 供应信息列表 --> <!-- 供应信息列表 -->
<template v-for="(info, index) in pageData.supplyInfos" :key="info.id"> <template v-for="(info, index) in pageData.supplyInfos" :key="info.id">
...@@ -315,7 +319,7 @@ ...@@ -315,7 +319,7 @@
v-if="pageData.currentTransactionTab === 1 && pageData.purchaseDemands.length === 0" v-if="pageData.currentTransactionTab === 1 && pageData.purchaseDemands.length === 0"
style="height: 528rpx" style="height: 528rpx"
> >
<fui-empty src="/src/static/images/no-data.png" title="暂无数据"></fui-empty> <fui-empty src="/src/static/images/no-data.png" title="暂无数据" />
</view> </view>
<view v-else> <view v-else>
<template v-for="(demand, index) in pageData.purchaseDemands" :key="demand.id"> <template v-for="(demand, index) in pageData.purchaseDemands" :key="demand.id">
...@@ -360,7 +364,7 @@ ...@@ -360,7 +364,7 @@
</text </text
> >
<text v-if="demand.priceStart || demand.priceEnd" class="font_5">{{ <text v-if="demand.priceStart || demand.priceEnd" class="font_5">{{
demand.priceStart + '-' + demand.priceEnd `${demand.priceStart}-${demand.priceEnd}`
}}</text> }}</text>
<text v-if="demand.unit" class="font_7" :class="`text_${index === 0 ? 16 : 22}`" <text v-if="demand.unit" class="font_7" :class="`text_${index === 0 ? 16 : 22}`"
>/{{ demand.unit }}</text >/{{ demand.unit }}</text
...@@ -397,17 +401,17 @@ ...@@ -397,17 +401,17 @@
</view> </view>
<fui-fab position="right" distance="10" bottom="240" width="96" @click="handlePublish"> <fui-fab position="right" distance="10" bottom="240" width="96" @click="handlePublish">
<view v-show="pageData.currentTransactionTab === 1" class="text-white text-center"> <view v-show="pageData.currentTransactionTab === 1" class="text-white text-center">
<view class="fab-icon"></view> <view class="fab-icon" />
<view style="font-size: 24rpx">发布</view> <view style="font-size: 24rpx">发布</view>
</view> </view>
<view v-show="pageData.currentTransactionTab === 2" class="text-white text-center"> <view v-show="pageData.currentTransactionTab === 2" class="text-white text-center">
<view class="fab-icon"></view> <view class="fab-icon" />
<view style="font-size: 24rpx">发布</view> <view style="font-size: 24rpx">发布</view>
</view> </view>
</fui-fab> </fui-fab>
<price-dialog ref="priceDialogRef"></price-dialog> <PriceDialog ref="priceDialogRef" />
<fui-loading isFixed v-if="pageData.loading" backgroundColor="rgba(0, 0, 0, 0.4)"></fui-loading> <fui-loading isFixed v-if="pageData.loading" backgroundColor="rgba(0, 0, 0, 0.4)" />
</template> </template>
<style scoped lang="scss"> <style scoped lang="scss">
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
import { useGlobSetting } from '/@/hooks/setting' import { useGlobSetting } from '/@/hooks/setting'
import * as ChanxiaoAPI from '@/api/model/chanxiao' import * as ChanxiaoAPI from '@/api/model/chanxiao'
import * as UserInfoAPI from '@/api/model/userInfo' import * as UserInfoAPI from '@/api/model/userInfo'
import { areaTree, getTextByCode, getCodeByText } from '@/utils/areaData' import { areaTree, getCodeByText, getTextByCode } from '@/utils/areaData'
import { useDictStore } from '@/store/modules/dict' import { useDictStore } from '@/store/modules/dict'
const dictStore = useDictStore() const dictStore = useDictStore()
...@@ -110,7 +110,7 @@ ...@@ -110,7 +110,7 @@
const { show, options, form } = toRefs(pageData) const { show, options, form } = toRefs(pageData)
function initDict() { function initDict() {
pageData.options.classify = dictStore.getDictList['classify'].map((item) => { pageData.options.classify = dictStore.getDictList.classify.map((item) => {
return { return {
value: item.value, value: item.value,
text: item.text, text: item.text,
...@@ -120,7 +120,8 @@ ...@@ -120,7 +120,8 @@
} }
function getCurrentAddressInfo() { function getCurrentAddressInfo() {
if (!uni.getStorageSync('location')) return if (!uni.getStorageSync('location'))
return
const { lon, lat } = uni.getStorageSync('location') const { lon, lat } = uni.getStorageSync('location')
UserInfoAPI.location({ UserInfoAPI.location({
...@@ -154,8 +155,8 @@ ...@@ -154,8 +155,8 @@
// 返回格式化的对象 // 返回格式化的对象
return { return {
name: fileName, name: fileName,
extname: extname, extname,
url: url, url,
} }
} }
...@@ -178,7 +179,7 @@ ...@@ -178,7 +179,7 @@
// 文件上传 // 文件上传
function handleUpload(file) { function handleUpload(file) {
uni.uploadFile({ uni.uploadFile({
url: globSetting.apiUrl + globSetting.urlPrefix + '/sys/common/upload', // 直接使用上传接口URL url: `${globSetting.apiUrl + globSetting.urlPrefix}/sys/common/upload`, // 直接使用上传接口URL
filePath: file.tempFiles[0].path, filePath: file.tempFiles[0].path,
name: 'file', name: 'file',
formData: { formData: {
...@@ -235,7 +236,7 @@ ...@@ -235,7 +236,7 @@
* 处理地区值 * 处理地区值
* @param formData 表单数据 * @param formData 表单数据
*/ */
const changeAddressValue = (formData) => { function changeAddressValue(formData) {
const addressValue = formData.address.split('/') const addressValue = formData.address.split('/')
if (addressValue.length === 3) { if (addressValue.length === 3) {
formData.province = getCodeByText(addressValue[0]) formData.province = getCodeByText(addressValue[0])
...@@ -257,14 +258,14 @@ ...@@ -257,14 +258,14 @@
v-model="form.title" v-model="form.title"
labelSize="28" labelSize="28"
label-width="180" label-width="180"
></fui-input> />
<fui-input <fui-input
label="说明" label="说明"
placeholder="请输入规格说明" placeholder="请输入规格说明"
v-model="form.inputTextArea" v-model="form.inputTextArea"
labelSize="28" labelSize="28"
label-width="180" label-width="180"
></fui-input> />
</view> </view>
<view class="mt20"> <view class="mt20">
<!-- 价格区间 --> <!-- 价格区间 -->
...@@ -298,7 +299,7 @@ ...@@ -298,7 +299,7 @@
v-model="form.count" v-model="form.count"
labelSize="28" labelSize="28"
label-width="180" label-width="180"
></fui-input> />
<fui-input <fui-input
required required
label="单位" label="单位"
...@@ -306,7 +307,7 @@ ...@@ -306,7 +307,7 @@
v-model="form.unit" v-model="form.unit"
labelSize="28" labelSize="28"
label-width="180" label-width="180"
></fui-input> />
</view> </view>
<view class="mt20"> <view class="mt20">
<view class="form-item required flex align-center" style="padding: 20rpx 10rpx"> <view class="form-item required flex align-center" style="padding: 20rpx 10rpx">
...@@ -350,19 +351,14 @@ ...@@ -350,19 +351,14 @@
:auto-upload="false" :auto-upload="false"
@select="handleUpload" @select="handleUpload"
@delete="handleDelete" @delete="handleDelete"
></uni-file-picker> />
</view> </view>
<view class="fui-btn__box" v-if="!form.id" style="margin-top: 30rpx"> <view class="fui-btn__box" v-if="!form.id" style="margin-top: 30rpx">
<fui-button text="发布需求" bold radius="96rpx" @click="submit"></fui-button> <fui-button text="发布需求" bold radius="96rpx" @click="submit" />
</view> </view>
</fui-form> </fui-form>
<fui-date-picker <fui-date-picker :show="show.time" type="3" @change="handleChangeTime" @cancel="show.time = false" />
:show="show.time"
type="3"
@change="handleChangeTime"
@cancel="show.time = false"
></fui-date-picker>
<fui-picker <fui-picker
:show="show.classify" :show="show.classify"
:layer="1" :layer="1"
...@@ -370,7 +366,7 @@ ...@@ -370,7 +366,7 @@
:options="options.classify" :options="options.classify"
@change="handleChangeClassify" @change="handleChangeClassify"
@cancel="show.classify = false" @cancel="show.classify = false"
></fui-picker> />
<fui-picker <fui-picker
:show="show.address" :show="show.address"
:options="options.address" :options="options.address"
...@@ -378,9 +374,9 @@ ...@@ -378,9 +374,9 @@
:layer="3" :layer="3"
@change="handleChangeAddress" @change="handleChangeAddress"
@cancel="show.address = false" @cancel="show.address = false"
></fui-picker> />
<fui-toast ref="toastRef"></fui-toast> <fui-toast ref="toastRef" />
</view> </view>
</view> </view>
<fui-date-picker <fui-date-picker
...@@ -389,7 +385,7 @@ ...@@ -389,7 +385,7 @@
@change="handleChangeTime" @change="handleChangeTime"
@cancel="show.time = false" @cancel="show.time = false"
minDate="2025-01-01" minDate="2025-01-01"
></fui-date-picker> />
<fui-picker <fui-picker
:show="show.classify" :show="show.classify"
:layer="1" :layer="1"
...@@ -397,7 +393,7 @@ ...@@ -397,7 +393,7 @@
:options="options.classify" :options="options.classify"
@change="handleChangeClassify" @change="handleChangeClassify"
@cancel="show.classify = false" @cancel="show.classify = false"
></fui-picker> />
<fui-picker <fui-picker
:show="show.address" :show="show.address"
:options="options.address" :options="options.address"
...@@ -405,9 +401,9 @@ ...@@ -405,9 +401,9 @@
:layer="3" :layer="3"
@change="handleChangeAddress" @change="handleChangeAddress"
@cancel="show.address = false" @cancel="show.address = false"
></fui-picker> />
<fui-toast ref="toastRef"></fui-toast> <fui-toast ref="toastRef" />
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>
......
<script setup lang="ts"> <script setup lang="ts">
import { reactive, toRefs } from 'vue' import { reactive, toRefs } from 'vue'
import { onLoad, onShow } from '@dcloudio/uni-app' import { onLoad, 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 ChanxiaoAPI from '@/api/model/chanxiao' import * as ChanxiaoAPI from '@/api/model/chanxiao'
import * as UserInfoAPI from '@/api/model/userInfo' import * as UserInfoAPI from '@/api/model/userInfo'
import { areaTree, getTextByCode, getCodeByText } from '@/utils/areaData' import { areaTree, getCodeByText, getTextByCode } 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((option) => { onLoad((option) => {
uni.setNavigationBarTitle({ uni.setNavigationBarTitle({
title: '发布供应需求', title: '发布供应需求',
})
// 获取数据详情
if (option.id) {
getDetails(option.id)
} else {
// 获取当前位置
getCurrentAddressInfo()
}
}) })
// 获取数据详情
if (option.id) { onShow(() => {
getDetails(option.id) // 数据字典赋值
} else { initDict()
// 获取当前位置 })
getCurrentAddressInfo()
} const pageData = reactive({
}) title: '发布供应需求',
show: {
onShow(() => { time1: false,
// 数据字典赋值 time2: false,
initDict() address: false,
}) status: false,
classify: false,
const pageData = reactive({
title: '发布供应需求',
show: {
time1: false,
time2: false,
address: false,
status: false,
classify: false,
},
options: {
address: [],
status: [],
classify: [],
},
form: {
id: '',
title: '',
productSpecs: '',
minPrice: '',
maxPrice: '',
unit: '',
currency: '',
supplyQuantity: '',
minOrderQuantity: '',
address: '',
detailedAddress: '',
supplyStartDate: '',
supplyEndDate: '',
status: '',
classifyText: '',
classify: '',
statusText: '',
province: '',
city: '',
country: '',
image: null,
imageObj: null,
},
rules: [
{
name: 'title',
rule: ['required'],
msg: ['请输入标题'],
},
{
name: 'minPrice',
rule: ['required'],
msg: ['请输入最低价格'],
},
{
name: 'maxPrice',
rule: ['required'],
msg: ['请输入最高价格'],
},
{
name: 'unit',
rule: ['required'],
msg: ['请输入单位'],
},
{
name: 'currency',
rule: ['required'],
msg: ['请选择币种'],
},
{
name: 'supplyQuantity',
rule: ['required'],
msg: ['请输入供应数量'],
},
{
name: 'minOrderQuantity',
rule: ['required'],
msg: ['请输入最小订单数量'],
},
{
name: 'address',
rule: ['required'],
msg: ['请选择省/市/区县'],
}, },
{ options: {
name: 'status', address: [],
rule: ['required'], status: [],
msg: ['请选择状态'], classify: [],
}, },
{ form: {
name: 'classify', id: '',
rule: ['required'], title: '',
msg: ['请选择分类'], productSpecs: '',
minPrice: '',
maxPrice: '',
unit: '',
currency: '',
supplyQuantity: '',
minOrderQuantity: '',
address: '',
detailedAddress: '',
supplyStartDate: '',
supplyEndDate: '',
status: '',
classifyText: '',
classify: '',
statusText: '',
province: '',
city: '',
country: '',
image: null,
imageObj: null,
}, },
], rules: [
}) {
name: 'title',
rule: ['required'],
msg: ['请输入标题'],
},
{
name: 'minPrice',
rule: ['required'],
msg: ['请输入最低价格'],
},
{
name: 'maxPrice',
rule: ['required'],
msg: ['请输入最高价格'],
},
{
name: 'unit',
rule: ['required'],
msg: ['请输入单位'],
},
{
name: 'currency',
rule: ['required'],
msg: ['请选择币种'],
},
{
name: 'supplyQuantity',
rule: ['required'],
msg: ['请输入供应数量'],
},
{
name: 'minOrderQuantity',
rule: ['required'],
msg: ['请输入最小订单数量'],
},
{
name: 'address',
rule: ['required'],
msg: ['请选择省/市/区县'],
},
{
name: 'status',
rule: ['required'],
msg: ['请选择状态'],
},
{
name: 'classify',
rule: ['required'],
msg: ['请选择分类'],
},
],
})
const { show, options, form } = toRefs(pageData) const { show, options, form } = toRefs(pageData)
function initDict() { function initDict() {
pageData.options.address = areaTree pageData.options.address = areaTree
console.log(dictStore.getDictList['purchase_status']) console.log(dictStore.getDictList.purchase_status)
pageData.options.status = dictStore.getDictList['purchase_status'].map((item) => { pageData.options.status = dictStore.getDictList.purchase_status.map((item) => {
return { return {
value: item.value, value: item.value,
text: item.text, text: item.text,
} }
}) })
pageData.options.classify = dictStore.getDictList['classify'].map((item) => { pageData.options.classify = dictStore.getDictList.classify.map((item) => {
return {
value: item.value,
text: item.text,
}
})
}
function getCurrentAddressInfo() {
if (!uni.getStorageSync('location'))
return
const { lon, lat } = uni.getStorageSync('location')
UserInfoAPI.location({
lon,
lat,
}).then((res) => {
pageData.form.province = res.province
pageData.form.city = res.city
pageData.form.country = res.country
pageData.form.address = `${res.province}/${res.city}/${res.country}`
})
}
function getDetails(id) {
ChanxiaoAPI.purchaseSellDetails({ id }).then((res) => {
pageData.form = res
pageData.form.address = `${getTextByCode(res.province)}/${getTextByCode(res.city)}/${getTextByCode(res.country)}`
pageData.form.statusText = pageData.options.status.find((item) => item.value == res.status).text
pageData.form.classifyText = pageData.options.classify.find((item) => item.value == res.classify).text
pageData.form.imageObj = pageData.form.image && parseUrlInfo(pageData.form.image)
})
}
function parseUrlInfo(url) {
// 从URL中提取文件名
const pathParts = url.split('/')
const fileName = pathParts[pathParts.length - 1]
// 提取扩展名
const fileParts = fileName.split('.')
const extname = fileParts[fileParts.length - 1]
// 返回格式化的对象
return { return {
value: item.value, name: fileName,
text: item.text, extname,
url,
} }
})
}
function getCurrentAddressInfo() {
if (!uni.getStorageSync('location')) return
const { lon, lat } = uni.getStorageSync('location')
UserInfoAPI.location({
lon,
lat,
}).then((res) => {
pageData.form.province = res.province
pageData.form.city = res.city
pageData.form.country = res.country
pageData.form.address = `${res.province}/${res.city}/${res.country}`
})
}
function getDetails(id) {
ChanxiaoAPI.purchaseSellDetails({ id }).then((res) => {
pageData.form = res
pageData.form.address = `${getTextByCode(res.province)}/${getTextByCode(res.city)}/${getTextByCode(res.country)}`
pageData.form.statusText = pageData.options.status.find((item) => item.value == res.status).text
pageData.form.classifyText = pageData.options.classify.find((item) => item.value == res.classify).text
pageData.form.imageObj = pageData.form.image && parseUrlInfo(pageData.form.image)
})
}
function parseUrlInfo(url) {
// 从URL中提取文件名
const pathParts = url.split('/')
const fileName = pathParts[pathParts.length - 1]
// 提取扩展名
const fileParts = fileName.split('.')
const extname = fileParts[fileParts.length - 1]
// 返回格式化的对象
return {
name: fileName,
extname: extname,
url: url,
} }
}
function handleChangeTime1(e) {
function handleChangeTime1(e) { pageData.form.supplyStartDate = e.result
pageData.form.supplyStartDate = e.result pageData.show.time1 = false
pageData.show.time1 = false }
} function handleChangeTime2(e) {
function handleChangeTime2(e) { pageData.form.supplyEndDate = e.result
pageData.form.supplyEndDate = e.result pageData.show.time2 = false
pageData.show.time2 = false }
} function handleChangeClassify(e) {
function handleChangeClassify(e) { pageData.form.classify = e.value
pageData.form.classify = e.value pageData.form.classifyText = e.text
pageData.form.classifyText = e.text pageData.show.classify = false
pageData.show.classify = false }
} function handleChangeAddress(e) {
function handleChangeAddress(e) { pageData.form.address = e.text.join('/')
pageData.form.address = e.text.join('/') pageData.show.address = false
pageData.show.address = false }
} function handleChangeStatus(e) {
function handleChangeStatus(e) { pageData.form.status = e.value
pageData.form.status = e.value pageData.form.statusText = e.text
pageData.form.statusText = e.text pageData.show.status = false
pageData.show.status = false }
}
const toastRef = ref()
const toastRef = ref() const uploadRef = ref()
const uploadRef = ref() // 文件上传
// 文件上传 function handleUpload(file) {
function handleUpload(file) { uni.uploadFile({
uni.uploadFile({ url: `${globSetting.apiUrl + globSetting.urlPrefix}/sys/common/upload`, // 直接使用上传接口URL
url: globSetting.apiUrl + globSetting.urlPrefix + '/sys/common/upload', // 直接使用上传接口URL filePath: file.tempFiles[0].path,
filePath: file.tempFiles[0].path, name: 'file',
name: 'file', formData: {
formData: { biz: 'temp',
biz: 'temp', },
}, header: {
header: { 'X-Access-Token': userStore.getToken,
'X-Access-Token': userStore.getToken, },
}, success: (res) => {
success: (res) => { if (res.statusCode === 200) {
if (res.statusCode === 200) { const data = JSON.parse(res.data)
const data = JSON.parse(res.data) if (data.code === 200 || data.code === 0) {
if (data.code === 200 || data.code === 0) { toastRef.value.show({
toastRef.value.show({ type: 'success',
type: 'success', text: '上传成功',
text: '上传成功', })
}) pageData.form.image = data.message // 保存返回的图片信息
pageData.form.image = data.message // 保存返回的图片信息 }
} }
} },
}, fail: (err) => {
fail: (err) => {
toastRef.value.show({
type: 'error',
text: '上传失败',
})
uploadRef.value.clearFiles()
pageData.form.image = null
},
})
}
// 文件删除
function handleDelete(file) {
uploadRef.value.clearFiles()
pageData.form.image = null
}
const formRef = ref()
function submit() {
formRef.value.validator(pageData.form, pageData.rules, true).then((res) => {
if (res.isPassed) {
changeAddressValue(pageData.form)
ChanxiaoAPI.supplyAdd(pageData.form).then((res) => {
toastRef.value.show({ toastRef.value.show({
type: 'success', type: 'error',
text: '需求发布成功', text: '上传失败',
}) })
uni.switchTab({ uploadRef.value.clearFiles()
url: '/pages/chanxiao/chanxiao', pageData.form.image = null
},
})
}
// 文件删除
function handleDelete(file) {
uploadRef.value.clearFiles()
pageData.form.image = null
}
const formRef = ref()
function submit() {
formRef.value.validator(pageData.form, pageData.rules, true).then((res) => {
if (res.isPassed) {
changeAddressValue(pageData.form)
ChanxiaoAPI.supplyAdd(pageData.form).then((res) => {
toastRef.value.show({
type: 'success',
text: '需求发布成功',
})
uni.switchTab({
url: '/pages/chanxiao/chanxiao',
})
}) })
}) }
})
}
/**
* 处理地区值
* @param formData 表单数据
*/
function changeAddressValue(formData) {
const addressValue = formData.address.split('/')
if (addressValue.length === 3) {
formData.province = getCodeByText(addressValue[0])
formData.city = getCodeByText(addressValue[1])
formData.country = getCodeByText(addressValue[2])
} }
})
}
/**
* 处理地区值
* @param formData 表单数据
*/
const changeAddressValue = (formData) => {
const addressValue = formData.address.split('/')
if (addressValue.length === 3) {
formData.province = getCodeByText(addressValue[0])
formData.city = getCodeByText(addressValue[1])
formData.country = getCodeByText(addressValue[2])
} }
}
</script> </script>
<template> <template>
...@@ -282,20 +283,43 @@ const changeAddressValue = (formData) => { ...@@ -282,20 +283,43 @@ const changeAddressValue = (formData) => {
<view class="formBox"> <view class="formBox">
<fui-form ref="formRef" label-weight="auto" top="60"> <fui-form ref="formRef" label-weight="auto" top="60">
<view class="mt20"> <view class="mt20">
<fui-input required label="供应标题" placeholder="请输入供应标题" v-model="form.title" <fui-input
labelSize="28" label-width="180"></fui-input> required
<fui-input label="规格说明" placeholder="请输入规格说明" v-model="form.productSpecs" label="供应标题"
labelSize="28" label-width="180"></fui-input> placeholder="请输入供应标题"
v-model="form.title"
labelSize="28"
label-width="180"
/>
<fui-input
label="规格说明"
placeholder="请输入规格说明"
v-model="form.productSpecs"
labelSize="28"
label-width="180"
/>
</view> </view>
<view class="mt20"> <view class="mt20">
<!-- 价格区间 --> <!-- 价格区间 -->
<view class="form-section" style="padding: 0 10rpx;"> <view class="form-section" style="padding: 0 10rpx">
<view class="form-item required flex align-center"> <view class="form-item required flex align-center">
<text class="label">价格区间</text> <text class="label">价格区间</text>
<view class="price-range"> <view class="price-range">
<input type="number" class="price-input" v-model="form.minPrice" placeholder="最低价" :min="0" /> <input
type="number"
class="price-input"
v-model="form.minPrice"
placeholder="最低价"
:min="0"
/>
<text class="price-separator">-</text> <text class="price-separator">-</text>
<input type="number" class="price-input" v-model="form.maxPrice" placeholder="最高价" :min="0"/> <input
type="number"
class="price-input"
v-model="form.maxPrice"
placeholder="最高价"
:min="0"
/>
</view> </view>
</view> </view>
</view> </view>
...@@ -303,30 +327,60 @@ const changeAddressValue = (formData) => { ...@@ -303,30 +327,60 @@ const changeAddressValue = (formData) => {
labelSize="28" label-width="180"></fui-input> labelSize="28" label-width="180"></fui-input>
<fui-input required label="最高价" placeholder="请输入最高价" v-model="form.maxPrice" <fui-input required label="最高价" placeholder="请输入最高价" v-model="form.maxPrice"
labelSize="28" label-width="180"></fui-input> --> labelSize="28" label-width="180"></fui-input> -->
<fui-input required label="计量单位" placeholder="请输入计量单位" v-model="form.unit" <fui-input
labelSize="28" label-width="180" ></fui-input> required
<fui-input required label="币种" placeholder="请输入币种" v-model="form.currency" label="计量单位"
labelSize="28" label-width="180"></fui-input> placeholder="请输入计量单位"
<fui-input type="number" required label="供应数量" placeholder="请输入供应数量" v-model="form.supplyQuantity" v-model="form.unit"
labelSize="28" label-width="180"></fui-input> labelSize="28"
<fui-input type="number" required label="最小起订量" placeholder="请输入最小起订量" v-model="form.minOrderQuantity" label-width="180"
labelSize="28" label-width="180"></fui-input> />
<fui-input
required
label="币种"
placeholder="请输入币种"
v-model="form.currency"
labelSize="28"
label-width="180"
/>
<fui-input
type="number"
required
label="供应数量"
placeholder="请输入供应数量"
v-model="form.supplyQuantity"
labelSize="28"
label-width="180"
/>
<fui-input
type="number"
required
label="最小起订量"
placeholder="请输入最小起订量"
v-model="form.minOrderQuantity"
labelSize="28"
label-width="180"
/>
</view> </view>
<view class="mt20"> <view class="mt20">
<view class="form-item required flex align-center" style="padding: 20rpx 10rpx;"> <view class="form-item required flex align-center" style="padding: 20rpx 10rpx">
<text class="label">省/市/区县</text> <text class="label">省/市/区县</text>
<view class="select-input" @click="show.address = true"> <view class="select-input" @click="show.address = true">
<text class="time-text" :class="{ placeholder: !form.address }"> <text class="time-text" :class="{ placeholder: !form.address }">
{{ form.address || '请选择省/市/区县' }} {{ form.address || '请选择省/市/区县' }}
</text> </text>
</view> </view>
</view> </view>
<fui-input label="详细地址" placeholder="请输入详细地址" v-model="form.detailedAddress" <fui-input
labelSize="28" label-width="180"></fui-input> label="详细地址"
placeholder="请输入详细地址"
v-model="form.detailedAddress"
labelSize="28"
label-width="180"
/>
<!-- 供应时间 --> <!-- 供应时间 -->
<view class="form-section" style="padding: 0 30rpx;"> <view class="form-section" style="padding: 0 30rpx">
<view class="form-item flex align-center"> <view class="form-item flex align-center">
<text class="label">供应时间</text> <text class="label">供应时间</text>
<view class="time-range"> <view class="time-range">
...@@ -348,7 +402,7 @@ const changeAddressValue = (formData) => { ...@@ -348,7 +402,7 @@ const changeAddressValue = (formData) => {
@click="show.time1 = true" labelSize="28" label-width="180"></fui-input> @click="show.time1 = true" labelSize="28" label-width="180"></fui-input>
<fui-input label="供应结束时间" placeholder="请选择供应结束时间" v-model="form.supplyEndDate" <fui-input label="供应结束时间" placeholder="请选择供应结束时间" v-model="form.supplyEndDate"
@click="show.time2 = true" labelSize="28" label-width="180"></fui-input> --> @click="show.time2 = true" labelSize="28" label-width="180"></fui-input> -->
<view class="form-section" style="padding: 0 10rpx;"> <view class="form-section" style="padding: 0 10rpx">
<view class="form-item required flex align-center"> <view class="form-item required flex align-center">
<text class="label">分类</text> <text class="label">分类</text>
<view class="time-input" @click="show.classify = true"> <view class="time-input" @click="show.classify = true">
...@@ -358,7 +412,7 @@ const changeAddressValue = (formData) => { ...@@ -358,7 +412,7 @@ const changeAddressValue = (formData) => {
</view> </view>
</view> </view>
</view> </view>
<view class="form-section" style="padding: 0 10rpx;"> <view class="form-section" style="padding: 0 10rpx">
<view class="form-item required flex align-center"> <view class="form-item required flex align-center">
<text class="label">状态</text> <text class="label">状态</text>
<view class="time-input" @click="show.status = true"> <view class="time-input" @click="show.status = true">
...@@ -368,278 +422,304 @@ const changeAddressValue = (formData) => { ...@@ -368,278 +422,304 @@ const changeAddressValue = (formData) => {
</view> </view>
</view> </view>
</view> </view>
</view> </view>
<view class="bg-white mt20" style="padding: 0.875rem 1rem"> <view class="bg-white mt20" style="padding: 0.875rem 1rem">
<view class="mb-1 flex justify-start"> 示例图片 </view> <view class="mb-1 flex justify-start"> 示例图片 </view>
<uni-file-picker :value="form.imageObj" ref="uploadRef" limit="1" :auto-upload="false" <uni-file-picker
@select="handleUpload" @delete="handleDelete"></uni-file-picker> :value="form.imageObj"
ref="uploadRef"
limit="1"
:auto-upload="false"
@select="handleUpload"
@delete="handleDelete"
/>
</view> </view>
<view class="fui-btn__box" v-if="!form.id" style="margin-top: 30rpx;"> <view class="fui-btn__box" v-if="!form.id" style="margin-top: 30rpx">
<fui-button text="发布需求" bold radius="96rpx" @click="submit"></fui-button> <fui-button text="发布需求" bold radius="96rpx" @click="submit" />
</view> </view>
</fui-form> </fui-form>
<fui-date-picker :show="show.time1" type="3" @change="handleChangeTime1" <fui-date-picker
@cancel="show.time1 = false" minDate="2025-01-01"></fui-date-picker> :show="show.time1"
<fui-date-picker :show="show.time2" type="3" @change="handleChangeTime2" type="3"
@cancel="show.time2 = false" minDate="2025-01-01"></fui-date-picker> @change="handleChangeTime1"
<fui-picker :show="show.status" :layer="1" :linkage="true" :options="options.status" @cancel="show.time1 = false"
@change="handleChangeStatus" @cancel="show.status = false"></fui-picker> minDate="2025-01-01"
<fui-picker :show="show.classify" :layer="1" :linkage="true" :options="options.classify" />
@change="handleChangeClassify" @cancel="show.classify = false"></fui-picker> <fui-date-picker
<fui-picker :show="show.address" :options="options.address" :linkage="true" :layer="3" :show="show.time2"
@change="handleChangeAddress" @cancel="show.address = false"></fui-picker> type="3"
@change="handleChangeTime2"
<fui-toast ref="toastRef"></fui-toast> @cancel="show.time2 = false"
minDate="2025-01-01"
/>
<fui-picker
:show="show.status"
:layer="1"
:linkage="true"
:options="options.status"
@change="handleChangeStatus"
@cancel="show.status = false"
/>
<fui-picker
:show="show.classify"
:layer="1"
:linkage="true"
:options="options.classify"
@change="handleChangeClassify"
@cancel="show.classify = false"
/>
<fui-picker
:show="show.address"
:options="options.address"
:linkage="true"
:layer="3"
@change="handleChangeAddress"
@cancel="show.address = false"
/>
<fui-toast ref="toastRef" />
</view> </view>
</view> </view>
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>
body { body {
background-color: #E6F5E8; background-color: #e6f5e8;
}
.page {
background-color: #E6F5E8;
width: 750rpx;
overflow-x: hidden;
.mt20 {
margin-top: 30rpx;
background: #FFF;
padding: 20rpx;
border-radius: 10rpx;
} }
.formBox { .page {
width: 690rpx; background-color: #e6f5e8;
margin: 30rpx auto; width: 750rpx;
} overflow-x: hidden;
.mt20 {
margin-top: 30rpx;
background: #fff;
padding: 20rpx;
border-radius: 10rpx;
}
.supply-form { .formBox {
background: transparent; width: 690rpx;
} margin: 30rpx auto;
}
.supply-form {
background: transparent;
}
.form-section {
// background: #ffffff;
// border-radius: 12rpx;
// margin-bottom: 20rpx;
.form-section {
// background: #ffffff;
// border-radius: 12rpx;
// margin-bottom: 20rpx;
// box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.04); // box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.04);
border-bottom: 1rpx solid #f5f5f5; border-bottom: 1rpx solid #f5f5f5;
} }
.form-item {
padding: 30rpx 0;
border-bottom: 1rpx solid #f5f5f5;
.form-item { &:last-child {
padding: 30rpx 0; border-bottom: none;
border-bottom: 1rpx solid #f5f5f5; }
&:last-child { &.required .label::before {
border-bottom: none; content: '*';
color: #ff4d4f;
margin-right: 8rpx;
}
// 添加点击区域样式
.select-input {
position: relative;
.form-row {
display: flex;
justify-content: space-between;
} }
&.required .label::before { .half-width {
content: '*'; width: 48%;
color: #ff4d4f;
margin-right: 8rpx;
} }
// 添加点击区域样式 .align-center {
.select-input { align-items: center;
position: relative;
} }
}
.form-row { .label {
display: flex; display: block;
justify-content: space-between; font-size: 28rpx;
} color: #333333;
font-weight: 500;
width: 180rpx;
// margin-right: 20rpx;
}
.half-width { .input {
width: 48%; width: 100%;
} height: 80rpx;
background: #f8f9fa;
border-radius: 8rpx;
padding: 0 20rpx;
font-size: 28rpx;
color: #333333;
.align-center { &::placeholder {
align-items: center; color: #999999;
} }
}
.label { .price-range {
display: block; display: flex;
font-size: 28rpx; align-items: center;
color: #333333; // justify-content: space-between;
font-weight: 500; }
width: 180rpx;
// margin-right: 20rpx;
}
.input { .price-input {
width: 100%; width: 15%;
height: 80rpx; // height: 80rpx;
background: #f8f9fa; // background: #f8f9fa;
border-radius: 8rpx; // border-radius: 8rpx;
padding: 0 20rpx; padding: 0 10rpx;
font-size: 28rpx; font-size: 28rpx;
color: #333333; text-align: center;
}
&::placeholder { .price-separator {
color: #999999; color: #666666;
font-size: 28rpx;
margin: 0 10rpx;
} }
}
.price-range { .select-input {
display: flex; flex: 1;
align-items: center; border-radius: 8rpx;
// justify-content: space-between; padding: 0 20rpx;
} display: flex;
align-items: center;
justify-content: space-between;
cursor: pointer;
}
.price-input { .select-text {
width: 15%; font-size: 28rpx;
// height: 80rpx; color: #333333;
// background: #f8f9fa; padding: 0 20rpx;
// border-radius: 8rpx; &.placeholder {
padding: 0 10rpx; color: #999999;
font-size: 28rpx; }
text-align: center; }
}
.price-separator { .select-arrow {
color: #666666; color: #999999;
font-size: 28rpx; font-size: 24rpx;
margin: 0 10rpx; line-height: 1;
} }
.select-input { .time-range {
flex: 1; display: flex;
border-radius: 8rpx; align-items: center;
padding: 0 20rpx; justify-content: space-between;
display: flex; }
align-items: center;
justify-content: space-between;
cursor: pointer;
}
.select-text { .time-input {
font-size: 28rpx; width: 45%;
color: #333333; // height: 80rpx;
padding: 0 20rpx; // background: #f8f9fa;
&.placeholder { border-radius: 8rpx;
color: #999999; display: flex;
align-items: center;
} }
}
.select-arrow { .time-text {
color: #999999; font-size: 28rpx;
font-size: 24rpx; color: #333333;
line-height: 1;
}
.time-range { &.placeholder {
display: flex; color: #999999;
align-items: center; }
justify-content: space-between; }
}
.time-input { .time-separator {
width: 45%; color: #666666;
// height: 80rpx; font-size: 28rpx;
// background: #f8f9fa; margin: 0 10rpx;
border-radius: 8rpx; }
display: flex;
align-items: center; .upload-area {
} margin-top: 10rpx;
}
.time-text { .custom-uploader {
font-size: 28rpx; :deep(.uni-file-picker__container) {
color: #333333; border: 2rpx dashed #d9d9d9;
border-radius: 8rpx;
background: #f8f9fa;
}
}
&.placeholder { .upload-placeholder {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 200rpx;
color: #999999; color: #999999;
} }
}
.time-separator { .upload-icon {
color: #666666; font-size: 48rpx;
font-size: 28rpx; margin-bottom: 10rpx;
margin: 0 10rpx; }
}
.upload-area { .upload-text {
margin-top: 10rpx; font-size: 24rpx;
} }
.custom-uploader { .submit-section {
:deep(.uni-file-picker__container) { background: transparent;
border: 2rpx dashed #d9d9d9; padding: 40rpx 0;
border-radius: 8rpx;
background: #f8f9fa;
} }
}
.upload-placeholder { .submit-btn {
display: flex; width: 100%;
flex-direction: column; height: 88rpx;
align-items: center; background: #5db66f;
justify-content: center; border-radius: 44rpx;
height: 200rpx; color: #ffffff;
color: #999999; font-size: 32rpx;
font-weight: 500;
border: none;
&:active {
background: #4ca85c;
opacity: 0.9;
}
}
} }
::v-deep .uni-input-placeholder {
.upload-icon { font-size: 28rpx !important;
font-size: 48rpx; color: #999999 !important;
margin-bottom: 10rpx;
} }
.upload-text { :deep(.fui-button) {
font-size: 24rpx; width: 690rpx;
border-color: #5db66f !important;
background: #5db66f !important;
} }
.submit-section { // 移除fui-form的默认样式
:deep(.fui-form) {
background: transparent; background: transparent;
padding: 40rpx 0;
} }
.submit-btn { :deep(.fui-form__item) {
width: 100%; background: transparent;
height: 88rpx;
background: #5DB66F;
border-radius: 44rpx;
color: #ffffff;
font-size: 32rpx;
font-weight: 500;
border: none; border: none;
margin-bottom: 0;
&:active { padding: 0;
background: #4ca85c;
opacity: 0.9;
}
} }
}
::v-deep .uni-input-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;
}
</style> </style>
<script setup lang="ts">
import { computed, reactive, ref, watch } from 'vue'
import { useDictStore } from '@/store/modules/dict'
import * as NongchangAPI from '@/api/model/nongchang'
// 定义Props
interface Props {
show: boolean
editData?: any
}
const props = withDefaults(defineProps<Props>(), {
show: false,
editData: null,
})
// 定义Emits
const emit = defineEmits<{
'update:show': [value: boolean]
submit: [data: any]
close: []
}>()
// 表单引用
const formRef = ref()
const loading = ref(false)
const showDeviceTypePicker = ref(false)
// 字典存储
const dictStore = useDictStore()
// 表单数据
const formData = reactive({
deviceName: '',
deviceType: '',
deviceTypeText: '',
deviceIdentifier: '',
})
// 设备类型选项 - 使用字典数据
const deviceTypeOptions = computed(() => {
return (
dictStore.getDictList.deviceType?.map((item: any) => ({
value: item.value,
text: item.text,
})) || []
)
})
// 设备类型选择器数据 (不再需要,因为fui-picker使用options属性)
// 计算属性
const dialogTitle = computed(() => {
return props.editData ? '编辑设备' : '添加设备'
})
const submitButtonText = computed(() => {
return props.editData ? '保存' : '确认'
})
// 表单验证规则
const rules = {
deviceName: [
{ required: true, message: '请输入设备名称', trigger: 'blur' },
{ min: 2, max: 50, message: '设备名称长度在2-50个字符之间', trigger: 'blur' },
],
deviceType: [{ required: true, message: '请选择设备类型', type: 'number', trigger: 'change' }],
deviceIdentifier: [
{ required: true, message: '请输入设备唯一标识', trigger: 'blur' },
{ min: 6, max: 100, message: '设备标识长度在6-100个字符之间', trigger: 'blur' },
{
validator: (rule: any, value: any, callback: any) => {
if (!/^[a-zA-Z0-9\-_:]+$/.test(value)) {
callback(new Error('设备标识只能包含字母、数字、下划线、中划线和冒号'))
} else {
callback()
}
},
trigger: 'blur',
},
],
}
// 监听显示状态
watch(
() => props.show,
(newVal) => {
if (newVal && props.editData) {
// 编辑模式,填充数据
resetFormData()
loadEditData()
} else if (newVal) {
// 添加模式,重置表单
resetFormData()
}
},
)
// 重置表单数据
function resetFormData() {
formData.deviceName = ''
formData.deviceType = ''
formData.deviceTypeText = ''
formData.deviceIdentifier = ''
// 清除验证状态
if (formRef.value) {
formRef.value.resetFields()
}
}
// 加载编辑数据
function loadEditData() {
if (!props.editData)
return
formData.deviceName = props.editData.deviceName || ''
formData.deviceType = props.editData.deviceType || ''
formData.deviceIdentifier = props.editData.deviceIdentifier || ''
// 设置设备类型文本
if (props.editData.deviceType) {
const typeOption = deviceTypeOptions.value.find((item) => item.value === props.editData.deviceType)
if (typeOption) {
formData.deviceTypeText = typeOption.text
} else {
// 如果字典中没有找到对应的文本,使用原始数据中的文本
formData.deviceTypeText = props.editData.deviceType_dictText || ''
}
} else {
formData.deviceTypeText = ''
}
}
// 设备类型选择确认
function handleDeviceTypeConfirm(e: any) {
formData.deviceType = e.value
formData.deviceTypeText = e.text
showDeviceTypePicker.value = false
}
// 提交表单
async function handleSubmit() {
try {
console.log(formData)
// 先进行表单验证
const valid = await formRef.value.validate()
if (!valid) {
return
}
loading.value = true
// 准备提交数据
const submitData = {
...formData,
}
// 根据 editData 判断是新增还是修改
let result
if (props.editData && props.editData.id) {
// 编辑设备,需要传递设备ID
result = await NongchangAPI.editDevice({
...submitData,
id: props.editData.id,
})
console.log('修改设备数据:', submitData)
} else {
// 新增设备
result = await NongchangAPI.addDevice(submitData)
console.log('新增设备数据:', submitData)
}
uni.showToast({ title: '操作成功', icon: 'success' })
emit('update:show', false)
emit('submitSuccess')
} catch (error) {
console.log('提交失败:', error)
uni.showToast({
title: '操作失败',
icon: 'none',
duration: 2000,
})
} finally {
loading.value = false
}
}
// 关闭弹窗
function handleClose() {
emit('update:show', false)
emit('close')
}
// 暴露方法给父组件
defineExpose({
resetFormData,
setLoading: (value: boolean) => {
loading.value = value
},
})
</script>
<template> <template>
<u-modal :show="show" :title="dialogTitle" :showConfirmButton="false" :showCancelButton="false" @close="handleClose" <u-modal
:closeOnClickOverlay="false"> :show="show"
:title="dialogTitle"
:showConfirmButton="false"
:showCancelButton="false"
@close="handleClose"
:closeOnClickOverlay="false"
>
<view class="dialog-content"> <view class="dialog-content">
<u-form :model="formData" :rules="rules" ref="formRef" label-width="180rpx"> <u-form :model="formData" :rules="rules" ref="formRef" label-width="180rpx">
<!-- 设备基本信息 --> <!-- 设备基本信息 -->
...@@ -11,7 +220,7 @@ ...@@ -11,7 +220,7 @@
</u-form-item> </u-form-item>
<u-form-item label="设备类型" prop="deviceType" required> <u-form-item label="设备类型" prop="deviceType" required>
<view class="address-display" @click="showDeviceTypePicker = true"> <view class="address-display" @click="showDeviceTypePicker = true">
<text :class="{ 'placeholder-text': !formData.deviceTypeText }"> <text :class="{ 'placeholder-text': !formData.deviceTypeText }">
{{ formData.deviceTypeText || '请选择设备类型' }} {{ formData.deviceTypeText || '请选择设备类型' }}
</text> </text>
...@@ -26,8 +235,14 @@ ...@@ -26,8 +235,14 @@
<!-- 操作按钮 --> <!-- 操作按钮 -->
<view class="dialog-buttons"> <view class="dialog-buttons">
<u-button type="primary" @click="handleSubmit" :loading="loading" size="normal" class="submit-btn" <u-button
color="var(--fui-color-success)"> type="primary"
@click="handleSubmit"
:loading="loading"
size="normal"
class="submit-btn"
color="var(--fui-color-success)"
>
{{ submitButtonText }} {{ submitButtonText }}
</u-button> </u-button>
<u-button @click="handleClose" size="normal" class="cancel-btn">取消</u-button> <u-button @click="handleClose" size="normal" class="cancel-btn">取消</u-button>
...@@ -35,350 +250,156 @@ ...@@ -35,350 +250,156 @@
</u-form> </u-form>
<!-- 设备类型选择器 --> <!-- 设备类型选择器 -->
<fui-picker :show="showDeviceTypePicker" :options="deviceTypeOptions" :layer="1" :linkage="true" <fui-picker
@change="handleDeviceTypeConfirm" @cancel="showDeviceTypePicker = false"></fui-picker> :show="showDeviceTypePicker"
:options="deviceTypeOptions"
:layer="1"
:linkage="true"
@change="handleDeviceTypeConfirm"
@cancel="showDeviceTypePicker = false"
/>
</view> </view>
</u-modal> </u-modal>
</template> </template>
<script setup lang="ts"> <style lang="scss" scoped>
import { ref, reactive, watch, computed } from 'vue' .dialog-content {
import { useDictStore } from '@/store/modules/dict' padding: 10rpx 30rpx;
import * as NongchangAPI from '@/api/model/nongchang' width: 90%;
max-height: 80vh;
// 定义Props overflow-y: auto;
interface Props {
show: boolean
editData?: any
}
const props = withDefaults(defineProps<Props>(), {
show: false,
editData: null
})
// 定义Emits
const emit = defineEmits<{
'update:show': [value: boolean]
'submit': [data: any]
'close': []
}>()
// 表单引用
const formRef = ref()
const loading = ref(false)
const showDeviceTypePicker = ref(false)
// 字典存储
const dictStore = useDictStore()
// 表单数据
const formData = reactive({
deviceName: '',
deviceType: '',
deviceTypeText: '',
deviceIdentifier: ''
})
// 设备类型选项 - 使用字典数据
const deviceTypeOptions = computed(() => {
return dictStore.getDictList['deviceType']?.map((item: any) => ({
value: item.value,
text: item.text
})) || []
})
// 设备类型选择器数据 (不再需要,因为fui-picker使用options属性)
// 计算属性
const dialogTitle = computed(() => {
return props.editData ? '编辑设备' : '添加设备'
})
const submitButtonText = computed(() => {
return props.editData ? '保存' : '确认'
})
// 表单验证规则
const rules = {
deviceName: [
{ required: true, message: '请输入设备名称', trigger: 'blur' },
{ min: 2, max: 50, message: '设备名称长度在2-50个字符之间', trigger: 'blur' }
],
deviceType: [
{ required: true, message: '请选择设备类型', type: 'number', trigger: 'change' }
],
deviceIdentifier: [
{ required: true, message: '请输入设备唯一标识', trigger: 'blur' },
{ min: 6, max: 100, message: '设备标识长度在6-100个字符之间', trigger: 'blur' },
{
validator: (rule: any, value: any, callback: any) => {
if (!/^[a-zA-Z0-9\-_:]+$/.test(value)) {
callback(new Error('设备标识只能包含字母、数字、下划线、中划线和冒号'))
} else {
callback()
}
},
trigger: 'blur'
}
]
}
// 监听显示状态
watch(() => props.show, (newVal) => {
if (newVal && props.editData) {
// 编辑模式,填充数据
resetFormData()
loadEditData()
} else if (newVal) {
// 添加模式,重置表单
resetFormData()
}
})
// 重置表单数据
const resetFormData = () => {
formData.deviceName = ''
formData.deviceType = ''
formData.deviceTypeText = ''
formData.deviceIdentifier = ''
// 清除验证状态
if (formRef.value) {
formRef.value.resetFields()
} }
}
// 加载编辑数据 .section-title {
const loadEditData = () => { font-size: 32rpx;
if (!props.editData) return font-weight: 600;
color: #333;
formData.deviceName = props.editData.deviceName || '' margin: 20rpx 0 30rpx 0;
formData.deviceType = props.editData.deviceType || '' padding-left: 20rpx;
formData.deviceIdentifier = props.editData.deviceIdentifier || '' border-left: 6rpx solid #5db66f;
// 设置设备类型文本
if (props.editData.deviceType) {
const typeOption = deviceTypeOptions.value.find(item => item.value === props.editData.deviceType)
if (typeOption) {
formData.deviceTypeText = typeOption.text
} else {
// 如果字典中没有找到对应的文本,使用原始数据中的文本
formData.deviceTypeText = props.editData.deviceType_dictText || ''
}
} else {
formData.deviceTypeText = ''
} }
}
// 设备类型选择确认
const handleDeviceTypeConfirm = (e: any) => {
formData.deviceType = e.value
formData.deviceTypeText = e.text
showDeviceTypePicker.value = false
}
// 提交表单
const handleSubmit = async () => {
try {
console.log(formData)
// 先进行表单验证
const valid = await formRef.value.validate()
if (!valid) {
return
}
loading.value = true .dialog-buttons {
display: flex;
gap: 20rpx;
margin-top: 40rpx;
// 准备提交数据 .submit-btn {
const submitData = { flex: 1;
...formData
}
// 根据 editData 判断是新增还是修改 ::v-deep .u-button {
let result background-color: #5db66f;
if (props.editData && props.editData.id) { border-color: #5db66f;
// 编辑设备,需要传递设备ID }
result = await NongchangAPI.editDevice({
...submitData,
id: props.editData.id
})
console.log('修改设备数据:', submitData)
} else {
// 新增设备
result = await NongchangAPI.addDevice(submitData)
console.log('新增设备数据:', submitData)
} }
uni.showToast({ title: '操作成功', icon: 'success' }) .cancel-btn {
emit('update:show', false) flex: 1;
emit('submitSuccess')
} catch (error) {
console.log('提交失败:', error)
uni.showToast({
title: '操作失败',
icon: 'none',
duration: 2000
})
} finally {
loading.value = false
}
}
// 关闭弹窗
const handleClose = () => {
emit('update:show', false)
emit('close')
}
// 暴露方法给父组件
defineExpose({
resetFormData,
setLoading: (value: boolean) => {
loading.value = value
}
})
</script>
<style lang="scss" scoped> ::v-deep .u-button {
.dialog-content { background-color: #fff;
padding: 10rpx 30rpx; color: #666;
width: 90%; border: 2rpx solid #dcdfe6;
max-height: 80vh; }
overflow-y: auto;
}
.section-title {
font-size: 32rpx;
font-weight: 600;
color: #333;
margin: 20rpx 0 30rpx 0;
padding-left: 20rpx;
border-left: 6rpx solid #5DB66F;
}
.dialog-buttons {
display: flex;
gap: 20rpx;
margin-top: 40rpx;
.submit-btn {
flex: 1;
::v-deep .u-button {
background-color: #5DB66F;
border-color: #5DB66F;
} }
} }
.cancel-btn { // uview-plus 表单样式调整
flex: 1; ::v-deep .u-form-item {
margin-bottom: 40rpx;
::v-deep .u-button { .u-form-item__body {
background-color: #fff; padding: 0;
color: #666; align-items: flex-start;
border: 2rpx solid #dcdfe6;
} }
}
}
// uview-plus 表单样式调整
::v-deep .u-form-item {
margin-bottom: 40rpx;
.u-form-item__body { .u-form-item__body__left__content__label {
padding: 0; font-size: 28rpx;
align-items: flex-start; color: #333;
} font-weight: 500;
width: 180rpx;
flex-shrink: 0;
text-align: right;
padding-right: 20rpx;
line-height: 80rpx;
}
.u-form-item__body__left__content__label { .u-form-item__body__right {
font-size: 28rpx; flex: 1;
color: #333; min-width: 0;
font-weight: 500; }
width: 180rpx;
flex-shrink: 0;
text-align: right;
padding-right: 20rpx;
line-height: 80rpx;
} }
.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;
}
.u-form-item__body__right { .placeholder-text {
flex: 1; color: #c0c4cc;
min-width: 0; }
}
}
.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 { ::v-deep .u-form-item__body__left__content__required {
color: #c0c4cc; position: static;
padding-right: 10rpx;
} }
}
::v-deep .u-form-item__body__left__content__required { // 输入框样式优化
position: static; ::v-deep .u-input {
padding-right: 10rpx; .u-input__content {
} padding: 0;
// 输入框样式优化 .u-input__content__field-wrapper {
::v-deep .u-input { border: none;
.u-input__content { border-radius: 0;
padding: 0;
.u-input__content__field-wrapper {
border: none;
border-radius: 0;
.u-input__content__field-wrapper__field { .u-input__content__field-wrapper__field {
font-size: 28rpx; font-size: 28rpx;
height: auto; height: auto;
} }
.u-input__content__field-wrapper__placeholder { .u-input__content__field-wrapper__placeholder {
color: #c0c4cc; color: #c0c4cc;
font-size: 28rpx; font-size: 28rpx;
}
} }
}
&.u-input--focus { &.u-input--focus {
.u-input__content__field-wrapper { .u-input__content__field-wrapper {
border-bottom-color: #5DB66F; border-bottom-color: #5db66f;
}
} }
} }
} }
}
// 模态框样式调整 // 模态框样式调整
::v-deep .u-modal { ::v-deep .u-modal {
.u-modal__content { .u-modal__content {
border-radius: 20rpx; border-radius: 20rpx;
padding: 20rpx 0rpx; padding: 20rpx 0rpx;
} }
.u-modal__header { .u-modal__header {
border-bottom: 2rpx solid #f0f0f0; border-bottom: 2rpx solid #f0f0f0;
padding: 30rpx; padding: 30rpx;
.u-modal__header__title { .u-modal__header__title {
font-size: 32rpx; font-size: 32rpx;
font-weight: 600; font-weight: 600;
color: #333; color: #333;
}
} }
} }
}
</style> </style>
<script setup>
import { reactive, ref } from 'vue'
import { onNavigationBarButtonTap } from '@dcloudio/uni-app'
import SaveDialog from './components/save-dialog.vue'
import * as NongchangAPI from '@/api/model/nongchang'
const isOnePage = ref(true)
const paging = ref(null)
const pageData = reactive({
param: {
pageNo: 1,
pageSize: 10,
deviceName: '',
},
list: [],
})
// 滑动操作选项
const swipeOptions = [
{
text: '编辑',
style: {
backgroundColor: 'var(--fui-color-primary)',
},
},
{
text: '删除',
style: {
backgroundColor: 'var(--fui-color-danger)',
},
},
]
function getList() {
if (!paging.value) return
NongchangAPI.getDeviceList(pageData.param)
.then((res) => {
pageData.total = res.total
paging.value.complete(res.records)
})
.catch(() => {
paging.value.complete(false)
})
}
function queryList(pageNo, pageSize) {
pageData.param.pageNo = pageNo
pageData.param.pageSize = pageSize
getList()
}
function handleSearch() {
// 重置页码为1,重新搜索
pageData.param.pageNo = 1
if (paging.value) {
paging.value.reload()
}
}
const showDialog = ref(false)
const currentEditData = ref(null)
onNavigationBarButtonTap((_) => {
showAddDialog()
})
function showAddDialog() {
currentEditData.value = null
showDialog.value = true
}
function showEditDialog(device) {
currentEditData.value = device
showDialog.value = true
}
function handleSubmitSuccess() {
// 提交成功后刷新列表
handleSearch()
}
function handleDialogClose() {
// 弹窗关闭后的处理逻辑
}
// 删除设备
async function handleDelete(id) {
try {
await uni.showModal({
title: '确认删除',
content: '确定要删除这个设备吗?',
success: async (res) => {
if (res.confirm) {
await NongchangAPI.delDevice(id)
uni.showToast({ title: '删除成功', icon: 'success' })
handleSearch()
}
},
})
} catch (error) {
uni.showToast({ title: '删除失败', icon: 'none' })
}
}
// 获取状态样式类
function getStatusClass(status) {
if (status === '已连接')
return 'status-connected'
if (status === '未连接')
return 'status-disconnected'
return 'status-unknown'
}
// 处理滑动打开事件
function handleSwipeOpen(index) {
// 关闭其他已打开的滑动单元格,确保同时只有一个处于打开状态
pageData.list.forEach((item, i) => {
item.isShow = i === index
})
}
// 处理滑动操作
function handleSwipeAction(e, device) {
const index = e.index
const position = e.position
if (position === 'right') {
if (index === 0) {
// 编辑操作
showEditDialog(device)
} else if (index === 1) {
// 删除操作
handleDelete(device.id)
}
}
}
</script>
<template> <template>
<view class="codefun-flex-col page"> <view class="codefun-flex-col page">
<z-paging ref="paging" v-model="pageData.list" @query="queryList"> <z-paging ref="paging" v-model="pageData.list" @query="queryList">
<view class="codefun-flex-col group_3"> <view class="codefun-flex-col group_3">
<view class="codefun-flex-row codefun-items-center section_2"> <view class="codefun-flex-row codefun-items-center section_2">
<image class="image_6" src="/static/images/codefun/6c5c5a3c082b8c60a307d3a7caee623c.png" /> <image class="image_6" src="/static/images/codefun/6c5c5a3c082b8c60a307d3a7caee623c.png" />
<u-input v-model="pageData.param.deviceName" placeholder="请输入设备名称搜索" border="none" <u-input
class="codefun-ml-8" @confirm="handleSearch" /> v-model="pageData.param.deviceName"
placeholder="请输入设备名称搜索"
border="none"
class="codefun-ml-8"
@confirm="handleSearch"
/>
</view> </view>
<!-- 设备列表 --> <!-- 设备列表 -->
<view class="device-list"> <view class="device-list">
<uni-swipe-action> <uni-swipe-action>
<uni-swipe-action-item v-for="(item, index) in pageData.list" :key="index" :right-options="swipeOptions" <uni-swipe-action-item
@click="(e) => handleSwipeAction(e, item)"> v-for="(item, index) in pageData.list"
:key="index"
:right-options="swipeOptions"
@click="(e) => handleSwipeAction(e, item)"
>
<view class="device-item"> <view class="device-item">
<view class="device-info"> <view class="device-info">
<view class="device-name">{{ item.deviceName }}</view> <view class="device-name">{{ item.deviceName }}</view>
...@@ -25,13 +166,12 @@ ...@@ -25,13 +166,12 @@
<text class="device-status" :class="getStatusClass(item.connectStatus)"> <text class="device-status" :class="getStatusClass(item.connectStatus)">
{{ item.connectStatus_dictText || '未知' }} {{ item.connectStatus_dictText || '未知' }}
</text> </text>
<view style="opacity: 0;">1</view> <view style="opacity: 0">1</view>
<view class="device-time">添加日期: {{ item.createTime }}</view> <view class="device-time">添加日期: {{ item.createTime }}</view>
</view> </view>
</view> </view>
</uni-swipe-action-item> </uni-swipe-action-item>
</uni-swipe-action> </uni-swipe-action>
</view> </view>
<!-- 空状态 --> <!-- 空状态 -->
...@@ -41,721 +181,595 @@ ...@@ -41,721 +181,595 @@
</view> </view>
</z-paging> </z-paging>
<!-- 弹窗组件 --> <!-- 弹窗组件 -->
<save-dialog :show="showDialog" :editData="currentEditData" @update:show="showDialog = $event" <SaveDialog
@submitSuccess="handleSubmitSuccess" @close="handleDialogClose" /> :show="showDialog"
:editData="currentEditData"
@update:show="showDialog = $event"
@submit-success="handleSubmitSuccess"
@close="handleDialogClose"
/>
</view> </view>
</template> </template>
<script setup> <style lang="scss">
import { nextTick, reactive, ref } from 'vue' body {
import { onLoad, onNavigationBarButtonTap, onShow } from '@dcloudio/uni-app' background-color: #e6f5e8;
import * as NongchangAPI from '@/api/model/nongchang'
import SaveDialog from './components/save-dialog.vue'
const isOnePage = ref(true)
const paging = ref(null)
const pageData = reactive({
param: {
pageNo: 1,
pageSize: 10,
deviceName: '',
},
list: [],
})
// 滑动操作选项
const swipeOptions = [
{
text: '编辑',
style: {
backgroundColor: 'var(--fui-color-primary)'
}
},
{
text: '删除',
style: {
backgroundColor: 'var(--fui-color-danger)'
}
} }
]
function getList() { .mt-5 {
if (!paging.value) return margin-top: 10rpx;
NongchangAPI.getDeviceList(pageData.param)
.then((res) => {
pageData.total = res.total
paging.value.complete(res.records)
})
.catch(() => {
paging.value.complete(false)
})
}
function queryList(pageNo, pageSize) {
pageData.param.pageNo = pageNo
pageData.param.pageSize = pageSize
getList()
}
function handleSearch() {
// 重置页码为1,重新搜索
pageData.param.pageNo = 1
if (paging.value) {
paging.value.reload()
}
}
const showDialog = ref(false)
const currentEditData = ref(null)
onNavigationBarButtonTap((_) => {
showAddDialog()
})
const showAddDialog = () => {
currentEditData.value = null
showDialog.value = true
}
const showEditDialog = (device) => {
currentEditData.value = device
showDialog.value = true
}
const handleSubmitSuccess = () => {
// 提交成功后刷新列表
handleSearch()
}
const handleDialogClose = () => {
// 弹窗关闭后的处理逻辑
}
// 删除设备
const handleDelete = async (id) => {
try {
await uni.showModal({
title: '确认删除',
content: '确定要删除这个设备吗?',
success: async (res) => {
if (res.confirm) {
await NongchangAPI.delDevice( id )
uni.showToast({ title: '删除成功', icon: 'success' })
handleSearch()
}
}
})
} catch (error) {
uni.showToast({ title: '删除失败', icon: 'none' })
}
}
// 获取状态样式类
const getStatusClass = (status) => {
if (status === '已连接') return 'status-connected'
if (status === '未连接') return 'status-disconnected'
return 'status-unknown'
}
// 处理滑动打开事件
const handleSwipeOpen = (index) => {
// 关闭其他已打开的滑动单元格,确保同时只有一个处于打开状态
pageData.list.forEach((item, i) => {
item.isShow = i === index
})
}
// 处理滑动操作
const handleSwipeAction = (e, device) => {
const index = e.index
const position = e.position
if (position === 'right') {
if (index === 0) {
// 编辑操作
showEditDialog(device)
} else if (index === 1) {
// 删除操作
handleDelete(device.id)
}
} }
}
</script>
<style lang="scss"> .mt-11 {
body { margin-top: 22rpx;
background-color: #e6f5e8; }
}
.mt-5 {
margin-top: 10rpx;
}
.mt-11 {
margin-top: 22rpx;
}
.ml-5 {
margin-left: 10rpx;
}
.ml-13 {
margin-left: 26rpx;
}
.ml-9 {
margin-left: 18rpx;
}
.page {
background-color: #e6f5e8;
mix-blend-mode: NOTTHROUGH;
width: 100%;
overflow-y: auto;
overflow-x: hidden;
height: 100%;
.section {
padding: 32rpx 24rpx 32rpx 36rpx;
background-color: #5db66f;
mix-blend-mode: NOTTHROUGH;
.image { .ml-5 {
border-radius: 64rpx; margin-left: 10rpx;
width: 108rpx; }
height: 42rpx;
}
.group { .ml-13 {
margin-right: 4rpx; margin-left: 26rpx;
}
.image_2 { .ml-9 {
mix-blend-mode: NOTTHROUGH; margin-left: 18rpx;
width: 34rpx; }
height: 22rpx;
}
.image_3 { .page {
mix-blend-mode: NOTTHROUGH; background-color: #e6f5e8;
width: 30rpx; mix-blend-mode: NOTTHROUGH;
height: 22rpx; width: 100%;
} overflow-y: auto;
overflow-x: hidden;
height: 100%;
.section {
padding: 32rpx 24rpx 32rpx 36rpx;
background-color: #5db66f;
mix-blend-mode: NOTTHROUGH;
.image_4 { .image {
width: 48rpx; border-radius: 64rpx;
height: 22rpx; width: 108rpx;
height: 42rpx;
} }
}
.group_2 { .group {
padding-left: 6rpx; margin-right: 4rpx;
.image_5 { .image_2 {
mix-blend-mode: NOTTHROUGH; mix-blend-mode: NOTTHROUGH;
width: 14rpx; width: 34rpx;
height: 26rpx; height: 22rpx;
} }
.pos { .image_3 {
position: absolute; mix-blend-mode: NOTTHROUGH;
left: 6rpx; width: 30rpx;
top: 50%; height: 22rpx;
transform: translateY(-50%); }
}
.text { .image_4 {
color: #ffffffe6; width: 48rpx;
line-height: 29.6rpx; height: 22rpx;
}
} }
.pos_2 { .group_2 {
position: absolute; padding-left: 6rpx;
right: 0;
top: 50%;
transform: translateY(-50%);
.text_2 { .image_5 {
line-height: 25.78rpx; mix-blend-mode: NOTTHROUGH;
width: 14rpx;
height: 26rpx;
} }
}
}
}
.group_3 { .pos {
padding: 28rpx 24rpx 58rpx; position: absolute;
left: 6rpx;
top: 50%;
transform: translateY(-50%);
}
.section_2 { .text {
padding: 16rpx 20rpx; color: #ffffffe6;
background-color: #ffffff; line-height: 29.6rpx;
border-radius: 1998rpx; }
mix-blend-mode: NOTTHROUGH;
.text_3 { .pos_2 {
color: #cccccc; position: absolute;
line-height: 26.02rpx; right: 0;
top: 50%;
transform: translateY(-50%);
.text_2 {
line-height: 25.78rpx;
}
}
} }
} }
.section_3 { .group_3 {
padding: 0 24rpx; padding: 28rpx 24rpx 58rpx;
background-color: #ffffff;
border-radius: 18.46rpx;
mix-blend-mode: NOTTHROUGH;
.group_4 { .section_2 {
padding: 42rpx 4rpx 30rpx 22rpx; padding: 16rpx 20rpx;
border-bottom: solid 2rpx #eeeeee; background-color: #ffffff;
border-radius: 1998rpx;
mix-blend-mode: NOTTHROUGH;
.image_7 { .text_3 {
width: 100rpx; color: #cccccc;
height: 86rpx; line-height: 26.02rpx;
} }
}
.group_7 { .section_3 {
margin-left: 32rpx; padding: 0 24rpx;
background-color: #ffffff;
border-radius: 18.46rpx;
mix-blend-mode: NOTTHROUGH;
.text_5 { .group_4 {
color: #5db66f; padding: 42rpx 4rpx 30rpx 22rpx;
font-size: 40rpx; border-bottom: solid 2rpx #eeeeee;
font-family: SourceHanSansCN;
line-height: 40rpx;
}
.text_7 { .image_7 {
line-height: 22.18rpx; width: 100rpx;
height: 86rpx;
} }
}
.text_4 { .group_7 {
color: #333333; margin-left: 32rpx;
line-height: 40rpx;
}
.group_5 { .text_5 {
width: 219.94rpx; color: #5db66f;
font-size: 40rpx;
font-family: SourceHanSansCN;
line-height: 40rpx;
}
.group_6 { .text_7 {
overflow: hidden; line-height: 22.18rpx;
}
}
.text-wrapper_2 { .text_4 {
padding: 8rpx 0 4rpx; color: #333333;
line-height: 40rpx;
}
.group_5 {
width: 219.94rpx;
.group_6 {
overflow: hidden; overflow: hidden;
width: 60rpx;
height: 40rpx; .text-wrapper_2 {
padding: 8rpx 0 4rpx;
overflow: hidden;
width: 60rpx;
height: 40rpx;
}
} }
}
.group_8 { .group_8 {
padding-top: 16rpx; padding-top: 16rpx;
.text-wrapper_3 {
padding: 8rpx 0 4rpx;
overflow: hidden;
width: 60rpx;
height: 40rpx;
.text_8 {
color: #ff9800;
}
}
}
.text-wrapper_3 { .text-wrapper {
padding: 8rpx 0 4rpx; padding: 8rpx 0 4rpx;
overflow: hidden; overflow: hidden;
width: 60rpx; width: 112rpx;
height: 40rpx; height: 40rpx;
.text_8 { .text_6 {
color: #ff9800; line-height: 25.74rpx;
} }
} }
} }
}
.text-wrapper { .group_9 {
padding: 8rpx 0 4rpx; padding: 12rpx 4rpx;
overflow: hidden;
width: 112rpx;
height: 40rpx;
.text_6 { .image_8 {
line-height: 25.74rpx; margin: 4rpx 0;
} width: 40rpx;
height: 40rpx;
} }
}
}
.group_9 { .text-wrapper_4 {
padding: 12rpx 4rpx; padding: 12rpx 0;
overflow: hidden;
.image_8 { width: 168rpx;
margin: 4rpx 0; height: 48rpx;
width: 40rpx; }
height: 40rpx;
}
.text-wrapper_4 { .image_9 {
padding: 12rpx 0; margin-right: 12rpx;
overflow: hidden; width: 16rpx;
width: 168rpx; height: 26rpx;
height: 48rpx; }
} }
.image_9 { .font_5 {
margin-right: 12rpx; font-size: 28rpx;
width: 16rpx; font-family: SourceHanSansCN;
height: 26rpx; line-height: 25.76rpx;
color: #5db66f;
} }
} }
.font_5 { .font_3 {
font-size: 28rpx; font-size: 28rpx;
font-family: SourceHanSansCN; font-family: SourceHanSansCN;
line-height: 25.76rpx; line-height: 25.76rpx;
color: #5db66f; color: #1f2937;
} }
}
.font_3 { .section_4 {
font-size: 28rpx; padding-left: 6rpx;
font-family: SourceHanSansCN; padding-bottom: 26rpx;
line-height: 25.76rpx; background-color: #ffffff;
color: #1f2937; border-radius: 26.28rpx;
} mix-blend-mode: NOTTHROUGH;
.section_4 {
padding-left: 6rpx;
padding-bottom: 26rpx;
background-color: #ffffff;
border-radius: 26.28rpx;
mix-blend-mode: NOTTHROUGH;
.list {
margin-left: 18rpx;
margin-right: 24rpx;
.list-item {
padding: 24rpx 0;
border-bottom: solid 2rpx #eeeeee;
.section_5 { .list {
padding: 12rpx 0 116rpx; margin-left: 18rpx;
background-image: url('/static/images/codefun/4be80e2618f3c4b4aa1ce64fd9063abf.png'); margin-right: 24rpx;
background-size: 100% 100%;
background-repeat: no-repeat; .list-item {
width: 160rpx; padding: 24rpx 0;
height: 160rpx; border-bottom: solid 2rpx #eeeeee;
.text-wrapper_5 { .section_5 {
padding: 8rpx 0; padding: 12rpx 0 116rpx;
background-image: linear-gradient(90deg, #43cf7c 0%, #5db66f 100%); background-image: url('/static/images/codefun/4be80e2618f3c4b4aa1ce64fd9063abf.png');
border-radius: 0rpx 8rpx 8rpx 0rpx; background-size: 100% 100%;
mix-blend-mode: NOTTHROUGH; background-repeat: no-repeat;
width: 84rpx; width: 160rpx;
height: 160rpx;
.font_6 {
font-size: 20rpx; .text-wrapper_5 {
font-family: SourceHanSansCN; padding: 8rpx 0;
line-height: 18.38rpx; background-image: linear-gradient(90deg, #43cf7c 0%, #5db66f 100%);
color: #ffffff; border-radius: 0rpx 8rpx 8rpx 0rpx;
mix-blend-mode: NOTTHROUGH;
width: 84rpx;
.font_6 {
font-size: 20rpx;
font-family: SourceHanSansCN;
line-height: 18.38rpx;
color: #ffffff;
}
} }
} }
}
.group_10 { .group_10 {
margin-right: 40rpx; margin-right: 40rpx;
.text_9 { .text_9 {
line-height: 22.34rpx; line-height: 22.34rpx;
} }
.text_10 { .text_10 {
line-height: 22.22rpx; line-height: 22.22rpx;
} }
.group_11 { .group_11 {
padding-left: 64rpx; padding-left: 64rpx;
.image_10 { .image_10 {
width: 28rpx; width: 28rpx;
height: 28rpx; height: 28rpx;
} }
.text-wrapper_6 { .text-wrapper_6 {
padding-top: 8rpx; padding-top: 8rpx;
overflow: hidden; overflow: hidden;
width: 48rpx; width: 48rpx;
height: 32rpx; height: 32rpx;
.text_11 { .text_11 {
line-height: 22.12rpx; line-height: 22.12rpx;
}
} }
}
.font_8 { .font_8 {
font-size: 24rpx; font-size: 24rpx;
font-family: SourceHanSansCN; font-family: SourceHanSansCN;
line-height: 22.28rpx; line-height: 22.28rpx;
color: #f44336; color: #f44336;
}
} }
} }
} }
} }
}
.group_14 { .group_14 {
margin: 18rpx 24rpx 0; margin: 18rpx 24rpx 0;
.text_14 { .text_14 {
line-height: 26.12rpx; line-height: 26.12rpx;
} }
.text-wrapper_8 { .text-wrapper_8 {
padding: 4rpx 0; padding: 4rpx 0;
overflow: hidden; overflow: hidden;
width: 48rpx; width: 48rpx;
height: 32rpx; height: 32rpx;
.text_15 { .text_15 {
line-height: 22.2rpx; line-height: 22.2rpx;
}
} }
} }
}
.font_7 { .font_7 {
font-size: 24rpx; font-size: 24rpx;
font-family: SourceHanSansCN; font-family: SourceHanSansCN;
line-height: 22.28rpx; line-height: 22.28rpx;
color: #5db66f; color: #5db66f;
} }
.group_15 { .group_15 {
margin-left: 24rpx; margin-left: 24rpx;
margin-top: 28rpx; margin-top: 28rpx;
width: 528.18rpx; width: 528.18rpx;
.text_16 { .text_16 {
line-height: 25.12rpx; line-height: 25.12rpx;
} }
.text_17 { .text_17 {
line-height: 26.26rpx; line-height: 26.26rpx;
}
} }
}
.group_16 { .group_16 {
margin-left: 24rpx; margin-left: 24rpx;
margin-top: 28rpx; margin-top: 28rpx;
width: 216.94rpx; width: 216.94rpx;
.text_18 {
line-height: 25.82rpx;
}
.text_18 { .text_19 {
line-height: 25.82rpx; line-height: 25.34rpx;
}
} }
.text_19 { .font_9 {
line-height: 25.34rpx; font-size: 28rpx;
font-family: SourceHanSansCN;
line-height: 25.76rpx;
color: #6b7280;
} }
}
.font_9 { .group_17 {
font-size: 28rpx; margin-left: 24rpx;
font-family: SourceHanSansCN; margin-top: 28rpx;
line-height: 25.76rpx;
color: #6b7280;
}
.group_17 { .text_20 {
margin-left: 24rpx; line-height: 26.16rpx;
margin-top: 28rpx; }
.text_20 { .text_21 {
line-height: 26.16rpx; line-height: 22.66rpx;
}
} }
.text_21 { .divider {
line-height: 22.66rpx; margin: 28rpx 18rpx 0 24rpx;
background-color: #f3f4f6;
height: 2rpx;
} }
}
.divider { .text_22 {
margin: 28rpx 18rpx 0 24rpx; margin-left: 24rpx;
background-color: #f3f4f6; margin-top: 32rpx;
height: 2rpx; line-height: 26.12rpx;
} }
.text_22 { .group_18 {
margin-left: 24rpx; margin-left: 24rpx;
margin-top: 32rpx; margin-top: 32rpx;
line-height: 26.12rpx;
}
.group_18 { .text_23 {
margin-left: 24rpx; line-height: 26.06rpx;
margin-top: 32rpx; }
.text_23 { .text_24 {
line-height: 26.06rpx; line-height: 22.66rpx;
}
} }
.text_24 { .font_10 {
line-height: 22.66rpx; font-size: 28rpx;
font-family: SourceHanSansCN;
line-height: 22.28rpx;
color: #1f2937;
} }
}
.font_10 { .group_19 {
font-size: 28rpx; margin-left: 24rpx;
font-family: SourceHanSansCN; margin-top: 28rpx;
line-height: 22.28rpx;
color: #1f2937;
}
.group_19 { .text_25 {
margin-left: 24rpx; line-height: 25.9rpx;
margin-top: 28rpx; }
.text_25 { .text_26 {
line-height: 25.9rpx; line-height: 25.78rpx;
}
} }
.text_26 { .group_20 {
line-height: 25.78rpx; margin-left: 24rpx;
} margin-top: 32rpx;
}
.group_20 { .text_27 {
margin-left: 24rpx; line-height: 25.96rpx;
margin-top: 32rpx; }
.text_27 { .text_28 {
line-height: 25.96rpx; line-height: 25.88rpx;
}
} }
.text_28 { .divider_2 {
line-height: 25.88rpx; margin-top: 28rpx;
background-color: #f3f4f6;
width: 716rpx;
height: 2rpx;
}
.text-wrapper_9 {
margin-left: 24rpx;
margin-top: 32rpx;
padding: 24rpx 0;
background-color: #5db66f;
border-radius: 400rpx;
mix-blend-mode: NOTTHROUGH;
.text_29 {
line-height: 25.9rpx;
}
} }
} }
.divider_2 { .font_4 {
margin-top: 28rpx; font-size: 24rpx;
background-color: #f3f4f6; font-family: SourceHanSansCN;
width: 716rpx; line-height: 22.28rpx;
height: 2rpx; color: #555555;
} }
}
.text-wrapper_9 { .image_6 {
margin-left: 24rpx; width: 32rpx;
margin-top: 32rpx; height: 32rpx;
padding: 24rpx 0; }
background-color: #5db66f;
border-radius: 400rpx;
mix-blend-mode: NOTTHROUGH;
.text_29 { .font {
line-height: 25.9rpx; font-size: 32rpx;
} font-family: SourceHanSansCN;
} line-height: 29.88rpx;
color: #333333;
} }
.font_4 { .font_2 {
font-size: 24rpx; font-size: 28rpx;
font-family: SourceHanSansCN; font-family: SourceHanSansCN;
line-height: 22.28rpx; line-height: 25.76rpx;
color: #555555; color: #ffffff;
} }
} }
.image_6 { /* 设备列表样式 */
width: 32rpx; .device-list {
height: 32rpx; margin-top: 20rpx;
}
.device-item {
background-color: #ffffff;
border-radius: 16rpx;
padding: 24rpx;
display: flex;
// justify-content: space-between;
align-items: center;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1);
}
::v-deep .uni-swipe {
border-radius: 16rpx;
margin-bottom: 20rpx;
} }
.font { .device-info {
flex: 1;
}
.device-name {
font-size: 32rpx; font-size: 32rpx;
font-family: SourceHanSansCN; font-weight: bold;
line-height: 29.88rpx;
color: #333333; color: #333333;
margin-bottom: 8rpx;
border-left: 6rpx solid #5db66f;
padding-left: 6rpx;
}
.device-details {
display: flex;
flex-direction: column;
gap: 6rpx;
margin-bottom: 8rpx;
}
.device-type,
.device-identifier {
font-size: 24rpx;
color: #666666;
}
.device-status-time {
display: flex;
flex-direction: column;
align-items: flex-end;
gap: 6rpx;
min-width: 180rpx;
}
.device-status {
font-size: 24rpx;
font-weight: bold;
}
.device-time {
font-size: 22rpx;
color: #999999;
}
.device-actions {
display: flex;
flex-direction: column;
gap: 12rpx;
} }
.font_2 { .status-connected {
color: #5db66f !important;
font-weight: bold;
}
.status-disconnected {
color: #f44336 !important;
font-weight: bold;
}
.status-unknown {
color: #ff9800 !important;
font-weight: bold;
}
.empty-state {
text-align: center;
padding: 100rpx 0;
color: #999999;
font-size: 28rpx; font-size: 28rpx;
font-family: SourceHanSansCN; }
line-height: 25.76rpx;
color: #ffffff;
}
}
/* 设备列表样式 */
.device-list {
margin-top: 20rpx;
}
.device-item {
background-color: #ffffff;
border-radius: 16rpx;
padding: 24rpx;
display: flex;
// justify-content: space-between;
align-items: center;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1);
}
::v-deep .uni-swipe {
border-radius: 16rpx;
margin-bottom: 20rpx;
}
.device-info {
flex: 1;
}
.device-name {
font-size: 32rpx;
font-weight: bold;
color: #333333;
margin-bottom: 8rpx;
border-left: 6rpx solid #5DB66F;
padding-left: 6rpx;
}
.device-details {
display: flex;
flex-direction: column;
gap: 6rpx;
margin-bottom: 8rpx;
}
.device-type,
.device-identifier {
font-size: 24rpx;
color: #666666;
}
.device-status-time {
display: flex;
flex-direction: column;
align-items: flex-end;
gap: 6rpx;
min-width: 180rpx;
}
.device-status {
font-size: 24rpx;
font-weight: bold;
}
.device-time {
font-size: 22rpx;
color: #999999;
}
.device-actions {
display: flex;
flex-direction: column;
gap: 12rpx;
}
.status-connected {
color: #5db66f !important;
font-weight: bold;
}
.status-disconnected {
color: #f44336 !important;
font-weight: bold;
}
.status-unknown {
color: #ff9800 !important;
font-weight: bold;
}
.empty-state {
text-align: center;
padding: 100rpx 0;
color: #999999;
font-size: 28rpx;
}
</style> </style>
<script setup lang="ts"> <script setup lang="ts">
import { reactive } from 'vue' import { reactive } from 'vue'
import { onPullDownRefresh, onLoad } from '@dcloudio/uni-app' import { onLoad, onPullDownRefresh } from '@dcloudio/uni-app'
import * as NongzhiAPI from '@/api/model/nongzhi' import * as NongzhiAPI from '@/api/model/nongzhi'
import Navigate from '@/utils/page/navigate' import Navigate from '@/utils/page/navigate'
import { url } from 'inspector'
// 下拉刷新 // 下拉刷新
onPullDownRefresh(() => { onPullDownRefresh(() => {
...@@ -275,7 +274,7 @@ ...@@ -275,7 +274,7 @@
function onFarmMachineryServiceClick(service: any) { function onFarmMachineryServiceClick(service: any) {
console.log('点击农机服务:', service) console.log('点击农机服务:', service)
// 在这里添加具体的服务点击逻辑 // 在这里添加具体的服务点击逻辑
Navigate.to('/pages/nongjifuwu/nongjifuwu?type=' + service.id) Navigate.to(`/pages/nongjifuwu/nongjifuwu?type=${service.id}`)
} }
// 技能培训点击事件 // 技能培训点击事件
...@@ -474,7 +473,7 @@ ...@@ -474,7 +473,7 @@
> >
<view class="codefun-flex-row codefun-items-center codefun-self-stretch"> <view class="codefun-flex-row codefun-items-center codefun-self-stretch">
<image class="image_11" :src="service.image" /> <image class="image_11" :src="service.image" />
<text class="font_5" :class="`text_33 ml-7`">{{ service.title }}</text> <text class="font_5 text_33 ml-7">{{ service.title }}</text>
</view> </view>
<text <text
class="codefun-self-start font_10" class="codefun-self-start font_10"
......
<script setup lang="ts">
import { reactive, ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import { areaTree } from '@/utils/areaData'
import { useUserStore } from '@/store/modules/user'
import { useGlobSetting } from '/@/hooks/setting'
import { useDictStore } from '@/store/modules/dict'
import * as NongchangAPI from '@/api/model/nongchang'
import { useFarmStore } from '@/store/modules/farm'
const dictStore = useDictStore()
// 表单引用
const formRef = ref()
const loading = ref(false)
const show = reactive({
address: false,
farmType: false,
})
const options = reactive({
address: areaTree,
farmType: [],
})
// 表单数据
const formData = reactive({
farmId: '',
baseName: '',
baseType: '',
baseTypeText: '',
scale: '',
provinceName: '',
cityName: '',
districtName: '',
detailedAddress: '',
province: '',
managerName: '',
contactPhone: '',
idCard: '',
plantedCrops: '',
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'],
},
],
province: [
{
required: true,
message: '请获取地址信息',
trigger: 'change',
// 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]$/,
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
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 }
// 将数组字段转换为逗号分隔的字符串
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,
})
// 延迟返回上一页
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
}
// 修复:修改页面上定义的 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>
<template> <template>
<view class="container"> <view class="container">
<u-form :model="formData" :rules="rules" ref="formRef" label-width="160rpx"> <u-form :model="formData" :rules="rules" ref="formRef" label-width="160rpx">
...@@ -10,7 +328,7 @@ ...@@ -10,7 +328,7 @@
<u-form-item label="基地类型" prop="baseType" required class="clickable" @click="show.farmType = true"> <u-form-item label="基地类型" prop="baseType" required class="clickable" @click="show.farmType = true">
<view class="address-display"> <view class="address-display">
<text :class="{'placeholder-text': !formData.baseTypeText}"> <text :class="{ 'placeholder-text': !formData.baseTypeText }">
{{ formData.baseTypeText || '请选择基地类型' }} {{ formData.baseTypeText || '请选择基地类型' }}
</text> </text>
</view> </view>
...@@ -29,7 +347,7 @@ ...@@ -29,7 +347,7 @@
<u-form-item label="省市区" prop="province" required class="clickable" @click="show.address = true"> <u-form-item label="省市区" prop="province" required class="clickable" @click="show.address = true">
<view class="address-display"> <view class="address-display">
<text :class="{'placeholder-text': !formData.province}"> <text :class="{ 'placeholder-text': !formData.province }">
{{ formData.province || '请选择省市区' }} {{ formData.province || '请选择省市区' }}
</text> </text>
</view> </view>
...@@ -72,538 +390,264 @@ ...@@ -72,538 +390,264 @@
<!-- 基地图片 --> <!-- 基地图片 -->
<view class="section-title">认证材料</view> <view class="section-title">认证材料</view>
<u-form-item label="基地图片" prop="baseImages"> <u-form-item label="基地图片" prop="baseImages">
<u-upload :fileList="formData.baseImages" @afterRead="(e) => afterRead(e, 'baseImages')" <u-upload
@delete="(e) => deletePic(e, 'baseImages')" name="1" multiple :maxCount="5" :fileList="formData.baseImages"
:previewFullImage="true"></u-upload> @after-read="(e) => afterRead(e, 'baseImages')"
@delete="(e) => deletePic(e, 'baseImages')"
name="1"
multiple
:maxCount="5"
:previewFullImage="true"
/>
</u-form-item> </u-form-item>
<u-form-item label="身份证明" prop="identityProveUrl" required> <u-form-item label="身份证明" prop="identityProveUrl" required>
<div> <div>
<u-upload :fileList="formData.identityProveUrl" @afterRead="(e) => afterRead(e, 'identityProveUrl')" <u-upload
@delete="(e) => deletePic(e, 'identityProveUrl')" name="identityProveUrl" multiple :maxCount="2" :fileList="formData.identityProveUrl"
:previewFullImage="true"></u-upload> @after-read="(e) => afterRead(e, 'identityProveUrl')"
@delete="(e) => deletePic(e, 'identityProveUrl')"
name="identityProveUrl"
multiple
:maxCount="2"
:previewFullImage="true"
/>
<div><i>身份证/营业执照图片</i></div> <div><i>身份证/营业执照图片</i></div>
</div> </div>
</u-form-item> </u-form-item>
<u-form-item label="场地证明" prop="landProveUrl" required> <u-form-item label="场地证明" prop="landProveUrl" required>
<div> <div>
<u-upload :fileList="formData.landProveUrl" @afterRead="(e) => afterRead(e, 'landProveUrl')" <u-upload
@delete="(e) => deletePic(e, 'landProveUrl')" name="landProveUrl" multiple :maxCount="2" :fileList="formData.landProveUrl"
:previewFullImage="true"></u-upload> @after-read="(e) => afterRead(e, 'landProveUrl')"
@delete="(e) => deletePic(e, 'landProveUrl')"
name="landProveUrl"
multiple
:maxCount="2"
:previewFullImage="true"
/>
<div><i>土地合同/场地照片</i></div> <div><i>土地合同/场地照片</i></div>
</div> </div>
</u-form-item> </u-form-item>
<u-form-item label="生产证明" prop="productionProveUrl" required> <u-form-item label="生产证明" prop="productionProveUrl" required>
<div> <div>
<u-upload :fileList="formData.productionProveUrl" <u-upload
@afterRead="(e) => afterRead(e, 'productionProveUrl')" :fileList="formData.productionProveUrl"
@delete="(e) => deletePic(e, 'productionProveUrl')" name="productionProveUrl" multiple @after-read="(e) => afterRead(e, 'productionProveUrl')"
:maxCount="2" :previewFullImage="true"></u-upload> @delete="(e) => deletePic(e, 'productionProveUrl')"
name="productionProveUrl"
multiple
:maxCount="2"
:previewFullImage="true"
/>
<div><i>现场作业照片/产品照片</i></div> <div><i>现场作业照片/产品照片</i></div>
</div> </div>
</u-form-item> </u-form-item>
<u-form-item label="质量证书"> <u-form-item label="质量证书">
<div> <div>
<u-upload :fileList="formData.qualityCertificateUrl" <u-upload
@afterRead="(e) => afterRead(e, 'qualityCertificateUrl')" :fileList="formData.qualityCertificateUrl"
@delete="(e) => deletePic(e, 'qualityCertificateUrl')" name="qualityCertificateUrl" multiple @after-read="(e) => afterRead(e, 'qualityCertificateUrl')"
:maxCount="2" :previewFullImage="true"></u-upload> @delete="(e) => deletePic(e, 'qualityCertificateUrl')"
name="qualityCertificateUrl"
multiple
:maxCount="2"
:previewFullImage="true"
/>
<div><i>质量认证证书</i></div> <div><i>质量认证证书</i></div>
</div> </div>
</u-form-item> </u-form-item>
<u-form-item label="其他材料"> <u-form-item label="其他材料">
<div> <div>
<u-upload :fileList="formData.otherMaterialUrl" @afterRead="(e) => afterRead(e, 'otherMaterialUrl')" <u-upload
@delete="(e) => deletePic(e, 'otherMaterialUrl')" name="otherMaterialUrl" multiple :maxCount="2" :fileList="formData.otherMaterialUrl"
:previewFullImage="true"></u-upload> @after-read="(e) => afterRead(e, 'otherMaterialUrl')"
@delete="(e) => deletePic(e, 'otherMaterialUrl')"
name="otherMaterialUrl"
multiple
:maxCount="2"
:previewFullImage="true"
/>
<div><i>其他补充材料</i></div> <div><i>其他补充材料</i></div>
</div> </div>
</u-form-item> </u-form-item>
<!-- 提交按钮 --> <!-- 提交按钮 -->
<view class="submit-btn-container"> <view class="submit-btn-container">
<u-button type="primary" @click="submitForm" :loading="loading">提交</u-button> <u-button type="primary" @click="submitForm" :loading="loading">提交</u-button>
</view> </view>
</u-form> </u-form>
<fui-picker :show="show.address" :options="options.address" :linkage="true" :layer="3" <fui-picker
@change="handleChangeAddress" @cancel="show.address = false"></fui-picker> :show="show.address"
<fui-picker :show="show.farmType" :layer="1" :linkage="true" :options="options.farmType" :options="options.address"
@change="handleChangeFarmType" @cancel="show.farmType = false"></fui-picker> :linkage="true"
:layer="3"
@change="handleChangeAddress"
@cancel="show.address = false"
/>
<fui-picker
:show="show.farmType"
:layer="1"
:linkage="true"
:options="options.farmType"
@change="handleChangeFarmType"
@cancel="show.farmType = false"
/>
</view> </view>
</template> </template>
<script setup lang="ts"> <style lang="scss" scoped>
import { ref, reactive, computed } from 'vue' .container {
import { areaTree } from '@/utils/areaData' padding: 30rpx;
import { onLoad } from '@dcloudio/uni-app' background-color: #f8f9fa;
import { useUserStore } from '@/store/modules/user' min-height: 100vh;
import { useGlobSetting } from '/@/hooks/setting' }
import { useDictStore } from '@/store/modules/dict'
import * as NongchangAPI from '@/api/model/nongchang'
import { useFarmStore } from '@/store/modules/farm'
const dictStore = useDictStore()
// 表单引用
const formRef = ref()
const loading = ref(false)
const show = reactive({
address: false,
farmType: false,
})
const options = reactive({
address: areaTree,
farmType: []
})
// 表单数据
const formData = reactive({
farmId: '',
baseName: '',
baseType: '',
baseTypeText: '',
scale: '',
provinceName: '',
cityName: '',
districtName: '',
detailedAddress: '',
province: '',
managerName: '',
contactPhone: '',
idCard: '',
plantedCrops: '',
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']
}
],
province: [
{
required: true, message: '请获取地址信息', trigger: 'change',
// 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]$/,
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
let 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: '部分图片上传失败',
})
},
})
})
}
// 删除图片
const deletePic = (event: any, key) => {
formData[key].splice(event.index, 1)
}
// 提交表单
const submitForm = async () => {
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({ .section-title {
title: '提交成功', font-size: 32rpx;
icon: 'success', font-weight: 600;
duration: 1500 color: #333;
}) margin: 40rpx 0 20rpx 0;
padding-left: 20rpx;
border-left: 6rpx solid #5db66f;
}
// 延迟返回上一页 .address-display {
setTimeout(() => { display: flex;
uni.navigateBack() justify-content: space-between;
}, 1500) align-items: center;
padding: 12rpx 18rpx;
background-color: transparent;
border-bottom: 2rpx solid #e4e7ed;
border-radius: 0;
cursor: pointer;
width: 100%;
} catch (error) { text {
console.error('API调用失败:', error) flex: 1;
uni.showToast({ font-size: 28rpx;
title: error.message || '提交失败,请重试', color: #333;
icon: 'none',
duration: 2000
})
} finally {
loading.value = false
} }
} catch (error) { .placeholder-text {
console.log('表单验证失败:', error) color: #c0c4cc;
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
}
// 修复:修改页面上定义的 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>
<style lang="scss" scoped>
.container {
padding: 30rpx;
background-color: #f8f9fa;
min-height: 100vh;
}
.section-title {
font-size: 32rpx;
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 { .suffix-text {
color: #c0c4cc; color: #909399;
margin-left: 10rpx;
} }
}
.suffix-text { .submit-btn-container {
color: #909399; margin: 60rpx 0;
margin-left: 10rpx;
}
.submit-btn-container { ::v-deep .u-button {
margin: 60rpx 0; height: 88rpx;
border-radius: 44rpx;
::v-deep .u-button { font-size: 32rpx;
height: 88rpx; background-color: #5db66f;
border-radius: 44rpx; border-color: #5db66f;
font-size: 32rpx; }
background-color: #5DB66F;
border-color: #5DB66F;
} }
}
// uview-plus 表单样式调整 // uview-plus 表单样式调整
::v-deep .u-form-item { ::v-deep .u-form-item {
margin-bottom: 40rpx; margin-bottom: 40rpx;
.u-form-item__body { .u-form-item__body {
padding: 0; padding: 0;
align-items: flex-start; align-items: flex-start;
} }
.u-form-item__body__left__content__label { .u-form-item__body__left__content__label {
font-size: 28rpx; font-size: 28rpx;
color: #333; color: #333;
font-weight: 500; font-weight: 500;
width: 160rpx; width: 160rpx;
flex-shrink: 0; flex-shrink: 0;
text-align: right; text-align: right;
padding-right: 20rpx; padding-right: 20rpx;
line-height: 80rpx; line-height: 80rpx;
} }
.u-form-item__body__right { .u-form-item__body__right {
flex: 1; flex: 1;
min-width: 0; min-width: 0;
}
} }
}
::v-deep .u-form-item__body__left__content__required {
position: static;
padding-right: 10rpx;
}
// 输入框样式优化 - 只保留下面的线 ::v-deep .u-form-item__body__left__content__required {
::v-deep .u-input { position: static;
.u-input__content { padding-right: 10rpx;
padding: 0; }
.u-input__content__field-wrapper { // 输入框样式优化 - 只保留下面的线
border: none; ::v-deep .u-input {
// border-bottom: 2rpx solid #e4e7ed; .u-input__content {
border-radius: 0; padding: 0;
.u-input__content__field-wrapper__field { .u-input__content__field-wrapper {
font-size: 28rpx; border: none;
// padding: 20rpx 0; // border-bottom: 2rpx solid #e4e7ed;
height: auto; border-radius: 0;
// min-height: 80rpx;
} .u-input__content__field-wrapper__field {
font-size: 28rpx;
// padding: 20rpx 0;
height: auto;
// min-height: 80rpx;
}
.u-input__content__field-wrapper__placeholder { .u-input__content__field-wrapper__placeholder {
color: #c0c4cc; color: #c0c4cc;
font-size: 28rpx; font-size: 28rpx;
}
} }
}
&.u-input--focus { &.u-input--focus {
.u-input__content__field-wrapper { .u-input__content__field-wrapper {
border-bottom-color: #5DB66F; border-bottom-color: #5db66f;
}
} }
} }
} }
}
// 上传组件样式调整 // 上传组件样式调整
::v-deep .u-upload { ::v-deep .u-upload {
margin-top: 10rpx; margin-top: 10rpx;
.u-upload__wrap { .u-upload__wrap {
padding: 0; padding: 0;
}
} }
}
// 选择器输入框样式 // 选择器输入框样式
::v-deep .u-input--readonly { ::v-deep .u-input--readonly {
.u-input__content__field-wrapper { .u-input__content__field-wrapper {
background-color: transparent; background-color: transparent;
.u-input__content__field-wrapper__field { .u-input__content__field-wrapper__field {
color: #333; color: #333;
}
} }
} }
}
// 表单项点击区域样式 // 表单项点击区域样式
::v-deep .u-form-item { ::v-deep .u-form-item {
&.clickable { &.clickable {
cursor: pointer; cursor: pointer;
.u-form-item__body__right { .u-form-item__body__right {
position: relative; position: relative;
&:after { &:after {
content: ''; content: '';
position: absolute; position: absolute;
top: 0; top: 0;
left: -20rpx; left: -20rpx;
right: -20rpx; right: -20rpx;
bottom: 0; bottom: 0;
}
} }
} }
} }
}
</style> </style>
<script setup lang="ts"> <script setup lang="ts">
import { nextTick, reactive, ref } from 'vue' import { nextTick, reactive, ref } from 'vue'
import { onLoad, onNavigationBarButtonTap, onShow } from '@dcloudio/uni-app' import { onLoad, onNavigationBarButtonTap, onShow } from '@dcloudio/uni-app'
import * as NongchangAPI from '@/api/model/nongchang' import * as NongchangAPI from '@/api/model/nongchang'
const isOnePage = ref(true) const isOnePage = ref(true)
const paging = ref(null) const paging = ref(null)
const pageData = reactive({ const pageData = reactive({
param: { param: {
pageNo: 1, pageNo: 1,
pageSize: 10, pageSize: 10,
baseName: '', baseName: '',
}, },
list: [], list: [],
total: 0, // 基地总数 total: 0, // 基地总数
type_success_total: 0, // 已认证 type_success_total: 0, // 已认证
type_unverified_total: 0, // 未认证 type_unverified_total: 0, // 未认证
})
onNavigationBarButtonTap((e) => {
console.log('onNavigationBarButtonTap', e)
})
onLoad(() => { })
onShow(() => {
nextTick(() => {
if (!isOnePage.value && paging.value) {
paging.value.reload()
}
isOnePage.value = false
}) })
}) onNavigationBarButtonTap((e) => {
function getList() { console.log('onNavigationBarButtonTap', e)
if (!paging.value) return })
NongchangAPI.getFarmbaseList(pageData.param) onLoad(() => {})
.then((res) => { onShow(() => {
pageData.total = res.total nextTick(() => {
paging.value.complete(res.records) if (!isOnePage.value && paging.value) {
}) paging.value.reload()
.catch(() => { }
paging.value.complete(false)
isOnePage.value = false
}) })
}
onNavigationBarButtonTap((_) => {
uni.navigateTo({
url: './add',
}) })
}) function getList() {
function queryList(pageNo, pageSize) { if (!paging.value)
pageData.param.pageNo = pageNo return
pageData.param.pageSize = pageSize NongchangAPI.getFarmbaseList(pageData.param)
getList() .then((res) => {
} pageData.total = res.total
paging.value.complete(res.records)
function handleSearch() { })
// 重置页码为1,重新搜索 .catch(() => {
pageData.param.pageNo = 1 paging.value.complete(false)
if (paging.value) { })
paging.value.reload()
} }
} onNavigationBarButtonTap((_) => {
const goDetail = (id) => { uni.navigateTo({
uni.navigateTo({ url: './add',
url: './add?id=' + id, })
}) })
} function queryList(pageNo, pageSize) {
function del(id) { pageData.param.pageNo = pageNo
uni.showModal({ pageData.param.pageSize = pageSize
title: '提示', getList()
content: '确定删除吗?', }
success: (res) => {
if (res.confirm) { function handleSearch() {
NongchangAPI.delFarmbase(id).then(() => { // 重置页码为1,重新搜索
uni.showToast({ pageData.param.pageNo = 1
title: '删除成功', if (paging.value) {
icon: 'none', paging.value.reload()
}
}
function goDetail(id) {
uni.navigateTo({
url: `./add?id=${id}`,
})
}
function del(id) {
uni.showModal({
title: '提示',
content: '确定删除吗?',
success: (res) => {
if (res.confirm) {
NongchangAPI.delFarmbase(id).then(() => {
uni.showToast({
title: '删除成功',
icon: 'none',
})
if (paging.value) {
paging.value.reload()
}
}) })
if (paging.value) { }
paging.value.reload() },
} })
}) }
}
},
})
}
</script> </script>
<template> <template>
...@@ -90,16 +91,24 @@ function del(id) { ...@@ -90,16 +91,24 @@ function del(id) {
<view class="codefun-flex-col group_3"> <view class="codefun-flex-col group_3">
<view class="codefun-flex-row codefun-items-center section_2"> <view class="codefun-flex-row codefun-items-center section_2">
<image class="image_6" src="/static/images/codefun/6c5c5a3c082b8c60a307d3a7caee623c.png" /> <image class="image_6" src="/static/images/codefun/6c5c5a3c082b8c60a307d3a7caee623c.png" />
<u-input v-model="pageData.param.baseName" placeholder="请输入搜索内容" border="none" class="codefun-ml-8" <u-input
@confirm="handleSearch" /> v-model="pageData.param.baseName"
placeholder="请输入搜索内容"
border="none"
class="codefun-ml-8"
@confirm="handleSearch"
/>
</view> </view>
<view class="codefun-mt-12 codefun-flex-col section_3"> <view class="codefun-mt-12 codefun-flex-col section_3">
<view class="codefun-flex-row codefun-justify-between group_4"> <view class="codefun-flex-row codefun-justify-between group_4">
<view class="codefun-flex-row codefun-self-start"> <view class="codefun-flex-row codefun-self-start">
<image class="codefun-shrink-0 image_7" <image
src="/static/images/codefun/db26a8ae3f4d5f1e0a3f11d8fb5bc491.png" /> class="codefun-shrink-0 image_7"
src="/static/images/codefun/db26a8ae3f4d5f1e0a3f11d8fb5bc491.png"
/>
<view <view
class="codefun-flex-col codefun-items-start codefun-shrink-0 codefun-self-center group_7"> class="codefun-flex-col codefun-items-start codefun-shrink-0 codefun-self-center group_7"
>
<text class="text_5">{{ pageData.total }}</text> <text class="text_5">{{ pageData.total }}</text>
<text class="font_4 text_7 mt-5">总基地数</text> <text class="font_4 text_7 mt-5">总基地数</text>
</view> </view>
...@@ -107,26 +116,34 @@ function del(id) { ...@@ -107,26 +116,34 @@ function del(id) {
</view> </view>
<view class="codefun-flex-col codefun-self-center group_5"> <view class="codefun-flex-col codefun-self-center group_5">
<view class="codefun-flex-row codefun-items-center group_6"> <view class="codefun-flex-row codefun-items-center group_6">
<image class="image_6" <image
src="/static/images/codefun/118c884c539aaba710313f0682db00e1.png" /> class="image_6"
src="/static/images/codefun/118c884c539aaba710313f0682db00e1.png"
/>
<view <view
class="codefun-ml-4 codefun-flex-col codefun-justify-start codefun-items-center text-wrapper"> class="codefun-ml-4 codefun-flex-col codefun-justify-start codefun-items-center text-wrapper"
>
<text class="font_3 text_6">已认证:</text> <text class="font_3 text_6">已认证:</text>
</view> </view>
<view <view
class="codefun-ml-4 codefun-flex-col codefun-justify-start codefun-items-center text-wrapper_2"> class="codefun-ml-4 codefun-flex-col codefun-justify-start codefun-items-center text-wrapper_2"
>
<text class="font_5">{{ pageData.type_success_total }}</text> <text class="font_5">{{ pageData.type_success_total }}</text>
</view> </view>
</view> </view>
<view class="codefun-flex-row codefun-items-center group_8"> <view class="codefun-flex-row codefun-items-center group_8">
<image class="image_6" <image
src="/static/images/codefun/27ef797870c2085d1a14446c50cf53e0.png" /> class="image_6"
src="/static/images/codefun/27ef797870c2085d1a14446c50cf53e0.png"
/>
<view <view
class="codefun-ml-4 codefun-flex-col codefun-justify-start codefun-items-center text-wrapper"> class="codefun-ml-4 codefun-flex-col codefun-justify-start codefun-items-center text-wrapper"
>
<text class="font_3 text_6">待认证:</text> <text class="font_3 text_6">待认证:</text>
</view> </view>
<view <view
class="codefun-ml-4 codefun-flex-col codefun-justify-start codefun-items-center text-wrapper_3"> class="codefun-ml-4 codefun-flex-col codefun-justify-start codefun-items-center text-wrapper_3"
>
<text class="font_3 text_8">{{ pageData.type_unverified_total }}</text> <text class="font_3 text_8">{{ pageData.type_unverified_total }}</text>
</view> </view>
</view> </view>
...@@ -136,7 +153,8 @@ function del(id) { ...@@ -136,7 +153,8 @@ function del(id) {
<view class="codefun-flex-row"> <view class="codefun-flex-row">
<image class="image_8" src="/static/images/codefun/c24e87154a833caadfcb70fb24ae52dc.png" /> <image class="image_8" src="/static/images/codefun/c24e87154a833caadfcb70fb24ae52dc.png" />
<view <view
class="codefun-ml-4 codefun-flex-col codefun-justify-start codefun-items-start text-wrapper_4"> class="codefun-ml-4 codefun-flex-col codefun-justify-start codefun-items-start text-wrapper_4"
>
<text class="font_5">基地认证指南</text> <text class="font_5">基地认证指南</text>
</view> </view>
</view> </view>
...@@ -145,11 +163,15 @@ function del(id) { ...@@ -145,11 +163,15 @@ function del(id) {
</view> </view>
<view class="codefun-mt-12 codefun-flex-col section_4" v-if="pageData.list.length"> <view class="codefun-mt-12 codefun-flex-col section_4" v-if="pageData.list.length">
<view class="codefun-flex-col codefun-self-stretch list"> <view class="codefun-flex-col codefun-self-stretch list">
<view class="codefun-flex-row codefun-items-center list-item" <view
v-for="(item, index) in pageData.list" :key="index"> class="codefun-flex-row codefun-items-center list-item"
v-for="(item, index) in pageData.list"
:key="index"
>
<view class="codefun-flex-col codefun-justify-start codefun-items-start section_5"> <view class="codefun-flex-col codefun-justify-start codefun-items-start section_5">
<view <view
class="codefun-flex-col codefun-justify-start codefun-items-center text-wrapper_5"> class="codefun-flex-col codefun-justify-start codefun-items-center text-wrapper_5"
>
<text class="font_6">{{ item.auditStatus_dictText }}</text> <text class="font_6">{{ item.auditStatus_dictText }}</text>
</view> </view>
</view> </view>
...@@ -162,18 +184,24 @@ function del(id) { ...@@ -162,18 +184,24 @@ function del(id) {
</view> </view>
</view> </view>
<view <view
class="codefun-mt-18 codefun-flex-row codefun-justify-between codefun-items-center group_11"> class="codefun-mt-18 codefun-flex-row codefun-justify-between codefun-items-center group_11"
>
<view class="codefun-flex-row" @click="goDetail(item.id)"> <view class="codefun-flex-row" @click="goDetail(item.id)">
<image class="image_10" <image
src="/static/images/codefun/3566724e23f8a91e60ae87c2744e4090.png" /> class="image_10"
src="/static/images/codefun/3566724e23f8a91e60ae87c2744e4090.png"
/>
<view <view
class="codefun-ml-4 codefun-flex-col codefun-justify-start codefun-items-center text-wrapper_6"> class="codefun-ml-4 codefun-flex-col codefun-justify-start codefun-items-center text-wrapper_6"
>
<text class="font_7 text_11">详情</text> <text class="font_7 text_11">详情</text>
</view> </view>
</view> </view>
<view class="codefun-flex-row codefun-items-center" @click="del(item.id)"> <view class="codefun-flex-row codefun-items-center" @click="del(item.id)">
<image class="codefun-shrink-0 image_10" <image
src="/static/images/codefun/8630d19ebb6334e2028daa7d7b8b5983.png" /> class="codefun-shrink-0 image_10"
src="/static/images/codefun/8630d19ebb6334e2028daa7d7b8b5983.png"
/>
<text class="font_8 ml-5">删除</text> <text class="font_8 ml-5">删除</text>
</view> </view>
</view> </view>
...@@ -187,492 +215,492 @@ function del(id) { ...@@ -187,492 +215,492 @@ function del(id) {
</template> </template>
<style scoped lang="scss"> <style scoped lang="scss">
body { body {
background-color: #e6f5e8; background-color: #e6f5e8;
} }
.mt-5 {
margin-top: 10rpx;
}
.mt-11 {
margin-top: 22rpx;
}
.ml-5 {
margin-left: 10rpx;
}
.ml-13 {
margin-left: 26rpx;
}
.ml-9 {
margin-left: 18rpx;
}
.page {
background-color: #e6f5e8;
mix-blend-mode: NOTTHROUGH;
width: 100%;
overflow-y: auto;
overflow-x: hidden;
height: 100%;
.section {
padding: 32rpx 24rpx 32rpx 36rpx;
background-color: #5db66f;
mix-blend-mode: NOTTHROUGH;
.image { .mt-5 {
border-radius: 64rpx; margin-top: 10rpx;
width: 108rpx; }
height: 42rpx;
}
.group { .mt-11 {
margin-right: 4rpx; margin-top: 22rpx;
}
.image_2 { .ml-5 {
mix-blend-mode: NOTTHROUGH; margin-left: 10rpx;
width: 34rpx; }
height: 22rpx;
}
.image_3 { .ml-13 {
mix-blend-mode: NOTTHROUGH; margin-left: 26rpx;
width: 30rpx; }
height: 22rpx;
}
.image_4 { .ml-9 {
width: 48rpx; margin-left: 18rpx;
height: 22rpx; }
}
}
.group_2 { .page {
padding-left: 6rpx; background-color: #e6f5e8;
mix-blend-mode: NOTTHROUGH;
width: 100%;
overflow-y: auto;
overflow-x: hidden;
height: 100%;
.section {
padding: 32rpx 24rpx 32rpx 36rpx;
background-color: #5db66f;
mix-blend-mode: NOTTHROUGH;
.image_5 { .image {
mix-blend-mode: NOTTHROUGH; border-radius: 64rpx;
width: 14rpx; width: 108rpx;
height: 26rpx; height: 42rpx;
} }
.pos { .group {
position: absolute; margin-right: 4rpx;
left: 6rpx;
top: 50%;
transform: translateY(-50%);
}
.text { .image_2 {
color: #ffffffe6; mix-blend-mode: NOTTHROUGH;
line-height: 29.6rpx; width: 34rpx;
} height: 22rpx;
}
.pos_2 { .image_3 {
position: absolute; mix-blend-mode: NOTTHROUGH;
right: 0; width: 30rpx;
top: 50%; height: 22rpx;
transform: translateY(-50%); }
.text_2 { .image_4 {
line-height: 25.78rpx; width: 48rpx;
height: 22rpx;
} }
} }
}
}
.group_3 { .group_2 {
padding: 28rpx 24rpx 58rpx; padding-left: 6rpx;
.section_2 { .image_5 {
padding: 16rpx 20rpx; mix-blend-mode: NOTTHROUGH;
background-color: #ffffff; width: 14rpx;
border-radius: 1998rpx; height: 26rpx;
mix-blend-mode: NOTTHROUGH; }
.pos {
position: absolute;
left: 6rpx;
top: 50%;
transform: translateY(-50%);
}
.text {
color: #ffffffe6;
line-height: 29.6rpx;
}
.pos_2 {
position: absolute;
right: 0;
top: 50%;
transform: translateY(-50%);
.text_3 { .text_2 {
color: #cccccc; line-height: 25.78rpx;
line-height: 26.02rpx; }
}
} }
} }
.section_3 { .group_3 {
padding: 0 24rpx; padding: 28rpx 24rpx 58rpx;
background-color: #ffffff;
border-radius: 18.46rpx;
mix-blend-mode: NOTTHROUGH;
.group_4 { .section_2 {
padding: 42rpx 4rpx 30rpx 22rpx; padding: 16rpx 20rpx;
border-bottom: solid 2rpx #eeeeee; background-color: #ffffff;
border-radius: 1998rpx;
mix-blend-mode: NOTTHROUGH;
.image_7 { .text_3 {
width: 100rpx; color: #cccccc;
height: 86rpx; line-height: 26.02rpx;
} }
}
.group_7 { .section_3 {
margin-left: 32rpx; padding: 0 24rpx;
background-color: #ffffff;
border-radius: 18.46rpx;
mix-blend-mode: NOTTHROUGH;
.text_5 { .group_4 {
color: #5db66f; padding: 42rpx 4rpx 30rpx 22rpx;
font-size: 40rpx; border-bottom: solid 2rpx #eeeeee;
font-family: SourceHanSansCN;
line-height: 40rpx;
}
.text_7 { .image_7 {
line-height: 22.18rpx; width: 100rpx;
height: 86rpx;
} }
}
.text_4 { .group_7 {
color: #333333; margin-left: 32rpx;
line-height: 40rpx;
}
.group_5 { .text_5 {
width: 219.94rpx; color: #5db66f;
font-size: 40rpx;
font-family: SourceHanSansCN;
line-height: 40rpx;
}
.group_6 { .text_7 {
overflow: hidden; line-height: 22.18rpx;
}
}
.text-wrapper_2 { .text_4 {
padding: 8rpx 0 4rpx; color: #333333;
line-height: 40rpx;
}
.group_5 {
width: 219.94rpx;
.group_6 {
overflow: hidden; overflow: hidden;
width: 60rpx;
height: 40rpx; .text-wrapper_2 {
padding: 8rpx 0 4rpx;
overflow: hidden;
width: 60rpx;
height: 40rpx;
}
} }
}
.group_8 { .group_8 {
padding-top: 16rpx; padding-top: 16rpx;
.text-wrapper_3 {
padding: 8rpx 0 4rpx;
overflow: hidden;
width: 60rpx;
height: 40rpx;
.text_8 {
color: #ff9800;
}
}
}
.text-wrapper_3 { .text-wrapper {
padding: 8rpx 0 4rpx; padding: 8rpx 0 4rpx;
overflow: hidden; overflow: hidden;
width: 60rpx; width: 112rpx;
height: 40rpx; height: 40rpx;
.text_8 { .text_6 {
color: #ff9800; line-height: 25.74rpx;
} }
} }
} }
}
.text-wrapper { .group_9 {
padding: 8rpx 0 4rpx; padding: 12rpx 4rpx;
overflow: hidden;
width: 112rpx;
height: 40rpx;
.text_6 { .image_8 {
line-height: 25.74rpx; margin: 4rpx 0;
} width: 40rpx;
height: 40rpx;
} }
}
}
.group_9 {
padding: 12rpx 4rpx;
.image_8 { .text-wrapper_4 {
margin: 4rpx 0; padding: 12rpx 0;
width: 40rpx; overflow: hidden;
height: 40rpx; width: 168rpx;
} height: 48rpx;
}
.text-wrapper_4 { .image_9 {
padding: 12rpx 0; margin-right: 12rpx;
overflow: hidden; width: 16rpx;
width: 168rpx; height: 26rpx;
height: 48rpx; }
} }
.image_9 { .font_5 {
margin-right: 12rpx; font-size: 28rpx;
width: 16rpx; font-family: SourceHanSansCN;
height: 26rpx; line-height: 25.76rpx;
color: #5db66f;
} }
} }
.font_5 { .font_3 {
font-size: 28rpx; font-size: 28rpx;
font-family: SourceHanSansCN; font-family: SourceHanSansCN;
line-height: 25.76rpx; line-height: 25.76rpx;
color: #5db66f; color: #1f2937;
} }
}
.font_3 {
font-size: 28rpx;
font-family: SourceHanSansCN;
line-height: 25.76rpx;
color: #1f2937;
}
.section_4 {
padding-left: 6rpx;
padding-bottom: 26rpx;
background-color: #ffffff;
border-radius: 26.28rpx;
mix-blend-mode: NOTTHROUGH;
.list {
margin-left: 18rpx;
margin-right: 24rpx;
.list-item { .section_4 {
padding: 24rpx 0; padding-left: 6rpx;
border-bottom: solid 2rpx #eeeeee; padding-bottom: 26rpx;
background-color: #ffffff;
border-radius: 26.28rpx;
mix-blend-mode: NOTTHROUGH;
.section_5 { .list {
padding: 12rpx 0 116rpx; margin-left: 18rpx;
background-image: url('/static/images/codefun/4be80e2618f3c4b4aa1ce64fd9063abf.png'); margin-right: 24rpx;
background-size: 100% 100%;
background-repeat: no-repeat; .list-item {
width: 160rpx; padding: 24rpx 0;
height: 160rpx; border-bottom: solid 2rpx #eeeeee;
.text-wrapper_5 { .section_5 {
padding: 8rpx 0; padding: 12rpx 0 116rpx;
background-image: linear-gradient(90deg, #43cf7c 0%, #5db66f 100%); background-image: url('/static/images/codefun/4be80e2618f3c4b4aa1ce64fd9063abf.png');
border-radius: 0rpx 8rpx 8rpx 0rpx; background-size: 100% 100%;
mix-blend-mode: NOTTHROUGH; background-repeat: no-repeat;
width: 84rpx; width: 160rpx;
height: 160rpx;
.font_6 {
font-size: 20rpx; .text-wrapper_5 {
font-family: SourceHanSansCN; padding: 8rpx 0;
line-height: 18.38rpx; background-image: linear-gradient(90deg, #43cf7c 0%, #5db66f 100%);
color: #ffffff; border-radius: 0rpx 8rpx 8rpx 0rpx;
mix-blend-mode: NOTTHROUGH;
width: 84rpx;
.font_6 {
font-size: 20rpx;
font-family: SourceHanSansCN;
line-height: 18.38rpx;
color: #ffffff;
}
} }
} }
}
.group_10 { .group_10 {
margin-right: 40rpx; margin-right: 40rpx;
.text_9 { .text_9 {
line-height: 22.34rpx; line-height: 22.34rpx;
} }
.text_10 { .text_10 {
line-height: 22.22rpx; line-height: 22.22rpx;
} }
.group_11 { .group_11 {
padding-left: 64rpx; padding-left: 64rpx;
.image_10 { .image_10 {
width: 28rpx; width: 28rpx;
height: 28rpx; height: 28rpx;
} }
.text-wrapper_6 { .text-wrapper_6 {
padding-top: 8rpx; padding-top: 8rpx;
overflow: hidden; overflow: hidden;
width: 48rpx; width: 48rpx;
height: 32rpx; height: 32rpx;
.text_11 { .text_11 {
line-height: 22.12rpx; line-height: 22.12rpx;
}
} }
}
.font_8 { .font_8 {
font-size: 24rpx; font-size: 24rpx;
font-family: SourceHanSansCN; font-family: SourceHanSansCN;
line-height: 22.28rpx; line-height: 22.28rpx;
color: #f44336; color: #f44336;
}
} }
} }
} }
} }
}
.group_14 { .group_14 {
margin: 18rpx 24rpx 0; margin: 18rpx 24rpx 0;
.text_14 { .text_14 {
line-height: 26.12rpx; line-height: 26.12rpx;
} }
.text-wrapper_8 { .text-wrapper_8 {
padding: 4rpx 0; padding: 4rpx 0;
overflow: hidden; overflow: hidden;
width: 48rpx; width: 48rpx;
height: 32rpx; height: 32rpx;
.text_15 { .text_15 {
line-height: 22.2rpx; line-height: 22.2rpx;
}
} }
} }
}
.font_7 { .font_7 {
font-size: 24rpx; font-size: 24rpx;
font-family: SourceHanSansCN; font-family: SourceHanSansCN;
line-height: 22.28rpx; line-height: 22.28rpx;
color: #5db66f; color: #5db66f;
} }
.group_15 { .group_15 {
margin-left: 24rpx; margin-left: 24rpx;
margin-top: 28rpx; margin-top: 28rpx;
width: 528.18rpx; width: 528.18rpx;
.text_16 { .text_16 {
line-height: 25.12rpx; line-height: 25.12rpx;
} }
.text_17 { .text_17 {
line-height: 26.26rpx; line-height: 26.26rpx;
}
} }
}
.group_16 { .group_16 {
margin-left: 24rpx; margin-left: 24rpx;
margin-top: 28rpx; margin-top: 28rpx;
width: 216.94rpx; width: 216.94rpx;
.text_18 { .text_18 {
line-height: 25.82rpx; line-height: 25.82rpx;
}
.text_19 {
line-height: 25.34rpx;
}
} }
.text_19 { .font_9 {
line-height: 25.34rpx; font-size: 28rpx;
font-family: SourceHanSansCN;
line-height: 25.76rpx;
color: #6b7280;
} }
}
.font_9 { .group_17 {
font-size: 28rpx; margin-left: 24rpx;
font-family: SourceHanSansCN; margin-top: 28rpx;
line-height: 25.76rpx;
color: #6b7280;
}
.group_17 { .text_20 {
margin-left: 24rpx; line-height: 26.16rpx;
margin-top: 28rpx; }
.text_20 { .text_21 {
line-height: 26.16rpx; line-height: 22.66rpx;
}
} }
.text_21 { .divider {
line-height: 22.66rpx; margin: 28rpx 18rpx 0 24rpx;
background-color: #f3f4f6;
height: 2rpx;
} }
}
.divider { .text_22 {
margin: 28rpx 18rpx 0 24rpx; margin-left: 24rpx;
background-color: #f3f4f6; margin-top: 32rpx;
height: 2rpx; line-height: 26.12rpx;
} }
.text_22 { .group_18 {
margin-left: 24rpx; margin-left: 24rpx;
margin-top: 32rpx; margin-top: 32rpx;
line-height: 26.12rpx;
}
.group_18 { .text_23 {
margin-left: 24rpx; line-height: 26.06rpx;
margin-top: 32rpx; }
.text_23 { .text_24 {
line-height: 26.06rpx; line-height: 22.66rpx;
}
} }
.text_24 { .font_10 {
line-height: 22.66rpx; font-size: 28rpx;
font-family: SourceHanSansCN;
line-height: 22.28rpx;
color: #1f2937;
} }
}
.font_10 { .group_19 {
font-size: 28rpx; margin-left: 24rpx;
font-family: SourceHanSansCN; margin-top: 28rpx;
line-height: 22.28rpx;
color: #1f2937;
}
.group_19 { .text_25 {
margin-left: 24rpx; line-height: 25.9rpx;
margin-top: 28rpx; }
.text_25 { .text_26 {
line-height: 25.9rpx; line-height: 25.78rpx;
}
} }
.text_26 { .group_20 {
line-height: 25.78rpx; margin-left: 24rpx;
} margin-top: 32rpx;
}
.group_20 { .text_27 {
margin-left: 24rpx; line-height: 25.96rpx;
margin-top: 32rpx; }
.text_27 { .text_28 {
line-height: 25.96rpx; line-height: 25.88rpx;
}
} }
.text_28 { .divider_2 {
line-height: 25.88rpx; margin-top: 28rpx;
background-color: #f3f4f6;
width: 716rpx;
height: 2rpx;
} }
}
.divider_2 { .text-wrapper_9 {
margin-top: 28rpx; margin-left: 24rpx;
background-color: #f3f4f6; margin-top: 32rpx;
width: 716rpx; padding: 24rpx 0;
height: 2rpx; background-color: #5db66f;
} border-radius: 400rpx;
mix-blend-mode: NOTTHROUGH;
.text-wrapper_9 {
margin-left: 24rpx;
margin-top: 32rpx;
padding: 24rpx 0;
background-color: #5db66f;
border-radius: 400rpx;
mix-blend-mode: NOTTHROUGH;
.text_29 { .text_29 {
line-height: 25.9rpx; line-height: 25.9rpx;
}
} }
} }
}
.font_4 { .font_4 {
font-size: 24rpx; font-size: 24rpx;
font-family: SourceHanSansCN; font-family: SourceHanSansCN;
line-height: 22.28rpx; line-height: 22.28rpx;
color: #555555; color: #555555;
}
} }
}
.image_6 { .image_6 {
width: 32rpx; width: 32rpx;
height: 32rpx; height: 32rpx;
} }
.font { .font {
font-size: 32rpx; font-size: 32rpx;
font-family: SourceHanSansCN; font-family: SourceHanSansCN;
line-height: 29.88rpx; line-height: 29.88rpx;
color: #333333; color: #333333;
} }
.font_2 { .font_2 {
font-size: 28rpx; font-size: 28rpx;
font-family: SourceHanSansCN; font-family: SourceHanSansCN;
line-height: 25.76rpx; line-height: 25.76rpx;
color: #ffffff; color: #ffffff;
}
} }
}
</style> </style>
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
import { reactive } from 'vue' import { reactive } from 'vue'
import * as LinghuoyonggongAPI from '@/api/model/linghuoyonggong' import * as LinghuoyonggongAPI from '@/api/model/linghuoyonggong'
import { useUserStore } from '@/store/modules/user' import { useUserStore } from '@/store/modules/user'
const { getUserInfo } = useUserStore() const { getUserInfo } = useUserStore()
const pageData = reactive({ const pageData = reactive({
...@@ -62,33 +63,30 @@ ...@@ -62,33 +63,30 @@
close, close,
}) })
</script> </script>
<template> <template>
<fui-dialog title="" :buttons="[]" :show="pageData.show" maskClosable> <fui-dialog title="" :buttons="[]" :show="pageData.show" maskClosable>
<view class="title flex justify-center"> <view class="title flex justify-center">
<view class="flex-1">报名</view> <view class="flex-1">报名</view>
<fui-icon class="close flex-basis" name="close" size="46" color="#999999" @click="close"></fui-icon> <fui-icon class="close flex-basis" name="close" size="46" color="#999999" @click="close" />
</view> </view>
<view class="text-left"> <view class="text-left">
<fui-form ref="formRef"> <fui-form ref="formRef">
<fui-input <fui-input marginTop="30" size="28" placeholder="请填写预留姓名" v-model="pageData.form.reservedname" />
marginTop="30"
size="28"
placeholder="请填写预留姓名"
v-model="pageData.form.reservedname"
></fui-input>
<fui-input <fui-input
marginTop="30" marginTop="30"
size="28" size="28"
placeholder="请填写预留手机" placeholder="请填写预留手机"
v-model="pageData.form.reservedmobile" v-model="pageData.form.reservedmobile"
></fui-input> />
<view style="margin-top: 30rpx"> <view style="margin-top: 30rpx">
<fui-button text="确定" bold radius="96rpx" @click="submit"></fui-button> <fui-button text="确定" bold radius="96rpx" @click="submit" />
</view> </view>
</fui-form> </fui-form>
</view> </view>
</fui-dialog> </fui-dialog>
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>
:deep(.fui-dialog__body) { :deep(.fui-dialog__body) {
background: linear-gradient(0deg, rgba(93, 182, 111, 0) 0%, rgba(93, 182, 111, 0.25) 100%); background: linear-gradient(0deg, rgba(93, 182, 111, 0) 0%, rgba(93, 182, 111, 0.25) 100%);
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
import { useGlobSetting } from '/@/hooks/setting' import { useGlobSetting } from '/@/hooks/setting'
import * as LinghuoyonggongAPI from '@/api/model/linghuoyonggong' import * as LinghuoyonggongAPI from '@/api/model/linghuoyonggong'
import * as UserInfoAPI from '@/api/model/userInfo' import * as UserInfoAPI from '@/api/model/userInfo'
import { areaTree, getTextByCode, getCodeByText } from '@/utils/areaData' import { areaTree, getCodeByText, getTextByCode } from '@/utils/areaData'
import { useDictStore } from '@/store/modules/dict' import { useDictStore } from '@/store/modules/dict'
const dictStore = useDictStore() const dictStore = useDictStore()
...@@ -124,15 +124,15 @@ ...@@ -124,15 +124,15 @@
function initDict() { function initDict() {
pageData.options.area = areaTree pageData.options.area = areaTree
console.log(dictStore.getDictList['purchase_status']) console.log(dictStore.getDictList.purchase_status)
pageData.options.urgentdegree = dictStore.getDictList['employment_urgent'].map((item) => { pageData.options.urgentdegree = dictStore.getDictList.employment_urgent.map((item) => {
return { return {
value: item.value, value: item.value,
text: item.text, text: item.text,
} }
}) })
pageData.options.type = dictStore.getDictList['employment_type'].map((item) => { pageData.options.type = dictStore.getDictList.employment_type.map((item) => {
return { return {
value: item.value, value: item.value,
text: item.text, text: item.text,
...@@ -141,7 +141,8 @@ ...@@ -141,7 +141,8 @@
} }
function getCurrentAddressInfo() { function getCurrentAddressInfo() {
if (!uni.getStorageSync('location')) return if (!uni.getStorageSync('location'))
return
const { lon, lat } = uni.getStorageSync('location') const { lon, lat } = uni.getStorageSync('location')
UserInfoAPI.location({ UserInfoAPI.location({
...@@ -152,8 +153,7 @@ ...@@ -152,8 +153,7 @@
pageData.form.city = res.city pageData.form.city = res.city
pageData.form.country = res.country pageData.form.country = res.country
pageData.form.areaText = `${res.province}/${res.city}/${res.country}` pageData.form.areaText = `${res.province}/${res.city}/${res.country}`
pageData.form.area = pageData.form.area = `${getCodeByText(res.province)},${getCodeByText(res.city)},${getCodeByText(res.country)}`
getCodeByText(res.province) + ',' + getCodeByText(res.city) + ',' + getCodeByText(res.country)
}) })
} }
...@@ -163,7 +163,7 @@ ...@@ -163,7 +163,7 @@
.then((res) => { .then((res) => {
console.log(res) console.log(res)
pageData.form = res pageData.form = res
let areaCopy = pageData.form.area.split(',') const areaCopy = pageData.form.area.split(',')
pageData.form.areaText = `${getTextByCode(areaCopy[0])}/${getTextByCode(areaCopy[1])}/${getTextByCode(areaCopy[2])}` pageData.form.areaText = `${getTextByCode(areaCopy[0])}/${getTextByCode(areaCopy[1])}/${getTextByCode(areaCopy[2])}`
pageData.form.urgentdegreeText = pageData.options.urgentdegree.find( pageData.form.urgentdegreeText = pageData.options.urgentdegree.find(
(item) => item.value == pageData.form.urgentdegree, (item) => item.value == pageData.form.urgentdegree,
...@@ -188,8 +188,8 @@ ...@@ -188,8 +188,8 @@
// 返回格式化的对象 // 返回格式化的对象
return { return {
name: fileName, name: fileName,
extname: extname, extname,
url: url, url,
} }
} }
...@@ -221,7 +221,7 @@ ...@@ -221,7 +221,7 @@
// 文件上传 // 文件上传
function handleUpload(file) { function handleUpload(file) {
uni.uploadFile({ uni.uploadFile({
url: globSetting.apiUrl + globSetting.urlPrefix + '/sys/common/upload', // 直接使用上传接口URL url: `${globSetting.apiUrl + globSetting.urlPrefix}/sys/common/upload`, // 直接使用上传接口URL
filePath: file.tempFiles[0].path, filePath: file.tempFiles[0].path,
name: 'file', name: 'file',
formData: { formData: {
...@@ -287,7 +287,7 @@ ...@@ -287,7 +287,7 @@
v-model="form.name" v-model="form.name"
labelSize="28" labelSize="28"
label-width="180" label-width="180"
></fui-input> />
<fui-input <fui-input
required required
label="工作内容" label="工作内容"
...@@ -295,7 +295,7 @@ ...@@ -295,7 +295,7 @@
v-model="form.content" v-model="form.content"
labelSize="28" labelSize="28"
label-width="180" label-width="180"
></fui-input> />
</view> </view>
<view class="mt20"> <view class="mt20">
<fui-input <fui-input
...@@ -307,7 +307,7 @@ ...@@ -307,7 +307,7 @@
v-model="form.workers" v-model="form.workers"
labelSize="28" labelSize="28"
label-width="180" label-width="180"
></fui-input> />
<fui-input <fui-input
required required
type="number" type="number"
...@@ -317,7 +317,7 @@ ...@@ -317,7 +317,7 @@
v-model="form.price" v-model="form.price"
labelSize="28" labelSize="28"
label-width="180" label-width="180"
></fui-input> />
<fui-input <fui-input
required required
label="类型" label="类型"
...@@ -326,7 +326,7 @@ ...@@ -326,7 +326,7 @@
labelSize="28" labelSize="28"
label-width="180" label-width="180"
@click="show.type = true" @click="show.type = true"
></fui-input> />
</view> </view>
<view class="mt20"> <view class="mt20">
<fui-input <fui-input
...@@ -337,7 +337,7 @@ ...@@ -337,7 +337,7 @@
labelSize="28" labelSize="28"
label-width="180" label-width="180"
@click="show.area = true" @click="show.area = true"
></fui-input> />
<fui-input <fui-input
required required
label="详细地址" label="详细地址"
...@@ -345,7 +345,7 @@ ...@@ -345,7 +345,7 @@
v-model="form.address" v-model="form.address"
labelSize="28" labelSize="28"
label-width="180" label-width="180"
></fui-input> />
<fui-input <fui-input
required required
label="紧急程度" label="紧急程度"
...@@ -354,7 +354,7 @@ ...@@ -354,7 +354,7 @@
labelSize="28" labelSize="28"
label-width="180" label-width="180"
@click="show.urgentdegree = true" @click="show.urgentdegree = true"
></fui-input> />
<!-- 时间范围 --> <!-- 时间范围 -->
<view class="form-section" style="padding: 0 30rpx"> <view class="form-section" style="padding: 0 30rpx">
<view class="form-item flex align-center"> <view class="form-item flex align-center">
...@@ -384,27 +384,17 @@ ...@@ -384,27 +384,17 @@
:auto-upload="false" :auto-upload="false"
@select="handleUpload" @select="handleUpload"
@delete="handleDelete" @delete="handleDelete"
></uni-file-picker> />
</view> </view>
<view class="fui-btn__box" v-if="!form.id" style="margin-top: 30rpx"> <view class="fui-btn__box" v-if="!form.id" style="margin-top: 30rpx">
<fui-button text="发布用工" bold radius="96rpx" @click="submit"></fui-button> <fui-button text="发布用工" bold radius="96rpx" @click="submit" />
</view> </view>
</fui-form> </fui-form>
</view> </view>
</view> </view>
<fui-date-picker <fui-date-picker :show="show.time1" type="3" @change="handleChangeTime1" @cancel="show.time1 = false" />
:show="show.time1" <fui-date-picker :show="show.time2" type="3" @change="handleChangeTime2" @cancel="show.time2 = false" />
type="3"
@change="handleChangeTime1"
@cancel="show.time1 = false"
></fui-date-picker>
<fui-date-picker
:show="show.time2"
type="3"
@change="handleChangeTime2"
@cancel="show.time2 = false"
></fui-date-picker>
<fui-picker <fui-picker
:show="show.type" :show="show.type"
:layer="1" :layer="1"
...@@ -412,7 +402,7 @@ ...@@ -412,7 +402,7 @@
:options="options.type" :options="options.type"
@change="handleChangetype" @change="handleChangetype"
@cancel="show.type = false" @cancel="show.type = false"
></fui-picker> />
<fui-picker <fui-picker
:show="show.urgentdegree" :show="show.urgentdegree"
:layer="1" :layer="1"
...@@ -420,7 +410,7 @@ ...@@ -420,7 +410,7 @@
:options="options.urgentdegree" :options="options.urgentdegree"
@change="handleChangeUrgentdegree" @change="handleChangeUrgentdegree"
@cancel="show.urgentdegree = false" @cancel="show.urgentdegree = false"
></fui-picker> />
<fui-picker <fui-picker
:show="show.area" :show="show.area"
:options="options.area" :options="options.area"
...@@ -428,10 +418,10 @@ ...@@ -428,10 +418,10 @@
:layer="3" :layer="3"
@change="handleChangeAddress" @change="handleChangeAddress"
@cancel="show.area = false" @cancel="show.area = false"
></fui-picker> />
<fui-toast ref="toastRef"></fui-toast> <fui-toast ref="toastRef" />
<fui-loading isFixed v-if="pageData.loading" backgroundColor="rgba(0, 0, 0, 0.4)"></fui-loading> <fui-loading isFixed v-if="pageData.loading" backgroundColor="rgba(0, 0, 0, 0.4)" />
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>
......
<script setup lang="ts"> <script setup lang="ts">
import { reactive } from 'vue' import { reactive } from 'vue'
import { onLoad, onReachBottom, onShow } from '@dcloudio/uni-app'
import RegisterDialog from './components/register-dialog.vue' import RegisterDialog from './components/register-dialog.vue'
import { onPullDownRefresh, onLoad, onShow, onReachBottom } from '@dcloudio/uni-app' import { getTextByCode } from '@/utils/areaData'
import { areaTree, getTextByCode, getCodeByText } from '@/utils/areaData'
import * as LinghuoyonggongAPI from '@/api/model/linghuoyonggong' import * as LinghuoyonggongAPI from '@/api/model/linghuoyonggong'
import Navigate from '@/utils/page/navigate' import Navigate from '@/utils/page/navigate'
...@@ -181,7 +181,7 @@ ...@@ -181,7 +181,7 @@
item.area = areaCache.get(cacheKey) item.area = areaCache.get(cacheKey)
} else { } else {
const areaCodes = item.area.split(',') const areaCodes = item.area.split(',')
const areaText = getTextByCode(areaCodes[0]) + ' ' + getTextByCode(areaCodes[1]) const areaText = `${getTextByCode(areaCodes[0])} ${getTextByCode(areaCodes[1])}`
areaCache.set(cacheKey, areaText) areaCache.set(cacheKey, areaText)
item.area = areaText item.area = areaText
} }
...@@ -248,7 +248,7 @@ ...@@ -248,7 +248,7 @@
function onEmploymentItemClick(item: any) { function onEmploymentItemClick(item: any) {
console.log('点击用工项:', item) console.log('点击用工项:', item)
// 在这里添加具体的用工项点击逻辑 // 在这里添加具体的用工项点击逻辑
Navigate.to('/pages/linghuoyonggong/form?id=' + item.id) Navigate.to(`/pages/linghuoyonggong/form?id=${item.id}`)
} }
// "我想去"按钮点击事件 // "我想去"按钮点击事件
...@@ -270,7 +270,7 @@ ...@@ -270,7 +270,7 @@
// 检查日期是否有效 // 检查日期是否有效
if (isNaN(d1.getTime()) || isNaN(d2.getTime())) { if (isNaN(d1.getTime()) || isNaN(d2.getTime())) {
throw new Error('无效的日期格式') throw new TypeError('无效的日期格式')
} }
// 设置时间部分为00:00:00,只比较日期部分 // 设置时间部分为00:00:00,只比较日期部分
...@@ -287,7 +287,8 @@ ...@@ -287,7 +287,8 @@
} }
onReachBottom(() => { onReachBottom(() => {
console.log('触底了') console.log('触底了')
if (pageData.total <= pageData.employmentList.length) return if (pageData.total <= pageData.employmentList.length)
return
pageData.search.pageNo++ pageData.search.pageNo++
getEmploymentList() getEmploymentList()
}) })
...@@ -325,7 +326,7 @@ ...@@ -325,7 +326,7 @@
</view> </view>
<view class="codefun-flex-col codefun-relative list"> <view class="codefun-flex-col codefun-relative list">
<view v-if="!pageData.employmentList || pageData.employmentList.length == 0" style="height: 700rpx"> <view v-if="!pageData.employmentList || pageData.employmentList.length == 0" style="height: 700rpx">
<fui-empty marginTop="100" src="/src/static/images/no-data.png" title="暂无数据"></fui-empty> <fui-empty marginTop="100" src="/src/static/images/no-data.png" title="暂无数据" />
</view> </view>
<template v-else> <template v-else>
<view <view
...@@ -393,12 +394,12 @@ ...@@ -393,12 +394,12 @@
<fui-fab position="right" distance="10" bottom="240" width="96" @click="handlePublish"> <fui-fab position="right" distance="10" bottom="240" width="96" @click="handlePublish">
<view class="text-white text-center"> <view class="text-white text-center">
<!-- <image src="/src/static/images/chanxiao/notepad.svg" style="width: 40rpx" mode="widthFix"></image> --> <!-- <image src="/src/static/images/chanxiao/notepad.svg" style="width: 40rpx" mode="widthFix"></image> -->
<view class="fab-icon"></view> <view class="fab-icon" />
<view style="font-size: 24rpx">发布</view> <view style="font-size: 24rpx">发布</view>
</view> </view>
</fui-fab> </fui-fab>
<register-dialog ref="registerDialogRef"></register-dialog> <RegisterDialog ref="registerDialogRef" />
<fui-loading isFixed v-if="pageData.loading" backgroundColor="rgba(0, 0, 0, 0.4)"></fui-loading> <fui-loading isFixed v-if="pageData.loading" backgroundColor="rgba(0, 0, 0, 0.4)" />
</template> </template>
<style scoped lang="scss"> <style scoped lang="scss">
......
...@@ -53,7 +53,7 @@ ...@@ -53,7 +53,7 @@
}) })
// 页面数据 // 页面数据
const defaultText = '湖南省农业服务平台' const defaultText = '数字农服'
const readConfirmShow = ref<boolean>(false) const readConfirmShow = ref<boolean>(false)
const form = ref() const form = ref()
const model = reactive({ const model = reactive({
...@@ -280,7 +280,7 @@ ...@@ -280,7 +280,7 @@
:loading="model.loading" :loading="model.loading"
/> />
</view> </view>
<view class="flex-center p-32rpx box-border btn-register" @click="goRegister"> 立即注册 </view> <view class="flex-center p-32rpx box-border btn-register" @click="goRegister"> 还没有账号,立即注册 </view>
</fui-form> </fui-form>
<!-- </view> --> <!-- </view> -->
<fui-checkbox-group class="checkbox" name="checkbox"> <fui-checkbox-group class="checkbox" name="checkbox">
...@@ -464,6 +464,7 @@ ...@@ -464,6 +464,7 @@
:deep(.fui-input__border-bottom) { :deep(.fui-input__border-bottom) {
right: 32rpx !important; right: 32rpx !important;
} }
.btn-register { .btn-register {
color: cadetblue; color: cadetblue;
} }
......
...@@ -56,7 +56,7 @@ ...@@ -56,7 +56,7 @@
// 注册参数 // 注册参数
const params = { const params = {
phone: model.form.data.phone, phone: model.form.data.phone,
password: model.form.data.password, password: model.form.data.password || '123@2025',
code: model.form.data.code, code: model.form.data.code,
} }
...@@ -179,14 +179,14 @@ ...@@ -179,14 +179,14 @@
<template> <template>
<view class="warp"> <view class="warp">
<!-- <image class="login-warp" src="/static/login/login_bg.png" /> --> <!-- <image class="login-warp" src="/static/login/login_bg.png" /> -->
<view class="register-bg-wrap">
<!-- <image class="register-bg" src="/static/images/register/register.png" /> -->
<view class="logo-content-wrap">
<view class="logo-text-1">你好,欢迎使用</view>
<view class="logo-text">数字农业服务平台</view>
</view>
</view>
<view class="register-form"> <view class="register-form">
<view class="register-bg-wrap">
<!-- <image class="register-bg" src="/static/images/register/register.png" /> -->
<view class="logo-content-wrap">
<view class="logo-text-1">你好,欢迎使用</view>
<view class="logo-text">数字农业服务平台</view>
</view>
</view>
<fui-form class="form" ref="form" top="50" :padding="['0rpx', '32rpx']"> <fui-form class="form" ref="form" top="50" :padding="['0rpx', '32rpx']">
<view class="reigister-form-item"> <view class="reigister-form-item">
<image class="reigister-form-image" src="/static/images/register/user.png" /> <image class="reigister-form-image" src="/static/images/register/user.png" />
...@@ -207,13 +207,13 @@ ...@@ -207,13 +207,13 @@
maxlength="11" maxlength="11"
/> />
<view class="reigister-form-item"> <view class="reigister-form-item !hidden">
<image class="reigister-form-image" src="/static/images/register/pwd.png" /> <image class="reigister-form-image" src="/static/images/register/pwd.png" />
<text>密码</text> <text>密码</text>
</view> </view>
<fui-input <fui-input
height="100rpx" height="100rpx"
class="input" class="input !hidden"
password password
autocomplete="new-password" autocomplete="new-password"
code code
...@@ -321,30 +321,33 @@ ...@@ -321,30 +321,33 @@
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
background-image: url(/static/images/register/register.png); background-image: url('/static/images/register/register.png');
background-size: 100% 100%; background-size: 100% 100%;
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: center; background-position: center;
.logo-content-wrap { .logo-content-wrap {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: left; justify-content: left;
align-items: flex-start; align-items: flex-start;
width: 86%; width: 86%;
.logo-text-1 { .logo-text-1 {
font-size: 30rpx; font-size: 30rpx;
font-weight: 400; font-weight: 400;
letter-spacing: 0px; letter-spacing: 0;
margin-top: 4.25rem; margin-top: 4.25rem;
color: rgba(51, 51, 51, 0.7); color: rgb(51 51 51 / 70%);
vertical-align: middle; vertical-align: middle;
} }
.logo-text { .logo-text {
font-size: 40rpx; font-size: 40rpx;
font-weight: 500; font-weight: 500;
letter-spacing: 0px; letter-spacing: 0;
margin-top: 40rpx; margin-top: 40rpx;
color: rgba(51, 51, 51, 1); color: rgb(51 51 51 / 100%);
vertical-align: middle; vertical-align: middle;
} }
} }
...@@ -354,18 +357,19 @@ ...@@ -354,18 +357,19 @@
position: absolute; position: absolute;
width: 100%; width: 100%;
height: 60vh; height: 60vh;
left: 0px; left: 0;
top: 450rpx; top: 0;
opacity: 1; opacity: 1;
border-radius: 14.03px 14.03px 0px 0px; border-radius: 14.03px 14.03px 0 0;
border: 1px solid #fff; border: 1px solid #fff;
background: linear-gradient( background: linear-gradient(
180deg, 180deg,
rgba(181, 238, 215, 1) 0%, rgb(181 238 215 / 100%) 0%,
rgba(181, 238, 215, 0.5) 30%, rgb(181 238 215 / 50%) 30%,
rgba(255, 255, 255, 0.8) 100% rgb(255 255 255 / 80%) 100%
); );
} }
.reigister-form-item { .reigister-form-item {
color: #000; color: #000;
display: flex; display: flex;
...@@ -373,10 +377,12 @@ ...@@ -373,10 +377,12 @@
justify-content: left; justify-content: left;
align-items: center; align-items: center;
margin: 10rpx; margin: 10rpx;
.reigister-form-image { .reigister-form-image {
width: 60rpx; width: 60rpx;
height: 60rpx; height: 60rpx;
} }
text { text {
font-size: 32rpx; font-size: 32rpx;
display: flex; display: flex;
...@@ -384,11 +390,11 @@ ...@@ -384,11 +390,11 @@
margin-left: 20rpx; margin-left: 20rpx;
} }
} }
.form { .form {
position: absolute;
top: 80rpx;
width: 100%; width: 100%;
z-index: 10; z-index: 10;
margin-top: 540rpx;
} }
.checkbox { .checkbox {
...@@ -421,6 +427,7 @@ ...@@ -421,6 +427,7 @@
:deep(.fui-input__border-bottom) { :deep(.fui-input__border-bottom) {
right: 32rpx !important; right: 32rpx !important;
} }
.btn-register { .btn-register {
color: cadetblue; color: cadetblue;
} }
......
<script setup lang="ts"> <script setup lang="ts">
import { useRuntime } from '@/hooks/app/useRuntime' import { useRuntime } from '@/hooks/app/useRuntime'
import { convertKB } from '@/utils' import { convertKB } from '@/utils'
import { calculateCacheSize, cleanCache } from '@/components/CacheImage/index' import { calculateCacheSize, cleanCache } from '@/components/CacheImage/index'
import { useUserStore } from '@/store/modules/user' import { useUserStore } from '@/store/modules/user'
import { useFarmStore } from '@/store/modules/farm' import { useFarmStore } from '@/store/modules/farm'
import { checkUpgrade } from '@/utils/upgrade' import { checkUpgrade } from '@/utils/upgrade'
import * as NongchangAPI from '@/api/model/nongchang' import * as NongchangAPI from '@/api/model/nongchang'
// import { Permissions, usePermissions } from '@/components/Permissions' // import { Permissions, usePermissions } from '@/components/Permissions'
// import { useUserPermissions } from '@/utils/auth' // import { useUserPermissions } from '@/utils/auth'
// const [registerPermissions, { request }] = usePermissions() // const [registerPermissions, { request }] = usePermissions()
const userStore = useUserStore() const userStore = useUserStore()
const farmStore = useFarmStore() const farmStore = useFarmStore()
const { app } = useRuntime() const { app } = useRuntime()
const version = computed(() => app.value.version) const version = computed(() => app.value.version)
onShow(() => { onShow(() => {
const { id, realname, phone, avatar } = userStore.getUserInfo const { id, realname, phone, avatar } = userStore.getUserInfo
model.id = id model.id = id
model.realname = realname model.realname = realname
model.phone = phone model.phone = phone
if (avatar) { if (avatar) {
model.avatar = avatar model.avatar = avatar
}
})
// 个人信息
function navMsg() {
uni.navigateTo({
url: '/pages/mine/components/myMessage',
})
}
// 退出登录
function logOut() {
Message.confirm('确认退出登录状态?', '温馨提示').then((confirm) => {
if (confirm) {
loginOut()
} }
}) })
} // 个人信息
function navMsg() {
uni.navigateTo({
url: '/pages/mine/components/myMessage',
})
}
// 退出登录
function logOut() {
Message.confirm('确认退出登录状态?', '温馨提示').then((confirm) => {
if (confirm) {
loginOut()
}
})
}
// 调用登出
function loginOut() {
model.loading = true
userStore.logout().finally(() => {
model.loading = false
})
}
// 调用登出 /**
function loginOut() { * 计算缓存
model.loading = true */
userStore.logout().finally(() => { function calculateCache() {
model.loading = false // 重新计算
const cacheIamgeSizeTotal = calculateCacheSize()
const { size: currentStorageSize, unit: currentStorageSizeUnit } = convertKB(cacheIamgeSizeTotal / 1024)
// 更新视图
items.find((item) => item.title === '系统缓存清除').suffix =
Number(currentStorageSize) === 0 ? '' : `${currentStorageSize}${currentStorageSizeUnit}`
}
const model = reactive({
id: '',
avatar: '/static/logo.png',
realname: '',
phone: '',
show: false,
descr: '',
state: '',
version: '',
loading: false,
})
// 用户默认层级
// const { isPermission } = useUserPermissions('user_default_zIndex_btn')
// 用户应急管理
// const { isPermission: emergencyPermission } = useUserPermissions('emergency_response_btn')
const pageData = reactive({
farmsListTotal: 0,
}) })
} const items = reactive<Recordable[]>([
{
/** title: '我的农场',
* 计算缓存 icon: 'nongchang2',
*/ disabled: false,
function calculateCache() { show: true,
// 重新计算 handle: () => {
const cacheIamgeSizeTotal = calculateCacheSize() if (pageData.farmsListTotal > 0) {
const { size: currentStorageSize, unit: currentStorageSizeUnit } = convertKB(cacheIamgeSizeTotal / 1024) uni.navigateTo({
url: '/pages/wode/wode',
// 更新视图 })
items.find((item) => item.title === '系统缓存清除').suffix = } else {
Number(currentStorageSize) === 0 ? '' : `${currentStorageSize}${currentStorageSizeUnit}` uni.navigateTo({
} url: '/pages/nongchang/create-nongchang-form',
})
const model = reactive({ }
id: '', },
avatar: '/static/logo.png', },
realname: '', {
phone: '', title: '我的基地',
show: false, icon: 'jidi',
descr: '', disabled: false,
state: '', show: true,
version: '', handle: () => {
loading: false,
})
// 用户默认层级
// const { isPermission } = useUserPermissions('user_default_zIndex_btn')
// 用户应急管理
// const { isPermission: emergencyPermission } = useUserPermissions('emergency_response_btn')
const pageData = reactive({
farmsListTotal: 0,
})
const items = reactive<Recordable[]>([
{
title: '我的农场',
icon: 'nongchang2',
disabled: false,
show: true,
handle: () => {
if (pageData.farmsListTotal > 0) {
uni.navigateTo({ uni.navigateTo({
url: '/pages/wode/wode', url: '/pages/jidiguanli/jidiguanli',
}) })
} else { },
},
{
title: '问题意见反馈',
icon: 'feedback',
disabled: false,
show: true,
handle: () => {
uni.navigateTo({ uni.navigateTo({
url: '/pages/nongchang/create-nongchang-form', url: '/pages/common/feedback/index',
}) })
} },
},
},
{
title: '我的基地',
icon: 'jidi',
disabled: false,
show: true,
handle: () => {
uni.navigateTo({
url: '/pages/jidiguanli/jidiguanli',
})
}, },
}, {
title: '系统缓存清除',
{ icon: 'clean',
title: '问题意见反馈', suffix: '',
icon: 'feedback', show: true,
disabled: false, handle: (item: Recordable) => {
show: true, if (!item.suffix) {
handle: () => { return
uni.navigateTo({ }
url: '/pages/common/feedback/index',
})
},
},
{
title: '系统缓存清除',
icon: 'clean',
suffix: '',
show: true,
handle: (item: Recordable) => {
if (!item.suffix) {
return
}
Message.confirm('确认清除缓存?', '温馨提示').then(async (confirm) => { Message.confirm('确认清除缓存?', '温馨提示').then(async (confirm) => {
if (confirm) { if (confirm) {
Message.loading('清理中...') Message.loading('清理中...')
try { try {
// 清理缓存 // 清理缓存
await cleanCache() await cleanCache()
// 重新计算 // 重新计算
calculateCache() calculateCache()
} finally { } finally {
// 延迟提示 // 延迟提示
setTimeout(() => { setTimeout(() => {
Message.toast('缓存清除成功') Message.toast('缓存清除成功')
Message.hideLoading() Message.hideLoading()
}, 500) }, 500)
}
} }
} })
}) },
}, },
}, {
{ title: '系统检查更新',
title: '系统检查更新', icon: 'update',
icon: 'update', suffix: '',
suffix: '', show: true,
show: true, handle: () => {
handle: () => { // #ifdef APP-PLUS
// #ifdef APP-PLUS // 检查更新
// 检查更新 checkUpgrade(true)
checkUpgrade(true) // #endif
// #endif },
}, },
}, {
{ title: `关于${$app.name}`,
title: `关于${$app.name}`, icon: 'about',
icon: 'about', show: true,
show: true, handle: () => {
handle: () => { uni.navigateTo({
uni.navigateTo({ url: '/pages/common/about/index',
url: '/pages/common/about/index', })
}) },
}, },
}, ])
])
function getFarmsList() {
function getFarmsList() { NongchangAPI.farmsList({
NongchangAPI.farmsList({ pageNo: 1,
pageNo: 1, pageSize: 10,
pageSize: 10, }).then((res) => {
}).then((res) => { console.log(res)
console.log(res) const { total } = res
const { total } = res pageData.farmsListTotal = total
pageData.farmsListTotal = total if (res.records.length) {
if(res.records.length){ farmStore.setFarmInfo(res.records[0])
farmStore.setFarmInfo(res.records[0]) }
} })
}
onShow(() => {
getFarmsList()
// 计算缓存
calculateCache()
}) })
}
watch(
onShow(() => { () => version.value,
getFarmsList() (value) => {
// 计算缓存 if (value) {
calculateCache() items.find((item) => item.title === '系统检查更新').suffix = `v${value}`
}) }
},
watch( )
() => version.value,
(value) => {
if (value) {
items.find((item) => item.title === '系统检查更新').suffix = `v${value}`
}
},
)
</script> </script>
<template> <template>
<view class="main page-bg"> <view class="main page-bg">
<view class="w-full h-250 flex flex-row items-center avatar pt-44px pl-6"> <view class="w-full h-250 flex flex-row items-center avatar pt-44px pl-6">
<CacheImage :src="model.avatar" width="150" height="150" radius="999" background="transparent" <CacheImage
style="box-shadow: 0 0 10rpx #cdcdcd" @click="navMsg" /> :src="model.avatar"
width="150"
height="150"
radius="999"
background="transparent"
style="box-shadow: 0 0 10rpx #cdcdcd"
@click="navMsg"
/>
<view class="flex flex-col ml-50rpx"> <view class="flex flex-col ml-50rpx">
<text class="text-#fff" style="text-shadow: 0 0 10rpx #888">{{ model.realname }}</text> <text class="text-#fff" style="text-shadow: 0 0 10rpx #888">{{ model.realname }}</text>
<view class="max-w-400rpx mt-20rpx flex-center"> <view class="max-w-400rpx mt-20rpx flex-center">
<fui-overflow-hidden width="100%" size="24" color="#fff" <fui-overflow-hidden
:text="model.phone ? `${model.phone}` : '- -'" /> width="100%"
size="24"
color="#fff"
:text="model.phone ? `${model.phone}` : '- -'"
/>
</view> </view>
</view> </view>
</view> </view>
<view class="px-6 pt-6"> <view class="px-6 pt-6">
<fui-list class="rd-3 overflow-hidden shadow" :top-border="false"> <fui-list class="rd-3 overflow-hidden shadow" :top-border="false">
<fui-list-cell arrow v-for="(item, index) in items.slice(0, 2)" :key="index" :bottom-border="false" <fui-list-cell
:class="{ disabled: item.disabled }" v-show="item.show" @tap="item.handle(item)"> arrow
<CacheImage :src="`/static/images/mine/${item.icon}.png`" width="42" height="42" v-for="(item, index) in items.slice(0, 2)"
background="transparent" /> :key="index"
:bottom-border="false"
:class="{ disabled: item.disabled }"
v-show="item.show"
@tap="item.handle(item)"
>
<CacheImage
:src="`/static/images/mine/${item.icon}.png`"
width="42"
height="42"
background="transparent"
/>
<text class="ml-3.5 text-30 text-#67c17a font-bold">{{ item.title }}</text> <text class="ml-3.5 text-30 text-#67c17a font-bold">{{ item.title }}</text>
<text v-show="index === 0 && pageData.farmsListTotal === 0" class="text-red">({{ <text v-show="index === 0 && pageData.farmsListTotal === 0" class="text-red"
pageData.farmsListTotal || 0 }})</text> >({{ pageData.farmsListTotal || 0 }})</text
<view v-show="index === 0 && pageData.farmsListTotal === 0" class="text-red flex-1 text-right">去添加 >
<view v-show="index === 0 && pageData.farmsListTotal === 0" class="text-red flex-1 text-right"
>去添加
</view> </view>
</fui-list-cell> </fui-list-cell>
</fui-list> </fui-list>
<fui-list class="rd-3 overflow-hidden shadow !mt-20rpx" :top-border="false"> <fui-list class="rd-3 overflow-hidden shadow !mt-20rpx" :top-border="false">
<fui-list-cell arrow v-for="(item, index) in items.slice(2, 10)" :key="index" :bottom-border="false" <fui-list-cell
class="pos-relative" :class="{ disabled: item.disabled }" v-show="item.show" arrow
@tap="item.handle(item)"> v-for="(item, index) in items.slice(2, 10)"
<CacheImage :src="`/static/images/mine/${item.icon}.png`" width="42" height="42" :key="index"
background="transparent" /> :bottom-border="false"
class="pos-relative"
:class="{ disabled: item.disabled }"
v-show="item.show"
@tap="item.handle(item)"
>
<CacheImage
:src="`/static/images/mine/${item.icon}.png`"
width="42"
height="42"
background="transparent"
/>
<text class="ml-3.5 text-30 text-#333333 font-500">{{ item.title }}</text> <text class="ml-3.5 text-30 text-#333333 font-500">{{ item.title }}</text>
<text v-if="item.suffix" class="pos-absolute right-70" <text
:style="{ color: item.icon === 'call' ? '#1890FF' : '#999' }"> v-if="item.suffix"
class="pos-absolute right-70"
:style="{ color: item.icon === 'call' ? '#1890FF' : '#999' }"
>
{{ item.suffix }} {{ item.suffix }}
</text> </text>
</fui-list-cell> </fui-list-cell>
</fui-list> </fui-list>
</view> </view>
<view class="p-6 pt-5 pb-2"> <view class="p-6 pt-5 pb-2">
<fui-button class="shadow" background="#fff" radius="18rpx" color="#4da25b" @click="logOut" <fui-button
:disabled="model.loading" :loading="model.loading"> class="shadow"
background="#fff"
radius="18rpx"
color="#4da25b"
@click="logOut"
:disabled="model.loading"
:loading="model.loading"
>
退出登录 退出登录
</fui-button> </fui-button>
</view> </view>
...@@ -260,90 +305,90 @@ watch( ...@@ -260,90 +305,90 @@ watch(
</template> </template>
<style lang="less" scoped> <style lang="less" scoped>
.main { .main {
width: 100%; width: 100%;
height: 100%; height: 100%;
// #ifdef H5 // #ifdef H5
height: calc(100vh - 60px); height: calc(100vh - 60px);
// #endif // #endif
} }
.page-bg { .page-bg {
background: url('/static/images/codefun/7a5dc4ee864fe55da98b41c14ee3b931.png') no-repeat top center; background: url('/static/images/codefun/7a5dc4ee864fe55da98b41c14ee3b931.png') no-repeat top center;
background-size: 100%; background-size: 100%;
} }
.userInfo_box { .userInfo_box {
background: #fff; background: #fff;
padding: 32rpx 30rpx; padding: 32rpx 30rpx;
display: flex; display: flex;
align-items: center; align-items: center;
padding-top: 120rpx; padding-top: 120rpx;
.user_info { .user_info {
height: 125rpx; height: 125rpx;
margin-left: 32rpx; margin-left: 32rpx;
display: flex;
flex-direction: column;
justify-content: space-around;
}
}
.fui-color-border {
border-color: #fff;
}
.me_action {
margin-top: 20rpx;
}
.fui-list__item {
flex: 1;
width: 100%;
display: flex; display: flex;
flex-direction: column; align-items: center;
justify-content: space-around; justify-content: space-between;
}
.fui-text__explain {
font-size: 28rpx;
color: #7f7f7f;
flex-shrink: 0;
}
.fui-list__img {
width: 48rpx;
height: 48rpx;
margin-right: 10rpx;
}
.action_text {
font-size: 32rpx;
} }
}
.loginout {
.fui-color-border { height: 104rpx;
border-color: #fff; background: #fff;
} font-weight: 400;
color: #1890ff;
.me_action { font-size: 32rpx;
margin-top: 20rpx; text-align: center;
} line-height: 104rpx;
margin-top: 20rpx;
.fui-list__item { }
flex: 1;
width: 100%; .avatar {
display: flex; font-weight: bold;
align-items: center; color: #fff;
justify-content: space-between; }
}
.border-bottom {
.fui-text__explain { &.disabled {
font-size: 28rpx; pointer-events: none;
color: #7f7f7f;
flex-shrink: 0; * {
} color: gray;
}
.fui-list__img {
width: 48rpx;
height: 48rpx;
margin-right: 10rpx;
}
.action_text {
font-size: 32rpx;
}
.loginout {
height: 104rpx;
background: #fff;
font-weight: 400;
color: #1890ff;
font-size: 32rpx;
text-align: center;
line-height: 104rpx;
margin-top: 20rpx;
}
.avatar {
font-weight: bold;
color: #fff;
}
.border-bottom {
&.disabled {
pointer-events: none;
* {
color: gray;
} }
} }
}
</style> </style>
<script setup lang="ts"> <script setup lang="ts">
import { reactive, toRefs } from 'vue' import { reactive, toRefs } from 'vue'
import { onLoad, 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'
...@@ -112,13 +112,13 @@ ...@@ -112,13 +112,13 @@
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 {
value: item.value, value: item.value,
text: item.text, text: item.text,
} }
}) })
pageData.options.farmType = dictStore.getDictList['farm_type'].map((item) => { pageData.options.farmType = dictStore.getDictList.farm_type.map((item) => {
return { return {
value: item.value, value: item.value,
text: item.text, text: item.text,
...@@ -148,7 +148,7 @@ ...@@ -148,7 +148,7 @@
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
filePath: file.tempFiles[0].path, filePath: file.tempFiles[0].path,
name: 'file', name: 'file',
formData: { formData: {
...@@ -212,38 +212,21 @@ ...@@ -212,38 +212,21 @@
<template> <template>
<fui-form ref="formRef"> <fui-form ref="formRef">
<fui-input required label="农场名称" placeholder="请输入农场名称" v-model="form.farmName"></fui-input> <fui-input required label="农场名称" placeholder="请输入农场名称" v-model="form.farmName" />
<fui-input required label="农场标语" placeholder="请输入农场标语" v-model="form.title"></fui-input> <fui-input required label="农场标语" placeholder="请输入农场标语" v-model="form.title" />
<fui-input <fui-input
required required
label="农场类型" label="农场类型"
placeholder="请选择农场类型" placeholder="请选择农场类型"
v-model="form.farmTypeText" v-model="form.farmTypeText"
@click="show.farmType = true" @click="show.farmType = true"
></fui-input> />
<fui-input required label="联系人" placeholder="请输入联系人" v-model="form.contactPerson"></fui-input> <fui-input required label="联系人" placeholder="请输入联系人" v-model="form.contactPerson" />
<fui-input required label="联系电话" placeholder="请输入联系电话" v-model="form.contactPhone"></fui-input> <fui-input required label="联系电话" placeholder="请输入联系电话" v-model="form.contactPhone" />
<fui-textarea <fui-textarea required label="农场描述" placeholder="请输入农场描述" v-model="pageData.form.description" />
required <fui-input required label="地区" placeholder="请选择地区" v-model="form.address" @click="show.address = true" />
label="农场描述" <fui-input required label="详细地址" placeholder="请输入详细地址" v-model="form.addressDetail" />
placeholder="请输入农场描述" <fui-input required label="主营业务" borderTop placeholder="请输入主营业务" v-model="form.mainBusiness" />
v-model="pageData.form.description"
></fui-textarea>
<fui-input
required
label="地区"
placeholder="请选择地区"
v-model="form.address"
@click="show.address = true"
></fui-input>
<fui-input required label="详细地址" placeholder="请输入详细地址" v-model="form.addressDetail"></fui-input>
<fui-input
required
label="主营业务"
borderTop
placeholder="请输入主营业务"
v-model="form.mainBusiness"
></fui-input>
<fui-input <fui-input
required required
label="主要产品" label="主要产品"
...@@ -251,14 +234,8 @@ ...@@ -251,14 +234,8 @@
placeholder="请选择主要产品" placeholder="请选择主要产品"
v-model="form.mainProductsText" v-model="form.mainProductsText"
@click="show.mainProducts = true" @click="show.mainProducts = true"
></fui-input> />
<fui-input <fui-input required label="总面积(亩)" borderTop placeholder="请输入总面积" v-model="form.totalArea" />
required
label="总面积(亩)"
borderTop
placeholder="请输入总面积"
v-model="form.totalArea"
></fui-input>
<view class="bg-white" style="padding: 0.875rem 0.35rem"> <view class="bg-white" style="padding: 0.875rem 0.35rem">
<view class="mb-1 flex justify-start"> 封面图片 </view> <view class="mb-1 flex justify-start"> 封面图片 </view>
<uni-file-picker <uni-file-picker
...@@ -267,10 +244,10 @@ ...@@ -267,10 +244,10 @@
:auto-upload="false" :auto-upload="false"
@select="handleUpload" @select="handleUpload"
@delete="handleDelete" @delete="handleDelete"
></uni-file-picker> />
</view> </view>
<view class="fui-btn__box bg-white p-4"> <view class="fui-btn__box bg-white p-4">
<fui-button text="添加农场" bold radius="96rpx" @click="submit"></fui-button> <fui-button text="添加农场" bold radius="96rpx" @click="submit" />
</view> </view>
</fui-form> </fui-form>
...@@ -281,7 +258,7 @@ ...@@ -281,7 +258,7 @@
:options="options.farmType" :options="options.farmType"
@change="handleChangeFarmType" @change="handleChangeFarmType"
@cancel="show.farmType = false" @cancel="show.farmType = false"
></fui-picker> />
<fui-picker <fui-picker
:show="show.mainProducts" :show="show.mainProducts"
:layer="1" :layer="1"
...@@ -289,7 +266,7 @@ ...@@ -289,7 +266,7 @@
:options="options.mainProducts" :options="options.mainProducts"
@change="handleChangeMainProducts" @change="handleChangeMainProducts"
@cancel="show.mainProducts = false" @cancel="show.mainProducts = false"
></fui-picker> />
<fui-picker <fui-picker
:show="show.address" :show="show.address"
:options="options.address" :options="options.address"
...@@ -297,10 +274,10 @@ ...@@ -297,10 +274,10 @@
:layer="3" :layer="3"
@change="handleChangeAddress" @change="handleChangeAddress"
@cancel="show.address = false" @cancel="show.address = false"
></fui-picker> />
<fui-toast ref="toastRef"></fui-toast> <fui-toast ref="toastRef" />
<fui-loading isFixed v-if="pageData.loading" backgroundColor="rgba(0, 0, 0, 0.4)"></fui-loading> <fui-loading isFixed v-if="pageData.loading" backgroundColor="rgba(0, 0, 0, 0.4)" />
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>
......
<script setup lang="ts"> <script setup lang="ts">
import { reactive } from 'vue' import { reactive } from 'vue'
import * as NongjifuwuAPI from '@/api/model/nongjifuwu' import * as NongjifuwuAPI from '@/api/model/nongjifuwu'
import { getCurrentDate } from '@/utils/date'
import { useUserStore } from '@/store/modules/user' import { useUserStore } from '@/store/modules/user'
const { getUserInfo } = useUserStore() const { getUserInfo } = useUserStore()
const pageData = reactive({ const pageData = reactive({
...@@ -112,60 +112,36 @@ ...@@ -112,60 +112,36 @@
close, close,
}) })
</script> </script>
<template> <template>
<fui-dialog title="" :buttons="[]" :show="pageData.show" maskClosable> <fui-dialog title="" :buttons="[]" :show="pageData.show" maskClosable>
<view class="title flex justify-center"> <view class="title flex justify-center">
<view class="flex-1">我有需要</view> <view class="flex-1">我有需要</view>
<fui-icon class="close flex-basis" name="close" size="46" color="#999999" @click="close"></fui-icon> <fui-icon class="close flex-basis" name="close" size="46" color="#999999" @click="close" />
</view> </view>
<view class="text-left"> <view class="text-left">
<fui-form ref="formRef"> <fui-form ref="formRef">
<fui-input <fui-input marginTop="30" size="24" placeholder="请填写预留手机" v-model="pageData.form.phone" />
marginTop="30" <fui-input marginTop="30" size="24" placeholder="请填写作业地区" v-model="pageData.form.scope" />
size="24" <fui-input marginTop="30" size="24" placeholder="请填写作业详细地址" v-model="pageData.form.address" />
placeholder="请填写预留手机"
v-model="pageData.form.phone"
></fui-input>
<fui-input
marginTop="30"
size="24"
placeholder="请填写作业地区"
v-model="pageData.form.scope"
></fui-input>
<fui-input
marginTop="30"
size="24"
placeholder="请填写作业详细地址"
v-model="pageData.form.address"
></fui-input>
<fui-input <fui-input
marginTop="30" marginTop="30"
size="24" size="24"
placeholder="请选择作业时间" placeholder="请选择作业时间"
v-model="pageData.form.time" v-model="pageData.form.time"
@click="dict.show.time = true" @click="dict.show.time = true"
></fui-input> />
<fui-textarea <fui-textarea v-model="pageData.form.demand" :marginTop="30" size="24" placeholder="简要说明作业需求" />
v-model="pageData.form.demand"
:marginTop="30"
size="24"
placeholder="简要说明作业需求"
></fui-textarea>
<view style="margin-top: 30rpx"> <view style="margin-top: 30rpx">
<fui-button type="warning" text="确定" bold radius="96rpx" @click="submit"></fui-button> <fui-button type="warning" text="确定" bold radius="96rpx" @click="submit" />
</view> </view>
</fui-form> </fui-form>
</view> </view>
</fui-dialog> </fui-dialog>
<fui-date-picker <fui-date-picker :show="dict.show.time" type="3" range @change="handleTimeChange" @cancel="handleTimeCancel" />
:show="dict.show.time"
type="3"
range
@change="handleTimeChange"
@cancel="handleTimeCancel"
></fui-date-picker>
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>
:deep(.fui-dialog__body) { :deep(.fui-dialog__body) {
background: linear-gradient(0deg, rgba(93, 182, 111, 0) 0%, rgba(93, 182, 111, 0.25) 100%); background: linear-gradient(0deg, rgba(93, 182, 111, 0) 0%, rgba(93, 182, 111, 0.25) 100%);
......
...@@ -124,8 +124,8 @@ ...@@ -124,8 +124,8 @@
// 返回格式化的对象 // 返回格式化的对象
return { return {
name: fileName, name: fileName,
extname: extname, extname,
url: url, url,
} }
} }
...@@ -147,7 +147,7 @@ ...@@ -147,7 +147,7 @@
// 文件上传 // 文件上传
function handleUpload(file) { function handleUpload(file) {
uni.uploadFile({ uni.uploadFile({
url: globSetting.apiUrl + globSetting.urlPrefix + '/sys/common/upload', // 直接使用上传接口URL url: `${globSetting.apiUrl + globSetting.urlPrefix}/sys/common/upload`, // 直接使用上传接口URL
filePath: file.tempFiles[0].path, filePath: file.tempFiles[0].path,
name: 'file', name: 'file',
formData: { formData: {
...@@ -213,7 +213,7 @@ ...@@ -213,7 +213,7 @@
v-model="form.name" v-model="form.name"
labelSize="28" labelSize="28"
label-width="180" label-width="180"
></fui-input> />
<view class="form-item required flex align-center" style="padding: 20rpx 10rpx"> <view class="form-item required flex align-center" style="padding: 20rpx 10rpx">
<text class="label">服务范围</text> <text class="label">服务范围</text>
<view class="time-input" @click="show.address = true"> <view class="time-input" @click="show.address = true">
...@@ -237,7 +237,7 @@ ...@@ -237,7 +237,7 @@
v-model="form.address" v-model="form.address"
labelSize="28" labelSize="28"
label-width="180" label-width="180"
></fui-input> />
<fui-input <fui-input
required required
label="联系方式" label="联系方式"
...@@ -245,7 +245,7 @@ ...@@ -245,7 +245,7 @@
v-model="form.phone" v-model="form.phone"
labelSize="28" labelSize="28"
label-width="180" label-width="180"
></fui-input> />
</view> </view>
<view class="mt20"> <view class="mt20">
<fui-input <fui-input
...@@ -255,7 +255,7 @@ ...@@ -255,7 +255,7 @@
v-model="form.demand" v-model="form.demand"
labelSize="28" labelSize="28"
label-width="180" label-width="180"
></fui-input> />
<!-- 作业时间 --> <!-- 作业时间 -->
<view class="form-section" style="padding: 0 10rpx"> <view class="form-section" style="padding: 0 10rpx">
<view class="form-item flex align-center"> <view class="form-item flex align-center">
...@@ -286,10 +286,10 @@ ...@@ -286,10 +286,10 @@
:auto-upload="false" :auto-upload="false"
@select="handleUpload" @select="handleUpload"
@delete="handleDelete" @delete="handleDelete"
></uni-file-picker> />
</view> </view>
<view class="fui-btn__box" v-if="!form.id" style="margin-top: 30rpx"> <view class="fui-btn__box" v-if="!form.id" style="margin-top: 30rpx">
<fui-button text="发布作业" bold radius="96rpx" @click="submit"></fui-button> <fui-button text="发布作业" bold radius="96rpx" @click="submit" />
</view> </view>
</fui-form> </fui-form>
...@@ -299,17 +299,17 @@ ...@@ -299,17 +299,17 @@
@change="handleChangeTime1" @change="handleChangeTime1"
@cancel="show.time1 = false" @cancel="show.time1 = false"
minDate="2025-01-01" minDate="2025-01-01"
></fui-date-picker> />
<fui-date-picker <fui-date-picker
:show="show.time2" :show="show.time2"
type="3" type="3"
@change="handleChangeTime2" @change="handleChangeTime2"
@cancel="show.time2 = false" @cancel="show.time2 = false"
minDate="2025-01-01" minDate="2025-01-01"
></fui-date-picker> />
<fui-toast ref="toastRef"></fui-toast> <fui-toast ref="toastRef" />
<fui-loading isFixed v-if="pageData.loading" backgroundColor="rgba(0, 0, 0, 0.4)"></fui-loading> <fui-loading isFixed v-if="pageData.loading" backgroundColor="rgba(0, 0, 0, 0.4)" />
<fui-picker <fui-picker
:show="show.address" :show="show.address"
:options="options.address" :options="options.address"
...@@ -317,7 +317,7 @@ ...@@ -317,7 +317,7 @@
:layer="3" :layer="3"
@change="handleChangeAddress" @change="handleChangeAddress"
@cancel="show.address = false" @cancel="show.address = false"
></fui-picker> />
</view> </view>
</view> </view>
</template> </template>
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
import * as nongjifuwu from '@/api/model/nongjifuwu' import * as nongjifuwu from '@/api/model/nongjifuwu'
import { useDictStore } from '@/store/modules/dict' import { useDictStore } from '@/store/modules/dict'
import { areaTree } from '@/utils/areaData' import { areaTree } from '@/utils/areaData'
const dictStore = useDictStore() const dictStore = useDictStore()
const userStore = useUserStore() const userStore = useUserStore()
const globSetting = useGlobSetting() const globSetting = useGlobSetting()
...@@ -111,8 +112,8 @@ ...@@ -111,8 +112,8 @@
// 返回格式化的对象 // 返回格式化的对象
return { return {
name: fileName, name: fileName,
extname: extname, extname,
url: url, url,
} }
} }
...@@ -121,7 +122,7 @@ ...@@ -121,7 +122,7 @@
// 文件上传 // 文件上传
function handleUpload(file) { function handleUpload(file) {
uni.uploadFile({ uni.uploadFile({
url: globSetting.apiUrl + globSetting.urlPrefix + '/sys/common/upload', // 直接使用上传接口URL url: `${globSetting.apiUrl + globSetting.urlPrefix}/sys/common/upload`, // 直接使用上传接口URL
filePath: file.tempFiles[0].path, filePath: file.tempFiles[0].path,
name: 'file', name: 'file',
formData: { formData: {
...@@ -178,6 +179,7 @@ ...@@ -178,6 +179,7 @@
pageData.show.address = false pageData.show.address = false
} }
</script> </script>
<template> <template>
<view class="page"> <view class="page">
<view class="formBox"> <view class="formBox">
...@@ -190,7 +192,7 @@ ...@@ -190,7 +192,7 @@
v-model="form.name" v-model="form.name"
labelSize="28" labelSize="28"
label-width="180" label-width="180"
></fui-input> />
<fui-input <fui-input
required required
label="联系方式" label="联系方式"
...@@ -198,7 +200,7 @@ ...@@ -198,7 +200,7 @@
v-model="form.phone" v-model="form.phone"
labelSize="28" labelSize="28"
label-width="180" label-width="180"
></fui-input> />
<view class="form-item required flex align-center" style="padding: 20rpx 10rpx"> <view class="form-item required flex align-center" style="padding: 20rpx 10rpx">
<text class="label">服务范围</text> <text class="label">服务范围</text>
<view class="time-input" @click="show.address = true"> <view class="time-input" @click="show.address = true">
...@@ -225,7 +227,7 @@ ...@@ -225,7 +227,7 @@
v-model="form.price" v-model="form.price"
labelSize="28" labelSize="28"
label-width="180" label-width="180"
></fui-input> />
</view> </view>
<view class="bg-white mt20" style="padding: 0.875rem 1rem"> <view class="bg-white mt20" style="padding: 0.875rem 1rem">
...@@ -238,16 +240,16 @@ ...@@ -238,16 +240,16 @@
:auto-upload="false" :auto-upload="false"
@select="handleUpload" @select="handleUpload"
@delete="handleDelete" @delete="handleDelete"
></uni-file-picker> />
</view> </view>
<view class="fui-btn__box" v-if="!form.id" style="margin-top: 30rpx"> <view class="fui-btn__box" v-if="!form.id" style="margin-top: 30rpx">
<fui-button text="发布作业" bold radius="96rpx" @click="submit"></fui-button> <fui-button text="发布作业" bold radius="96rpx" @click="submit" />
</view> </view>
</fui-form> </fui-form>
<fui-toast ref="toastRef"></fui-toast> <fui-toast ref="toastRef" />
<fui-loading isFixed v-if="pageData.loading" backgroundColor="rgba(0, 0, 0, 0.4)"></fui-loading> <fui-loading isFixed v-if="pageData.loading" backgroundColor="rgba(0, 0, 0, 0.4)" />
<fui-picker <fui-picker
:show="show.address" :show="show.address"
:options="options.address" :options="options.address"
...@@ -255,7 +257,7 @@ ...@@ -255,7 +257,7 @@
:layer="3" :layer="3"
@change="handleChangeAddress" @change="handleChangeAddress"
@cancel="show.address = false" @cancel="show.address = false"
></fui-picker> />
</view> </view>
</view> </view>
</template> </template>
......
<script setup lang="ts"> <script setup lang="ts">
import { reactive } from 'vue' import { reactive } from 'vue'
import { onLoad, onReachBottom, onShow } from '@dcloudio/uni-app'
import ApplyDialog from './components/apply-dialog.vue' import ApplyDialog from './components/apply-dialog.vue'
import { onPullDownRefresh, onLoad, onShow, onReachBottom } from '@dcloudio/uni-app'
import * as NongjifuwuAPI from '@/api/model/nongjifuwu' import * as NongjifuwuAPI from '@/api/model/nongjifuwu'
import Navigate from '@/utils/page/navigate' import Navigate from '@/utils/page/navigate'
...@@ -80,7 +80,8 @@ ...@@ -80,7 +80,8 @@
onReachBottom(() => { onReachBottom(() => {
console.log('触底了') console.log('触底了')
if (pageData.total <= pageData.farmMachineList.length) return if (pageData.total <= pageData.farmMachineList.length)
return
pageData.search.pageNo++ pageData.search.pageNo++
getFarmMachineList() getFarmMachineList()
}) })
...@@ -117,7 +118,7 @@ ...@@ -117,7 +118,7 @@
class="codefun-flex-col codefun-relative section_4" class="codefun-flex-col codefun-relative section_4"
style="height: 700rpx" style="height: 700rpx"
> >
<fui-empty marginTop="100" src="/src/static/images/no-data.png" title="暂无数据"></fui-empty> <fui-empty marginTop="100" src="/src/static/images/no-data.png" title="暂无数据" />
</view> </view>
<view class="codefun-flex-col codefun-relative section_4"> <view class="codefun-flex-col codefun-relative section_4">
<view class="codefun-flex-row group_6" v-for="item in pageData.farmMachineList" :key="item.id"> <view class="codefun-flex-row group_6" v-for="item in pageData.farmMachineList" :key="item.id">
...@@ -272,13 +273,13 @@ ...@@ -272,13 +273,13 @@
</view> </view>
<fui-fab position="right" distance="10" bottom="240" width="96" @click="handlePublish"> <fui-fab position="right" distance="10" bottom="240" width="96" @click="handlePublish">
<view class="text-white text-center"> <view class="text-white text-center">
<view class="fab-icon"></view> <view class="fab-icon" />
<view style="font-size: 24rpx">发布</view> <view style="font-size: 24rpx">发布</view>
</view> </view>
</fui-fab> </fui-fab>
<ApplyDialog ref="applyDialogRef"></ApplyDialog> <ApplyDialog ref="applyDialogRef" />
<fui-loading isFixed v-if="pageData.loading" backgroundColor="rgba(0, 0, 0, 0.4)"></fui-loading> <fui-loading isFixed v-if="pageData.loading" backgroundColor="rgba(0, 0, 0, 0.4)" />
</template> </template>
<style scoped lang="scss"> <style scoped lang="scss">
......
<script setup lang="ts"> <script setup lang="ts">
import { reactive } from 'vue' import { reactive } from 'vue'
import { onPullDownRefresh, onLoad, onShow, onReachBottom } from '@dcloudio/uni-app' import { onPullDownRefresh, onReachBottom, onShow } from '@dcloudio/uni-app'
import * as NongzhiAPI from '@/api/model/nongzhi' import * as NongzhiAPI from '@/api/model/nongzhi'
import { useDictStore } from '@/store/modules/dict' import { useDictStore } from '@/store/modules/dict'
...@@ -113,7 +113,7 @@ ...@@ -113,7 +113,7 @@
}) })
function initDict() { function initDict() {
pageData.categoryList1 = dictStore.getDictList['category'].map((item) => { pageData.categoryList1 = dictStore.getDictList.category.map((item) => {
return { return {
text: item.text, text: item.text,
value: item.value, value: item.value,
...@@ -181,7 +181,8 @@ ...@@ -181,7 +181,8 @@
} }
onReachBottom(() => { onReachBottom(() => {
if (pagedata.total <= pageData.products.length) return if (pagedata.total <= pageData.products.length)
return
pageData.search.pageNo++ pageData.search.pageNo++
getGoodsList() getGoodsList()
}) })
...@@ -215,7 +216,7 @@ ...@@ -215,7 +216,7 @@
<view class="fui-filter__item" @tap="filterTap1"> <view class="fui-filter__item" @tap="filterTap1">
<text>{{ pageData.range1 }}</text> <text>{{ pageData.range1 }}</text>
<view class="fui-filter__icon" :class="{ 'fui-icon__ani': pageData.rangeShow1 }"> <view class="fui-filter__icon" :class="{ 'fui-icon__ani': pageData.rangeShow1 }">
<fui-icon name="turningdown" :size="32"></fui-icon> <fui-icon name="turningdown" :size="32" />
</view> </view>
</view> </view>
</fui-dropdown-menu> </fui-dropdown-menu>
...@@ -232,14 +233,14 @@ ...@@ -232,14 +233,14 @@
<view class="fui-filter__item" @tap="filterTap2"> <view class="fui-filter__item" @tap="filterTap2">
<text>{{ pageData.range2 }}</text> <text>{{ pageData.range2 }}</text>
<view class="fui-filter__icon" :class="{ 'fui-icon__ani': pageData.rangeShow2 }"> <view class="fui-filter__icon" :class="{ 'fui-icon__ani': pageData.rangeShow2 }">
<fui-icon name="turningdown" :size="32"></fui-icon> <fui-icon name="turningdown" :size="32" />
</view> </view>
</view> </view>
</fui-dropdown-menu> </fui-dropdown-menu>
</view> </view>
<view class="codefun-mt-6 codefun-flex-col codefun-self-stretch"> <view class="codefun-mt-6 codefun-flex-col codefun-self-stretch">
<view v-if="!pageData.products || pageData.products.length == 0" style="height: 700rpx"> <view v-if="!pageData.products || pageData.products.length == 0" style="height: 700rpx">
<fui-empty marginTop="100" src="/src/static/images/no-data.png" title="暂无数据"></fui-empty> <fui-empty marginTop="100" src="/src/static/images/no-data.png" title="暂无数据" />
</view> </view>
<template v-else> <template v-else>
<view <view
......
<template>
<u-modal
:show="show"
:title="dialogTitle"
:showConfirmButton="false"
:showCancelButton="false"
@close="handleClose"
:closeOnClickOverlay="false"
>
<view class="dialog-content">
<u-form :model="formData" :rules="rules" ref="formRef" label-width="auto">
<!-- 资源基本信息 -->
<!-- <view class="section-title">资源基本信息</view> -->
<u-form-item label="" prop="fileName">
<u-input v-model="formData.fileName" placeholder="请输入文件名称" border="bottom" />
</u-form-item>
<!-- <u-form-item label="文件类型" prop="fileType" required>
<u-input v-model="formData.fileType" placeholder="请选择文件类型" border="bottom"
@click="showFileTypePicker = true" />
</u-form-item> -->
<u-form-item label="上传文件" prop="file" required>
<view class="file-upload">
<u-button v-if="!formData.file" @click="chooseFile" type="primary" class="ui-button">
<text class="font_10">选择文件</text>
</u-button>
<view v-else class="file-info">
<view class="file-name-container">
<text class="file-name">{{ formData.file.name }}</text>
<text class="remove-icon" @click="removeFile">×</text>
</view>
</view>
</view>
</u-form-item>
<!-- 操作按钮 -->
<view class="dialog-buttons">
<u-button
type="primary"
@click="handleSubmit"
:loading="loading"
size="normal"
class="submit-btn"
color="var(--fui-color-success)"
>
{{ submitButtonText }}
</u-button>
<u-button @click="handleClose" size="normal" class="cancel-btn">取消</u-button>
</view>
</u-form>
</view>
</u-modal>
</template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, reactive, watch, computed } from 'vue' import { computed, reactive, ref, watch } from 'vue'
import { useUserStore } from '@/store/modules/user' import { useUserStore } from '@/store/modules/user'
import { useGlobSetting } from '/@/hooks/setting' import { useGlobSetting } from '/@/hooks/setting'
import * as WodeAPI from '@/api/model/wode' import * as WodeAPI from '@/api/model/wode'
const lemonjkFileSelect = uni.requireNativePlugin('lemonjk-FileSelect')
// 定义Props
interface Props {
show: boolean
editData?: any
}
const props = withDefaults(defineProps<Props>(), { const props = withDefaults(defineProps<Props>(), {
show: false, show: false,
...@@ -79,6 +17,14 @@ ...@@ -79,6 +17,14 @@
submitSuccess: [] submitSuccess: []
}>() }>()
const lemonjkFileSelect = uni.requireNativePlugin('lemonjk-FileSelect')
// 定义Props
interface Props {
show: boolean
editData?: any
}
// 表单引用 // 表单引用
const formRef = ref() const formRef = ref()
const loading = ref(false) const loading = ref(false)
...@@ -155,7 +101,7 @@ ...@@ -155,7 +101,7 @@
) )
// 重置表单数据 // 重置表单数据
const resetFormData = () => { function resetFormData() {
formData.fileName = '' formData.fileName = ''
formData.fileType = '' formData.fileType = ''
formData.fileTypeText = '' formData.fileTypeText = ''
...@@ -168,8 +114,9 @@ ...@@ -168,8 +114,9 @@
} }
// 加载编辑数据 // 加载编辑数据
const loadEditData = () => { function loadEditData() {
if (!props.editData) return if (!props.editData)
return
formData.fileName = props.editData.fileName || '' formData.fileName = props.editData.fileName || ''
formData.fileType = props.editData.fileType || '' formData.fileType = props.editData.fileType || ''
...@@ -180,7 +127,7 @@ ...@@ -180,7 +127,7 @@
} }
const uplpoadFile = ref(null) const uplpoadFile = ref(null)
// 选择文件 // 选择文件
const chooseFile = () => { function chooseFile() {
// #ifdef H5 // #ifdef H5
uni.chooseFile({ uni.chooseFile({
count: 1, count: 1,
...@@ -219,7 +166,7 @@ ...@@ -219,7 +166,7 @@
// #ifndef H5 // #ifndef H5
lemonjkFileSelect.showNativePicker( lemonjkFileSelect.showNativePicker(
{ {
//各属性配置见下方【showPicker可配置参数说明】 // 各属性配置见下方【showPicker可配置参数说明】
pathScope: '/Download', pathScope: '/Download',
mimeType: '*/*', mimeType: '*/*',
utisType: ['public.data'], utisType: ['public.data'],
...@@ -243,7 +190,7 @@ ...@@ -243,7 +190,7 @@
} }
// 移除文件 // 移除文件
const removeFile = () => { function removeFile() {
formData.file = null formData.file = null
// 移除文件后触发验证 // 移除文件后触发验证
if (formRef.value) { if (formRef.value) {
...@@ -252,7 +199,7 @@ ...@@ -252,7 +199,7 @@
} }
// 根据文件扩展名获取文件类型 // 根据文件扩展名获取文件类型
const getFileTypeByExt = (ext) => { function getFileTypeByExt(ext) {
const map = { const map = {
doc: 'doc', doc: 'doc',
docx: 'doc', docx: 'doc',
...@@ -280,7 +227,7 @@ ...@@ -280,7 +227,7 @@
const userStore = useUserStore() const userStore = useUserStore()
const globSetting = useGlobSetting() const globSetting = useGlobSetting()
// 提交表单 // 提交表单
const handleSubmit = async () => { async function handleSubmit() {
try { try {
console.log(formData) console.log(formData)
// 先进行表单验证 // 先进行表单验证
...@@ -313,7 +260,7 @@ ...@@ -313,7 +260,7 @@
// API留空 // API留空
console.log('上传资源数据:', submitData) console.log('上传资源数据:', submitData)
uni.uploadFile({ uni.uploadFile({
url: globSetting.apiUrl + globSetting.urlPrefix + '/sys/common/upload', // 直接使用上传接口URL url: `${globSetting.apiUrl + globSetting.urlPrefix}/sys/common/upload`, // 直接使用上传接口URL
filePath: uplpoadFile.value, filePath: uplpoadFile.value,
name: 'file', name: 'file',
formData: { formData: {
...@@ -377,12 +324,67 @@ ...@@ -377,12 +324,67 @@
} }
// 关闭弹窗 // 关闭弹窗
const handleClose = () => { function handleClose() {
emit('update:show', false) emit('update:show', false)
emit('close') emit('close')
} }
</script> </script>
<template>
<u-modal
:show="show"
:title="dialogTitle"
:showConfirmButton="false"
:showCancelButton="false"
@close="handleClose"
:closeOnClickOverlay="false"
>
<view class="dialog-content">
<u-form :model="formData" :rules="rules" ref="formRef" label-width="auto">
<!-- 资源基本信息 -->
<!-- <view class="section-title">资源基本信息</view> -->
<u-form-item label="" prop="fileName">
<u-input v-model="formData.fileName" placeholder="请输入文件名称" border="bottom" />
</u-form-item>
<!-- <u-form-item label="文件类型" prop="fileType" required>
<u-input v-model="formData.fileType" placeholder="请选择文件类型" border="bottom"
@click="showFileTypePicker = true" />
</u-form-item> -->
<u-form-item label="上传文件" prop="file" required>
<view class="file-upload">
<u-button v-if="!formData.file" @click="chooseFile" type="primary" class="ui-button">
<text class="font_10">选择文件</text>
</u-button>
<view v-else class="file-info">
<view class="file-name-container">
<text class="file-name">{{ formData.file.name }}</text>
<text class="remove-icon" @click="removeFile">×</text>
</view>
</view>
</view>
</u-form-item>
<!-- 操作按钮 -->
<view class="dialog-buttons">
<u-button
type="primary"
@click="handleSubmit"
:loading="loading"
size="normal"
class="submit-btn"
color="var(--fui-color-success)"
>
{{ submitButtonText }}
</u-button>
<u-button @click="handleClose" size="normal" class="cancel-btn">取消</u-button>
</view>
</u-form>
</view>
</u-modal>
</template>
<style lang="scss" scoped> <style lang="scss" scoped>
.dialog-content { .dialog-content {
padding: 10rpx 30rpx; padding: 10rpx 30rpx;
......
<template>
<view class="codefun-flex-col page">
<z-paging ref="paging" v-model="pageData.list" @query="queryList">
<view class="codefun-flex-col group_3">
<view class="codefun-flex-row codefun-items-center section_2">
<image class="image_6" src="/static/images/codefun/6c5c5a3c082b8c60a307d3a7caee623c.png" />
<u-input
v-model="pageData.param.fileName"
placeholder="请输入文件名称搜索"
border="none"
class="codefun-ml-8"
@confirm="handleSearch"
/>
</view>
<!-- 资源列表 - 根据图片样式修改 -->
<view class="resource-list">
<view v-for="(item, index) in pageData.list" :key="index" class="resource-item">
<view class="resource-content">
<view class="resource-main">
<view class="resource-name">{{ item.fileName }}</view>
<view class="resource-meta">
<text class="resource-size">{{ item.fileSize }}</text>
<text class="separator">|</text>
<text class="download-count">已下载{{ item.downloadCount || 0 }}</text>
<text class="separator">|</text>
<text class="upload-time">{{ formatTime(item.createTime) }}</text>
</view>
</view>
<view
class="codefun-flex-col codefun-justify-start codefun-items-center text-wrapper_4"
@click.stop="handleDownload(item)"
>
<text class="font_10">下载</text>
</view>
<!-- <view class="download-section">
<view class="download-btn" @click="handleDownload(item)">
<text class="btn-text">下载</text>
</view>
</view> -->
</view>
</view>
</view>
<!-- 空状态 -->
<!-- <view class="empty-state" v-if="pageData.list.length === 0">
<image class="empty-icon" src="/static/images/empty.png" mode="aspectFit"></image>
<text class="empty-text">暂无资源</text>
</view> -->
</view>
</z-paging>
<!-- 弹窗组件 -->
<save-dialog
:show="showDialog"
:editData="currentEditData"
@update:show="showDialog = $event"
@submitSuccess="handleSubmitSuccess"
/>
</view>
</template>
<script setup> <script setup>
import { nextTick, reactive, ref } from 'vue' import { reactive, ref } from 'vue'
import { onLoad, onNavigationBarButtonTap, onShow } from '@dcloudio/uni-app' import { onNavigationBarButtonTap } from '@dcloudio/uni-app'
import * as API from '@/api/model/wode'
import SaveDialog from './components/save-dialog.vue' import SaveDialog from './components/save-dialog.vue'
import * as API from '@/api/model/wode'
const isOnePage = ref(true) const isOnePage = ref(true)
const paging = ref(null) const paging = ref(null)
...@@ -104,19 +43,20 @@ ...@@ -104,19 +43,20 @@
showAddDialog() showAddDialog()
}) })
const showAddDialog = () => { function showAddDialog() {
currentEditData.value = null currentEditData.value = null
showDialog.value = true showDialog.value = true
} }
// 格式化时间显示 // 格式化时间显示
const formatTime = (time) => { function formatTime(time) {
if (!time) return '' if (!time)
return ''
// 如果是完整的时间字符串,可以格式化为图片中的样式 // 如果是完整的时间字符串,可以格式化为图片中的样式
return time.includes(' ') ? time : `${time} 14:00` return time.includes(' ') ? time : `${time} 14:00`
} }
// 下载资源 // 下载资源
const handleDownload = async (resource) => { async function handleDownload(resource) {
await API.downloadResource({ id: resource.id }) await API.downloadResource({ id: resource.id })
// 更新下载次数 // 更新下载次数
const index = pageData.list.findIndex((item) => item.id === resource.id) const index = pageData.list.findIndex((item) => item.id === resource.id)
...@@ -134,21 +74,83 @@ ...@@ -134,21 +74,83 @@
} }
// 格式化文件大小 // 格式化文件大小
const formatFileSize = (bytes) => { function formatFileSize(bytes) {
if (!bytes) return '125kb' if (!bytes)
return '125kb'
const k = 1024 const k = 1024
const sizes = ['B', 'KB', 'MB', 'GB'] const sizes = ['B', 'KB', 'MB', 'GB']
const i = Math.floor(Math.log(bytes) / Math.log(k)) const i = Math.floor(Math.log(bytes) / Math.log(k))
return parseFloat((bytes / Math.pow(k, i)).toFixed(0)) + sizes[i].toLowerCase() return Number.parseFloat((bytes / k ** i).toFixed(0)) + sizes[i].toLowerCase()
} }
const handleSubmitSuccess = () => { function handleSubmitSuccess() {
showDialog.value = false showDialog.value = false
// 重新加载数据 // 重新加载数据
handleSearch() handleSearch()
} }
</script> </script>
<template>
<view class="codefun-flex-col page">
<z-paging ref="paging" v-model="pageData.list" @query="queryList">
<view class="codefun-flex-col group_3">
<view class="codefun-flex-row codefun-items-center section_2">
<image class="image_6" src="/static/images/codefun/6c5c5a3c082b8c60a307d3a7caee623c.png" />
<u-input
v-model="pageData.param.fileName"
placeholder="请输入文件名称搜索"
border="none"
class="codefun-ml-8"
@confirm="handleSearch"
/>
</view>
<!-- 资源列表 - 根据图片样式修改 -->
<view class="resource-list">
<view v-for="(item, index) in pageData.list" :key="index" class="resource-item">
<view class="resource-content">
<view class="resource-main">
<view class="resource-name">{{ item.fileName }}</view>
<view class="resource-meta">
<text class="resource-size">{{ item.fileSize }}</text>
<text class="separator">|</text>
<text class="download-count">已下载{{ item.downloadCount || 0 }}</text>
<text class="separator">|</text>
<text class="upload-time">{{ formatTime(item.createTime) }}</text>
</view>
</view>
<view
class="codefun-flex-col codefun-justify-start codefun-items-center text-wrapper_4"
@click.stop="handleDownload(item)"
>
<text class="font_10">下载</text>
</view>
<!-- <view class="download-section">
<view class="download-btn" @click="handleDownload(item)">
<text class="btn-text">下载</text>
</view>
</view> -->
</view>
</view>
</view>
<!-- 空状态 -->
<!-- <view class="empty-state" v-if="pageData.list.length === 0">
<image class="empty-icon" src="/static/images/empty.png" mode="aspectFit"></image>
<text class="empty-text">暂无资源</text>
</view> -->
</view>
</z-paging>
<!-- 弹窗组件 -->
<SaveDialog
:show="showDialog"
:editData="currentEditData"
@update:show="showDialog = $event"
@submit-success="handleSubmitSuccess"
/>
</view>
</template>
<style lang="scss"> <style lang="scss">
body { body {
background: #e6f5e8; background: #e6f5e8;
......
...@@ -184,6 +184,15 @@ ...@@ -184,6 +184,15 @@
} }
}) })
}) })
WeatherAPI.alarm(`${pageData.weather.lat},${pageData.weather.lon}`).then((res) => {
console.log('WeatherAPI.alarm', res)
// pageData.weather.warning = res.data.alerts?.[0]?.description || ''
// TODO: 测试数据
pageData.weather.warning =
'雨花区气象台24日11时19分继续发布大风蓝色预警信号:预计未来24小时内临桂将出现6级(或阵风7级)以上大风,请做好防范。'
})
} }
// 页面数据 // 页面数据
...@@ -375,13 +384,13 @@ ...@@ -375,13 +384,13 @@
} }
// 农产品关注点击事件 // 农产品关注点击事件
function onProductFollowClick(product: any) { function _onProductFollowClick(product: any) {
console.log('点击关注农产品:', product) console.log('点击关注农产品:', product)
// 在这里添加具体的关注逻辑 // 在这里添加具体的关注逻辑
} }
// 查看更多农技课堂 // 查看更多农技课堂
function onViewMoreClass() { function _onViewMoreClass() {
console.log('查看全部农技课堂') console.log('查看全部农技课堂')
// 在这里添加具体的查看逻辑 // 在这里添加具体的查看逻辑
} }
...@@ -389,7 +398,7 @@ ...@@ -389,7 +398,7 @@
// 轮播视频切换的时候触发 // 轮播视频切换的时候触发
function handleChangeVideo(e: any) { function handleChangeVideo(e: any) {
const currentIndex = e.detail.current const currentIndex = e.detail.current
const prevIndex = pageData.current const _prevIndex = pageData.current
pageData.current = currentIndex pageData.current = currentIndex
pageData.agricultureClass.title = pageData.agricultureClass.videoList[currentIndex]?.title pageData.agricultureClass.title = pageData.agricultureClass.videoList[currentIndex]?.title
...@@ -458,7 +467,7 @@ ...@@ -458,7 +467,7 @@
<view class="codefun-flex-col codefun-relative group_3"> <view class="codefun-flex-col codefun-relative group_3">
<view class="codefun-flex-col"> <view class="codefun-flex-col">
<view class="codefun-flex-col codefun-self-stretch group_4"> <view class="codefun-flex-col codefun-self-stretch group_4">
<view class="codefun-flex-col section_3"> <view class="codefun-flex-col section_3" :class="{ '!pb-6': !pageData.weather.warning }">
<view class="codefun-flex-row codefun-justify-between" style="align-items: center"> <view class="codefun-flex-row codefun-justify-between" style="align-items: center">
<view <view
class="codefun-flex-row codefun-items-center codefun-relative codefun-overflow-hidden" class="codefun-flex-row codefun-items-center codefun-relative codefun-overflow-hidden"
...@@ -474,7 +483,7 @@ ...@@ -474,7 +483,7 @@
style="width: 400rpx" style="width: 400rpx"
> >
<up-notice-bar <up-notice-bar
v-if="pageData.weather.detailedLocation != '获取中'" v-if="pageData.weather.detailedLocation !== '获取中'"
icon="" icon=""
bgColor="#FFFFFF00" bgColor="#FFFFFF00"
color="#5db66f" color="#5db66f"
...@@ -559,7 +568,18 @@ ...@@ -559,7 +568,18 @@
</view> </view>
</view> </view>
</view> </view>
<view class="codefun-flex-row section_4" v-if="pageData.weather.warning"> <view class="my-2" v-if="pageData.weather.warning">
<fui-notice-bar
:content="pageData.weather.warning"
scrollable
:padding="['0', '32rpx']"
>
<view class="fui-icon__box">
<fui-icon name="notice" :size="36" color="#FF2B2B" />
</view>
</fui-notice-bar>
</view>
<!-- <view class="codefun-flex-row section_4" v-if="pageData.weather.warning">
<image <image
class="codefun-shrink-0 image_10" class="codefun-shrink-0 image_10"
src="/static/images/codefun/344155285176a7ac7ccd670a2a1daf19.png" src="/static/images/codefun/344155285176a7ac7ccd670a2a1daf19.png"
...@@ -569,7 +589,7 @@ ...@@ -569,7 +589,7 @@
> >
<text class="text_12">{{ pageData.weather.warning }}</text> <text class="text_12">{{ pageData.weather.warning }}</text>
</view> </view>
</view> </view> -->
</view> </view>
<view class="codefun-flex-col codefun-relative section_5"> <view class="codefun-flex-col codefun-relative section_5">
<view class="codefun-flex-row"> <view class="codefun-flex-row">
...@@ -884,7 +904,7 @@ ...@@ -884,7 +904,7 @@
.section_3 { .section_3 {
width: 694rpx; width: 694rpx;
// margin-right: 28rpx; // margin-right: 28rpx;
padding: 20rpx 28rpx 58rpx; padding: 28rpx;
background-image: linear-gradient(180deg, #dcfce7 0%, #f8fef9 100%); background-image: linear-gradient(180deg, #dcfce7 0%, #f8fef9 100%);
border-radius: 16rpx; border-radius: 16rpx;
mix-blend-mode: NOTTHROUGH; mix-blend-mode: NOTTHROUGH;
...@@ -1184,7 +1204,7 @@ ...@@ -1184,7 +1204,7 @@
border-radius: 16rpx; border-radius: 16rpx;
mix-blend-mode: NOTTHROUGH; mix-blend-mode: NOTTHROUGH;
width: 32rpx; width: 32rpx;
height: 32rpx; height: 40rpx;
} }
.codefun-mr-4 { .codefun-mr-4 {
margin-right: 10rpx; margin-right: 10rpx;
......
<script setup lang="ts"> <script setup lang="ts">
import { reactive } from 'vue' import { reactive } from 'vue'
import { onLoad, onPullDownRefresh } from '@dcloudio/uni-app' import { onLoad, onPullDownRefresh } from '@dcloudio/uni-app'
import * as WodeAPI from '@/api/model/wode' import SaveDialog from '../device/components/save-dialog.vue'
import * as NongchangAPI from '@/api/model/nongchang' import * as WodeAPI from '@/api/model/wode'
import SaveDialog from '../device/components/save-dialog.vue' import * as NongchangAPI from '@/api/model/nongchang'
// 下拉刷新
onPullDownRefresh(() => { // 下拉刷新
setTimeout(function () { onPullDownRefresh(() => {
uni.stopPullDownRefresh() setTimeout(function () {
uni.showToast({ uni.stopPullDownRefresh()
title: '刷新成功', uni.showToast({
icon: 'success', title: '刷新成功',
duration: 1500 icon: 'success',
}) duration: 1500,
}, 1000) })
}) }, 1000)
})
onLoad(() => {
getBizCommonFileList() onLoad(() => {
getFarmsList() getBizCommonFileList()
}) getFarmsList()
})
// 页面数据
const pageData = reactive({ // 页面数据
// 用户信息 const pageData = reactive({
userInfo: { // 用户信息
avatar: '/static/images/codefun/8653455b786fbf94ae1c3946f11e7d40.png', userInfo: {
farmName: '007农场', avatar: '/static/images/codefun/8653455b786fbf94ae1c3946f11e7d40.png',
certification: { farmName: '007农场',
icon: '/static/images/codefun/b6079649e1f0ba231d158cb10bea118f.png', certification: {
text: '已认证农场主', icon: '/static/images/codefun/b6079649e1f0ba231d158cb10bea118f.png',
}, text: '已认证农场主',
farmDescription: '华北绿色农业示范基地',
settingsIcon: '/static/images/codefun/1458747d012f7cb820f99627876e8fa6.png',
ncId: 0,
},
// 统计数据
statistics: [
{ id: 1, value: '0', label: '我的基地', url: '/pages/jidiguanli/jidiguanli' },
{ id: 2, value: '¥3266', label: '累计收益', url: '' },
{ id: 3, value: '8', label: '服务订单', url: '' },
],
// 消息中心
messageCenter: {
icon: '/static/images/codefun/41d4366b8b071c40d285a8f48c696d8a.png',
title: '消息中心',
description: '预警通知/服务进度/订单状态',
notificationCount: '6',
arrowIcon: '/static/images/codefun/f29a8c39eb37da965d0a764a567a1c77.png',
},
// 功能模块
features: [
{
id: 1,
icon: '/static/images/codefun/a1b5d5fd677e3e3c32cdfe7a476aee19.png',
title: '资源库',
count: '38个资源可用',
description: '合同模板/政策文件/财务表',
status: '离线可用',
statusClass: 'text_14',
arrowIcon: '/static/images/codefun/f29a8c39eb37da965d0a764a567a1c77.png',
url: '/pages/resource/resource'
},
{
id: 2,
icon: '/static/images/codefun/d38158bc612aa1c6a022fae41afd8a42.png',
title: '物联设备',
count: '2台在线',
description: '灌溉设备/气象站绑定管理',
actionText: '添加设备',
arrowIcon: '/static/images/codefun/f29a8c39eb37da965d0a764a567a1c77.png',
addIcon: '/static/images/codefun/2ff61f748e26b18760ca166aa8cfa15a.png',
url: '/pages/device/device'
},
],
// 常用资源
commonResources: {
title: '常用资源',
actionText: '',
icon: {
1: {
icon: '/src/static/images/codefun/doc_img.png',
name: '文档格式',
},
2: {
icon: '/src/static/images/codefun/elx_img.png',
name: '表格格式',
},
3: {
icon: '/src/static/images/codefun/pdf_img.png',
name: 'PDF格式',
}, },
farmDescription: '华北绿色农业示范基地',
settingsIcon: '/static/images/codefun/1458747d012f7cb820f99627876e8fa6.png',
ncId: 0,
}, },
resources: [
// { // 统计数据
// id: 1, statistics: [
// icon: '/static/images/codefun/38f8cccf12ace58fd9cd4612dce944b0.png', { id: 1, value: '0', label: '我的基地', url: '/pages/jidiguanli/jidiguanli' },
// title: '水稻种植合同模版', { id: 2, value: '¥3266', label: '累计收益', url: '' },
// size: '125kb', { id: 3, value: '8', label: '服务订单', url: '' },
// actionText: '下载',
// },
// {
// id: 2,
// icon: '/static/images/codefun/38f8cccf12ace58fd9cd4612dce944b0.png',
// title: '玉米种植技术指南',
// size: '210kb',
// actionText: '下载',
// },
// {
// id: 3,
// icon: '/static/images/codefun/38f8cccf12ace58fd9cd4612dce944b0.png',
// title: '肥料使用记录表',
// size: '86kb',
// actionText: '下载',
// },
], ],
},
// 我的设备 // 消息中心
myDevices: { messageCenter: {
title: '我的设备', icon: '/static/images/codefun/41d4366b8b071c40d285a8f48c696d8a.png',
actionText: '添加设备', title: '消息中心',
devices: [ description: '预警通知/服务进度/订单状态',
notificationCount: '6',
arrowIcon: '/static/images/codefun/f29a8c39eb37da965d0a764a567a1c77.png',
},
// 功能模块
features: [
{ {
id: 1, id: 1,
image: '/static/images/codefun/8bd62352939b47e71f09a93a6ab344b2.png', icon: '/static/images/codefun/a1b5d5fd677e3e3c32cdfe7a476aee19.png',
name: '智能灌溉控制器', title: '资源库',
lastConnection: '上次链接:10分钟前', count: '38个资源可用',
status: '正常', description: '合同模板/政策文件/财务表',
statusIcon: '/static/images/codefun/e9da7be7465ae5310ccbc8a61ec653af.png', status: '离线可用',
statusClass: 'text_24', statusClass: 'text_14',
arrowIcon: '/static/images/codefun/f29a8c39eb37da965d0a764a567a1c77.png',
url: '/pages/resource/resource',
}, },
{ {
id: 2, id: 2,
image: '/static/images/codefun/81937c2666c800cf5966c29c2891b7c4.png', icon: '/static/images/codefun/d38158bc612aa1c6a022fae41afd8a42.png',
name: '土壤监测传感器', title: '物联设备',
lastConnection: '上次链接:10分钟前', count: '2台在线',
status: '离线', description: '灌溉设备/气象站绑定管理',
statusIcon: '/static/images/codefun/1d16bdeaf73b863640e5855843a54682.png', actionText: '添加设备',
arrowIcon: '/static/images/codefun/f29a8c39eb37da965d0a764a567a1c77.png',
addIcon: '/static/images/codefun/2ff61f748e26b18760ca166aa8cfa15a.png',
url: '/pages/device/device',
}, },
], ],
},
// 客服与帮助 // 常用资源
support: { commonResources: {
services: [ title: '常用资源',
{ actionText: '',
id: 1, icon: {
icon: '/static/images/codefun/e4267d4e96c1020d60dfbbf315b662cb.png', 1: {
title: '在线客服', icon: '/src/static/images/codefun/doc_img.png',
arrowIcon: '/static/images/codefun/543b9b7cb3072527207b45b678ca5794.png', name: '文档格式',
}, },
], 2: {
helps: [ icon: '/src/static/images/codefun/elx_img.png',
{ name: '表格格式',
id: 1, },
icon: '/static/images/codefun/46ebd858a611104ee741fc252ca6f0ce.png', 3: {
title: '帮助中心', icon: '/src/static/images/codefun/pdf_img.png',
arrowIcon: '/static/images/codefun/0314db942874f91963bc16e91b9798bc.png', name: 'PDF格式',
}, },
{
id: 2,
icon: '/static/images/codefun/559cc3a424e888da63761cafa26dad82.png',
title: '问题反馈',
arrowIcon: '/static/images/codefun/0314db942874f91963bc16e91b9798bc.png',
}, },
], resources: [
}, // {
}) // id: 1,
// icon: '/static/images/codefun/38f8cccf12ace58fd9cd4612dce944b0.png',
function getBizCommonFileList() { // title: '水稻种植合同模版',
WodeAPI.bizCommonFileList({ // size: '125kb',
pageNo: 1, // actionText: '下载',
pageSize: 4, // },
}).then((res) => { // {
const { records } = res // id: 2,
pageData.commonResources.resources = records // icon: '/static/images/codefun/38f8cccf12ace58fd9cd4612dce944b0.png',
}) // title: '玉米种植技术指南',
} // size: '210kb',
function getFarmBaseList(id) { // actionText: '下载',
NongchangAPI.getFarmBaseList({ id }).then((res) => { // },
pageData.statistics[0].value = res.length // {
}) // id: 3,
} // icon: '/static/images/codefun/38f8cccf12ace58fd9cd4612dce944b0.png',
function getFarmsList() { // title: '肥料使用记录表',
NongchangAPI.farmsList({ // size: '86kb',
pageNo: 1, // actionText: '下载',
pageSize: 10, // },
}).then((res) => { ],
const { records, total } = res },
pageData.userInfo.farmName = records[0]?.farmName
pageData.userInfo.certification.icon = // 我的设备
records[0]?.certificationStatus === '0' myDevices: {
? '' title: '我的设备',
: '/static/images/codefun/b6079649e1f0ba231d158cb10bea118f.png' actionText: '添加设备',
pageData.userInfo.certification.text = records[0]?.certificationStatus_dictText devices: [
pageData.userInfo.farmDescription = records[0]?.description {
pageData.userInfo.ncId = records[0]?.id id: 1,
image: '/static/images/codefun/8bd62352939b47e71f09a93a6ab344b2.png',
getFarmBaseList(pageData.userInfo.ncId) name: '智能灌溉控制器',
lastConnection: '上次链接:10分钟前',
status: '正常',
statusIcon: '/static/images/codefun/e9da7be7465ae5310ccbc8a61ec653af.png',
statusClass: 'text_24',
},
{
id: 2,
image: '/static/images/codefun/81937c2666c800cf5966c29c2891b7c4.png',
name: '土壤监测传感器',
lastConnection: '上次链接:10分钟前',
status: '离线',
statusIcon: '/static/images/codefun/1d16bdeaf73b863640e5855843a54682.png',
},
],
},
// 客服与帮助
support: {
services: [
{
id: 1,
icon: '/static/images/codefun/e4267d4e96c1020d60dfbbf315b662cb.png',
title: '在线客服',
arrowIcon: '/static/images/codefun/543b9b7cb3072527207b45b678ca5794.png',
},
],
helps: [
{
id: 1,
icon: '/static/images/codefun/46ebd858a611104ee741fc252ca6f0ce.png',
title: '帮助中心',
arrowIcon: '/static/images/codefun/0314db942874f91963bc16e91b9798bc.png',
},
{
id: 2,
icon: '/static/images/codefun/559cc3a424e888da63761cafa26dad82.png',
title: '问题反馈',
arrowIcon: '/static/images/codefun/0314db942874f91963bc16e91b9798bc.png',
},
],
},
}) })
}
function getBizCommonFileList() {
// 用户信息设置点击事件 WodeAPI.bizCommonFileList({
function onSettingsClick() { pageNo: 1,
console.log('点击设置') pageSize: 4,
// 在这里添加具体的设置点击逻辑 }).then((res) => {
} const { records } = res
pageData.commonResources.resources = records
// 消息中心点击事件 })
function onMessageCenterClick() { }
console.log('点击消息中心') function getFarmBaseList(id) {
// 在这里添加具体的消息中心点击逻辑 NongchangAPI.getFarmBaseList({ id }).then((res) => {
} pageData.statistics[0].value = res.length
})
// 功能模块点击事件 }
function onFeatureClick(feature: any) { function getFarmsList() {
console.log('点击功能模块:', feature) NongchangAPI.farmsList({
// 在这里添加具体的功能模块点击逻辑 pageNo: 1,
uni.navigateTo({ pageSize: 10,
url: feature.url, }).then((res) => {
const { records, total } = res
pageData.userInfo.farmName = records[0]?.farmName
pageData.userInfo.certification.icon =
records[0]?.certificationStatus === '0'
? ''
: '/static/images/codefun/b6079649e1f0ba231d158cb10bea118f.png'
pageData.userInfo.certification.text = records[0]?.certificationStatus_dictText
pageData.userInfo.farmDescription = records[0]?.description
pageData.userInfo.ncId = records[0]?.id
getFarmBaseList(pageData.userInfo.ncId)
})
}
// 用户信息设置点击事件
function onSettingsClick() {
console.log('点击设置')
// 在这里添加具体的设置点击逻辑
}
// 消息中心点击事件
function onMessageCenterClick() {
console.log('点击消息中心')
// 在这里添加具体的消息中心点击逻辑
}
// 功能模块点击事件
function onFeatureClick(feature: any) {
console.log('点击功能模块:', feature)
// 在这里添加具体的功能模块点击逻辑
uni.navigateTo({
url: feature.url,
})
}
const showDialog = ref(false)
const currentEditData = ref(null)
onNavigationBarButtonTap((_) => {
showAddDialog()
}) })
} function showAddDialog() {
const showDialog = ref(false) currentEditData.value = null
const currentEditData = ref(null) showDialog.value = true
onNavigationBarButtonTap((_) => { }
showAddDialog()
}) function onAddClick(feature: any) {
const showAddDialog = () => { console.log('点击功能模块:', feature)
currentEditData.value = null if (feature.id === 2) showAddDialog()
showDialog.value = true }
} // 常用资源点击事件
function onResourceClick(resource: any) {
const onAddClick = (feature: any) => { console.log('点击资源:', resource)
console.log('点击功能模块:', feature) // 在这里添加具体的资源点击逻辑
if (feature.id === 2) showAddDialog() }
} // 资源下载点击事件
// 常用资源点击事件 async function onDownloadClick(e, resource: any) {
function onResourceClick(resource: any) { // 阻止事件冒泡
console.log('点击资源:', resource) e?.stopPropagation()
// 在这里添加具体的资源点击逻辑
} const { downloadResource } = await import('@/utils')
// 资源下载点击事件 // 使用封装的下载方法
async function onDownloadClick(e, resource: any) { const result = await downloadResource(resource)
// 阻止事件冒泡
e?.stopPropagation() if (!result.success) {
console.error('下载失败:', result.error)
const { downloadResource } = await import('@/utils') }
}
// 使用封装的下载方法
const result = await downloadResource(resource) // 查看所有资源
function onViewAllResources() {
if (!result.success) { console.log('查看所有资源')
console.error('下载失败:', result.error) // 在这里添加具体的查看所有资源逻辑
}
// 我的设备标题点击事件
function onMyDevicesTitleClick() {
console.log('点击我的设备标题')
// 在这里添加具体的设备标题点击逻辑
}
// 设备点击事件
function onDeviceClick(device: any) {
console.log('点击设备:', device)
// 在这里添加具体的设备点击逻辑
}
// 客服点击事件
function onServiceClick(service: any) {
console.log('点击客服:', service)
// 在这里添加具体的客服点击逻辑
}
// 帮助点击事件
function onHelpClick(help: any) {
console.log('点击帮助:', help)
// 在这里添加具体的帮助点击逻辑
} }
}
// 查看所有资源
function onViewAllResources() {
console.log('查看所有资源')
// 在这里添加具体的查看所有资源逻辑
}
// 我的设备标题点击事件
function onMyDevicesTitleClick() {
console.log('点击我的设备标题')
// 在这里添加具体的设备标题点击逻辑
}
// 设备点击事件
function onDeviceClick(device: any) {
console.log('点击设备:', device)
// 在这里添加具体的设备点击逻辑
}
// 客服点击事件
function onServiceClick(service: any) {
console.log('点击客服:', service)
// 在这里添加具体的客服点击逻辑
}
// 帮助点击事件
function onHelpClick(help: any) {
console.log('点击帮助:', help)
// 在这里添加具体的帮助点击逻辑
}
</script> </script>
<template> <template>
...@@ -306,13 +304,18 @@ function onHelpClick(help: any) { ...@@ -306,13 +304,18 @@ function onHelpClick(help: any) {
<view class="codefun-flex-row codefun-items-center codefun-self-stretch"> <view class="codefun-flex-row codefun-items-center codefun-self-stretch">
<text class="font_2 text_2">{{ pageData.userInfo.farmName }}</text> <text class="font_2 text_2">{{ pageData.userInfo.farmName }}</text>
<view <view
class="codefun-flex-row codefun-items-center codefun-shrink-0 section_2 codefun-ml-6"> class="codefun-flex-row codefun-items-center codefun-shrink-0 section_2 codefun-ml-6"
<image v-show="pageData.userInfo.certification.icon" >
<image
v-show="pageData.userInfo.certification.icon"
class="codefun-shrink-0 image_7 mr-1" class="codefun-shrink-0 image_7 mr-1"
:src="pageData.userInfo.certification.icon" /> :src="pageData.userInfo.certification.icon"
<text class="font_3 text_3" />
:style="{ color: pageData.userInfo.certification.icon ? '' : '#fbc428' }">{{ <text
pageData.userInfo.certification.text }}</text> class="font_3 text_3"
:style="{ color: pageData.userInfo.certification.icon ? '' : '#fbc428' }"
>{{ pageData.userInfo.certification.text }}</text
>
</view> </view>
</view> </view>
<text class="codefun-self-start font_1 codefun-mt-10">{{ <text class="codefun-self-start font_1 codefun-mt-10">{{
...@@ -324,9 +327,15 @@ function onHelpClick(help: any) { ...@@ -324,9 +327,15 @@ function onHelpClick(help: any) {
</view> </view>
<view class="codefun-flex-col codefun-justify-start section_3"> <view class="codefun-flex-col codefun-justify-start section_3">
<view class="codefun-flex-row"> <view class="codefun-flex-row">
<navigator v-for="stat in pageData.statistics" :url="stat.url" :key="stat.id" <navigator
class="codefun-flex-col codefun-items-center group_6 equal-division-item" hover-class="none" v-for="stat in pageData.statistics"
:render-link="false" :class="{ 'codefun-ml-32': stat.id > 1 }"> :url="stat.url"
:key="stat.id"
class="codefun-flex-col codefun-items-center group_6 equal-division-item"
hover-class="none"
:render-link="false"
:class="{ 'codefun-ml-32': stat.id > 1 }"
>
<text class="font_4">{{ stat.value }}</text> <text class="font_4">{{ stat.value }}</text>
<text class="font_5 codefun-mt-16">{{ stat.label }}</text> <text class="font_5 codefun-mt-16">{{ stat.label }}</text>
</navigator> </navigator>
...@@ -336,14 +345,17 @@ function onHelpClick(help: any) { ...@@ -336,14 +345,17 @@ function onHelpClick(help: any) {
<view class="codefun-flex-col codefun-relative group_7"> <view class="codefun-flex-col codefun-relative group_7">
<view class="codefun-flex-col"> <view class="codefun-flex-col">
<!-- 消息中心 --> <!-- 消息中心 -->
<view class="codefun-flex-row codefun-justify-between codefun-items-center section_12" <view
@click="onMessageCenterClick"> class="codefun-flex-row codefun-justify-between codefun-items-center section_12"
@click="onMessageCenterClick"
>
<view class="codefun-flex-row group_8"> <view class="codefun-flex-row group_8">
<image class="image_10" :src="pageData.messageCenter.icon" /> <image class="image_10" :src="pageData.messageCenter.icon" />
<view class="codefun-flex-col group_9 codefun-ml-12"> <view class="codefun-flex-col group_9 codefun-ml-12">
<text class="codefun-self-start font">{{ pageData.messageCenter.title }}</text> <text class="codefun-self-start font">{{ pageData.messageCenter.title }}</text>
<view <view
class="codefun-flex-col codefun-justify-start codefun-items-start codefun-self-stretch text-wrapper_2 codefun-mt-4"> class="codefun-flex-col codefun-justify-start codefun-items-start codefun-self-stretch text-wrapper_2 codefun-mt-4"
>
<text class="font_7">{{ pageData.messageCenter.description }}</text> <text class="font_7">{{ pageData.messageCenter.description }}</text>
</view> </view>
</view> </view>
...@@ -357,9 +369,13 @@ function onHelpClick(help: any) { ...@@ -357,9 +369,13 @@ function onHelpClick(help: any) {
</view> </view>
<!-- 资源/设备 --> <!-- 资源/设备 -->
<view class="codefun-flex-row equal-division codefun-mt-12"> <view class="codefun-flex-row equal-division codefun-mt-12">
<view v-for="(feature, index) in pageData.features" :key="feature.id" <view
class="codefun-flex-col section_5 section_11" :class="{ 'codefun-ml-12': index > 0 }" v-for="(feature, index) in pageData.features"
@click="onFeatureClick(feature)"> :key="feature.id"
class="codefun-flex-col section_5 section_11"
:class="{ 'codefun-ml-12': index > 0 }"
@click="onFeatureClick(feature)"
>
<view class="codefun-flex-row codefun-self-stretch"> <view class="codefun-flex-row codefun-self-stretch">
<view class="codefun-flex-row codefun-items-center codefun-flex-1"> <view class="codefun-flex-row codefun-items-center codefun-flex-1">
<image class="codefun-shrink-0 image_10" :src="feature.icon" /> <image class="codefun-shrink-0 image_10" :src="feature.icon" />
...@@ -368,20 +384,28 @@ function onHelpClick(help: any) { ...@@ -368,20 +384,28 @@ function onHelpClick(help: any) {
<text class="font_8 codefun-mt-8">{{ feature.count }}</text> <text class="font_8 codefun-mt-8">{{ feature.count }}</text>
</view> </view>
</view> </view>
<image class="codefun-shrink-0 codefun-self-start image_11" :class="{ <image
image_12: feature.id === 1, class="codefun-shrink-0 codefun-self-start image_11"
image_13: feature.id === 2, :class="{
'codefun-ml-8': feature.id === 1, image_12: feature.id === 1,
}" :src="feature.arrowIcon" /> image_13: feature.id === 2,
'codefun-ml-8': feature.id === 1,
}"
:src="feature.arrowIcon"
/>
</view> </view>
<text class="codefun-self-stretch font_7 codefun-mt-10">{{ feature.description }}</text> <text class="codefun-self-stretch font_7 codefun-mt-10">{{ feature.description }}</text>
<view v-if="feature.status" <view
class="codefun-flex-col codefun-justify-start codefun-items-center codefun-self-start view mt-2"> v-if="feature.status"
class="codefun-flex-col codefun-justify-start codefun-items-center codefun-self-start view mt-2"
>
<text class="font_6" :class="feature.statusClass">{{ feature.status }}</text> <text class="font_6" :class="feature.statusClass">{{ feature.status }}</text>
</view> </view>
<view v-if="feature.actionText && feature.addIcon" <view
v-if="feature.actionText && feature.addIcon"
class="codefun-flex-row codefun-justify-evenly codefun-items-center codefun-self-start view_2 mt-2" class="codefun-flex-row codefun-justify-evenly codefun-items-center codefun-self-start view_2 mt-2"
@click.stop="onAddClick(feature)"> @click.stop="onAddClick(feature)"
>
<image class="image_14" :src="feature.addIcon" /> <image class="image_14" :src="feature.addIcon" />
<text class="font_3">{{ feature.actionText }}</text> <text class="font_3">{{ feature.actionText }}</text>
</view> </view>
...@@ -399,8 +423,10 @@ function onHelpClick(help: any) { ...@@ -399,8 +423,10 @@ function onHelpClick(help: any) {
<view class="codefun-flex-col list"> <view class="codefun-flex-col list">
<view <view
class="codefun-flex-row codefun-justify-between codefun-items-center list-item codefun-mt-24" class="codefun-flex-row codefun-justify-between codefun-items-center list-item codefun-mt-24"
v-for="resource in pageData.commonResources.resources" :key="resource.id" v-for="resource in pageData.commonResources.resources"
@click="onResourceClick(resource)"> :key="resource.id"
@click="onResourceClick(resource)"
>
<view class="codefun-flex-row"> <view class="codefun-flex-row">
<image class="image_15" :src="pageData.commonResources.icon[resource.fileType]?.icon" /> <image class="image_15" :src="pageData.commonResources.icon[resource.fileType]?.icon" />
<view class="codefun-flex-col codefun-items-start group_14 codefun-ml-12"> <view class="codefun-flex-col codefun-items-start group_14 codefun-ml-12">
...@@ -408,8 +434,10 @@ function onHelpClick(help: any) { ...@@ -408,8 +434,10 @@ function onHelpClick(help: any) {
<text class="font_6 codefun-mt-12">{{ resource.fileSize }}</text> <text class="font_6 codefun-mt-12">{{ resource.fileSize }}</text>
</view> </view>
</view> </view>
<view class="codefun-flex-col codefun-justify-start codefun-items-center text-wrapper_4" <view
@click.stop="(e) => onDownloadClick(e, resource)"> class="codefun-flex-col codefun-justify-start codefun-items-center text-wrapper_4"
@click.stop="(e) => onDownloadClick(e, resource)"
>
<text class="font_10">下载</text> <text class="font_10">下载</text>
</view> </view>
</view> </view>
...@@ -424,9 +452,13 @@ function onHelpClick(help: any) { ...@@ -424,9 +452,13 @@ function onHelpClick(help: any) {
</view> </view>
<view class="codefun-flex-col codefun-mt-16"> <view class="codefun-flex-col codefun-mt-16">
<view class="codefun-flex-col section_12"> <view class="codefun-flex-col section_12">
<view class="codefun-flex-row codefun-justify-between codefun-items-center" <view
v-for="(device, index) in pageData.myDevices.devices" :key="device.id" class="codefun-flex-row codefun-justify-between codefun-items-center"
:class="{ 'codefun-mt-16': index > 0 }" @click="onDeviceClick(device)"> v-for="(device, index) in pageData.myDevices.devices"
:key="device.id"
:class="{ 'codefun-mt-16': index > 0 }"
@click="onDeviceClick(device)"
>
<view class="codefun-flex-row codefun-items-center"> <view class="codefun-flex-row codefun-items-center">
<image class="image_17" :src="device.image" /> <image class="image_17" :src="device.image" />
<view class="codefun-flex-col codefun-items-start codefun-ml-8"> <view class="codefun-flex-col codefun-items-start codefun-ml-8">
...@@ -436,17 +468,23 @@ function onHelpClick(help: any) { ...@@ -436,17 +468,23 @@ function onHelpClick(help: any) {
</view> </view>
<view class="codefun-flex-row codefun-items-center"> <view class="codefun-flex-row codefun-items-center">
<image class="codefun-shrink-0 image_18" :src="device.statusIcon" /> <image class="codefun-shrink-0 image_18" :src="device.statusIcon" />
<text class="font_6" :class="device.statusClass || ''" <text
:style="{ color: device.status === '正常' ? '#13e000' : '#999999' }"> class="font_6"
:class="device.statusClass || ''"
:style="{ color: device.status === '正常' ? '#13e000' : '#999999' }"
>
{{ device.status }} {{ device.status }}
</text> </text>
</view> </view>
</view> </view>
</view> </view>
<view class="codefun-flex-col section_9 codefun-mt-12"> <view class="codefun-flex-col section_9 codefun-mt-12">
<view class="codefun-flex-row codefun-justify-between codefun-items-center" <view
v-for="service in pageData.support.services" :key="service.id" class="codefun-flex-row codefun-justify-between codefun-items-center"
@click="onServiceClick(service)"> v-for="service in pageData.support.services"
:key="service.id"
@click="onServiceClick(service)"
>
<view class="codefun-flex-row codefun-items-center"> <view class="codefun-flex-row codefun-items-center">
<image class="codefun-shrink-0 image_19" :src="service.icon" /> <image class="codefun-shrink-0 image_19" :src="service.icon" />
<text class="font_13 codefun-ml-8">{{ service.title }}</text> <text class="font_13 codefun-ml-8">{{ service.title }}</text>
...@@ -454,9 +492,13 @@ function onHelpClick(help: any) { ...@@ -454,9 +492,13 @@ function onHelpClick(help: any) {
<image class="image_20" :src="service.arrowIcon" /> <image class="image_20" :src="service.arrowIcon" />
</view> </view>
<view class="codefun-flex-col codefun-mt-20"> <view class="codefun-flex-col codefun-mt-20">
<view class="codefun-flex-row codefun-justify-between codefun-items-center" <view
v-for="help in pageData.support.helps" :key="help.id" class="codefun-flex-row codefun-justify-between codefun-items-center"
:class="{ 'codefun-mt-20': help.id > 1 }" @click="onHelpClick(help)"> v-for="help in pageData.support.helps"
:key="help.id"
:class="{ 'codefun-mt-20': help.id > 1 }"
@click="onHelpClick(help)"
>
<view class="codefun-flex-row codefun-items-center"> <view class="codefun-flex-row codefun-items-center">
<image class="codefun-shrink-0 image_21" :src="help.icon" /> <image class="codefun-shrink-0 image_21" :src="help.icon" />
<text class="font_13 codefun-ml-8">{{ help.title }}</text> <text class="font_13 codefun-ml-8">{{ help.title }}</text>
...@@ -470,435 +512,435 @@ function onHelpClick(help: any) { ...@@ -470,435 +512,435 @@ function onHelpClick(help: any) {
</view> </view>
</view> </view>
<!-- 弹窗组件 --> <!-- 弹窗组件 -->
<save-dialog :show="showDialog" :editData="currentEditData" @update:show="showDialog = $event" /> <SaveDialog :show="showDialog" :editData="currentEditData" @update:show="showDialog = $event" />
</view> </view>
</template> </template>
<style scoped lang="scss"> <style scoped lang="scss">
.page { .page {
background-color: #e6f5e8; background-color: #e6f5e8;
mix-blend-mode: NOTTHROUGH; mix-blend-mode: NOTTHROUGH;
width: 100%; width: 100%;
overflow-y: auto; overflow-y: auto;
overflow-x: hidden; overflow-x: hidden;
height: 100%; height: 100%;
padding-bottom: 44rpx; padding-bottom: 44rpx;
.group { .group {
.section { .section {
padding: 24rpx 20rpx 88rpx; padding: 24rpx 20rpx 88rpx;
background-image: url('/static/images/codefun/7a5dc4ee864fe55da98b41c14ee3b931.png'); background-image: url('/static/images/codefun/7a5dc4ee864fe55da98b41c14ee3b931.png');
background-size: 100% 100%; background-size: 100% 100%;
background-repeat: no-repeat; background-repeat: no-repeat;
.group_2 { .group_2 {
margin-right: 8rpx; margin-right: 8rpx;
padding: 0 12rpx; padding: 0 12rpx;
.image {
border-radius: 64rpx;
width: 108rpx;
height: 42rpx;
}
.image_2 {
mix-blend-mode: NOTTHROUGH;
width: 34rpx;
height: 22rpx;
}
.image_3 {
mix-blend-mode: NOTTHROUGH;
width: 30rpx;
height: 22rpx;
}
.image_4 { .image {
width: 48rpx; border-radius: 64rpx;
height: 22rpx; width: 108rpx;
} height: 42rpx;
} }
.group_3 { .image_2 {
margin-right: 8rpx; mix-blend-mode: NOTTHROUGH;
margin-top: 42rpx; width: 34rpx;
padding: 16rpx 8rpx 0; height: 22rpx;
}
.text { .image_3 {
color: #ffffffe6; mix-blend-mode: NOTTHROUGH;
} width: 30rpx;
height: 22rpx;
}
.image_5 { .image_4 {
mix-blend-mode: NOTTHROUGH; width: 48rpx;
width: 44rpx; height: 22rpx;
height: 42rpx; }
} }
.pos { .group_3 {
position: absolute; margin-right: 8rpx;
right: 8rpx; margin-top: 42rpx;
top: 50%; padding: 16rpx 8rpx 0;
transform: translateY(-50%);
}
}
.group_4 { .text {
.image_6 { color: #ffffffe6;
mix-blend-mode: NOTTHROUGH; }
border-radius: 50%;
width: 96rpx;
height: 96rpx;
}
.group_5 { .image_5 {
margin-top: 8rpx; mix-blend-mode: NOTTHROUGH;
margin-bottom: 8rpx; width: 44rpx;
height: 42rpx;
}
.text_2 { .pos {
color: #ffffff; position: absolute;
right: 8rpx;
top: 50%;
transform: translateY(-50%);
} }
}
.section_2 { .group_4 {
padding: 8rpx; .image_6 {
background-color: #ffffff;
border-radius: 400rpx;
mix-blend-mode: NOTTHROUGH; mix-blend-mode: NOTTHROUGH;
height: 42rpx; border-radius: 50%;
width: 96rpx;
height: 96rpx;
}
.image_7 { .group_5 {
mix-blend-mode: NOTTHROUGH; margin-top: 8rpx;
width: 18rpx; margin-bottom: 8rpx;
height: 12rpx;
.text_2 {
color: #ffffff;
} }
.text_3 { .section_2 {
font-size: 22rpx; padding: 8rpx;
line-height: 22rpx; background-color: #ffffff;
border-radius: 400rpx;
mix-blend-mode: NOTTHROUGH;
height: 42rpx;
.image_7 {
mix-blend-mode: NOTTHROUGH;
width: 18rpx;
height: 12rpx;
}
.text_3 {
font-size: 22rpx;
line-height: 22rpx;
}
} }
} }
}
.image_9 { .image_9 {
margin-right: 8rpx; margin-right: 8rpx;
}
} }
}
.section_3 { .section_3 {
margin-right: 16rpx; margin-right: 16rpx;
margin-top: 24rpx; margin-top: 24rpx;
padding: 32rpx 0; padding: 32rpx 0;
background-color: #ffffff; background-color: #ffffff;
border-radius: 16rpx; border-radius: 16rpx;
mix-blend-mode: NOTTHROUGH; mix-blend-mode: NOTTHROUGH;
.group_6 {
flex: 1 1 186.88rpx;
.font_4 {
font-size: 36rpx;
line-height: 36rpx;
font-weight: 600;
color: #20602d;
}
.font_5 { .group_6 {
font-size: 28rpx; flex: 1 1 186.88rpx;
line-height: 28rpx;
color: #4e5969; .font_4 {
font-size: 36rpx;
line-height: 36rpx;
font-weight: 600;
color: #20602d;
}
.font_5 {
font-size: 28rpx;
line-height: 28rpx;
color: #4e5969;
}
} }
} }
} }
}
.group_7 { .group_7 {
margin-top: -64rpx; margin-top: -64rpx;
padding: 0 20rpx; padding: 0 20rpx;
.section_12 { .section_12 {
margin-right: 16rpx; margin-right: 16rpx;
padding: 24rpx; padding: 24rpx;
background-color: #ffffff; background-color: #ffffff;
border-radius: 16rpx; border-radius: 16rpx;
mix-blend-mode: NOTTHROUGH; mix-blend-mode: NOTTHROUGH;
.group_8 {
overflow: hidden;
width: 411.4rpx;
height: 80rpx;
.group_9 { .group_8 {
padding-top: 8rpx;
overflow: hidden; overflow: hidden;
width: 307.4rpx; width: 411.4rpx;
height: 80rpx; height: 80rpx;
.text-wrapper_2 { .group_9 {
padding: 8rpx 0; padding-top: 8rpx;
overflow: hidden; overflow: hidden;
width: 308rpx; width: 307.4rpx;
height: 80rpx;
.text-wrapper_2 {
padding: 8rpx 0;
overflow: hidden;
width: 308rpx;
}
} }
} }
}
.group_10 { .group_10 {
margin-right: 8rpx; margin-right: 8rpx;
.text-wrapper { .text-wrapper {
padding: 8rpx 0; padding: 8rpx 0;
background-color: #ff5454; background-color: #ff5454;
border-radius: 20000rpx; border-radius: 20000rpx;
mix-blend-mode: NOTTHROUGH; mix-blend-mode: NOTTHROUGH;
width: 40rpx; width: 40rpx;
height: 40rpx; height: 40rpx;
}
} }
}
.image_17 { .image_17 {
border-radius: 24rpx; border-radius: 24rpx;
width: 92rpx; width: 92rpx;
height: 92rpx; height: 92rpx;
} }
.font_11 { .font_11 {
font-size: 28rpx; font-size: 28rpx;
line-height: 28rpx; line-height: 28rpx;
color: #15161a; color: #15161a;
} }
.image_18 { .image_18 {
width: 72rpx; width: 72rpx;
height: 12rpx; height: 12rpx;
} }
.text_24 { .text_24 {
color: #13e000; color: #13e000;
}
} }
}
.equal-division { .equal-division {
margin-right: 16rpx; margin-right: 16rpx;
.section_5 { .section_5 {
flex: 1 1 336rpx; flex: 1 1 336rpx;
.font_8 { .font_8 {
font-size: 24rpx; font-size: 24rpx;
line-height: 24rpx; line-height: 24rpx;
color: #4cd964; color: #4cd964;
} }
.image_12 { .image_12 {
margin-right: 8rpx; margin-right: 8rpx;
margin-top: 8rpx; margin-top: 8rpx;
} }
.view { .view {
padding: 12rpx 16rpx; padding: 12rpx 16rpx;
border-radius: 12rpx; border-radius: 12rpx;
overflow: hidden; overflow: hidden;
background-color: #4fc5fd33; background-color: #4fc5fd33;
mix-blend-mode: NOTTHROUGH; mix-blend-mode: NOTTHROUGH;
.text_14 { .text_14 {
color: #4fbdfb; color: #4fbdfb;
}
} }
}
.group_12 { .group_12 {
margin-left: 16rpx; margin-left: 16rpx;
} }
.image_13 { .image_13 {
margin: 8rpx 8rpx 0 40rpx; margin: 8rpx 8rpx 0 40rpx;
} }
.view_2 { .view_2 {
padding: 12rpx 16rpx; padding: 12rpx 16rpx;
border-radius: 12rpx; border-radius: 12rpx;
overflow: hidden; overflow: hidden;
background-color: rgba(93, 182, 111, 0.2); background-color: rgba(93, 182, 111, 0.2);
mix-blend-mode: NOTTHROUGH; mix-blend-mode: NOTTHROUGH;
width: 152rpx; width: 152rpx;
.image_14 { .image_14 {
width: 20rpx; width: 20rpx;
height: 20rpx; height: 20rpx;
}
} }
} }
.section_11 {
padding: 20rpx 24rpx;
background-color: #ffffff;
border-radius: 16rpx;
mix-blend-mode: NOTTHROUGH;
height: 220rpx;
}
} }
.section_11 { .image_10 {
padding: 20rpx 24rpx;
background-color: #ffffff;
border-radius: 16rpx; border-radius: 16rpx;
mix-blend-mode: NOTTHROUGH; width: 80rpx;
height: 220rpx; height: 80rpx;
} }
}
.image_10 {
border-radius: 16rpx;
width: 80rpx;
height: 80rpx;
}
.image_11 { .image_11 {
mix-blend-mode: NOTTHROUGH; mix-blend-mode: NOTTHROUGH;
width: 12rpx; width: 12rpx;
height: 22rpx; height: 22rpx;
} }
.font_7 { .font_7 {
font-size: 22rpx; font-size: 22rpx;
line-height: 22rpx; line-height: 22rpx;
color: #6b7280; color: #6b7280;
} }
.group_13 { .group_13 {
padding-bottom: 32rpx; padding-bottom: 32rpx;
.text_16 { .text_16 {
margin-right: 8rpx; margin-right: 8rpx;
}
} }
}
.list { .list {
margin-right: 16rpx; margin-right: 16rpx;
padding: 32rpx 24rpx; padding: 32rpx 24rpx;
background-color: #ffffff; background-color: #ffffff;
border-radius: 16rpx; border-radius: 16rpx;
mix-blend-mode: NOTTHROUGH; mix-blend-mode: NOTTHROUGH;
.list-item { .list-item {
&:first-child { &:first-child {
margin-top: 0; margin-top: 0;
} }
.image_15 { .image_15 {
width: 54rpx; width: 54rpx;
height: 72rpx; height: 72rpx;
} }
.group_14 { .group_14 {
margin-top: 8rpx; margin-top: 8rpx;
.font_9 { .font_9 {
font-size: 28rpx; font-size: 28rpx;
line-height: 28rpx; line-height: 28rpx;
color: #333333; color: #333333;
}
} }
}
.text-wrapper_4 { .text-wrapper_4 {
padding: 16rpx 0; padding: 16rpx 0;
background-color: #5db66f26; background-color: #5db66f26;
border-radius: 400rpx; border-radius: 400rpx;
mix-blend-mode: NOTTHROUGH; mix-blend-mode: NOTTHROUGH;
width: 136rpx; width: 136rpx;
.font_10 { .font_10 {
font-size: 24rpx; font-size: 24rpx;
line-height: 24rpx; line-height: 24rpx;
color: #16a34a; color: #16a34a;
}
} }
} }
} }
}
.font_6 { .font_6 {
font-size: 24rpx; font-size: 24rpx;
line-height: 24rpx; line-height: 24rpx;
color: #999999; color: #999999;
} }
.text_22 { .text_22 {
margin-right: 16rpx; margin-right: 16rpx;
} }
.section_9 { .section_9 {
margin-right: 16rpx; margin-right: 16rpx;
padding: 28rpx 24rpx; padding: 28rpx 24rpx;
background-color: #ffffff; background-color: #ffffff;
border-radius: 16rpx; border-radius: 16rpx;
mix-blend-mode: NOTTHROUGH; mix-blend-mode: NOTTHROUGH;
.image_19 { .image_19 {
width: 40rpx; width: 40rpx;
height: 40rpx; height: 40rpx;
} }
.font_13 { .font_13 {
font-size: 28rpx; font-size: 28rpx;
line-height: 28rpx; line-height: 28rpx;
color: #1d2129; color: #1d2129;
} }
.image_21 { .image_21 {
width: 38rpx; width: 38rpx;
height: 38rpx; height: 38rpx;
}
} }
} }
}
.font { .font {
font-size: 32rpx; font-size: 32rpx;
line-height: 32rpx; line-height: 32rpx;
color: #000000; color: #000000;
} }
.font_1 { .font_1 {
font-size: 24rpx; font-size: 24rpx;
line-height: 24rpx; line-height: 24rpx;
color: #ffffff; color: #ffffff;
} }
.font_3 { .font_3 {
font-size: 24rpx; font-size: 24rpx;
line-height: 24rpx; line-height: 24rpx;
color: #5db66f; color: #5db66f;
} }
.font_2 { .font_2 {
font-size: 32rpx; font-size: 32rpx;
line-height: 32rpx; line-height: 32rpx;
font-weight: 600; font-weight: 600;
color: #333333; color: #333333;
} }
.image_8 { .image_8 {
width: 36rpx; width: 36rpx;
height: 36rpx; height: 36rpx;
}
} }
}
.equal-division_2 { .equal-division_2 {
margin-right: 8rpx; margin-right: 8rpx;
.group_15 { .group_15 {
flex: 1 1 148.4rpx; flex: 1 1 148.4rpx;
.font_14 { .font_14 {
font-size: 20rpx; font-size: 20rpx;
line-height: 20rpx; line-height: 20rpx;
color: #666666; color: #666666;
}
} }
} }
}
.section_6 { .section_6 {
padding: 16rpx 0; padding: 16rpx 0;
background-color: #ffffff; background-color: #ffffff;
mix-blend-mode: NOTTHROUGH; mix-blend-mode: NOTTHROUGH;
border-top: solid 1rpx #e7e7e7; border-top: solid 1rpx #e7e7e7;
} }
.equal-division-item { .equal-division-item {
padding: 8rpx 0; padding: 8rpx 0;
} }
.image_20 { .image_20 {
width: 32rpx; width: 32rpx;
height: 32rpx; height: 32rpx;
}
} }
}
</style> </style>
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="64px" height="64.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M402.432 307.968m-286.5152 0a286.5152 286.5152 0 1 0 573.0304 0 286.5152 286.5152 0 1 0-573.0304 0Z" fill="#9FDFFF" /><path d="M731.648 498.5856m-253.0816 0a253.0816 253.0816 0 1 0 506.1632 0 253.0816 253.0816 0 1 0-506.1632 0Z" fill="#78CCFF" /><path d="M268.4416 522.4448m-229.2224 0a229.2224 229.2224 0 1 0 458.4448 0 229.2224 229.2224 0 1 0-458.4448 0Z" fill="#78CCFF" /><path d="M266.0864 522.4448h463.2064v229.2224H266.0864z" fill="#78CCFF" /><path d="M543.6416 260.864l-187.9552 293.888 189.7472 27.648L450.56 803.84l281.088-289.8944-213.8624-32.3584z" fill="#FFB612" /><path d="M297.6256 904.9088c0 37.8368-27.2896 68.4544-60.928 68.4544s-60.928-30.6688-60.928-68.4544c0-37.8368 60.928-112.7424 60.928-112.7424s60.928 74.9056 60.928 112.7424zM664.6784 904.9088c0 37.8368-27.2896 68.4544-60.928 68.4544s-60.928-30.6688-60.928-68.4544c0-37.8368 60.928-112.7424 60.928-112.7424s60.928 74.9056 60.928 112.7424z" fill="#78CCFF" /><path d="M481.1264 904.9088c0 37.8368-27.2896 68.4544-60.928 68.4544s-60.928-30.6688-60.928-68.4544c0-37.8368 60.928-112.7424 60.928-112.7424s60.928 74.9056 60.928 112.7424zM848.2304 904.9088c0 37.8368-27.2896 68.4544-60.928 68.4544s-60.928-30.6688-60.928-68.4544c0-37.8368 60.928-112.7424 60.928-112.7424s60.928 74.9056 60.928 112.7424z" fill="#9FDFFF" /></svg>
\ No newline at end of file
...@@ -48,4 +48,4 @@ export const useFarmStore = defineStore({ ...@@ -48,4 +48,4 @@ export const useFarmStore = defineStore({
// Need to be used outside the setup // Need to be used outside the setup
export function useFarmStoreWithOut() { export function useFarmStoreWithOut() {
return useFarmStore(store) return useFarmStore(store)
} }
\ No newline at end of file
...@@ -11,7 +11,7 @@ interface AreaNode { ...@@ -11,7 +11,7 @@ interface AreaNode {
* 将areaList转换为树形结构(省市县三级联动) * 将areaList转换为树形结构(省市县三级联动)
* @returns 树形结构的地区数据 * @returns 树形结构的地区数据
*/ */
export const convertToTree = (): AreaNode[] => { export function convertToTree(): AreaNode[] {
const { province_list, city_list, county_list } = areaList const { province_list, city_list, county_list } = areaList
const tree: AreaNode[] = [] const tree: AreaNode[] = []
...@@ -56,7 +56,7 @@ export const convertToTree = (): AreaNode[] => { ...@@ -56,7 +56,7 @@ export const convertToTree = (): AreaNode[] => {
// 导出树形结构数据(懒加载) // 导出树形结构数据(懒加载)
let areaTreeCache: AreaNode[] | null = null let areaTreeCache: AreaNode[] | null = null
export const getAreaTree = (): AreaNode[] => { export function getAreaTree(): AreaNode[] {
if (!areaTreeCache) { if (!areaTreeCache) {
areaTreeCache = convertToTree() areaTreeCache = convertToTree()
} }
...@@ -71,18 +71,18 @@ export const areaTree = getAreaTree() ...@@ -71,18 +71,18 @@ export const areaTree = getAreaTree()
* @param code 地区代码 * @param code 地区代码
* @returns 完整的地区名称 * @returns 完整的地区名称
*/ */
export const getFullAreaName = (code: string): string => { export function getFullAreaName(code: string): string {
const { province_list, city_list, county_list } = areaList const { province_list, city_list, county_list } = areaList
let name = '' let name = ''
if (county_list[code]) { if (county_list[code]) {
// 如果是区县代码,获取完整的省市县名称 // 如果是区县代码,获取完整的省市县名称
const cityCode = code.substring(0, 4) + '00' const cityCode = `${code.substring(0, 4)}00`
const provinceCode = code.substring(0, 2) + '0000' const provinceCode = `${code.substring(0, 2)}0000`
name = `${province_list[provinceCode]}${city_list[cityCode]}${county_list[code]}` name = `${province_list[provinceCode]}${city_list[cityCode]}${county_list[code]}`
} else if (city_list[code]) { } else if (city_list[code]) {
// 如果是城市代码,获取完整的省市名称 // 如果是城市代码,获取完整的省市名称
const provinceCode = code.substring(0, 2) + '0000' const provinceCode = `${code.substring(0, 2)}0000`
name = `${province_list[provinceCode]}${city_list[code]}` name = `${province_list[provinceCode]}${city_list[code]}`
} else if (province_list[code]) { } else if (province_list[code]) {
// 如果是省份代码,直接返回省份名称 // 如果是省份代码,直接返回省份名称
...@@ -114,8 +114,6 @@ export function getCodeByText(text) { ...@@ -114,8 +114,6 @@ export function getCodeByText(text) {
const entry = Object.entries(obj).find(([_, value]) => value === text) const entry = Object.entries(obj).find(([_, value]) => value === text)
return entry ? entry[0] : null return entry ? entry[0] : null
} }
return findCode(areaList.province_list) return findCode(areaList.province_list) || findCode(areaList.city_list) || findCode(areaList.county_list)
|| findCode(areaList.city_list)
|| findCode(areaList.county_list)
} }
...@@ -6,11 +6,11 @@ export default { ...@@ -6,11 +6,11 @@ export default {
/** /**
* 服务协议地址 * 服务协议地址
*/ */
services: 'https://app.yiring.com/agri/app/agreement.html', services: 'https://app.yiring.com/agri/services.html',
/** /**
* 隐私政策地址 * 隐私政策地址
*/ */
privacy: 'https://app.yiring.com/agri/app/guide.html', privacy: 'https://app.yiring.com/agri/privacy.html',
/** /**
* 从内部打开指定页面 * 从内部打开指定页面
......
...@@ -206,7 +206,7 @@ export function downloadFile(options: DownloadOptions): Promise<DownloadResult> ...@@ -206,7 +206,7 @@ export function downloadFile(options: DownloadOptions): Promise<DownloadResult>
/* #endif */ /* #endif */
// 其他平台使用原生下载 // 其他平台使用原生下载
/* #ifndef H5*/ /* #ifndef H5 */
return downloadFileForNative(options) return downloadFileForNative(options)
/* #endif */ /* #endif */
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论