bonus-material-app/src/pages/business/directApply.vue

784 lines
23 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="accept page-common">
<div class="card">
<h2 style="padding: 4rpx 0; font-weight: bold">转出方信息</h2>
<uni-forms
:model="formDataOut"
ref="formOut"
label-width="200rpx"
:rule="rulesOut.value"
>
<uni-forms-item label="转出单位:" name="unitId" required>
<eselect
style="width: 100%; height: 90rpx"
v-model="formDataOut.unitId"
:detailValue="formDataOut.backUnitName"
ref="treeSelect"
:options="unitListOut"
@change="getProjectOut"
@clear="clearUnitOut"
:disabled="isEdit"
></eselect>
</uni-forms-item>
<uni-forms-item label="转出工程:" name="projectId" required>
<eselect
style="width: 100%; height: 90rpx"
v-model="formDataOut.projectId"
:detailValue="formDataOut.backProName"
ref="treeSelect2"
:options="proListOut"
@change="changeProOut"
@clear="clearProOut"
:disabled="isEdit"
></eselect>
</uni-forms-item>
<uni-forms-item label="转出人:" name="leaseOutPerson" required>
<uni-easyinput
v-model="formDataOut.leaseOutPerson"
maxlength="10"
placeholder="请输入转出人"
/>
</uni-forms-item>
<uni-forms-item label="联系电话:" name="phoneOut" required>
<uni-easyinput
v-model="formDataOut.phoneOut"
maxlength="11"
placeholder="请输入联系电话"
/>
</uni-forms-item>
</uni-forms>
</div>
<div class="card">
<h2 style="padding: 4rpx 0; font-weight: bold">转入方信息</h2>
<uni-forms :model="formDataIn" ref="formIn" label-width="200rpx" :rule="rulesIn.value">
<uni-forms-item label="转入单位:" name="unitId" required>
<eselect
style="width: 100%; height: 90rpx"
v-model="formDataIn.unitId"
:detailValue="formDataIn.leaseUnitName"
ref="treeSelect"
:options="unitListIn"
@change="getProjectIn"
@clear="clearUnitIn"
></eselect>
</uni-forms-item>
<uni-forms-item label="转入工程:" name="projectId" required>
<eselect
style="width: 100%; height: 90rpx"
v-model="formDataIn.projectId"
:detailValue="formDataIn.leaseProName"
ref="treeSelect2"
:options="proListIn"
@change="changeProIn"
@clear="clearProIn"
></eselect>
</uni-forms-item>
<uni-forms-item label="转入人:" name="leaseInPerson" required>
<uni-easyinput
v-model="formDataIn.leaseInPerson"
maxlength="10"
placeholder="请输入转入人"
/>
</uni-forms-item>
<uni-forms-item label="联系电话:" name="phoneIn" required>
<uni-easyinput
v-model="formDataIn.phoneIn"
maxlength="11"
placeholder="请输入联系电话"
/>
</uni-forms-item>
</uni-forms>
</div>
<div class="card">
<uni-forms-item label="附件" required>
<div class="upload-wrapper" style="display: flex; flex-wrap: wrap">
<!-- 上传按钮,仅当上传图片数量少于 3 张时显示 -->
<div class="upload" @click="uploadImg" v-if="bmFileInfos.length < 3">+</div>
<!-- 动态展示已上传的图片 -->
<div
class="upload"
@click="uploadImg"
v-for="(img, index) in bmFileInfos"
:key="index"
>
<div class="image-container">
<image
:src="img.urlTemp"
style="width: 160rpx; height: 160rpx"
mode=""
></image>
<!-- 删除 logo这里用一个 span 模拟,可替换为实际的 logo 图片 -->
<span class="delete-logo" @click.stop="deleteImg(index)">&times;</span>
</div>
</div>
</div>
</uni-forms-item>
</div>
<div class="footer-btn">
<button class="btn-cont" @click="addDirect">添加直转明细</button>
</div>
</view>
</template>
<script setup>
import { ref, reactive, nextTick } from 'vue'
import eselect from '@/components/tree-select/eselect.vue'
import { onLoad, onReady } from '@dcloudio/uni-app'
import { baseURL } from '@/utils/http'
import {
getUnitList,
getProjectList,
getConfigList,
getLevelThreeType,
insertApp,
getAgreementInfoById,
getListsByConfigId,
getTypeDataList,
leaseTask,
} from '../../services/back.js'
import { getDirectRotationDetail } from '@/services/integratedQuery'
const taskInfo = ref({})
const treeSelect = ref(null)
const treeSelect2 = ref(null)
const formDataOut = ref({
unitId: '',
projectId: '',
leaseOutPerson: '',
phoneOut: '',
})
const formDataIn = ref({
unitId: '',
projectId: '',
leaseInPerson: '',
phoneIn: '',
})
let opt = reactive({})
const isEdit = ref(false)
const unitListOut = ref([])
const proListOut = ref([])
const unitListIn = ref([])
const proListIn = ref([])
const agreementId = ref('')
const agreementIdIn = ref('')
const maTypeSelectList = ref([])
// 定义 form 引用
const formOut = ref(null)
const formIn = ref(null)
const imgBeseUrl2 = ref('') //图片展示
const imgBeseUrl = ref('') //图片展示
const bmFileInfos = ref([]) //图片数组
// 定义表单验证规则
const rulesOut = ref({
unitId: {
rules: [
{
required: true,
errorMessage: '转出单位为必填项',
trigger: 'change',
},
],
},
projectId: {
rules: [
{
required: true,
errorMessage: '转出工程为必填项',
trigger: 'change',
},
],
},
leaseOutPerson: {
rules: [
{
required: true,
errorMessage: '转出人为必填项',
trigger: 'blur',
},
],
},
phoneOut: {
rules: [
{
required: true,
errorMessage: '联系电话为必填项',
trigger: 'blur',
},
{
pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
errorMessage: '请输入正确的手机号码',
trigger: 'blur',
},
],
},
})
const rulesIn = ref({
unitId: {
rules: [
{
required: true,
errorMessage: '转入单位为必填项',
trigger: 'change',
},
],
},
projectId: {
rules: [
{
required: true,
errorMessage: '转入工程为必填项',
trigger: 'change',
},
],
},
leaseInPerson: {
rules: [
{
required: true,
errorMessage: '转入人为必填项',
trigger: 'blur',
},
],
},
phoneIn: {
rules: [
{
required: true,
errorMessage: '联系电话为必填项',
trigger: 'blur',
},
{
pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
errorMessage: '请输入正确的手机号码',
trigger: 'blur',
},
],
},
})
// 获取详情
const getDetails = async () => {
try {
const res = await getDirectRotationDetail({ id: opt.id })
console.log('🚀 ~ getDetails ~ res', res)
formDataOut.value.unitId = res.data.backUnitId
formDataOut.value.backUnitName = res.data.backUnitName
formDataOut.value.projectId = res.data.backProId
formDataOut.value.backProName = res.data.backProName
formDataOut.value.leaseOutPerson = res.data.backMan
formDataOut.value.phoneOut = res.data.backPhone
formDataIn.value.unitId = res.data.leaseUnitId
formDataIn.value.leaseUnitName = res.data.leaseUnitName
formDataIn.value.projectId = res.data.leaseProId
formDataIn.value.leaseProName = res.data.leaseProName
formDataIn.value.leaseInPerson = res.data.leaseMan
formDataIn.value.phoneIn = res.data.leasePhone
agreementId.value = res.data.backAgreementId
agreementIdIn.value = res.data.leaseAgreementId
bmFileInfos.value = res.data.dirUrls
} catch (error) {
console.log('🚀 ~ getDetails ~ error', error)
}
}
//单位
const getUnitOut = () => {
// proId.value=e.id;
let obj = {
projectId: formDataOut.value.projectId,
}
getUnitList(obj)
.then((res) => {
console.log("xxxxxxxxxx",res)
unitListOut.value = res.data
// getAgreement()
if (formDataOut.value.unitId && formDataOut.value.projectId) {
getAgreementOut()
}
})
.catch((error) => {
console.log(error)
})
}
//工程
const getProjectOut = async (e) => {
console.log('🚀 ~ getProject ~ e:', e)
formDataOut.value.unitId = e?.id || ''
let obj = {
unitId: formDataOut.value.unitId,
// "isApp":true
}
try {
const res = await getProjectList(obj)
proListOut.value = res.data
// proId.value=""
// treeSelect2.value.clearInput();
agreementId.value = ''
if (formDataOut.value.unitId && formDataOut.value.projectId) {
await getAgreementOut()
// getMaType();
}
} catch (error) {
console.log(error)
}
}
//单位
const getUnitIn = () => {
// proId.value=e.id;
let obj = {
projectId: formDataIn.value.projectId,
}
getUnitList(obj)
.then((res) => {
console.log(res)
unitListIn.value = res.data
if (formDataIn.value.unitId && formDataIn.value.projectId) {
getAgreementIn()
}
})
.catch((error) => {
console.log(error)
})
}
//工程
const getProjectIn = async (e) => {
console.log('🚀 ~ getProject ~ e:', e)
formDataIn.value.unitId = e?.id || ''
let obj = {
unitId: formDataIn.value.unitId,
// "isApp":true
}
try {
const res = await getProjectList(obj)
proListIn.value = res.data
agreementIdIn.value = ''
if (formDataIn.value.unitId && formDataIn.value.projectId) {
await getAgreementIn()
// getMaType();
}
} catch (error) {
console.log(error)
}
}
//工程选择
const changeProOut = (e) => {
console.log(e)
formDataOut.value.projectId = e.id
getUnitOut()
// getAgreement()
}
const changeProIn = (e) => {
console.log(e)
formDataIn.value.projectId = e.id
getUnitIn()
}
//协议
const getAgreementOut = async () => {
let obj = {
unitId: formDataOut.value.unitId,
projectId: formDataOut.value.projectId,
}
getAgreementInfoById(obj)
.then((res) => {
console.log(res)
if (res.code == 200) {
agreementId.value = res.data.agreementId
} else {
agreementId.value = ''
}
})
.catch((error) => {
console.log(error)
})
}
//协议
const getAgreementIn = async () => {
let obj = {
unitId: formDataIn.value.unitId,
projectId: formDataIn.value.projectId,
}
getAgreementInfoById(obj)
.then((res) => {
console.log(res)
if (res.code == 200) {
agreementIdIn.value = res.data.agreementId
} else {
agreementIdIn.value = ''
}
})
.catch((error) => {
console.log(error)
})
}
//添加明细
const addDirect = async () => {
console.log('🚀 ~ addDirect ~ formDataOut:', formDataOut.value)
console.log('🚀 ~ addDirect ~ formDataIn:', formDataIn.value)
let flag = true
await formOut.value.validate((valid) => {
console.log('🚀 ~ addDirect ~ valid:', valid)
if (valid) {
flag = false
}
})
await formIn.value.validate((valid) => {
if (valid) {
flag = false
}
})
if (bmFileInfos.value.length == 0) {
flag = false
await uni.showToast({
title: '请上传附件!',
icon: 'none',
})
}
if (flag) {
if (agreementId.value == '') {
await uni.showToast({
title: '转出方没有相匹配的协议!',
icon: 'none',
})
} else if (agreementIdIn.value == '') {
await uni.showToast({
title: '转入方没有相匹配的协议!',
icon: 'none',
})
} else {
// 序列化数据
const formDataOutStr = encodeURIComponent(JSON.stringify(formDataOut.value))
const formDataInStr = encodeURIComponent(JSON.stringify(formDataIn.value))
const bmFileInfosStr = encodeURIComponent(JSON.stringify(bmFileInfos.value))
const url = `/pages/business/directApplyDetail?agreementId=${agreementId.value}&agreementIdIn=${agreementIdIn.value}&formDataOut=${formDataOutStr}&formDataIn=${formDataInStr}&bmFileInfos=${bmFileInfosStr}&id=${opt.id}`
await uni.navigateTo({
url: url,
})
}
}
}
onReady((opt) => {
console.log('🚀 ~ onReady ~ formOut:')
if (formOut.value) {
// 设置表单验证规则
formOut.value.setRules(rulesOut.value)
} else {
console.error('表单formOut引用未正确初始化')
}
if (formIn.value) {
// 设置表单验证规则
formIn.value.setRules(rulesIn.value)
} else {
console.error('表单formIn引用未正确初始化')
}
})
console.log('🚀 ~ opt:', opt)
onLoad((options) => {
console.log("uuuuuuuuuuuuu",options)
if(options && options.params){
opt = JSON.parse(options.params)
}
if (opt.type == 'edit') {
isEdit.value = true
getDetails()
console.log('🚀 ~ onLoad ~ opt:', formDataIn.value)
}
getUnitOut()
getProjectOut()
getUnitIn()
getProjectIn()
})
//上传
const uploadImg = (item) => {
if (bmFileInfos.value.length >= 3) {
uni.showToast({
title: '最多上传3张图片',
icon: 'none',
})
return
}
uni.chooseImage({
count: 3 - bmFileInfos.value.length, //图片可选择数量
sizeType: ['original', 'compressed'], //original 原图compressed 压缩图,默认二者都有
sourceType: ['album', 'camera'], //album 从相册选图camera 使用相机,默认二者都有。
success: (res) => {
console.log(res)
let imgFiles = res.tempFilePaths //图片的本地文件路径列表
imgFiles.forEach((filePath) => {
console.log('2222222222222222222222')
bmFileInfos.value.push({ urlTemp: filePath })
})
console.log('🚀 ~ uploadImg ~ imgFiles:', imgFiles)
// imgBeseUrl.value = imgFiles[0]
// console.log('本地地址', imgFiles)
// console.log('请求地址', baseURL+"/file/upload")
bmFileInfos.value.forEach((item, index) => {
uni.uploadFile({
// url: baseURL+"/file/upload",//app
url: '/file/upload', //h5
filePath: item.urlTemp,
name: 'file',
success: (res) => {
res = JSON.parse(res.data)
console.log('上传成功', res.code)
console.log('上传成功', res.data)
if (res.code && res.code == 200) {
bmFileInfos.value[index] = {
...bmFileInfos.value[index],
name: res.data.name,
url: res.data.url,
}
uni.showToast({ title: '上传成功', icon: 'none' })
} else {
uni.showToast({ title: '上传失败', icon: 'none' })
}
},
fail: (err) => {
console.error('上传失败', err)
},
})
})
// this.$refs.vForm.clearValidate()
},
})
}
const deleteImg = (index) => {
bmFileInfos.value.splice(index, 1)
// bmFileInfosTemp.value.splice(index, 1);
}
//删除
const delRow = (index) => {
console.log(index)
console.log(typeList.value)
typeList.value.splice(index, 1)
}
const clearUnitOut = () => {
formDataOut.value.unitId = ''
agreementId.value = ''
getUnitOut()
getProjectOut()
}
const clearProOut = () => {
formDataOut.value.projectId = ''
agreementId.value = ''
getProjectOut()
}
const clearUnitIn = () => {
formDataIn.value.unitId = ''
formDataIn.value.leaseUnitName = ''
formDataIn.value.projectId = ''
formDataIn.value.leaseProName = ''
getUnitIn()
getProjectIn()
}
const clearProIn = () => {
formDataIn.value.projectId = ''
getProjectIn()
}
</script>
<style lang="scss">
.accept {
padding: 24rpx;
height: 95vh;
word-break: break-all;
background-color: #f7f8fa;
display: flex;
flex-direction: column;
// 卡片样式
.card {
padding: 32rpx;
background-color: #fff;
border-radius: 20rpx;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.06);
margin-bottom: 24rpx;
// 卡片头部
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 24rpx;
.title {
font-size: 32rpx;
font-weight: 600;
color: #262626;
position: relative;
padding-left: 24rpx;
&::before {
content: '';
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
width: 6rpx;
height: 28rpx;
background: #3784fb;
border-radius: 6rpx;
}
}
.header-right {
.tip {
font-size: 26rpx;
color: #8c8c8c;
}
}
}
// 操作按钮样式
.uni-group {
display: flex;
justify-content: center;
align-items: center;
.uni-icons {
padding: 8rpx;
border-radius: 8rpx;
transition: all 0.3s ease;
&:active {
transform: scale(0.9);
opacity: 0.8;
}
}
}
// 选择区域
.select-area {
padding: 24rpx 0;
border-bottom: 2rpx solid #f5f5f5;
}
// // 表格区域
// .table-area {
// margin-top: 24rpx;
// margin: 24rpx -32rpx 0;
// overflow-x: auto;
// :deep(.uni-table) {
// width: 1080rpx;
// padding: 0 10rpx;
// .uni-table-tr {
// .uni-table-th {
// min-width: 140rpx;
// &:last-child {
// min-width: 120rpx;
// }
// }
// .uni-table-td {
// .action-btn {
// display: inline-flex;
// padding: 12rpx;
// border-radius: 8rpx;
// transition: all 0.3s ease;
// margin: 0 8rpx;
// &:active {
// background-color: rgba(0, 0, 0, 0.05);
// }
// &.delete:active {
// background-color: rgba(255, 77, 79, 0.05);
// }
// }
// }
// }
// }
// }
}
// 底部按钮
.footer-btn {
margin-top: auto;
padding: 32rpx;
background: #fff;
box-shadow: 0 -4rpx 16rpx rgba(0, 0, 0, 0.05);
.btn-cont {
width: 100%;
height: 88rpx;
line-height: 88rpx;
text-align: center;
background: linear-gradient(135deg, #4b8eff 0%, #3784fb 100%);
color: #fff;
border-radius: 44rpx;
font-size: 32rpx;
font-weight: 600;
box-shadow: 0 6rpx 20rpx rgba(55, 132, 251, 0.2);
transition: all 0.3s ease;
&:active {
transform: scale(0.98);
opacity: 0.9;
box-shadow: 0 2rpx 8rpx rgba(55, 132, 251, 0.2);
}
}
}
}
// 上传区域样式
.upload {
width: 160rpx;
height: 160rpx;
background-color: #f7f8fa;
border: 2rpx dashed #d9d9d9;
border-radius: 12rpx;
display: flex;
justify-content: center;
align-items: center;
font-size: 48rpx;
color: #bfbfbf;
transition: all 0.3s ease;
&:active {
background-color: #f0f0f0;
border-color: #3784fb;
}
image {
width: 100%;
height: 100%;
border-radius: 12rpx;
object-fit: cover;
}
}
.image-container {
position: relative;
display: inline-block;
}
.delete-logo {
position: absolute;
top: 5px;
right: 5px;
font-size: 20px;
color: white;
background-color: rgba(0, 0, 0, 0.5);
border-radius: 50%;
width: 20px;
height: 20px;
line-height: 20px;
text-align: center;
cursor: pointer;
}
</style>