增加新需求以及页面

This commit is contained in:
BianLzhaoMin 2025-03-27 17:45:44 +08:00
parent ab1f5a54e3
commit a8706903fc
5 changed files with 205 additions and 261 deletions

View File

@ -22,6 +22,12 @@
"style": { "style": {
"navigationBarTitleText": "意见收集" "navigationBarTitleText": "意见收集"
} }
},
{
"path": "pages/error/index",
"style": {
"navigationBarTitleText": "意见收集"
}
} }
], ],
"globalStyle": { "globalStyle": {

51
src/pages/error/index.vue Normal file
View File

@ -0,0 +1,51 @@
<template>
<view class="content">
<view class="success-container">
<up-icon name="close" color="#ff0000" size="80" bold="true"></up-icon>
<text class="success">此二维码已失效</text>
</view>
</view>
</template>
<script setup></script>
<style lang="scss" scoped>
.content {
height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
background-color: #f5f5f5;
overflow-y: auto;
}
::v-deep .opinion-form {
width: 90%;
height: auto;
}
.input-content {
background-color: #fff;
}
.success-container {
width: 100vw;
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
padding: 120rpx 0;
background-color: #fff;
box-sizing: border-box;
.success {
font-weight: bold;
font-size: 16px;
}
.thanks {
font-size: 13px;
padding: 10rpx 0;
color: #848181;
}
}
</style>

View File

@ -1,244 +1,48 @@
<template> <template>
<view class="content"> <view class="content">
<!-- 意见收集 --> <text class="text-box">
<template v-if="!isSuccess"> &emsp;&emsp;我用十年青春,赴你最后之约我用十年青春,赴你最后之约我用十年青春,赴你最后之约我用十年青春,赴你最后之约我用十年青春,赴你最后之约我用十年青春,赴你最后之约我用十年青春,赴你最后之约我用十年青春,赴你最后之约我用十年青春,赴你最后之约
<up-form </text>
labelPosition="top"
:model="opinionModel"
ref="opinionModelRef"
:rules="opinionRules"
labelWidth="auto"
class="opinion-form"
>
<up-form-item label="姓名" prop="userName" required>
<up-input
v-model="opinionModel.userName"
class="input-content"
placeholder="填写姓名"
clearable
/>
</up-form-item>
<up-form-item label="电话" prop="userPhone" required>
<up-input
v-model="opinionModel.userPhone"
class="input-content"
placeholder="填写电话"
clearable
/>
</up-form-item>
<up-form-item label="意见归属单位/部门" prop="userCompany">
<up-input
v-model="opinionModel.unit"
class="input-content"
placeholder="填写归属单位/部门"
clearable
/>
</up-form-item>
<up-form-item label="意见" prop="options" required>
<up-textarea
v-model="opinionModel.options"
placeholder="请输入内容"
class="input-content"
:maxlength="500"
count
style="max-height: 500px; overflow-y: auto"
height="300px"
clearable
>
</up-textarea>
</up-form-item>
<up-form-item> <view>
<up-button <up-button
type="primary" type="primary"
text="提交意见" text="填写意见"
style="margin-top: 30rpx" style="margin-top: 30rpx"
@tap="onSubmitOptions" @tap="onSubmitOptions"
/> />
</up-form-item> </view>
</up-form>
</template>
<template v-else>
<view class="success-container">
<up-icon name="checkbox-mark" color="#2979ff" size="80" bold="true"></up-icon>
<text class="success">提交成功</text>
<text class="thanks">感谢您宝贵的意见</text>
</view>
<view style="width: 100vw">
<up-button
type="primary"
text="返回"
@tap="onContinueFill"
style="width: 95%; margin: 30rpx auto"
/>
<!-- <up-button
text="退出"
:plain="true"
type="primary"
@tap="onExit"
style="width: 95%; margin: 0 auto"
/> -->
</view>
</template>
<up-modal
:show="showModal"
title="温馨提示"
content="是否确认退出?"
showCancelButton
@confirm="onConfirm"
/>
</view> </view>
</template> </template>
<script setup> <script setup>
import { submitOptionsApi } from '@/services/options.js'
import { ref } from 'vue' import { ref } from 'vue'
const isError = ref(false)
// //
const opinionModel = ref({
userName: '',
userPhone: '',
unit: '',
options: '',
})
const opinionRules = ref({
userName: [
{
type: 'string',
required: true,
message: '请填写姓名',
trigger: ['blur', 'change'],
},
{
pattern: /^[\u4e00-\u9fa5]{2,6}$/,
//
transform(value) {
return String(value)
},
message: '请填写正确的姓名',
},
],
userPhone: [
{
type: 'string',
required: true,
message: '请填写电话',
trigger: ['blur', 'change'],
},
{
pattern: /^1[3-9]\d{9}$/,
//
transform(value) {
return String(value)
},
message: '请填写正确的手机号码',
},
],
options: [
{
type: 'string',
required: true,
message: '请填写意见',
trigger: ['blur', 'change'],
},
{
max: 500,
message: '字数不能超过500',
},
],
})
//
const opinionModelRef = ref(null)
//
const isSuccess = ref(false)
//
const showModal = ref(false)
//
const onSubmitOptions = () => { const onSubmitOptions = () => {
opinionModelRef.value uni.navigateTo({ url: '/pages/opinion/index' })
.validate()
.then(async (valid) => {
if (valid) {
console.log('opinionModel.value', opinionModel.value)
const res = await submitOptionsApi(opinionModel.value)
if (res.code === 0) {
uni.$u.toast('提交成功')
isSuccess.value = true
opinionModel.value.options = ''
opinionModel.value.userPhone = ''
opinionModel.value.userName = ''
opinionModel.value.unit = ''
} else {
uni.$u.toast(res.msg + '提交失败')
}
}
})
.catch(() => {
//
})
} }
// if (isError.value) {
const onContinueFill = () => { uni.redirectTo({ url: '/pages/error/index' })
isSuccess.value = false
}
// 退
const onExit = () => {
showModal.value = true
}
// 退
const onConfirm = () => {
uni.redirectTo({ url: '/pages/index/index' })
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.content { .content {
height: 100vh; height: 100vh;
padding: 20px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; justify-content: space-between;
background-color: #f5f5f5; background-color: #f5f5f5;
overflow-y: auto; overflow-y: auto;
}
::v-deep .opinion-form {
width: 90%;
height: auto;
}
.input-content { .text-box {
background-color: #fff; line-height: 2.2;
} font-size: 12px;
letter-spacing: 2px;
.success-container {
width: 100vw;
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
padding: 120rpx 0;
background-color: #fff;
box-sizing: border-box;
.success {
font-weight: bold;
font-size: 16px;
}
.thanks {
font-size: 13px;
padding: 10rpx 0;
color: #848181;
} }
} }
</style> </style>

View File

@ -10,44 +10,64 @@
labelWidth="auto" labelWidth="auto"
class="opinion-form" class="opinion-form"
> >
<up-form-item label="姓名" prop="userName" required> <up-form-item label="姓名" prop="userName">
<up-input <up-input
v-model="opinionModel.userName" v-model="opinionModel.userName"
class="input-content" class="input-content"
placeholder="填写姓名" placeholder="填写姓名"
clearable
/> />
</up-form-item> </up-form-item>
<up-form-item label="电话" prop="userPhone" required> <up-form-item label="电话" prop="userPhone">
<up-input <up-input
v-model="opinionModel.userPhone" v-model="opinionModel.userPhone"
class="input-content" class="input-content"
placeholder="填写电话" placeholder="填写电话"
clearable
/> />
</up-form-item> </up-form-item>
<up-form-item label="意见归属单位/部门" prop="userCompany"> <!-- <up-form-item label="意见归属单位/部门" prop="userCompany">
<up-input <up-input
v-model="opinionModel.unit" v-model="opinionModel.unit"
class="input-content" class="input-content"
placeholder="填写归属单位/部门" placeholder="填写归属单位/部门"
clearable
/> />
</up-form-item> </up-form-item> -->
<up-form-item label="意见" prop="options" required> <up-form-item label="意见" prop="options" required>
<up-textarea <up-textarea
v-model="opinionModel.options" v-model="opinionModel.options"
placeholder="请输入内容" placeholder="请输入内容"
class="input-content" class="input-content"
style="min-height: 30vh" :maxlength="500"
:maxlength="3"
count count
style="max-height: 500px; overflow-y: auto"
height="300px"
clearable
>
</up-textarea>
</up-form-item>
<up-form-item label="附件(最多上传5张图片)">
<up-upload
name="1"
multiple
:maxCount="5"
accept="image"
@delete="deletePic"
:fileList="fileList"
@afterRead="afterRead"
/> />
</up-form-item> </up-form-item>
<up-button <up-form-item>
type="primary" <up-button
text="提交意见" type="primary"
style="margin-top: 30rpx" text="提交意见"
@tap="onSubmitOptions" style="margin-top: 30rpx"
></up-button> @tap="onSubmitOptions"
/>
</up-form-item>
</up-form> </up-form>
</template> </template>
@ -60,17 +80,17 @@
<view style="width: 100vw"> <view style="width: 100vw">
<up-button <up-button
type="primary" type="primary"
text="继续填写" text="返回"
@tap="onContinueFill" @tap="onContinueFill"
style="width: 95%; margin: 30rpx auto" style="width: 95%; margin: 30rpx auto"
/> />
<up-button <!-- <up-button
text="退出" text="退出"
:plain="true" :plain="true"
type="primary" type="primary"
@tap="onExit" @tap="onExit"
style="width: 95%; margin: 0 auto" style="width: 95%; margin: 0 auto"
/> /> -->
</view> </view>
</template> </template>
@ -88,8 +108,6 @@
import { submitOptionsApi } from '@/services/options.js' import { submitOptionsApi } from '@/services/options.js'
import { ref } from 'vue' import { ref } from 'vue'
console.log('submitOptionsApi', submitOptionsApi)
// //
const opinionModel = ref({ const opinionModel = ref({
userName: '', userName: '',
@ -97,30 +115,43 @@ const opinionModel = ref({
unit: '', unit: '',
options: '', options: '',
}) })
const opinionRules = ref({
userName: {
type: 'string',
required: true,
message: '请填写姓名',
trigger: ['blur', 'change'],
},
userPhone: [
{
type: 'string',
required: true,
message: '请填写电话',
trigger: ['blur', 'change'],
},
{ const fileList = ref([])
pattern: /^1[3-9]\d{9}$/,
// const opinionRules = ref({
transform(value) { // userName: [
return String(value) // {
}, // type: 'string',
message: '请填写正确的手机号码', // required: true,
}, // message: '',
], // trigger: ['blur', 'change'],
// },
// {
// pattern: /^[\u4e00-\u9fa5]{2,6}$/,
// //
// transform(value) {
// return String(value)
// },
// message: '',
// },
// ],
// userPhone: [
// {
// type: 'string',
// required: true,
// message: '',
// trigger: ['blur', 'change'],
// },
// {
// pattern: /^1[3-9]\d{9}$/,
// //
// transform(value) {
// return String(value)
// },
// message: '',
// },
// ],
options: [ options: [
{ {
type: 'string', type: 'string',
@ -128,6 +159,10 @@ const opinionRules = ref({
message: '请填写意见', message: '请填写意见',
trigger: ['blur', 'change'], trigger: ['blur', 'change'],
}, },
{
max: 500,
message: '字数不能超过500',
},
], ],
}) })
@ -179,6 +214,54 @@ const onExit = () => {
const onConfirm = () => { const onConfirm = () => {
uni.redirectTo({ url: '/pages/index/index' }) uni.redirectTo({ url: '/pages/index/index' })
} }
//
const deletePic = (event) => {
fileList.value.splice(event.index, 1)
}
//
const afterRead = async (event) => {
console.log('event', event)
let lists = [].concat(event.file)
let fileListLen = fileList.value.length
lists.map((item) => {
fileList.value.push({
...item,
status: 'uploading',
message: '上传中',
})
})
for (let i = 0; i < lists.length; i++) {
const result = await uploadFilePromise(lists[i].url)
let item = fileList.value[fileListLen]
fileList.value.splice(fileListLen, 1, {
...item,
status: 'success',
message: '',
url: result,
})
fileListLen++
}
}
const uploadFilePromise = (url) => {
return new Promise((resolve, reject) => {
let a = uni.uploadFile({
url: 'http://192.168.2.21:7001/upload',
filePath: url,
name: 'file',
formData: {
user: 'test',
},
success: (res) => {
setTimeout(() => {
resolve(res.data.data)
}, 1000)
},
})
})
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@ -188,9 +271,11 @@ const onConfirm = () => {
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
background-color: #f5f5f5; background-color: #f5f5f5;
overflow-y: auto;
} }
::v-deep .opinion-form { ::v-deep .opinion-form {
width: 90%; width: 90%;
height: auto;
} }
.input-content { .input-content {

View File

@ -1,14 +1,12 @@
import { useMemberStore } from '@/stores' import { useMemberStore } from '@/stores'
console.log('useMemberStore()', useMemberStore())
/** /**
* 添加拦截器 * 添加拦截器
* 拦截 request 请求 * 拦截 request 请求
* baseURL 设置请求ip地址和端口 * baseURL 设置请求ip地址和端口
*/ */
const ENV = process.env.NODE_ENV const ENV = process.env.NODE_ENV
const baseURL = ENV === 'development' ? 'http://192.168.0.38:8080' : 'http://192.168.0.14:21666' const baseURL = ENV === 'development' ? '/api' : 'http://192.168.0.14:21666'
/** /**
* httpInterceptor 分别拦截 request uploadFile 请求 * httpInterceptor 分别拦截 request uploadFile 请求