|
|
@@ -1,17 +1,13 @@
|
|
|
<script lang="ts" setup>
|
|
|
-import { addQuestionReportData,REPORTDATA, getQuestionTypeList, pageQuestionReportData,getPerson } from '@/api/questionReqort'
|
|
|
-import { AddQuestionReportDataReq, PageQuestionReportDataReq, QuestionListRes, QuestionType, QuestionTypeListRes } from '@/api/questionReqort/types'
|
|
|
-import type { ApiResponse, PageResp } from '@/api/types'
|
|
|
+import { addQuestionReportData, getQuestionTypeList, pageQuestionReportData,getPerson } from '@/api/questionReqort'
|
|
|
+import { AddQuestionReportDataReq, PageQuestionReportDataReq, QuestionListRes, QuestionType } from '@/api/questionReqort/types'
|
|
|
import { getCachedWecomVisitorProfile, getWecomInternalUser } from '@/api/wecom'
|
|
|
-import { computed, onMounted, ref, watch } from 'vue'
|
|
|
+import { onMounted, ref, watch } from 'vue'
|
|
|
import GridAddress from '@/components/address/gridAddress/index.vue'
|
|
|
import { showNotify } from 'vant'
|
|
|
-import dayjs from 'dayjs';
|
|
|
import { onLoad } from '@dcloudio/uni-app'
|
|
|
-import useUserState from '@/store/userState'
|
|
|
|
|
|
const active = ref(0)
|
|
|
-const userState = useUserState()
|
|
|
|
|
|
interface ReportFormData extends AddQuestionReportDataReq {
|
|
|
location?: string
|
|
|
@@ -48,7 +44,8 @@ const createInitialFormData = (): ReportFormData => ({
|
|
|
|
|
|
const formData = ref<ReportFormData>(createInitialFormData())
|
|
|
const range = ref<{ text: string; value: string }[]>([])
|
|
|
-const rangePerson = ref([]) as any
|
|
|
+const submitting = ref(false)
|
|
|
+const mobileRegex = /^1[3-9]\d{9}$/
|
|
|
|
|
|
const rules = ref({
|
|
|
questionType: [{ required: true, message: '请选择类型' }],
|
|
|
@@ -67,12 +64,14 @@ const handleAddressFinish = async(value: AddressSelection) => {
|
|
|
formData.value.chargerCode = ''
|
|
|
formData.value.addrName = value.selectedOptions[value.tabIndex]?.areaName || ''
|
|
|
addressList.value = value
|
|
|
- const { data } = await getPerson({parentCode:value.value})
|
|
|
- personData.value = (data || []) as GridPerson[]
|
|
|
- rangePerson.value = personData.value.map((item) => ({
|
|
|
- text: item.areaName,
|
|
|
- value: item.areaName,
|
|
|
- }))
|
|
|
+ try {
|
|
|
+ const { data } = await getPerson({parentCode:value.value})
|
|
|
+ personData.value = (data || []) as GridPerson[]
|
|
|
+ } catch (e) {
|
|
|
+ personData.value = []
|
|
|
+ showNotify('获取网格员失败,请稍后重试')
|
|
|
+ console.error('获取网格员失败:', e)
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/* 获取群主手机号 */
|
|
|
@@ -84,6 +83,7 @@ onLoad((option) => {
|
|
|
})
|
|
|
const ownerPhone = ref('')
|
|
|
const visitorPhone = ref('')
|
|
|
+const listContactPerson = ref('')
|
|
|
|
|
|
const fillVisitorName = () => {
|
|
|
const profile = getCachedWecomVisitorProfile()
|
|
|
@@ -91,6 +91,7 @@ const fillVisitorName = () => {
|
|
|
|
|
|
visitorPhone.value = profile.mobile || ''
|
|
|
formData.value.contactPerson = profile.name
|
|
|
+ listContactPerson.value = profile.name
|
|
|
}
|
|
|
|
|
|
const fillVisitorPhone = () => {
|
|
|
@@ -115,6 +116,7 @@ const getOwnerPhone = async () => {
|
|
|
}
|
|
|
|
|
|
const submit = async () => {
|
|
|
+ if (submitting.value) return
|
|
|
console.log(`output->formData.value`,formData.value)
|
|
|
if (!formData.value.questionType) {
|
|
|
showNotify('请选择问题类型')
|
|
|
@@ -132,80 +134,55 @@ const submit = async () => {
|
|
|
showNotify('请输入联系人电话')
|
|
|
return
|
|
|
}
|
|
|
+ if (!mobileRegex.test(formData.value.contactPhone)) {
|
|
|
+ showNotify('请输入正确的手机号')
|
|
|
+ return
|
|
|
+ }
|
|
|
if (!addressList.value || addressList.value.selectedOptions.length === 0) {
|
|
|
showNotify('请选择所在地')
|
|
|
return
|
|
|
}
|
|
|
- formData.value.chargerCode = personData.value.find(
|
|
|
- item => item.areaName === formData.value.chargerName
|
|
|
- )?.areaCode || '' // 添加兜底处理
|
|
|
- formData.value.contactPersonPhone = formData.value.contactPhone || ''
|
|
|
- console.log('formData.value',formData.value)
|
|
|
-
|
|
|
- /* 获取群主手机号(不阻塞流程,报错也继续执行) */
|
|
|
+ submitting.value = true
|
|
|
try {
|
|
|
- await getOwnerPhone();
|
|
|
- } catch (e) {
|
|
|
- console.error('获取群主手机号失败:', e);
|
|
|
- }
|
|
|
- const { data } = await addQuestionReportData({
|
|
|
- ...formData.value,
|
|
|
- ...(ownerPhone.value ? { ownerPhone: ownerPhone.value } : {}),
|
|
|
- // personList:formData.value.person1+','+formData.value.person2,
|
|
|
- streetCode: addressList.value.selectedOptions[1] ? addressList.value.selectedOptions[1].areaCode : '',
|
|
|
- streetName: addressList.value.selectedOptions[1] ? addressList.value.selectedOptions[1].areaName : '',
|
|
|
- communityCode: addressList.value.selectedOptions[2] ? addressList.value.selectedOptions[2].areaCode : '',
|
|
|
- communityName: addressList.value.selectedOptions[2] ? addressList.value.selectedOptions[2].areaName : '',
|
|
|
- grid: addressList.value.selectedOptions[3] ? addressList.value.selectedOptions[3].areaCode : '',
|
|
|
- gridName: addressList.value.selectedOptions[3] ? addressList.value.selectedOptions[3].areaName : '',
|
|
|
- })
|
|
|
- if (data) {
|
|
|
- uni.showToast({
|
|
|
- title: '上报成功',
|
|
|
- icon: 'success',
|
|
|
- duration: 1000,
|
|
|
- })
|
|
|
- formData.value = createInitialFormData()
|
|
|
- visitorPhone.value = ''
|
|
|
- addressList.value = null
|
|
|
- data.districtCode = '330205'
|
|
|
- data.districtName = '江北区'
|
|
|
- // reportCY(data)
|
|
|
- }
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
-// 上报到城运
|
|
|
-const reportCY = async (params:any) => {
|
|
|
- const { data } = await REPORTDATA({
|
|
|
- data:{
|
|
|
- otherTaskNum:params.uuid.replace(/-/g,''),
|
|
|
- // eventTitle:params.questionTitle,
|
|
|
- eventDesc:params.questionContent,
|
|
|
- eventTypeCode:'109000',
|
|
|
- eventTypeName:'民事纠纷',
|
|
|
- subTypeCode:'109002',
|
|
|
- subTypeName:'邻里纠纷',
|
|
|
- reportTime: dayjs(new Date()).format('YYYY-MM-DD HH:mm:ss'),
|
|
|
- reporter:params.contactPerson,
|
|
|
- address:params.districtName+params.streetName+params.communityName,
|
|
|
-
|
|
|
- districtCode:'330205',
|
|
|
- districtName:'江北区',
|
|
|
- gridCode:params.grid,
|
|
|
- gridName:params.gridName,
|
|
|
- communityCode:params.communityCode,
|
|
|
- communityName:params.communityName,
|
|
|
- streetCode:params.streetCode,
|
|
|
- streetName:params.streetName,
|
|
|
- },
|
|
|
- dataId:params.uuid.replace(/-/g,''),
|
|
|
- dataType:'main',
|
|
|
- timestamp:new Date().getTime(),
|
|
|
- })
|
|
|
- console.log(data)
|
|
|
- if (data.code== '200'){
|
|
|
+ formData.value.chargerCode = personData.value.find(
|
|
|
+ item => item.areaName === formData.value.chargerName
|
|
|
+ )?.areaCode || '' // 添加兜底处理
|
|
|
+ formData.value.contactPersonPhone = formData.value.contactPhone || ''
|
|
|
+ console.log('formData.value',formData.value)
|
|
|
+
|
|
|
+ /* 获取群主手机号(不阻塞流程,报错也继续执行) */
|
|
|
+ try {
|
|
|
+ await getOwnerPhone();
|
|
|
+ } catch (e) {
|
|
|
+ console.error('获取群主手机号失败:', e);
|
|
|
+ }
|
|
|
|
|
|
+ const { data } = await addQuestionReportData({
|
|
|
+ ...formData.value,
|
|
|
+ ...(ownerPhone.value ? { ownerPhone: ownerPhone.value } : {}),
|
|
|
+ // personList:formData.value.person1+','+formData.value.person2,
|
|
|
+ streetCode: addressList.value.selectedOptions[1] ? addressList.value.selectedOptions[1].areaCode : '',
|
|
|
+ streetName: addressList.value.selectedOptions[1] ? addressList.value.selectedOptions[1].areaName : '',
|
|
|
+ communityCode: addressList.value.selectedOptions[2] ? addressList.value.selectedOptions[2].areaCode : '',
|
|
|
+ communityName: addressList.value.selectedOptions[2] ? addressList.value.selectedOptions[2].areaName : '',
|
|
|
+ grid: addressList.value.selectedOptions[3] ? addressList.value.selectedOptions[3].areaCode : '',
|
|
|
+ gridName: addressList.value.selectedOptions[3] ? addressList.value.selectedOptions[3].areaName : '',
|
|
|
+ })
|
|
|
+ if (data) {
|
|
|
+ uni.showToast({
|
|
|
+ title: '上报成功',
|
|
|
+ icon: 'success',
|
|
|
+ duration: 1000,
|
|
|
+ })
|
|
|
+ formData.value = createInitialFormData()
|
|
|
+ visitorPhone.value = ''
|
|
|
+ addressList.value = null
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ showNotify('提交失败,请稍后重试')
|
|
|
+ console.error('提交失败:', e)
|
|
|
+ } finally {
|
|
|
+ submitting.value = false
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -228,36 +205,6 @@ const listLoadVersion = ref(0)
|
|
|
/** 合并并发 init,避免 watch 与重复进入导致多次 reset/请求交错 */
|
|
|
let listInitPromise: Promise<void> | null = null
|
|
|
|
|
|
-/** 列表接口调试:最近一次请求参数与完整响应 */
|
|
|
-const showListRawJsonPopup = ref(false)
|
|
|
-const showApiFullUrlPopup = ref(false)
|
|
|
-const listLastReqParams = ref<PageQuestionReportDataReq | null>(null)
|
|
|
-const listLastApiResponse = ref<ApiResponse<PageResp<QuestionListRes>> | null>(null)
|
|
|
-
|
|
|
-const listReqParamsJson = computed(() => {
|
|
|
- if (!listLastReqParams.value) return '{}'
|
|
|
- return JSON.stringify(listLastReqParams.value, null, 2)
|
|
|
-})
|
|
|
-
|
|
|
-const listApiRawJson = computed(() => {
|
|
|
- if (!listLastApiResponse.value) return '{}'
|
|
|
- return JSON.stringify(listLastApiResponse.value, null, 2)
|
|
|
-})
|
|
|
-
|
|
|
-const httpsOrigin = computed(() => {
|
|
|
- if (typeof window === 'undefined') return ''
|
|
|
- const host = window.location.host || ''
|
|
|
- return host ? `https://${host}` : ''
|
|
|
-})
|
|
|
-
|
|
|
-const listApiFullUrl = computed(() => `${httpsOrigin.value}/api/questionReport/pageQuestionReportData`)
|
|
|
-const detailApiFullUrl = computed(() => `${httpsOrigin.value}/api/questionReport/detailsQuestionReportData/{id}`)
|
|
|
-const currentPageUrl = computed(() => {
|
|
|
- if (typeof window === 'undefined') return ''
|
|
|
- return window.location.href || ''
|
|
|
-})
|
|
|
-const detailPageUrl = computed(() => `${httpsOrigin.value}/subPages/pages/reportProblems/detail?id={id}`)
|
|
|
-
|
|
|
const resetQuestionList = () => {
|
|
|
list.value = []
|
|
|
pageInfo.value.pageNumber = 1
|
|
|
@@ -269,6 +216,11 @@ const resetQuestionList = () => {
|
|
|
|
|
|
const questList = async () => {
|
|
|
if (listRequesting.value || finished.value) return
|
|
|
+ if (!listContactPerson.value) {
|
|
|
+ finished.value = true
|
|
|
+ showNotify('未获取到当前登录用户信息,无法查询问题答复')
|
|
|
+ return
|
|
|
+ }
|
|
|
|
|
|
const requestVersion = listLoadVersion.value
|
|
|
listRequesting.value = true
|
|
|
@@ -278,13 +230,11 @@ const questList = async () => {
|
|
|
const reqParams: PageQuestionReportDataReq = {
|
|
|
pageNumber: currentPage,
|
|
|
pageSize: pageInfo.value.pageSize,
|
|
|
- contactPerson: formData.value.contactPerson || '',
|
|
|
+ contactPerson: listContactPerson.value,
|
|
|
}
|
|
|
const res = await pageQuestionReportData(reqParams)
|
|
|
if (requestVersion !== listLoadVersion.value) return
|
|
|
|
|
|
- listLastReqParams.value = reqParams
|
|
|
- listLastApiResponse.value = res
|
|
|
const records = res.data.records || []
|
|
|
|
|
|
list.value = currentPage === 1 ? records : list.value.concat(records)
|
|
|
@@ -316,7 +266,7 @@ const handleGoDetail = (item: QuestionListRes) => {
|
|
|
}
|
|
|
|
|
|
const areaShow = ref(false)
|
|
|
-const hanleSelectArea = () => {
|
|
|
+const handleSelectArea = () => {
|
|
|
areaShow.value = true
|
|
|
}
|
|
|
|
|
|
@@ -329,7 +279,6 @@ const changeQuestionType = (e: any) => {
|
|
|
formData.value.contactPersonPhone = contactPersonPhone
|
|
|
addressList.value = null
|
|
|
personData.value = []
|
|
|
- rangePerson.value = []
|
|
|
areaShow.value = false
|
|
|
}
|
|
|
|
|
|
@@ -337,20 +286,26 @@ onMounted(async () => {
|
|
|
fillVisitorName()
|
|
|
|
|
|
// 问题类型下拉
|
|
|
- const { data } = await getQuestionTypeList({
|
|
|
- page: 1,
|
|
|
- limit: 9999,
|
|
|
- category: QuestionType.QUESTION,
|
|
|
- })
|
|
|
- if (data.records) {
|
|
|
- range.value = data.records.map((item) => {
|
|
|
- return {
|
|
|
- text: item.typeName,
|
|
|
- value: item.typeName,
|
|
|
- }
|
|
|
+ try {
|
|
|
+ const { data } = await getQuestionTypeList({
|
|
|
+ page: 1,
|
|
|
+ limit: 9999,
|
|
|
+ category: QuestionType.QUESTION,
|
|
|
})
|
|
|
- } else {
|
|
|
+ if (data.records) {
|
|
|
+ range.value = data.records.map((item) => {
|
|
|
+ return {
|
|
|
+ text: item.typeName,
|
|
|
+ value: item.typeName,
|
|
|
+ }
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ range.value = []
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
range.value = []
|
|
|
+ showNotify('获取问题类型失败,请稍后重试')
|
|
|
+ console.error('获取问题类型失败:', e)
|
|
|
}
|
|
|
})
|
|
|
|
|
|
@@ -386,17 +341,13 @@ watch(active, async (value) => {
|
|
|
</uni-forms-item>
|
|
|
<!-- 问题所在地 -->
|
|
|
<uni-forms-item label="所在地" required name="addrName">
|
|
|
- <uni-easyinput v-model="formData.addrName" placeholder="请选择所在地" @focus="hanleSelectArea"></uni-easyinput>
|
|
|
+ <uni-easyinput v-model="formData.addrName" placeholder="请选择所在地" @focus="handleSelectArea"></uni-easyinput>
|
|
|
<GridAddress v-model="areaShow" @finish="handleAddressFinish"></GridAddress>
|
|
|
</uni-forms-item>
|
|
|
<!-- 详细地址-->
|
|
|
<uni-forms-item label="详细位置" name="addrDetailName">
|
|
|
<uni-easyinput v-model="formData.addrDetailName" placeholder="请输入"></uni-easyinput>
|
|
|
</uni-forms-item>
|
|
|
- <!-- 负责人下拉 -->
|
|
|
- <!-- <uni-forms-item label="负责人" required name="person">
|
|
|
- <uni-data-select v-model="formData.chargerName" :localdata="rangePerson"></uni-data-select>
|
|
|
- </uni-forms-item> -->
|
|
|
<!-- 联系人姓名 -->
|
|
|
<uni-forms-item label="您的姓名" required name="contactPerson">
|
|
|
<uni-easyinput v-model="formData.contactPerson" placeholder="请输入"></uni-easyinput>
|
|
|
@@ -408,15 +359,11 @@ watch(active, async (value) => {
|
|
|
</view>
|
|
|
</uni-forms-item>
|
|
|
</uni-forms>
|
|
|
- <van-button class="w-full mb-3" type="primary" @click="submit">提交</van-button>
|
|
|
+ <van-button class="w-full mb-3" type="primary" :loading="submitting" :disabled="submitting" @click="submit">提交</van-button>
|
|
|
</view>
|
|
|
</van-tab>
|
|
|
<van-tab title="问题答复">
|
|
|
<view class="tab-container">
|
|
|
- <view class="mb-[8px]">
|
|
|
- <van-button size="small" plain type="primary" @click="showListRawJsonPopup = true">查看接口原始JSON</van-button>
|
|
|
- <van-button class="ml-[8px]" size="small" plain type="primary" @click="showApiFullUrlPopup = true">查看完整访问地址</van-button>
|
|
|
- </view>
|
|
|
<van-list
|
|
|
v-model:loading="loading"
|
|
|
:finished="finished"
|
|
|
@@ -443,52 +390,6 @@ watch(active, async (value) => {
|
|
|
</view>
|
|
|
</view>
|
|
|
</van-list>
|
|
|
- <van-popup
|
|
|
- v-model:show="showListRawJsonPopup"
|
|
|
- round
|
|
|
- position="bottom"
|
|
|
- :style="{ height: '75%' }"
|
|
|
- >
|
|
|
- <view class="json-popup">
|
|
|
- <view class="json-title">请求参数</view>
|
|
|
- <scroll-view scroll-y class="json-scroll json-scroll--small">
|
|
|
- <text class="json-text">{{ listReqParamsJson }}</text>
|
|
|
- </scroll-view>
|
|
|
- <view class="json-title">列表接口完整JSON</view>
|
|
|
- <scroll-view scroll-y class="json-scroll">
|
|
|
- <text class="json-text">{{ listApiRawJson }}</text>
|
|
|
- </scroll-view>
|
|
|
- </view>
|
|
|
- </van-popup>
|
|
|
- <van-popup
|
|
|
- v-model:show="showApiFullUrlPopup"
|
|
|
- round
|
|
|
- position="bottom"
|
|
|
- :style="{ height: '55%' }"
|
|
|
- >
|
|
|
- <view class="json-popup">
|
|
|
- <view class="json-title">当前HTTPS域名</view>
|
|
|
- <scroll-view scroll-y class="json-scroll json-scroll--small">
|
|
|
- <text class="json-text">{{ httpsOrigin || '当前环境未获取到浏览器域名' }}</text>
|
|
|
- </scroll-view>
|
|
|
- <view class="json-title">问题答复列表接口</view>
|
|
|
- <scroll-view scroll-y class="json-scroll json-scroll--small">
|
|
|
- <text class="json-text">{{ listApiFullUrl }}</text>
|
|
|
- </scroll-view>
|
|
|
- <view class="json-title">详情接口</view>
|
|
|
- <scroll-view scroll-y class="json-scroll">
|
|
|
- <text class="json-text">{{ detailApiFullUrl }}</text>
|
|
|
- </scroll-view>
|
|
|
- <view class="json-title">当前页面访问地址</view>
|
|
|
- <scroll-view scroll-y class="json-scroll json-scroll--small">
|
|
|
- <text class="json-text">{{ currentPageUrl || '当前环境未获取到页面地址' }}</text>
|
|
|
- </scroll-view>
|
|
|
- <view class="json-title">详情页访问地址</view>
|
|
|
- <scroll-view scroll-y class="json-scroll">
|
|
|
- <text class="json-text">{{ detailPageUrl }}</text>
|
|
|
- </scroll-view>
|
|
|
- </view>
|
|
|
- </van-popup>
|
|
|
</view>
|
|
|
</van-tab>
|
|
|
</van-tabs>
|
|
|
@@ -507,9 +408,6 @@ watch(active, async (value) => {
|
|
|
box-sizing: border-box;
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
- > uni-view:first-child {
|
|
|
- flex: 1;
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
.contact-phone-field {
|
|
|
@@ -546,6 +444,7 @@ watch(active, async (value) => {
|
|
|
display: -webkit-box; /* 将对象作为弹性伸缩盒子模型显示 */
|
|
|
-webkit-box-orient: vertical; /* 设置或检索伸缩盒对象的子元素的排列方式 */
|
|
|
-webkit-line-clamp: 3; /* 限制在一个块元素显示的文本的行数 */
|
|
|
+ line-clamp: 3;
|
|
|
overflow: hidden; /* 隐藏溢出的内容 */
|
|
|
}
|
|
|
.type {
|
|
|
@@ -554,38 +453,4 @@ watch(active, async (value) => {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-.json-popup {
|
|
|
- height: 100%;
|
|
|
- display: flex;
|
|
|
- flex-direction: column;
|
|
|
- padding: 12px;
|
|
|
-}
|
|
|
-
|
|
|
-.json-title {
|
|
|
- font-size: 16px;
|
|
|
- font-weight: 500;
|
|
|
- margin-bottom: 10px;
|
|
|
-}
|
|
|
-
|
|
|
-.json-scroll {
|
|
|
- flex: 1;
|
|
|
- overflow: hidden;
|
|
|
- background: #f7f8fa;
|
|
|
- border-radius: 8px;
|
|
|
- padding: 12px;
|
|
|
-}
|
|
|
-
|
|
|
-.json-scroll--small {
|
|
|
- flex: 0 0 auto;
|
|
|
- max-height: 120px;
|
|
|
- margin-bottom: 10px;
|
|
|
-}
|
|
|
-
|
|
|
-.json-text {
|
|
|
- white-space: pre-wrap;
|
|
|
- word-break: break-all;
|
|
|
- font-size: 13px;
|
|
|
- line-height: 20px;
|
|
|
-}
|
|
|
-
|
|
|
</style>
|