提交 bacbcda4 作者: 方治民

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

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