提交 e07d0d6f 作者: 宇宙超人

产销发布页面修改,选择器去掉input事件,app端下载文件方法修改

上级 7ef27b6c
<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: '发布采购需求',
})
// 获取数据详情
if (option.id) {
getDetails(option.id)
} else {
// 获取当前位置
getCurrentAddressInfo()
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: '发布采购需求',
})
// 获取数据详情
if (option.id) {
getDetails(option.id)
} else {
// 获取当前位置
getCurrentAddressInfo()
}
})
onShow(() => {
// 数据字典赋值
initDict()
})
const pageData = reactive({
title: '发布采购需求',
show: {
time: false,
classify: false,
address: false,
},
options: {
address: [],
classify: [],
},
form: {
id: '',
title: '',
count: '',
unit: '',
deadLine: '',
priceStart: '',
priceEnd: '',
address: '',
province: '',
city: '',
country: '',
classify: '',
classifyText: '',
inputTextArea: '',
image: null,
imageObj: null,
},
rules: [
{
name: 'title',
rule: ['required'],
msg: ['请输入标题'],
},
{
name: 'count',
rule: ['required'],
msg: ['请输入数量'],
},
{
name: 'unit',
rule: ['required'],
msg: ['请输入单位'],
},
{
name: 'deadLine',
rule: ['required'],
msg: ['请选择截至时间'],
},
{
name: 'priceStart',
rule: ['required'],
msg: ['请输入最低价'],
},
{
name: 'priceEnd',
rule: ['required'],
msg: ['请输入最高价'],
},
{
name: 'address',
rule: ['required'],
msg: ['请选择省/市/区县'],
},
{
name: 'classify',
rule: ['required'],
msg: ['请选择分类'],
},
{
name: 'image',
rule: ['required'],
msg: ['请上传示例图片'],
},
],
})
const { show, options, form } = toRefs(pageData)
function initDict() {
pageData.options.classify = dictStore.getDictList['classify'].map((item) => {
return {
value: item.value,
text: item.text,
}
})
pageData.options.address = areaTree
}
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}`
})
}
onShow(() => {
// 数据字典赋值
initDict()
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.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 pageData = reactive({
title: '发布采购需求',
show: {
time: false,
classify: false,
address: false,
// 提取扩展名
const fileParts = fileName.split('.')
const extname = fileParts[fileParts.length - 1]
// 返回格式化的对象
return {
name: fileName,
extname: extname,
url: url,
}
}
function handleChangeTime(e) {
pageData.form.deadLine = e.result
pageData.show.time = 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
}
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',
},
options: {
address: [],
classify: [],
header: {
'X-Access-Token': userStore.getToken,
},
form: {
id: '',
title: '',
count: 0,
unit: '',
deadLine: '',
priceStart: 0,
priceEnd: 0,
address: '',
province: '',
city: '',
country: '',
classify: '',
classifyText: '',
inputTextArea: '',
image: null,
imageObj: null,
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: () => {
toastRef.value.show({
type: 'error',
text: '上传失败',
})
uploadRef.value.clearFiles()
pageData.form.image = null
},
rules: [
{
name: 'title',
rule: ['required'],
msg: ['请输入标题'],
},
{
name: 'count',
rule: ['required'],
msg: ['请输入数量'],
},
{
name: 'unit',
rule: ['required'],
msg: ['请输入单位'],
},
{
name: 'deadLine',
rule: ['required'],
msg: ['请选择截至时间'],
},
{
name: 'priceStart',
rule: ['required'],
msg: ['请输入最低价'],
},
{
name: 'priceEnd',
rule: ['required'],
msg: ['请输入最高价'],
},
{
name: 'address',
rule: ['required'],
msg: ['请选择省/市/区县'],
},
{
name: 'classify',
rule: ['required'],
msg: ['请选择分类'],
},
{
name: 'image',
rule: ['required'],
msg: ['请上传示例图片'],
},
],
})
}
// 文件删除
function handleDelete() {
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.purchaseSellAdd(pageData.form).then(() => {
toastRef.value.show({
type: 'success',
text: '需求发布成功',
})
uni.switchTab({
url: '/pages/chanxiao/chanxiao',
})
})
}
})
}
/**
* 处理地区值
* @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>
<view class="page">
<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.inputTextArea" labelSize="28"
label-width="180"></fui-input>
</view>
<view class="mt20">
<!-- 价格区间 -->
<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.priceStart" placeholder="最低价"
:min="0" />
<text class="price-separator">-</text>
<input type="number" class="price-input" v-model="form.priceEnd" placeholder="最高价"
:min="0" />
</view>
</view>
</view>
<fui-input type="number" required label="数量" placeholder="请输入数量" v-model="form.count" labelSize="28"
label-width="180"></fui-input>
<fui-input required label="单位" placeholder="请输入计量单位" 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;">
<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>
const { show, options, form } = toRefs(pageData)
<!-- 截至时间 -->
<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.time = true">
<text class="time-text" :class="{ placeholder: !form.deadLine }">
{{ form.deadLine || '请选择截止时间' }}
</text>
</view>
</view>
</view>
<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">
<text class="select-text" :class="{ placeholder: !form.classifyText }">
{{ form.classifyText || '请选择分类' }}
</text>
</view>
</view>
</view>
</view>
function initDict() {
pageData.options.classify = dictStore.getDictList['classify'].map((item) => {
return {
value: item.value,
text: item.text,
}
})
pageData.options.address = areaTree
<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>
</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>
</fui-form>
<fui-date-picker :show="show.time" type="3" @change="handleChangeTime"
@cancel="show.time = false"></fui-date-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>
</view>
</view>
<fui-date-picker :show="show.time" type="3" @change="handleChangeTime" @cancel="show.time = false"
minDate="2025-01-01"></fui-date-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>
</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;
}
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}`
})
.formBox {
width: 690rpx;
margin: 30rpx auto;
}
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.classifyText = pageData.options.classify.find((item) => item.value == res.classify)?.text
pageData.form.imageObj = pageData.form.image && parseUrlInfo(pageData.form.image)
})
.purchase-form {
background: transparent;
}
function parseUrlInfo(url) {
// 从URL中提取文件名
const pathParts = url.split('/')
const fileName = pathParts[pathParts.length - 1]
// 提取扩展名
const fileParts = fileName.split('.')
const extname = fileParts[fileParts.length - 1]
.form-section {
// background: #ffffff;
// border-radius: 12rpx;
// margin-bottom: 20rpx;
// 返回格式化的对象
return {
name: fileName,
extname: extname,
url: url,
// box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.04);
border-bottom: 1rpx solid #f5f5f5;
}
.form-item {
padding: 30rpx 0;
border-bottom: 1rpx solid #f5f5f5;
&:last-child {
border-bottom: none;
}
&.required .label::before {
content: '*';
color: #ff4d4f;
margin-right: 8rpx;
}
// 添加点击区域样式
.select-input {
position: relative;
}
}
function handleChangeTime(e) {
pageData.form.deadLine = e.result
pageData.show.time = false
.form-row {
display: flex;
justify-content: space-between;
}
function handleChangeClassify(e) {
pageData.form.classify = e.value
pageData.form.classifyText = e.text
pageData.show.classify = false
.half-width {
width: 48%;
}
function handleChangeAddress(e) {
pageData.form.address = e.text.join('/')
pageData.show.address = false
.align-center {
align-items: center;
}
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: () => {
toastRef.value.show({
type: 'error',
text: '上传失败',
})
uploadRef.value.clearFiles()
pageData.form.image = null
},
})
.label {
display: block;
font-size: 28rpx;
color: #333333;
font-weight: 500;
width: 180rpx;
// margin-right: 20rpx;
}
// 文件删除
function handleDelete() {
uploadRef.value.clearFiles()
pageData.form.image = null
.input {
width: 100%;
height: 80rpx;
background: #f8f9fa;
border-radius: 8rpx;
padding: 0 20rpx;
font-size: 28rpx;
color: #333333;
&::placeholder {
color: #999999;
}
}
const formRef = ref()
function submit() {
formRef.value.validator(pageData.form, pageData.rules, true).then((res) => {
if (res.isPassed) {
changeAddressValue(pageData.form)
ChanxiaoAPI.purchaseSellAdd(pageData.form).then(() => {
toastRef.value.show({
type: 'success',
text: '需求发布成功',
})
uni.switchTab({
url: '/pages/chanxiao/chanxiao',
})
})
}
})
.price-range {
display: flex;
align-items: center;
// justify-content: space-between;
}
.price-input {
width: 15%;
// height: 80rpx;
// background: #f8f9fa;
// border-radius: 8rpx;
padding: 0 10rpx;
font-size: 28rpx;
text-align: center;
}
.price-separator {
color: #666666;
font-size: 28rpx;
margin: 0 10rpx;
}
.select-input {
flex: 1;
border-radius: 8rpx;
padding: 0 20rpx;
display: flex;
align-items: center;
justify-content: space-between;
cursor: pointer;
}
/**
* 处理地区值
* @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])
.select-text {
font-size: 28rpx;
color: #333333;
padding: 0 20rpx;
&.placeholder {
color: #999999;
}
}
</script>
<template>
<fui-form ref="formRef">
<fui-input required label="标题" borderTop placeholder="请输入标题" v-model="form.title"></fui-input>
<fui-input required label="数量" borderTop placeholder="请输入数量" v-model="form.count"></fui-input>
<fui-input required label="单位" borderTop placeholder="请输入单位" v-model="form.unit"></fui-input>
<fui-input
required
label="截至时间"
borderTop
placeholder="请选择截至时间"
v-model="form.deadLine"
@click="show.time = true"
></fui-input>
<fui-input required label="最低价" placeholder="请输入最低价" v-model="form.priceStart"></fui-input>
<fui-input required label="最高价" placeholder="请输入最高价" v-model="form.priceEnd"></fui-input>
<fui-input
required
label="省/市/区县"
placeholder="请选择省/市/区县"
v-model="form.address"
@click="show.address = true"
></fui-input>
<fui-input
required
label="分类"
placeholder="请选择分类"
v-model="form.classifyText"
@click="show.classify = true"
></fui-input>
<fui-input label="说明" placeholder="请输入说明" v-model="form.inputTextArea"></fui-input>
<view class="bg-white" style="padding: 0.875rem 0.35rem">
<view class="mb-1 flex justify-start">
<text class="pr-1" style="color: #ff2b2b">*</text>
示例图片
</view>
<uni-file-picker
:value="form.imageObj"
ref="uploadRef"
limit="1"
:auto-upload="false"
@select="handleUpload"
@delete="handleDelete"
></uni-file-picker>
</view>
<view class="fui-btn__box bg-white p-4" v-if="!form.id">
<fui-button text="发布需求" bold radius="96rpx" @click="submit"></fui-button>
</view>
</fui-form>
<fui-date-picker
:show="show.time"
type="3"
@change="handleChangeTime"
@cancel="show.time = false"
></fui-date-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>
.select-arrow {
color: #999999;
font-size: 24rpx;
line-height: 1;
}
<fui-toast ref="toastRef"></fui-toast>
</template>
.time-range {
display: flex;
align-items: center;
justify-content: space-between;
}
<style lang="scss" scoped>
:deep(.fui-button) {
border-color: #ff9800 !important;
background: #ff9800 !important;
.time-input {
width: 45%;
// height: 80rpx;
// background: #f8f9fa;
border-radius: 8rpx;
display: flex;
align-items: center;
}
.time-text {
font-size: 28rpx;
color: #333333;
padding: 0 20rpx;
&.placeholder {
color: #999999;
}
}
.time-separator {
color: #666666;
font-size: 28rpx;
margin: 0 10rpx;
}
.upload-area {
margin-top: 10rpx;
}
.custom-uploader {
:deep(.uni-file-picker__container) {
border: 2rpx dashed #d9d9d9;
border-radius: 8rpx;
background: #f8f9fa;
}
}
.upload-placeholder {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 200rpx;
color: #999999;
}
.upload-icon {
font-size: 48rpx;
margin-bottom: 10rpx;
}
.upload-text {
font-size: 24rpx;
}
.submit-section {
background: transparent;
padding: 40rpx 0;
}
.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;
}
}
}
::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 { 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: '发布供应需求',
})
// 获取数据详情
if (option.id) {
getDetails(option.id)
} else {
// 获取当前位置
getCurrentAddressInfo()
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: '发布供应需求',
})
// 获取数据详情
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: ['请选择省/市/区县'],
},
{
name: 'status',
rule: ['required'],
msg: ['请选择状态'],
},
{
name: 'classify',
rule: ['required'],
msg: ['请选择分类'],
},
],
})
const { show, options, form } = toRefs(pageData)
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) => {
return {
value: item.value,
text: item.text,
}
})
}
onShow(() => {
// 数据字典赋值
initDict()
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}`
})
}
const pageData = reactive({
title: '发布供应需求',
show: {
time1: false,
time2: false,
address: false,
status: false,
classify: false,
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,
},
options: {
address: [],
status: [],
classify: [],
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 // 保存返回的图片信息
}
}
},
form: {
id: '',
title: '',
productSpecs: '',
minPrice: 0,
maxPrice: 0,
unit: '',
currency: '',
supplyQuantity: '',
minOrderQuantity: '',
address: '',
detailedAddress: '',
supplyStartDate: '',
supplyEndDate: '',
status: '',
classifyText: '',
classify: '',
statusText: '',
province: '',
city: '',
country: '',
image: null,
imageObj: null,
fail: (err) => {
toastRef.value.show({
type: 'error',
text: '上传失败',
})
uploadRef.value.clearFiles()
pageData.form.image = 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: ['请选择分类'],
},
],
})
}
// 文件删除
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 表单数据
*/
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>
const { show, options, form } = toRefs(pageData)
<template>
<view class="page">
<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>
</view>
<view class="mt20">
<!-- 价格区间 -->
<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" />
<text class="price-separator">-</text>
<input type="number" class="price-input" v-model="form.maxPrice" placeholder="最高价" :min="0"/>
</view>
</view>
</view>
<!-- <fui-input required label="最低价" placeholder="请输入最低价" v-model="form.minPrice"
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>
</view>
<view class="mt20">
<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>
function initDict() {
pageData.options.address = areaTree
console.log(dictStore.getDictList['purchase_status'])
<!-- 供应时间 -->
<view class="form-section" style="padding: 0 30rpx;">
<view class="form-item flex align-center">
<text class="label">供应时间</text>
<view class="time-range">
<view class="time-input" @click="show.time1 = true">
<text class="time-text" :class="{ placeholder: !form.supplyStartDate }">
{{ form.supplyStartDate || '供应开始时间' }}
</text>
</view>
<text class="time-separator">-</text>
<view class="time-input" @click="show.time2 = true">
<text class="time-text" :class="{ placeholder: !form.supplyEndDate }">
{{ form.supplyEndDate || '供应结束时间' }}
</text>
</view>
</view>
</view>
</view>
<!-- <fui-input label="供应开始时间" placeholder="请选择供应开始时间" v-model="form.supplyStartDate"
@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-item required flex align-center">
<text class="label">分类</text>
<view class="time-input" @click="show.classify = true">
<text class="select-text" :class="{ placeholder: !form.classifyText }">
{{ form.classifyText || '请选择分类' }}
</text>
</view>
</view>
</view>
<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">
<text class="select-text" :class="{ placeholder: !form.statusText }">
{{ form.statusText || '请选择状态' }}
</text>
</view>
</view>
</view>
</view>
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,
}
})
<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>
</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>
</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>
</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;
}
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}`
})
.formBox {
width: 690rpx;
margin: 30rpx auto;
}
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)
})
.supply-form {
background: transparent;
}
function parseUrlInfo(url) {
// 从URL中提取文件名
const pathParts = url.split('/')
const fileName = pathParts[pathParts.length - 1]
// 提取扩展名
const fileParts = fileName.split('.')
const extname = fileParts[fileParts.length - 1]
.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;
}
// 返回格式化的对象
return {
name: fileName,
extname: extname,
url: url,
.form-item {
padding: 30rpx 0;
border-bottom: 1rpx solid #f5f5f5;
&:last-child {
border-bottom: none;
}
&.required .label::before {
content: '*';
color: #ff4d4f;
margin-right: 8rpx;
}
// 添加点击区域样式
.select-input {
position: relative;
}
}
function handleChangeTime1(e) {
pageData.form.supplyStartDate = e.result
pageData.show.time1 = false
.form-row {
display: flex;
justify-content: space-between;
}
function handleChangeTime2(e) {
pageData.form.supplyEndDate = e.result
pageData.show.time2 = false
.half-width {
width: 48%;
}
function handleChangeClassify(e) {
pageData.form.classify = e.value
pageData.form.classifyText = e.text
pageData.show.classify = false
.align-center {
align-items: center;
}
function handleChangeAddress(e) {
pageData.form.address = e.text.join('/')
pageData.show.address = false
.label {
display: block;
font-size: 28rpx;
color: #333333;
font-weight: 500;
width: 180rpx;
// margin-right: 20rpx;
}
function handleChangeStatus(e) {
pageData.form.status = e.value
pageData.form.statusText = e.text
pageData.show.status = false
.input {
width: 100%;
height: 80rpx;
background: #f8f9fa;
border-radius: 8rpx;
padding: 0 20rpx;
font-size: 28rpx;
color: #333333;
&::placeholder {
color: #999999;
}
}
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
},
})
.price-range {
display: flex;
align-items: center;
// justify-content: space-between;
}
// 文件删除
function handleDelete(file) {
uploadRef.value.clearFiles()
pageData.form.image = null
.price-input {
width: 15%;
// height: 80rpx;
// background: #f8f9fa;
// border-radius: 8rpx;
padding: 0 10rpx;
font-size: 28rpx;
text-align: center;
}
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',
})
})
}
})
.price-separator {
color: #666666;
font-size: 28rpx;
margin: 0 10rpx;
}
.select-input {
flex: 1;
border-radius: 8rpx;
padding: 0 20rpx;
display: flex;
align-items: center;
justify-content: space-between;
cursor: pointer;
}
/**
* 处理地区值
* @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])
.select-text {
font-size: 28rpx;
color: #333333;
padding: 0 20rpx;
&.placeholder {
color: #999999;
}
}
</script>
<template>
<fui-form ref="formRef">
<fui-input required label="供应标题" placeholder="请输入供应标题" v-model="form.title"></fui-input>
<fui-input label="规格说明" borderTop placeholder="请输入规格说明" v-model="form.productSpecs"></fui-input>
<fui-input required label="最低价" borderTop placeholder="请输入最低价" v-model="form.minPrice"></fui-input>
<fui-input required label="最高价" borderTop placeholder="请输入最高价" v-model="form.maxPrice"></fui-input>
<fui-input required label="计量单位" borderTop placeholder="请输入计量单位" v-model="form.unit"></fui-input>
<fui-input required label="币种" borderTop placeholder="请输入币种" v-model="form.currency"></fui-input>
<fui-input
required
label="供应数量"
borderTop
placeholder="请输入供应数量"
v-model="form.supplyQuantity"
></fui-input>
<fui-input
required
label="最小起订量"
borderTop
placeholder="请输入最小起订量"
v-model="form.minOrderQuantity"
></fui-input>
<fui-input
required
label="省/市/区县"
placeholder="请选择省/市/区县"
v-model="form.address"
@click="show.address = true"
></fui-input>
<fui-input label="详细地址" placeholder="请输入详细地址" v-model="form.detailedAddress"></fui-input>
<fui-input
label="供应开始时间"
borderTop
placeholder="请选择供应开始时间"
v-model="form.supplyStartDate"
@click="show.time1 = true"
></fui-input>
<fui-input
label="供应结束时间"
borderTop
placeholder="请选择供应结束时间"
v-model="form.supplyEndDate"
@click="show.time2 = true"
></fui-input>
<fui-input
required
label="分类"
placeholder="请选择分类"
v-model="form.classifyText"
@click="show.classify = true"
></fui-input>
<fui-input
label="状态"
placeholder="请选择状态"
v-model="form.statusText"
@click="show.status = true"
></fui-input>
<view class="bg-white" 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>
</view>
<view class="fui-btn__box bg-white p-4" v-if="!form.id">
<fui-button text="发布需求" bold radius="96rpx" @click="submit"></fui-button>
</view>
</fui-form>
<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-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>
</template>
.select-arrow {
color: #999999;
font-size: 24rpx;
line-height: 1;
}
<style lang="scss" scoped>
:deep(.fui-button) {
border-color: #ff9800 !important;
background: #ff9800 !important;
.time-range {
display: flex;
align-items: center;
justify-content: space-between;
}
.time-input {
width: 45%;
// height: 80rpx;
// background: #f8f9fa;
border-radius: 8rpx;
display: flex;
align-items: center;
}
.time-text {
font-size: 28rpx;
color: #333333;
&.placeholder {
color: #999999;
}
}
.time-separator {
color: #666666;
font-size: 28rpx;
margin: 0 10rpx;
}
.upload-area {
margin-top: 10rpx;
}
.custom-uploader {
:deep(.uni-file-picker__container) {
border: 2rpx dashed #d9d9d9;
border-radius: 8rpx;
background: #f8f9fa;
}
}
.upload-placeholder {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 200rpx;
color: #999999;
}
.upload-icon {
font-size: 48rpx;
margin-bottom: 10rpx;
}
.upload-text {
font-size: 24rpx;
}
.submit-section {
background: transparent;
padding: 40rpx 0;
}
.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;
}
}
}
::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>
<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,8 +11,13 @@
</u-form-item>
<u-form-item label="设备类型" prop="deviceType" required>
<u-input v-model="formData.deviceTypeText" placeholder="请选择设备类型" border="bottom"
@click="showDeviceTypePicker = true" />
<view class="address-display" @click="showDeviceTypePicker = true">
<text :class="{ 'placeholder-text': !formData.deviceTypeText }">
{{ formData.deviceTypeText || '请选择设备类型' }}
</text>
</view>
<!-- <u-input v-model="formData.deviceTypeText" placeholder="请选择设备类型" border="bottom"
@click="showDeviceTypePicker = true" /> -->
</u-form-item>
<u-form-item label="设备标识" prop="deviceIdentifier" required>
......@@ -21,7 +26,8 @@
<!-- 操作按钮 -->
<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>
......@@ -100,7 +106,7 @@ const rules = {
{ min: 2, max: 50, message: '设备名称长度在2-50个字符之间', trigger: 'blur' }
],
deviceType: [
{ required: true, message: '请选择设备类型',type:'number', trigger: 'change' }
{ required: true, message: '请选择设备类型', type: 'number', trigger: 'change' }
],
deviceIdentifier: [
{ required: true, message: '请输入设备唯一标识', trigger: 'blur' },
......@@ -136,7 +142,7 @@ const resetFormData = () => {
formData.deviceType = ''
formData.deviceTypeText = ''
formData.deviceIdentifier = ''
// 清除验证状态
if (formRef.value) {
formRef.value.resetFields()
......@@ -146,11 +152,11 @@ const resetFormData = () => {
// 加载编辑数据
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)
......@@ -181,14 +187,14 @@ const handleSubmit = async () => {
if (!valid) {
return
}
loading.value = true
// 准备提交数据
const submitData = {
...formData
}
// 根据 editData 判断是新增还是修改
let result
if (props.editData && props.editData.id) {
......@@ -207,11 +213,11 @@ const handleSubmit = async () => {
uni.showToast({ title: '操作成功', icon: 'success' })
emit('update:show', false)
emit('submitSuccess')
} catch (error) {
console.log('提交失败:', error)
uni.showToast({
title: '操作失败',
uni.showToast({
title: '操作失败',
icon: 'none',
duration: 2000
})
......@@ -256,17 +262,19 @@ defineExpose({
display: flex;
gap: 20rpx;
margin-top: 40rpx;
.submit-btn {
flex: 1;
::v-deep .u-button {
background-color: #5DB66F;
border-color: #5DB66F;
}
}
.cancel-btn {
flex: 1;
::v-deep .u-button {
background-color: #fff;
color: #666;
......@@ -300,6 +308,27 @@ defineExpose({
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;
}
}
::v-deep .u-form-item__body__left__content__required {
position: static;
......@@ -340,11 +369,11 @@ defineExpose({
border-radius: 20rpx;
padding: 20rpx 0rpx;
}
.u-modal__header {
border-bottom: 2rpx solid #f0f0f0;
padding: 30rpx;
.u-modal__header__title {
font-size: 32rpx;
font-weight: 600;
......
......@@ -8,9 +8,12 @@
<u-input v-model="formData.baseName" placeholder="请输入基地名称" border="bottom" />
</u-form-item>
<u-form-item label="基地类型" prop="baseType" required>
<u-input v-model="formData.baseTypeText" placeholder="请选择基地类型" border="bottom"
@click="show.farmType = true" />
<u-form-item label="基地类型" prop="baseType" required class="clickable" @click="show.farmType = true">
<view class="address-display">
<text :class="{'placeholder-text': !formData.baseTypeText}">
{{ formData.baseTypeText || '请选择基地类型' }}
</text>
</view>
</u-form-item>
<u-form-item label="规模" prop="scale" required>
......@@ -24,9 +27,12 @@
<!-- 地址信息 -->
<view class="section-title">地址信息</view>
<u-form-item label="省市区" prop="province" required>
<u-input v-model="formData.province" placeholder="请选择省市区" border="bottom"
@click="show.address = true" />
<u-form-item label="省市区" prop="province" required class="clickable" @click="show.address = true">
<view class="address-display">
<text :class="{'placeholder-text': !formData.province}">
{{ formData.province || '请选择省市区' }}
</text>
</view>
</u-form-item>
<u-form-item label="详细地址" prop="detailedAddress" required>
......@@ -464,10 +470,18 @@ onLoad((pageOptions) => {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20rpx 0;
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;
......@@ -572,4 +586,24 @@ onLoad((pageOptions) => {
}
}
}
// 表单项点击区域样式
::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 { reactive } from 'vue'
import { onPullDownRefresh, onHide, onUnload } from '@dcloudio/uni-app'
import { onPullDownRefresh } from '@dcloudio/uni-app'
import dayjs from 'dayjs'
import { closeSplashscreenAndChechUpgrade } from '@/utils/upgrade'
import * as WeatherAPI from '@/api/model/weather'
......
......@@ -8,7 +8,11 @@ import SaveDialog from '../device/components/save-dialog.vue'
onPullDownRefresh(() => {
setTimeout(function () {
uni.stopPullDownRefresh()
Message.toast('刷新成功')
uni.showToast({
title: '刷新成功',
icon: 'success',
duration: 1500
})
}, 1000)
})
......@@ -244,9 +248,9 @@ function onResourceClick(resource: any) {
}
// 资源下载点击事件
function onDownloadClick(resource: any) {
function onDownloadClick(e, resource: any) {
// 阻止事件冒泡
event?.stopPropagation()
e?.stopPropagation()
// 显示加载提示
uni.showLoading({
......@@ -281,7 +285,11 @@ function downloadFileForWeb(resource: any) {
// 清理
document.body.removeChild(link)
uni.hideLoading()
Message.toast('开始下载')
uni.showToast({
title: '开始下载',
icon: 'success',
duration: 1500
})
}
// 原生平台下载文件函数
......@@ -294,7 +302,11 @@ function downloadFileForNative(resource: any) {
tempFilePath: res.tempFilePath,
success: (saveRes) => {
uni.hideLoading()
Message.toast('下载成功')
uni.showToast({
title: '下载成功',
icon: 'success',
duration: 1500
})
// 提示用户文件已保存
uni.showModal({
......@@ -307,7 +319,11 @@ function downloadFileForNative(resource: any) {
fileType: resource.fileType?.toString() || '',
showMenu: true,
fail: () => {
Message.toast('无法打开文件')
uni.showToast({
title: '无法打开文件',
icon: 'error',
duration: 1500
})
},
})
}
......@@ -317,18 +333,30 @@ function downloadFileForNative(resource: any) {
fail: (err) => {
uni.hideLoading()
console.error('保存文件失败:', err)
Message.toast('保存文件失败')
uni.showToast({
title: '保存文件失败',
icon: 'error',
duration: 1500
})
},
})
} else {
uni.hideLoading()
Message.toast(`下载失败,状态码: ${res.statusCode}`)
uni.showToast({
title: `下载失败,状态码: ${res.statusCode}`,
icon: 'error',
duration: 1500
})
}
},
fail: (err) => {
uni.hideLoading()
console.error('下载失败:', err)
Message.toast('网络错误,下载失败')
uni.showToast({
title: '网络错误,下载失败',
icon: 'error',
duration: 1500
})
},
})
}
......@@ -478,7 +506,7 @@ function onHelpClick(help: any) {
</view>
</view>
<view class="codefun-flex-col codefun-justify-start codefun-items-center text-wrapper_4"
@click.stop="onDownloadClick(resource)">
@click.stop="(e) => onDownloadClick(e, resource)">
<text class="font_10">下载</text>
</view>
</view>
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论