lcw
This commit is contained in:
25540
package-lock.json
generated
25540
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -52,6 +52,10 @@
|
|||||||
"xlsx": "^0.18.5"
|
"xlsx": "^0.18.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@babel/core": "^7.29.0",
|
||||||
|
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6",
|
||||||
|
"@babel/plugin-proposal-optional-chaining": "^7.21.0",
|
||||||
|
"@babel/preset-env": "^7.29.2",
|
||||||
"@element-plus/icons": "^0.0.11",
|
"@element-plus/icons": "^0.0.11",
|
||||||
"@toast-ui/editor": "^3.0.2",
|
"@toast-ui/editor": "^3.0.2",
|
||||||
"@vue/cli-plugin-babel": "~4.5.0",
|
"@vue/cli-plugin-babel": "~4.5.0",
|
||||||
|
|||||||
@ -155,7 +155,7 @@ header {
|
|||||||
}
|
}
|
||||||
|
|
||||||
&::v-deep .el-form-item--default {
|
&::v-deep .el-form-item--default {
|
||||||
width: 23%;
|
// width: 23%;
|
||||||
padding-bottom: 20px;
|
padding-bottom: 20px;
|
||||||
margin: 0 1%;
|
margin: 0 1%;
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
src/assets/images/01.mp3
Normal file
BIN
src/assets/images/01.mp3
Normal file
Binary file not shown.
BIN
src/assets/images/02.mp3
Normal file
BIN
src/assets/images/02.mp3
Normal file
Binary file not shown.
BIN
src/assets/images/03.mp3
Normal file
BIN
src/assets/images/03.mp3
Normal file
Binary file not shown.
BIN
src/assets/images/04.mp3
Normal file
BIN
src/assets/images/04.mp3
Normal file
Binary file not shown.
BIN
src/assets/images/05.mp3
Normal file
BIN
src/assets/images/05.mp3
Normal file
Binary file not shown.
BIN
src/assets/images/06.mp3
Normal file
BIN
src/assets/images/06.mp3
Normal file
Binary file not shown.
BIN
src/assets/images/07.mp3
Normal file
BIN
src/assets/images/07.mp3
Normal file
Binary file not shown.
BIN
src/assets/images/08.mp3
Normal file
BIN
src/assets/images/08.mp3
Normal file
Binary file not shown.
BIN
src/assets/images/09.mp3
Normal file
BIN
src/assets/images/09.mp3
Normal file
Binary file not shown.
BIN
src/assets/images/10.mp3
Normal file
BIN
src/assets/images/10.mp3
Normal file
Binary file not shown.
BIN
src/assets/images/11.mp3
Normal file
BIN
src/assets/images/11.mp3
Normal file
Binary file not shown.
BIN
src/assets/images/12.mp3
Normal file
BIN
src/assets/images/12.mp3
Normal file
Binary file not shown.
BIN
src/assets/images/13.mp3
Normal file
BIN
src/assets/images/13.mp3
Normal file
Binary file not shown.
BIN
src/assets/images/14.mp3
Normal file
BIN
src/assets/images/14.mp3
Normal file
Binary file not shown.
BIN
src/assets/images/16.mp3
Normal file
BIN
src/assets/images/16.mp3
Normal file
Binary file not shown.
@ -12,7 +12,7 @@
|
|||||||
<el-input-number v-model="listQuery[item.prop]" v-else-if="item.type == 'number'" :step="item.step || 1" style="width: 100%" :min="item.min || 0" :max="item.max || 1000" :disabled="item.disabled" />
|
<el-input-number v-model="listQuery[item.prop]" v-else-if="item.type == 'number'" :step="item.step || 1" style="width: 100%" :min="item.min || 0" :max="item.max || 1000" :disabled="item.disabled" />
|
||||||
|
|
||||||
<!--选择 select-->
|
<!--选择 select-->
|
||||||
<MOSTY.Select v-else-if="item.type == 'select'" filterable :multiple="item.multiple" v-model="listQuery[item.prop]" :dictEnum="item.options" width="100%" clearable :placeholder="`请选择${item.label}`" :disabled="item.disabled" />
|
<MOSTY.Select v-else-if="item.type == 'select'" :filterable="item.filterable" :multiple="item.multiple" v-model="listQuery[item.prop]" :dictEnum="item.options" width="100%" clearable :placeholder="`请选择${item.label}`" :disabled="item.disabled" />
|
||||||
|
|
||||||
<!-- 部门department -->
|
<!-- 部门department -->
|
||||||
<template v-else-if="item.type === 'department'">
|
<template v-else-if="item.type === 'department'">
|
||||||
|
|||||||
@ -30,20 +30,40 @@ const countdown = ref(0) // 倒计时时间(秒)
|
|||||||
|
|
||||||
// 音频播放器实例映射
|
// 音频播放器实例映射
|
||||||
const audioPlayers = ref({
|
const audioPlayers = ref({
|
||||||
|
'01': null, // 预警信息
|
||||||
'02': null, // 信息上报
|
'02': null, // 信息上报
|
||||||
'03': null, // 研判审批
|
'03': null, // 研判审批
|
||||||
'04': null, // 研判指令
|
'04': null, // 研判指令
|
||||||
'05': null, // 线索下发,
|
'05': null, // 线索下发,
|
||||||
'06': null, // 警情监测
|
'06': null, // 警情监测
|
||||||
|
'07': null, // 线索处理
|
||||||
|
'08': null, // 线索下发
|
||||||
|
'09': null, // 线索处理
|
||||||
|
'10': null, // 林安码
|
||||||
|
'11': null, // 发布了新的线索
|
||||||
|
'12': null, // 有新的研判指令
|
||||||
|
'13': null, // 有新的研判约稿通知
|
||||||
|
'14': null, // 有新的公文发布
|
||||||
|
'15': null, // 有新的待审核工作(补发音效)
|
||||||
})
|
})
|
||||||
|
|
||||||
// 音频文件路径映射
|
// 音频文件路径映射
|
||||||
const audioPaths = {
|
const audioPaths = {
|
||||||
'02': require('@/assets/images/cjyp.mp3'),
|
'01': require('@/assets/images/01.mp3'),//高级预计信息前置
|
||||||
'03': require('@/assets/images/ypbg.mp3'),
|
'02': require('@/assets/images/02.mp3'),//一般预警信息前置
|
||||||
'04': require('@/assets/images/ypzl.mp3'),
|
'03': require('@/assets/images/03.mp3'),//信息前置
|
||||||
'05': require('@/assets/images/xsyp.mp3'),
|
'04': require('@/assets/images/04.mp3'),//红色预警
|
||||||
'06': require('@/assets/images/jqjc.mp3')
|
'05': require('@/assets/images/05.mp3'),//新的重点人
|
||||||
|
'06': require('@/assets/images/06.mp3'),//一级临控预警
|
||||||
|
'07': require('@/assets/images/07.mp3'),//有新的布控预警情
|
||||||
|
'08': require('@/assets/images/08.mp3'),//有新的标签预警
|
||||||
|
'09': require('@/assets/images/09.mp3'),//信息汇聚系统有新信息
|
||||||
|
'10': require('@/assets/images/10.mp3'),//林安码
|
||||||
|
'11': require('@/assets/images/11.mp3'),//发布了新的线索
|
||||||
|
'12': require('@/assets/images/12.mp3'),//有新的研判指令
|
||||||
|
'13': require('@/assets/images/13.mp3'),//有新的研判约稿通知
|
||||||
|
'14': require('@/assets/images/14.mp3'),//有新的公文发布
|
||||||
|
'15': require('@/assets/images/16.mp3'),//有新的警情监测预警,请注意查收
|
||||||
}
|
}
|
||||||
|
|
||||||
// 初始化音频播放器
|
// 初始化音频播放器
|
||||||
@ -59,14 +79,85 @@ const initAudioPlayers = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 根据类型播放音频
|
// 根据类型播放音频
|
||||||
const playAudioByType = (type) => {
|
const playAudioByType = (val) => {
|
||||||
if (audioPlayers.value[type]) {
|
|
||||||
try {
|
|
||||||
audioPlayers.value[type].play()
|
switch (val.typeMasgeLx) {
|
||||||
} catch (error) {
|
case '01'://预警
|
||||||
console.error(`播放类型${type}的音频失败:`, error)
|
// 01 布控预警、02 七类重点人、03 政保
|
||||||
}
|
switch (val.yjlb) {
|
||||||
|
case '01':
|
||||||
|
switch (val.yjJb) {
|
||||||
|
case '01':
|
||||||
|
audioPlayers.value['01'].play()
|
||||||
|
audioPlayers.value['06'].play()
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
audioPlayers.value['02'].play()
|
||||||
|
audioPlayers.value['07'].play()
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case '02':
|
||||||
|
switch (val.yjJb) {
|
||||||
|
case '01':
|
||||||
|
audioPlayers.value['01'].play()
|
||||||
|
audioPlayers.value['04'].play()
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
audioPlayers.value['02'].play()
|
||||||
|
audioPlayers.value['05'].play()
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case '03':
|
||||||
|
break
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case '02'://信息汇聚
|
||||||
|
audioPlayers.value['03'].play()
|
||||||
|
audioPlayers.value['09'].play()
|
||||||
|
break
|
||||||
|
case '03'://约稿
|
||||||
|
audioPlayers.value['03'].play()
|
||||||
|
audioPlayers.value['13'].play()
|
||||||
|
break
|
||||||
|
case '04'://指令
|
||||||
|
audioPlayers.value['03'].play()
|
||||||
|
audioPlayers.value['12'].play()
|
||||||
|
break
|
||||||
|
case '05'://新线索
|
||||||
|
audioPlayers.value['03'].play()
|
||||||
|
audioPlayers.value['11'].play()
|
||||||
|
break
|
||||||
|
case '06'://监测
|
||||||
|
audioPlayers.value['02'].play()
|
||||||
|
audioPlayers.value['15'].play()
|
||||||
|
break
|
||||||
|
// case '07':
|
||||||
|
// audioPlayers.value['07'].play()
|
||||||
|
// break
|
||||||
|
case '08'://林安码
|
||||||
|
audioPlayers.value['03'].play()
|
||||||
|
audioPlayers.value['10'].play()
|
||||||
|
break
|
||||||
|
// case '10':
|
||||||
|
// audioPlayers.value['10'].play()
|
||||||
|
// break
|
||||||
|
default:
|
||||||
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// if (audioPlayers.value[type]) {
|
||||||
|
// try {
|
||||||
|
// audioPlayers.value[type].play()
|
||||||
|
// } catch (error) {
|
||||||
|
// console.error(`播放类型${type}的音频失败:`, error)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
// 手动关闭
|
// 手动关闭
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
@ -108,7 +199,7 @@ onMounted(() => {
|
|||||||
dataList.value = newsDate
|
dataList.value = newsDate
|
||||||
// dataList.value.unshift({...newsDate.data,typeMasgeLx:newsDate.type})
|
// dataList.value.unshift({...newsDate.data,typeMasgeLx:newsDate.type})
|
||||||
// 根据消息类型播放音频
|
// 根据消息类型播放音频
|
||||||
playAudioByType(newsDate[0].typeMasgeLx)
|
playAudioByType(newsDate[0])
|
||||||
resetCountdown()
|
resetCountdown()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -117,20 +208,19 @@ const idEntityCard = ref(getItem('idEntityCard'))
|
|||||||
const dataModel = () => {
|
const dataModel = () => {
|
||||||
qcckGet({}, '/mosty-gsxt/dsjJbxx/message').then(res => {
|
qcckGet({}, '/mosty-gsxt/dsjJbxx/message').then(res => {
|
||||||
if (res) {
|
if (res) {
|
||||||
const yjmasg = res.filter(item => item.type === '01')
|
// const yjmasg = res.filter(item => item.type === '01')
|
||||||
if (yjmasg.length > 0) {
|
// if (yjmasg.length > 0) {
|
||||||
emitter.emit('openYp', yjmasg[0].obj); // 触发音频播放
|
// emitter.emit('openYp', yjmasg[0].obj); // 触发音频播放
|
||||||
} else {
|
// }
|
||||||
const data = res.filter(item => item.sfzList.includes(idEntityCard.value))
|
const data = res.filter(item => item.sfzList.includes(idEntityCard.value))
|
||||||
const infoMasge = data.map(item => {
|
const infoMasge = data.map(item => {
|
||||||
return {
|
return {
|
||||||
...item.obj,
|
...item.obj,
|
||||||
typeMasgeLx: item.type
|
typeMasgeLx: item.type
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
console.log(infoMasge,"xxxxxxxxxxxx");
|
console.log(infoMasge, "xxxxxxxxxxxx");
|
||||||
emitter.emit('webSocketMessage', infoMasge)
|
emitter.emit('webSocketMessage', infoMasge)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
|
<div class="test-item" v-if="item.typeMasgeLx == '01'" @click="goDetail(item.id, item.typeMasgeLx, item)">
|
||||||
|
<div class="item-header">
|
||||||
|
<div class="item-title">{{ item.yjBt || '' }}</div>
|
||||||
|
<div class="item-type">{{ item.yjlb == '01' ? '布控预警' : item.yjlb == '02' ? '七类重点人' : '政保' }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="item-message">{{ item.yjNr }}</div>
|
||||||
|
<div class="item-time">{{ item.yjSj || '' }}</div>
|
||||||
|
</div>
|
||||||
<div class="test-item" v-if="item.typeMasgeLx == '02'" @click="goDetail(item.id, item.typeMasgeLx)">
|
<div class="test-item" v-if="item.typeMasgeLx == '02'" @click="goDetail(item.id, item.typeMasgeLx)">
|
||||||
<div class="item-header">
|
<div class="item-header">
|
||||||
<div class="item-title">{{ item.qbmc || '' }}</div>
|
<div class="item-title">{{ item.qbmc || '' }}</div>
|
||||||
@ -9,11 +17,11 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="test-item" v-if="item.typeMasgeLx == '03'" @click="goDetail(item.id, item.typeMasgeLx)">
|
<div class="test-item" v-if="item.typeMasgeLx == '03'" @click="goDetail(item.id, item.typeMasgeLx)">
|
||||||
<div class="item-header">
|
<div class="item-header">
|
||||||
<div class="item-title">{{ item.bgmc || '' }}</div>
|
<div class="item-title">{{ item.ypyt || '' }}</div>
|
||||||
<div class="item-type">{{ informationMap[item.typeMasgeLx] }}</div>
|
<div class="item-type">{{ informationMap[item.typeMasgeLx] }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="item-message" v-html="item.bgnr"></div>
|
<div class="item-message">{{ item.ssbm }}</div>
|
||||||
<div class="item-time">{{ item.xtCjsj || '' }}</div>
|
<div class="item-time">{{ item.ypsj || '' }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="test-item" v-if="item.typeMasgeLx == '04'" @click="goDetail(item.id, item.typeMasgeLx)">
|
<div class="test-item" v-if="item.typeMasgeLx == '04'" @click="goDetail(item.id, item.typeMasgeLx)">
|
||||||
<div class="item-header">
|
<div class="item-header">
|
||||||
@ -31,18 +39,27 @@
|
|||||||
<div class="item-message" v-html="item.zlnr"></div>
|
<div class="item-message" v-html="item.zlnr"></div>
|
||||||
<div class="item-time">{{ item.xtCjsj || '' }}</div>
|
<div class="item-time">{{ item.xtCjsj || '' }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="test-item" v-if="item.typeMasgeLx == '06'" @click="goDetail(item.id, item.typeMasgeLx)">
|
<div class="test-item" v-if="item.typeMasgeLx == '06'" @click="goDetail(item.id, item.typeMasgeLx)">
|
||||||
<div class="item-header">
|
<div class="item-header">
|
||||||
<div class="item-title">{{ item.gxdwmc || '' }}</div>
|
<div class="item-title">{{ item.gxdwmc || '' }}</div>
|
||||||
<div class="item-type">{{ informationMap[item.typeMasgeLx] }}</div>
|
<div class="item-type">{{ informationMap[item.typeMasgeLx] }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="item-message" >{{ item.bcjjnr }}</div>
|
<div class="item-message">{{ item.bcjjnr }}</div>
|
||||||
<div class="item-time">{{ item.bjsj || '' }}</div>
|
<div class="item-time">{{ item.bjsj || '' }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="test-item" v-if="item.typeMasgeLx == '08'" @click="goDetail(item.id, item.typeMasgeLx)">
|
||||||
|
<div class="item-header">
|
||||||
|
<div class="item-title">{{ item.qbmc || '' }}</div>
|
||||||
|
<div class="item-type">{{ informationMap[item.typeMasgeLx] }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="item-message">{{ item.qbnr }}</div>
|
||||||
|
<div class="item-time">{{ item.sxsbsj || '' }}</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
|
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
|
import emitter from "@/utils/eventBus.js"; // 导入
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
item: {
|
item: {
|
||||||
@ -51,32 +68,39 @@ const props = defineProps({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
const informationMap = {
|
const informationMap = {
|
||||||
'01': '报警信息',
|
'01': '预警信息',
|
||||||
'02': '信息上报',
|
'02': '信息上报',
|
||||||
'03': '研判审批',
|
'03': '研判约稿',
|
||||||
'04': '研判指令',
|
'04': '研判指令',
|
||||||
'05': '线索下发',
|
'05': '线索下发',
|
||||||
|
'06': '警情监测',
|
||||||
|
'08': '林安码信息',
|
||||||
}
|
}
|
||||||
const emit=defineEmits(['goDetail'])
|
const emit = defineEmits(['goDetail'])
|
||||||
const goDetail = (id, lx) => {
|
const goDetail = (id, lx, val) => {
|
||||||
let path = ''
|
let path = ''
|
||||||
switch (lx) {
|
switch (lx) {
|
||||||
|
case '01':
|
||||||
|
emitter.emit('openYp', val);
|
||||||
|
break;
|
||||||
case '02':
|
case '02':
|
||||||
path = '/InfoCollection'
|
path = '/InfoCollection'
|
||||||
break;
|
break;
|
||||||
case '03':
|
case '03':
|
||||||
path = '/strategicResearchs'
|
path = '/dataReduction'
|
||||||
break;
|
break;
|
||||||
default:
|
|
||||||
case '04':
|
case '04':
|
||||||
path = '/judgmentCommand'
|
path = '/judgmentCommand'
|
||||||
break;
|
break;
|
||||||
case '05':
|
case '05':
|
||||||
path = '/InstructionInformation'
|
path = '/InstructionInformation'
|
||||||
|
break;
|
||||||
|
case '06':
|
||||||
|
path = '/policeReport'
|
||||||
|
break;
|
||||||
|
case '08':
|
||||||
|
path = '/lamXs'
|
||||||
break;
|
break;
|
||||||
case '06':
|
|
||||||
path = '/policeReport'
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
router.push({
|
router.push({
|
||||||
path: path,
|
path: path,
|
||||||
|
|||||||
@ -29,8 +29,6 @@ const routes = computed(() => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
console.log(data);
|
|
||||||
|
|
||||||
return generateMenus(data);
|
return generateMenus(data);
|
||||||
});
|
});
|
||||||
if (!store.getters.token) {
|
if (!store.getters.token) {
|
||||||
|
|||||||
@ -918,10 +918,19 @@ export const publicRoutes = [
|
|||||||
|
|
||||||
// ]
|
// ]
|
||||||
// },
|
// },
|
||||||
|
// {
|
||||||
|
// path: "/forumPost2",
|
||||||
|
// name: "forumPost2",
|
||||||
|
// component: () => import("@/views/forumPost/index.vue"),
|
||||||
|
// meta: {
|
||||||
|
// title: "情报论坛",
|
||||||
|
// icon: "article-ranking"
|
||||||
|
// }
|
||||||
|
// },
|
||||||
{
|
{
|
||||||
path: "/forumPost",
|
path: "/forumPost",
|
||||||
name: "forumPost",
|
name: "forumPost",
|
||||||
component: () => import("@/views/forumPost/index.vue"),
|
component: () => import("@/views/backOfficeSystem/luntan/index.vue"),
|
||||||
meta: {
|
meta: {
|
||||||
title: "情报论坛",
|
title: "情报论坛",
|
||||||
icon: "article-ranking"
|
icon: "article-ranking"
|
||||||
|
|||||||
@ -7,10 +7,9 @@
|
|||||||
</Search>
|
</Search>
|
||||||
</div>
|
</div>
|
||||||
<!-- 表格 -->
|
<!-- 表格 -->
|
||||||
<div class="margTop">
|
<div class="margTop" style="padding: 0;">
|
||||||
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="pageData.tableHeight"
|
<WarnDataTable :data="pageData.tableData" :columns="pageData.tableColumn" :tableHeight="pageData.tableHeight"
|
||||||
:key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth"
|
:loading="pageData.tableConfiger.loading" @selection-change="chooseData">
|
||||||
@chooseData="chooseData">
|
|
||||||
<template #bqList="{ row }">
|
<template #bqList="{ row }">
|
||||||
<ul>
|
<ul>
|
||||||
<li class="one_text_detail marks mb4" :key="index" v-for="(item, index) in row.bqList">{{ item.bqMc }}({{
|
<li class="one_text_detail marks mb4" :key="index" v-for="(item, index) in row.bqList">{{ item.bqMc }}({{
|
||||||
@ -20,9 +19,7 @@
|
|||||||
<template #ryXb="{ row }">
|
<template #ryXb="{ row }">
|
||||||
<DictTag :tag="false" :value="row.ryXb" :options="D_BZ_XB" />
|
<DictTag :tag="false" :value="row.ryXb" :options="D_BZ_XB" />
|
||||||
</template>
|
</template>
|
||||||
<template #ryJg="{ row }">
|
|
||||||
<DictTag :tag="false" :value="row.ryJg" :options="D_BZ_XZQHDM" />
|
|
||||||
</template>
|
|
||||||
<template #ryMz="{ row }">
|
<template #ryMz="{ row }">
|
||||||
<DictTag :tag="false" :value="row.ryMz" :options="D_BZ_MZ" />
|
<DictTag :tag="false" :value="row.ryMz" :options="D_BZ_MZ" />
|
||||||
</template>
|
</template>
|
||||||
@ -47,12 +44,13 @@
|
|||||||
|
|
||||||
<!-- 操作 -->
|
<!-- 操作 -->
|
||||||
<template #controls="{ row }">
|
<template #controls="{ row }">
|
||||||
<el-link size="small" type="success" @click="handleSend(row.id)">移入</el-link>
|
<el-link size="small" type="success" @click="handleSend(row.id)">移入重点人</el-link>
|
||||||
|
<el-link size="small" type="success" @click="handleMoveToFocus(row.id)">移入关注库</el-link>
|
||||||
<el-link size="small" type="primary" @click="addEdit('edit', row)">编辑</el-link>
|
<el-link size="small" type="primary" @click="addEdit('edit', row)">编辑</el-link>
|
||||||
<el-link size="small" type="danger" @click="deleteRow(row.id)" v-if="isShiQzDelet">删除</el-link>
|
<el-link size="small" type="danger" @click="deleteRow(row.id)" v-if="isShiQzDelet">删除</el-link>
|
||||||
<el-link size="small" type="primary" @click="addEdit('detail', row)">详情</el-link>
|
<el-link size="small" type="primary" @click="addEdit('detail', row)">详情</el-link>
|
||||||
</template>
|
</template>
|
||||||
</MyTable>
|
</WarnDataTable>
|
||||||
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="pageData.tableHeight" :pageConfiger="{
|
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="pageData.tableHeight" :pageConfiger="{
|
||||||
...pageData.pageConfiger,
|
...pageData.pageConfiger,
|
||||||
total: pageData.total
|
total: pageData.total
|
||||||
@ -68,7 +66,7 @@
|
|||||||
import { ElMessage } from "element-plus";
|
import { ElMessage } from "element-plus";
|
||||||
import ChooseUser from "@/components/ChooseList/ChooseUser/index.vue";
|
import ChooseUser from "@/components/ChooseList/ChooseUser/index.vue";
|
||||||
import PageTitle from "@/components/aboutTable/PageTitle.vue";
|
import PageTitle from "@/components/aboutTable/PageTitle.vue";
|
||||||
import MyTable from "@/components/aboutTable/MyTable.vue";
|
import WarnDataTable from "@/views/backOfficeSystem/ces/components/WarnDataTable.vue";
|
||||||
import Pages from "@/components/aboutTable/Pages.vue";
|
import Pages from "@/components/aboutTable/Pages.vue";
|
||||||
import Search from "@/components/aboutTable/Search.vue";
|
import Search from "@/components/aboutTable/Search.vue";
|
||||||
import AddForm from "@/views/backOfficeSystem/DeploymentDisposal/mpvPeo/components/addForm.vue";
|
import AddForm from "@/views/backOfficeSystem/DeploymentDisposal/mpvPeo/components/addForm.vue";
|
||||||
@ -127,17 +125,18 @@ const pageData = reactive({
|
|||||||
pageSize: 20,
|
pageSize: 20,
|
||||||
pageCurrent: 1
|
pageCurrent: 1
|
||||||
},
|
},
|
||||||
controlsWidth: 150,
|
controlsWidth: 340,
|
||||||
tableColumn: [
|
tableColumn: [
|
||||||
{ label: "姓名", prop: "ryXm", width: 150 },
|
{ label: "姓名", prop: "ryXm", width: 150 },
|
||||||
{ label: "性别", prop: "ryXb", showSolt: true, width: 100 },
|
{ label: "性别", prop: "ryXb", slotName: "ryXb" },
|
||||||
{ label: "籍贯", prop: "ryJg", showSolt: true, width: 100 },
|
{ label: "籍贯", prop: "ryJg", width: 100 },
|
||||||
{ label: "身份证", prop: "rySfzh", width: 200 },
|
{ label: "身份证", prop: "rySfzh", width: 200 },
|
||||||
{ label: "民族", prop: "ryMz", showSolt: true, width: 100 },
|
{ label: "民族", prop: "ryMz", slotName: "ryMz" },
|
||||||
{ label: "户籍地区划", prop: "hjdQh", showSolt: true, width: 150 },
|
{ label: "户籍地区划", prop: "hjdQh", width: 150, slotName: "hjdQh" },
|
||||||
{ label: "户籍派出所", prop: "hjdPcsmc", width: 200 },
|
{ label: "户籍派出所", prop: "hjdPcsmc" },
|
||||||
{ label: "户籍地详址", prop: "hjdXz", width: 200 },
|
{ label: "户籍地详址", prop: "hjdXz", width: 200 },
|
||||||
{ label: "审核状态", prop: "zdrZt", showSolt: true },
|
{ label: "审核状态", prop: "zdrZt", slotName: "zdrZt" },
|
||||||
|
{ label: "操作", prop: "controls", slotName: "controls", width: 280 },
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
const isShiQzDelet = ref(false)
|
const isShiQzDelet = ref(false)
|
||||||
@ -188,7 +187,14 @@ const handleSend = (id) => {
|
|||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleMoveToFocus = (id) => {
|
||||||
|
proxy.$confirm("确定要移至关注库?", "警告", { type: "warning" }).then(() => {
|
||||||
|
qcckPost({ id, rylx: '03' }, "/mosty-gsxt/tbGsxtZdry/rylxyd").then(() => {
|
||||||
|
proxy.$message({ type: "success", message: "移除成功" });
|
||||||
|
getList();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}
|
||||||
const chooseData = (data) => {
|
const chooseData = (data) => {
|
||||||
ids.value = Array.isArray(data) ? data.map((item) => item.id) : [];
|
ids.value = Array.isArray(data) ? data.map((item) => item.id) : [];
|
||||||
choosList.value = Array.isArray(data) ? data : [];
|
choosList.value = Array.isArray(data) ? data : [];
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<!-- 搜索 -->
|
<!-- 搜索 -->
|
||||||
<div ref="searchBox" class="mt10">
|
<div ref="searchBox" class="mt10">
|
||||||
<Search :searchArr="searchConfiger" @submit="onSearch" >
|
<Search :searchArr="searchConfiger" @submit="onSearch">
|
||||||
<el-button type="primary" size="small" @click="addEdit('add', '')">
|
<el-button type="primary" size="small" @click="addEdit('add', '')">
|
||||||
<el-icon style="vertical-align: middle">
|
<el-icon style="vertical-align: middle">
|
||||||
<CirclePlus />
|
<CirclePlus />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
@ -13,10 +13,9 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 表格 -->
|
<!-- 表格 -->
|
||||||
<div class="margTop">
|
<div class="margTop" style="padding: 0;">
|
||||||
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="pageData.tableHeight"
|
<WarnDataTable :data="pageData.tableData" :columns="pageData.tableColumn" :tableHeight="pageData.tableHeight"
|
||||||
:key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth"
|
:loading="pageData.tableConfiger.loading" @selection-change="chooseData">
|
||||||
@chooseData="chooseData">
|
|
||||||
<template #bqList="{ row }">
|
<template #bqList="{ row }">
|
||||||
<ul>
|
<ul>
|
||||||
<li class="one_text_detail marks mb4" :key="index" v-for="(item, index) in row.bqList">{{ item.bqMc }}({{
|
<li class="one_text_detail marks mb4" :key="index" v-for="(item, index) in row.bqList">{{ item.bqMc }}({{
|
||||||
@ -54,7 +53,8 @@
|
|||||||
|
|
||||||
<!-- 操作 -->
|
<!-- 操作 -->
|
||||||
<template #controls="{ row }">
|
<template #controls="{ row }">
|
||||||
<el-link size="small" type="success" @click="handleremove(row.id)">移除</el-link>
|
<el-link size="small" type="success" @click="handleremove(row.id)">移入基础库</el-link>
|
||||||
|
<el-link size="small" type="success" @click="handleZdr(row.id)">移入重点人</el-link>
|
||||||
<el-link size="small" type="success" v-if="row.zdrZt == '01' || row.zdrZt == '03'"
|
<el-link size="small" type="success" v-if="row.zdrZt == '01' || row.zdrZt == '03'"
|
||||||
@click="handleSend(row.id)">送审</el-link>
|
@click="handleSend(row.id)">送审</el-link>
|
||||||
<el-link size="small" type="primary" v-if="row.zdrZt == '01' || row.zdrZt == '03'"
|
<el-link size="small" type="primary" v-if="row.zdrZt == '01' || row.zdrZt == '03'"
|
||||||
@ -62,7 +62,7 @@
|
|||||||
<el-link size="small" type="primary" @click="addEdit('detail', row)">详情</el-link>
|
<el-link size="small" type="primary" @click="addEdit('detail', row)">详情</el-link>
|
||||||
<el-link size="small" type="danger" @click="deleteRow(row.id)">删除</el-link>
|
<el-link size="small" type="danger" @click="deleteRow(row.id)">删除</el-link>
|
||||||
</template>
|
</template>
|
||||||
</MyTable>
|
</WarnDataTable>
|
||||||
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="pageData.tableHeight" :pageConfiger="{
|
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="pageData.tableHeight" :pageConfiger="{
|
||||||
...pageData.pageConfiger,
|
...pageData.pageConfiger,
|
||||||
total: pageData.total
|
total: pageData.total
|
||||||
@ -84,7 +84,7 @@ import { ElMessage } from "element-plus";
|
|||||||
import ChooseUser from "@/components/ChooseList/ChooseUser/index.vue";
|
import ChooseUser from "@/components/ChooseList/ChooseUser/index.vue";
|
||||||
import ZxsForm from "./components/zxsForm.vue";
|
import ZxsForm from "./components/zxsForm.vue";
|
||||||
import PageTitle from "@/components/aboutTable/PageTitle.vue";
|
import PageTitle from "@/components/aboutTable/PageTitle.vue";
|
||||||
import MyTable from "@/components/aboutTable/MyTable.vue";
|
import WarnDataTable from "@/views/backOfficeSystem/ces/components/WarnDataTable.vue";
|
||||||
import Pages from "@/components/aboutTable/Pages.vue";
|
import Pages from "@/components/aboutTable/Pages.vue";
|
||||||
import Search from "@/components/aboutTable/Search.vue";
|
import Search from "@/components/aboutTable/Search.vue";
|
||||||
import AddForm from "./components/addForm.vue";
|
import AddForm from "./components/addForm.vue";
|
||||||
@ -94,8 +94,8 @@ import { useRouter, useRoute } from 'vue-router'
|
|||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const { proxy } = getCurrentInstance();
|
const { proxy } = getCurrentInstance();
|
||||||
const { D_ZDRGK_GKZT,D_GS_ZDQT_ZT, D_GS_ZDR_RYJB, D_BZ_XB, D_BZ_MZ, D_BZ_XZQHDM, D_GS_ZDR_BK_ZT, D_GS_ZDR_CZZT, D_GS_BQ_ZL, D_GS_BQ_LB, D_GS_BQ_LX, D_GS_ZDR_YJDJ, D_GS_BK_SSJZ, D_GS_BK_SQLX, D_BZ_SF, D_GS_XS_LY, D_BZ_SSZT, D_GS_XS_LX, D_GS_XS_QTLX } =
|
const { D_ZDRGK_GKZT, D_GS_ZDQT_ZT, D_GS_ZDR_RYJB, D_BZ_XB, D_BZ_MZ, D_BZ_XZQHDM, D_GS_ZDR_BK_ZT, D_GS_ZDR_CZZT, D_GS_BQ_ZL, D_GS_BQ_LB, D_GS_BQ_LX, D_GS_ZDR_YJDJ, D_GS_BK_SSJZ, D_GS_BK_SQLX, D_BZ_SF, D_GS_XS_LY, D_BZ_SSZT, D_GS_XS_LX, D_GS_XS_QTLX } =
|
||||||
proxy.$dict('D_ZDRGK_GKZT',"D_GS_ZDQT_ZT", "D_GS_ZDR_RYJB", "D_BZ_XB", "D_BZ_MZ", "D_BZ_XZQHDM", "D_GS_ZDR_BK_ZT", "D_GS_ZDR_CZZT", "D_GS_BQ_ZL", "D_GS_BQ_LB", "D_GS_BQ_LX", "D_GS_ZDR_YJDJ", "D_GS_BK_SSJZ", "D_GS_BK_SQLX", "D_BZ_SF", "D_GS_XS_LY", "D_BZ_SSZT", "D_GS_XS_LX", "D_GS_XS_QTLX");
|
proxy.$dict('D_ZDRGK_GKZT', "D_GS_ZDQT_ZT", "D_GS_ZDR_RYJB", "D_BZ_XB", "D_BZ_MZ", "D_BZ_XZQHDM", "D_GS_ZDR_BK_ZT", "D_GS_ZDR_CZZT", "D_GS_BQ_ZL", "D_GS_BQ_LB", "D_GS_BQ_LX", "D_GS_ZDR_YJDJ", "D_GS_BK_SSJZ", "D_GS_BK_SQLX", "D_BZ_SF", "D_GS_XS_LY", "D_BZ_SSZT", "D_GS_XS_LX", "D_GS_XS_QTLX");
|
||||||
const obj = ref({});
|
const obj = ref({});
|
||||||
const showzxs = ref(false);
|
const showzxs = ref(false);
|
||||||
const zxsDilof = ref();
|
const zxsDilof = ref();
|
||||||
@ -148,28 +148,29 @@ const pageData = reactive({
|
|||||||
pageSize: 20,
|
pageSize: 20,
|
||||||
pageCurrent: 1
|
pageCurrent: 1
|
||||||
},
|
},
|
||||||
controlsWidth: 250,
|
controlsWidth: 280,
|
||||||
tableColumn: [
|
tableColumn: [
|
||||||
{ label: "姓名", prop: "ryXm",width: 100 },
|
{ label: "姓名", prop: "ryXm", width: 100 },
|
||||||
{ label: "性别", prop: "ryXb", showSolt: true, width: 80 },
|
{ label: "性别", prop: "ryXb", slotName: "ryXb", width: 80 },
|
||||||
{ label: "身份证", prop: "rySfzh", width: 170 },
|
{ label: "身份证", prop: "rySfzh", width: 170 },
|
||||||
{ label: "民族", prop: "ryMz", showSolt: true, width: 80 },
|
{ label: "民族", prop: "ryMz", slotName: "ryMz", width: 80 },
|
||||||
{ label: "户籍派出所", prop: "hjdPcsmc" },
|
{ label: "户籍派出所", prop: "hjdPcsmc" },
|
||||||
{ label: "标签", prop: "bqList", showSolt: true, showOverflowTooltip: true },
|
{ label: "标签", prop: "bqList", slotName: "bqList", showOverflowTooltip: true },
|
||||||
{ label: "管辖单位", prop: "gxSsbmmc" },
|
{ label: "管辖单位", prop: "gxSsbmmc" },
|
||||||
{ label: "管控状态", prop: "zdrBkZt", showOverflowTooltip: true,showSolt: true, width: 100 },
|
{ label: "管控状态", prop: "zdrBkZt", showOverflowTooltip: true, slotName: "zdrBkZt", width: 100 },
|
||||||
{ label: "审核状态", prop: "zdrZt", showSolt: true, width: 100 },
|
{ label: "审核状态", prop: "zdrZt", slotName: "zdrZt", width: 100 },
|
||||||
{ label: "入库时间", prop: "zdrRkkssj", },
|
{ label: "入库时间", prop: "zdrRkkssj", },
|
||||||
|
{ label: "操作", prop: "controls", slotName: "controls", width: 280 },
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
tabHeightFn();
|
tabHeightFn();
|
||||||
if (route.query.id) {
|
if (route.query.id) {
|
||||||
addEdit('x', {
|
addEdit('x', {
|
||||||
id: route.query.id
|
id: route.query.id
|
||||||
})
|
})
|
||||||
}else{
|
} else {
|
||||||
getList();
|
getList();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -195,7 +196,7 @@ const getList = () => {
|
|||||||
pageData.tableConfiger.loading = true;
|
pageData.tableConfiger.loading = true;
|
||||||
// 人员类型D_ZDRY_RYLX(01 重点 02 普通〉
|
// 人员类型D_ZDRY_RYLX(01 重点 02 普通〉
|
||||||
// rylx: '01',
|
// rylx: '01',
|
||||||
let data = {...pageData.pageConfiger, ...queryFrom.value,rylx: '03' };
|
let data = { ...pageData.pageConfiger, ...queryFrom.value, rylx: '03' };
|
||||||
qcckGet(data, "/mosty-gsxt/tbGsxtZdry/selectPage").then((res) => {
|
qcckGet(data, "/mosty-gsxt/tbGsxtZdry/selectPage").then((res) => {
|
||||||
pageData.tableData = res.records || [];
|
pageData.tableData = res.records || [];
|
||||||
pageData.total = res.total;
|
pageData.total = res.total;
|
||||||
@ -224,6 +225,14 @@ const handleremove = (id) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleZdr = (id) => {
|
||||||
|
proxy.$confirm("确定要移至重点人?", "警告", { type: "warning" }).then(() => {
|
||||||
|
qcckPost({ id, rylx: '01' }, "/mosty-gsxt/tbGsxtZdry/rylxyd").then(() => {
|
||||||
|
proxy.$message({ type: "success", message: "移除成功" });
|
||||||
|
getList();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const chooseData = (data) => {
|
const chooseData = (data) => {
|
||||||
ids.value = Array.isArray(data) ? data.map((item) => item.id) : [];
|
ids.value = Array.isArray(data) ? data.map((item) => item.id) : [];
|
||||||
|
|||||||
@ -4,9 +4,16 @@
|
|||||||
<span class="title">{{ title }}重点人管理</span>
|
<span class="title">{{ title }}重点人管理</span>
|
||||||
<div>
|
<div>
|
||||||
<el-button type="primary" size="small" v-if="butShow" :loading="loading" @click="submit">保存</el-button>
|
<el-button type="primary" size="small" v-if="butShow" :loading="loading" @click="submit">保存</el-button>
|
||||||
|
<el-button type="primary" size="small" v-if="showAuditShBtn && showButData"
|
||||||
|
@click="openAuditDialog('sh')">审核</el-button>
|
||||||
|
<el-button type="primary" size="small" v-if="showAuditSpBtn && showButData"
|
||||||
|
@click="openAuditDialog('sp')">审批</el-button>
|
||||||
<el-button size="small" @click="close">关闭</el-button>
|
<el-button size="small" @click="close">关闭</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<AuditDialog v-model="auditDialogVisible" :title="auditTitle" :formData="auditForm" :rules="auditRules"
|
||||||
|
:reasonProp="auditReasonProp" :loading="auditLoading" :dictEnum="D_BZ_SF" @cancel="handleAuditCancel"
|
||||||
|
@submit="handleAuditSubmit" />
|
||||||
<div class="form_cnt flex just-between">
|
<div class="form_cnt flex just-between">
|
||||||
<div class="left_box">
|
<div class="left_box">
|
||||||
<ul class="anchor-list">
|
<ul class="anchor-list">
|
||||||
@ -20,8 +27,8 @@
|
|||||||
:class="activeSection === 'character-section' ? 'active' : ''">背景信息</li>
|
:class="activeSection === 'character-section' ? 'active' : ''">背景信息</li>
|
||||||
<li @click="scrollToSection('controlInfo-section')"
|
<li @click="scrollToSection('controlInfo-section')"
|
||||||
:class="activeSection === 'controlInfo-section' ? 'active' : ''" v-if="!butShow">管控信息</li>
|
:class="activeSection === 'controlInfo-section' ? 'active' : ''" v-if="!butShow">管控信息</li>
|
||||||
<li @click="scrollToSection('featinfo-section')"
|
<li @click="scrollToSection('featinfo-section')" :class="activeSection === 'featinfo-section' ? 'active' : ''"
|
||||||
:class="activeSection === 'featinfo-section' ? 'active' : ''" v-if="!butShow">全要素布控</li>
|
v-if="!butShow">全要素布控</li>
|
||||||
<li @click="scrollToSection('demandsInfo-section')"
|
<li @click="scrollToSection('demandsInfo-section')"
|
||||||
:class="activeSection === 'demandsInfo-section' ? 'active' : ''" v-if="!butShow">密切联系人</li>
|
:class="activeSection === 'demandsInfo-section' ? 'active' : ''" v-if="!butShow">密切联系人</li>
|
||||||
<li @click="scrollToSection('requestInfo-section')"
|
<li @click="scrollToSection('requestInfo-section')"
|
||||||
@ -69,13 +76,13 @@
|
|||||||
<div id="judgmentRecord-section" v-if="!butShow">
|
<div id="judgmentRecord-section" v-if="!butShow">
|
||||||
<VisitRecord ref="visitRecord" :disabled="disabled" :showBut="showBut" :dataList="listQuery" />
|
<VisitRecord ref="visitRecord" :disabled="disabled" :showBut="showBut" :dataList="listQuery" />
|
||||||
</div>
|
</div>
|
||||||
<div id="historyAssembly-section" v-if="!butShow" >
|
<div id="historyAssembly-section" v-if="!butShow">
|
||||||
<CaseInfo ref="caseInfo" :disabled="disabled" :showBut="showBut" :dataList="listQuery" />
|
<CaseInfo ref="caseInfo" :disabled="disabled" :showBut="showBut" :dataList="listQuery" />
|
||||||
</div>
|
</div>
|
||||||
<div id="joblogging-section" v-if="!butShow">
|
<div id="joblogging-section" v-if="!butShow">
|
||||||
<ActualPerformance ref="actualPerformance" :disabled="disabled" :showBut="showBut" :dataList="listQuery" />
|
<ActualPerformance ref="actualPerformance" :disabled="disabled" :showBut="showBut" :dataList="listQuery" />
|
||||||
</div>
|
</div>
|
||||||
<div id="joblogging-joblog" v-if="!butShow" >
|
<div id="joblogging-joblog" v-if="!butShow">
|
||||||
<CzModel ref="czModel" :disabled="disabled" :showBut="showBut" :dataList="listQuery" />
|
<CzModel ref="czModel" :disabled="disabled" :showBut="showBut" :dataList="listQuery" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -87,6 +94,7 @@
|
|||||||
import { getItem } from "@/utils/storage";
|
import { getItem } from "@/utils/storage";
|
||||||
import { qcckGet, qcckPost, qcckPut } from "@/api/qcckApi.js";
|
import { qcckGet, qcckPost, qcckPut } from "@/api/qcckApi.js";
|
||||||
import { tbGsxtZdrySelectVoById, tbGsxtZdrySave } from "@/api/zdr.js";
|
import { tbGsxtZdrySelectVoById, tbGsxtZdrySave } from "@/api/zdr.js";
|
||||||
|
import AuditDialog from "./auditDialog.vue";
|
||||||
import ControlInfo from '../../mpvGroup/model/controlInfo.vue'
|
import ControlInfo from '../../mpvGroup/model/controlInfo.vue'
|
||||||
import Info from "../model/info.vue";
|
import Info from "../model/info.vue";
|
||||||
import PersonnelTags from '../model/personnelTags.vue'
|
import PersonnelTags from '../model/personnelTags.vue'
|
||||||
@ -101,10 +109,11 @@ import CaseInfo from '../model/caseInfo.vue'
|
|||||||
import ActualPerformance from '../model/actualPerformance.vue'
|
import ActualPerformance from '../model/actualPerformance.vue'
|
||||||
import CzModel from '../model/czModel.vue'
|
import CzModel from '../model/czModel.vue'
|
||||||
import { useRouter, useRoute } from 'vue-router'
|
import { useRouter, useRoute } from 'vue-router'
|
||||||
import { ref, onUnmounted, getCurrentInstance } from "vue";
|
import { ref, onUnmounted, getCurrentInstance, computed, reactive } from "vue";
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const { proxy } = getCurrentInstance();
|
const { proxy } = getCurrentInstance();
|
||||||
|
const { D_BZ_SF } = proxy.$dict("D_BZ_SF");
|
||||||
const emit = defineEmits(["updateDate"]);
|
const emit = defineEmits(["updateDate"]);
|
||||||
const chooseMarksVisible = ref(false);
|
const chooseMarksVisible = ref(false);
|
||||||
const dialogForm = ref(false); //弹窗
|
const dialogForm = ref(false); //弹窗
|
||||||
@ -115,23 +124,50 @@ const listQuery = ref({});
|
|||||||
const butShow = ref(false)
|
const butShow = ref(false)
|
||||||
const title = ref('新增')
|
const title = ref('新增')
|
||||||
const showData = ref(false)
|
const showData = ref(false)
|
||||||
|
const modeType = ref("detail")
|
||||||
|
const currentRowId = ref("")
|
||||||
|
const auditDialogVisible = ref(false)
|
||||||
|
const auditLoading = ref(false)
|
||||||
|
const auditForm = reactive({
|
||||||
|
id: "",
|
||||||
|
sftg: undefined,
|
||||||
|
shBtgyy: "",
|
||||||
|
spBtgyy: ""
|
||||||
|
})
|
||||||
|
const auditRules = reactive({
|
||||||
|
sftg: [{ required: true, message: "请选择是否通过", trigger: "change" }],
|
||||||
|
shBtgyy: [{ required: true, message: "请输入不通过原因", trigger: "blur" }],
|
||||||
|
spBtgyy: [{ required: true, message: "请输入不通过原因", trigger: "blur" }]
|
||||||
|
})
|
||||||
|
const auditTitle = computed(() => modeType.value === "sp" ? "审批" : "审核")
|
||||||
|
const auditReasonProp = computed(() => modeType.value === "sp" ? "spBtgyy" : "shBtgyy")
|
||||||
|
const showAuditShBtn = computed(() => modeType.value === "detail" && dataListQuery.value?.zdrZt == "02")
|
||||||
|
const showAuditSpBtn = computed(() => modeType.value === "detail" && dataListQuery.value?.zdrZt == "04")
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
rylx: {
|
rylx: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '01'
|
default: '01'
|
||||||
}
|
},
|
||||||
|
showButData: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
const dataListQuery = ref({})
|
||||||
// 初始化数据
|
// 初始化数据
|
||||||
const init = (type, row) => {
|
const init = (type, row) => {
|
||||||
dialogForm.value = true;
|
dialogForm.value = true;
|
||||||
|
modeType.value = type;
|
||||||
|
currentRowId.value = row?.id || "";
|
||||||
if (type == 'add') {
|
if (type == 'add') {
|
||||||
butShow.value = true
|
butShow.value = true
|
||||||
title.value = '新增'
|
title.value = '新增'
|
||||||
disabled.value = false
|
disabled.value = false
|
||||||
showBut.value = false
|
showBut.value = false
|
||||||
|
listQuery.value = {}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
butShow.value = false
|
butShow.value = false
|
||||||
|
dataListQuery.value = { ...row }
|
||||||
tbGsxtZdrySelectVoById({ id: row.id }).then(res => {
|
tbGsxtZdrySelectVoById({ id: row.id }).then(res => {
|
||||||
listQuery.value = { ...res }
|
listQuery.value = { ...res }
|
||||||
})
|
})
|
||||||
@ -143,8 +179,7 @@ const init = (type, row) => {
|
|||||||
disabled.value = true
|
disabled.value = true
|
||||||
showBut.value = false
|
showBut.value = false
|
||||||
title.value = '删除'
|
title.value = '删除'
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
disabled.value = true
|
disabled.value = true
|
||||||
showBut.value = false
|
showBut.value = false
|
||||||
title.value = '详情'
|
title.value = '详情'
|
||||||
@ -213,7 +248,7 @@ const submit = async () => {
|
|||||||
info.value.throwData()
|
info.value.throwData()
|
||||||
// personnelTags.value.throwData(),
|
// personnelTags.value.throwData(),
|
||||||
]);
|
]);
|
||||||
tbGsxtZdrySave({...infoData,rylx:props.rylx}).then(res => {
|
tbGsxtZdrySave({ ...infoData, rylx: props.rylx }).then(res => {
|
||||||
proxy.$message({
|
proxy.$message({
|
||||||
message: '新增成功',
|
message: '新增成功',
|
||||||
type: 'success',
|
type: 'success',
|
||||||
@ -224,10 +259,47 @@ const submit = async () => {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const butzt = ref()
|
||||||
|
const openAuditDialog = (type) => {
|
||||||
|
// modeType.value = type;
|
||||||
|
butzt.value = type
|
||||||
|
auditForm.id = currentRowId.value || listQuery.value?.id || "";
|
||||||
|
auditForm.sftg = undefined;
|
||||||
|
auditForm.shBtgyy = "";
|
||||||
|
auditForm.spBtgyy = "";
|
||||||
|
auditDialogVisible.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleAuditCancel = () => {
|
||||||
|
auditDialogVisible.value = false;
|
||||||
|
auditLoading.value = false;
|
||||||
|
// modeType.value = "detail";
|
||||||
|
auditForm.id = "";
|
||||||
|
auditForm.sftg = undefined;
|
||||||
|
auditForm.shBtgyy = "";
|
||||||
|
auditForm.spBtgyy = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleAuditSubmit = () => {
|
||||||
|
auditLoading.value = true;
|
||||||
|
const url = butzt.value === "sp" ? "/mosty-gsxt/tbGsxtZdry/updateSp" : "/mosty-gsxt/tbGsxtZdry/updateSh";
|
||||||
|
const successMsg = modeType.value === "sp" ? "审批成功" : "审核成功";
|
||||||
|
qcckPost(auditForm, url).then(() => {
|
||||||
|
proxy.$message({
|
||||||
|
message: successMsg,
|
||||||
|
type: 'success',
|
||||||
|
})
|
||||||
|
auditDialogVisible.value = false;
|
||||||
|
modeType.value = "detail";
|
||||||
|
close();
|
||||||
|
}).catch(() => {
|
||||||
|
auditLoading.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// 关闭
|
// 关闭
|
||||||
const close = () => {
|
const close = () => {
|
||||||
if (route.query.id) {
|
if (route.query.id) {
|
||||||
const query = { ...route.query };
|
const query = { ...route.query };
|
||||||
delete query.id;
|
delete query.id;
|
||||||
router.replace({ query });
|
router.replace({ query });
|
||||||
@ -235,6 +307,14 @@ const close = () => {
|
|||||||
|
|
||||||
dialogForm.value = false;
|
dialogForm.value = false;
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
|
auditLoading.value = false;
|
||||||
|
auditDialogVisible.value = false;
|
||||||
|
modeType.value = "detail";
|
||||||
|
currentRowId.value = "";
|
||||||
|
auditForm.id = "";
|
||||||
|
auditForm.sftg = undefined;
|
||||||
|
auditForm.shBtgyy = "";
|
||||||
|
auditForm.spBtgyy = "";
|
||||||
emit('updateDate')
|
emit('updateDate')
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,75 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog :model-value="modelValue" :title="title" width="500px" @update:model-value="handleModelValueChange"
|
||||||
|
@close="handleCancel">
|
||||||
|
<el-form :model="formData" ref="elAuditForm" label-width="100px" :rules="rules" style="width: 100%;">
|
||||||
|
<el-form-item label="是否通过" prop="sftg" class="mt10 mb10">
|
||||||
|
<MOSTY.Select filterable v-model="formData.sftg" :dictEnum="dictEnum" style="width: 100%;" clearable
|
||||||
|
placeholder="请选择是否通过" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="不通过原因" :prop="reasonProp" v-if="formData.sftg == 0">
|
||||||
|
<MOSTY.Other style="width: 100%;" clearable v-model="formData[reasonProp]" type="textarea"
|
||||||
|
placeholder="请输入不通过原因" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<div class="flex just-center">
|
||||||
|
<el-button @click="handleCancel">取消</el-button>
|
||||||
|
<el-button type="primary" @click="handleSubmit" v-loading="loading">确定</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import * as MOSTY from "@/components/MyComponents/index";
|
||||||
|
import { ref } from "vue";
|
||||||
|
|
||||||
|
defineProps({
|
||||||
|
modelValue: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
default: "审核"
|
||||||
|
},
|
||||||
|
formData: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({})
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({})
|
||||||
|
},
|
||||||
|
reasonProp: {
|
||||||
|
type: String,
|
||||||
|
default: "shBtgyy"
|
||||||
|
},
|
||||||
|
loading: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
dictEnum: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const emit = defineEmits(["update:modelValue", "cancel", "submit"]);
|
||||||
|
const elAuditForm = ref();
|
||||||
|
|
||||||
|
const handleModelValueChange = (val) => {
|
||||||
|
emit("update:modelValue", val);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCancel = () => {
|
||||||
|
emit("cancel");
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmit = () => {
|
||||||
|
elAuditForm.value.validate((valid) => {
|
||||||
|
if (!valid) return;
|
||||||
|
emit("submit");
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
@ -1,8 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<!-- 搜索 -->
|
<!-- 搜索 -->
|
||||||
<div ref="searchBox" class="mt10">
|
<div ref="searchBox" class="mt10">
|
||||||
<Search :searchArr="searchConfiger" @submit="onSearch" >
|
<Search :searchArr="searchConfiger" @submit="onSearch">
|
||||||
<el-button type="primary" size="small" @click="addEdit('add', '')">
|
<el-button type="primary" size="small" @click="addEdit('add', '')">
|
||||||
<el-icon style="vertical-align: middle">
|
<el-icon style="vertical-align: middle">
|
||||||
<CirclePlus />
|
<CirclePlus />
|
||||||
@ -13,10 +13,9 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 表格 -->
|
<!-- 表格 -->
|
||||||
<div class="margTop">
|
<div class="margTop" style="padding: 0;">
|
||||||
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="pageData.tableHeight"
|
<WarnDataTable :data="pageData.tableData" :columns="pageData.tableColumn" :tableHeight="pageData.tableHeight"
|
||||||
:key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth"
|
:loading="pageData.tableConfiger.loading" @selection-change="chooseData">
|
||||||
@chooseData="chooseData">
|
|
||||||
<template #bqList="{ row }">
|
<template #bqList="{ row }">
|
||||||
<ul>
|
<ul>
|
||||||
<li class="one_text_detail marks mb4" :key="index" v-for="(item, index) in row.bqList">{{ item.bqMc }}({{
|
<li class="one_text_detail marks mb4" :key="index" v-for="(item, index) in row.bqList">{{ item.bqMc }}({{
|
||||||
@ -39,7 +38,7 @@
|
|||||||
<DictTag :tag="false" :value="row.zdrRyjb" :options="D_GS_ZDR_RYJB" />
|
<DictTag :tag="false" :value="row.zdrRyjb" :options="D_GS_ZDR_RYJB" />
|
||||||
</template>
|
</template>
|
||||||
<template #zdrBkZt="{ row }">
|
<template #zdrBkZt="{ row }">
|
||||||
<DictTag :tag="false" :value="row.zdrBkZt" :options="D_ZDRGK_GKZT" />
|
<DictTag :tag="false" :value="row.zdrBkZt" :options="D_BZ_RCBKZT" />
|
||||||
</template>
|
</template>
|
||||||
<template #zdrCzzt="{ row }">
|
<template #zdrCzzt="{ row }">
|
||||||
<DictTag :tag="false" :value="row.zdrCzzt" :options="D_GS_ZDR_CZZT" />
|
<DictTag :tag="false" :value="row.zdrCzzt" :options="D_GS_ZDR_CZZT" />
|
||||||
@ -54,7 +53,9 @@
|
|||||||
|
|
||||||
<!-- 操作 -->
|
<!-- 操作 -->
|
||||||
<template #controls="{ row }">
|
<template #controls="{ row }">
|
||||||
<el-link size="small" type="success" @click="handleremove(row.id)">移除</el-link>
|
<!-- <el-link size="small" type="success" @click="handleremove(row.id)">移至关注库</el-link> -->
|
||||||
|
<el-link size="small" type="success" @click="handleMoveToFocus(row.id)">移入关注库</el-link>
|
||||||
|
<el-link size="small" type="success" @click="handleremove(row.id)">移入基础库</el-link>
|
||||||
<el-link size="small" type="success" v-if="row.zdrZt == '01' || row.zdrZt == '03'"
|
<el-link size="small" type="success" v-if="row.zdrZt == '01' || row.zdrZt == '03'"
|
||||||
@click="handleSend(row.id)">送审</el-link>
|
@click="handleSend(row.id)">送审</el-link>
|
||||||
<el-link size="small" type="primary" v-if="row.zdrZt == '01' || row.zdrZt == '03'"
|
<el-link size="small" type="primary" v-if="row.zdrZt == '01' || row.zdrZt == '03'"
|
||||||
@ -62,7 +63,7 @@
|
|||||||
<el-link size="small" type="primary" @click="addEdit('detail', row)">详情</el-link>
|
<el-link size="small" type="primary" @click="addEdit('detail', row)">详情</el-link>
|
||||||
<el-link size="small" type="danger" @click="deleteRow(row.id)">删除</el-link>
|
<el-link size="small" type="danger" @click="deleteRow(row.id)">删除</el-link>
|
||||||
</template>
|
</template>
|
||||||
</MyTable>
|
</WarnDataTable>
|
||||||
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="pageData.tableHeight" :pageConfiger="{
|
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="pageData.tableHeight" :pageConfiger="{
|
||||||
...pageData.pageConfiger,
|
...pageData.pageConfiger,
|
||||||
total: pageData.total
|
total: pageData.total
|
||||||
@ -84,7 +85,7 @@ import { ElMessage } from "element-plus";
|
|||||||
import ChooseUser from "@/components/ChooseList/ChooseUser/index.vue";
|
import ChooseUser from "@/components/ChooseList/ChooseUser/index.vue";
|
||||||
import ZxsForm from "./components/zxsForm.vue";
|
import ZxsForm from "./components/zxsForm.vue";
|
||||||
import PageTitle from "@/components/aboutTable/PageTitle.vue";
|
import PageTitle from "@/components/aboutTable/PageTitle.vue";
|
||||||
import MyTable from "@/components/aboutTable/MyTable.vue";
|
import WarnDataTable from "@/views/backOfficeSystem/ces/components/WarnDataTable.vue";
|
||||||
import Pages from "@/components/aboutTable/Pages.vue";
|
import Pages from "@/components/aboutTable/Pages.vue";
|
||||||
import Search from "@/components/aboutTable/Search.vue";
|
import Search from "@/components/aboutTable/Search.vue";
|
||||||
import AddForm from "./components/addForm.vue";
|
import AddForm from "./components/addForm.vue";
|
||||||
@ -95,8 +96,8 @@ import { getItem } from "@/utils/storage.js";
|
|||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const { proxy } = getCurrentInstance();
|
const { proxy } = getCurrentInstance();
|
||||||
const { D_GS_ZDQT_ZT, D_GS_ZDR_RYJB, D_BZ_XB, D_BZ_MZ, D_BZ_XZQHDM, D_ZDRGK_GKZT, D_GS_ZDR_CZZT, D_GS_BQ_ZL, D_GS_BQ_LB, D_GS_BQ_LX, D_GS_ZDR_YJDJ, D_GS_BK_SSJZ, D_GS_BK_SQLX, D_BZ_SF, D_GS_XS_LY, D_BZ_SSZT, D_GS_XS_LX, D_GS_XS_QTLX } =
|
const { D_GS_ZDQT_ZT, D_GS_ZDR_RYJB, D_BZ_XB, D_BZ_MZ, D_BZ_RCBKZT, D_BZ_XZQHDM, D_ZDRGK_GKZT, D_GS_ZDR_CZZT, D_GS_BQ_ZL, D_GS_BQ_LB, D_GS_BQ_LX, D_GS_ZDR_YJDJ, D_GS_BK_SSJZ, D_GS_BK_SQLX, D_BZ_SF, D_GS_XS_LY, D_BZ_SSZT, D_GS_XS_LX, D_GS_XS_QTLX } =
|
||||||
proxy.$dict("D_GS_ZDQT_ZT", "D_GS_ZDR_RYJB", "D_BZ_XB", "D_BZ_MZ", "D_BZ_XZQHDM", "D_ZDRGK_GKZT", "D_GS_ZDR_CZZT", "D_GS_BQ_ZL", "D_GS_BQ_LB", "D_GS_BQ_LX", "D_GS_ZDR_YJDJ", "D_GS_BK_SSJZ", "D_GS_BK_SQLX", "D_BZ_SF", "D_GS_XS_LY", "D_BZ_SSZT", "D_GS_XS_LX", "D_GS_XS_QTLX");
|
proxy.$dict("D_GS_ZDQT_ZT", "D_BZ_RCBKZT", "D_GS_ZDR_RYJB", "D_BZ_XB", "D_BZ_MZ", "D_BZ_XZQHDM", "D_ZDRGK_GKZT", "D_GS_ZDR_CZZT", "D_GS_BQ_ZL", "D_GS_BQ_LB", "D_GS_BQ_LX", "D_GS_ZDR_YJDJ", "D_GS_BK_SSJZ", "D_GS_BK_SQLX", "D_BZ_SF", "D_GS_XS_LY", "D_BZ_SSZT", "D_GS_XS_LX", "D_GS_XS_QTLX");
|
||||||
const obj = ref({});
|
const obj = ref({});
|
||||||
const showzxs = ref(false);
|
const showzxs = ref(false);
|
||||||
const zxsDilof = ref();
|
const zxsDilof = ref();
|
||||||
@ -151,28 +152,29 @@ const pageData = reactive({
|
|||||||
},
|
},
|
||||||
controlsWidth: 250,
|
controlsWidth: 250,
|
||||||
tableColumn: [
|
tableColumn: [
|
||||||
{ label: "姓名", prop: "ryXm",width: 100 },
|
{ label: "姓名", prop: "ryXm", width: 100 },
|
||||||
{ label: "性别", prop: "ryXb", showSolt: true, width: 80 },
|
{ label: "性别", prop: "ryXb", slotName: "ryXb", width: 80 },
|
||||||
{ label: "身份证", prop: "rySfzh", width: 170 },
|
{ label: "身份证", prop: "rySfzh", width: 170 },
|
||||||
{ label: "民族", prop: "ryMz", showSolt: true, width: 80 },
|
{ label: "民族", prop: "ryMz", slotName: "ryMz", width: 80 },
|
||||||
{ label: "户籍派出所", prop: "hjdPcsmc" },
|
{ label: "户籍派出所", prop: "hjdPcsmc" },
|
||||||
{ label: "标签", prop: "bqList", showSolt: true, showOverflowTooltip: true },
|
{ label: "标签", prop: "bqList", slotName: "bqList", showOverflowTooltip: true },
|
||||||
{ label: "管辖单位", prop: "gxSsbmmc" },
|
{ label: "协管单位", prop: "gxSsbmmc" },
|
||||||
{ label: "管控状态", prop: "zdrBkZt", showOverflowTooltip: true,showSolt: true, width: 100 },
|
{ label: "管控状态", prop: "zdrBkZt", showOverflowTooltip: true, slotName: "zdrBkZt", width: 100 },
|
||||||
{ label: "审核状态", prop: "zdrZt", showSolt: true, width: 100 },
|
{ label: "审核状态", prop: "zdrZt", slotName: "zdrZt", width: 100 },
|
||||||
{ label: "入库时间", prop: "zdrRkkssj", },
|
{ label: "入库时间", prop: "zdrRkkssj", },
|
||||||
|
{ label: "操作", prop: "controls", slotName: "controls", width: 250 },
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
const isShiQzDelet = ref(false)
|
const isShiQzDelet = ref(false)
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
tabHeightFn();
|
tabHeightFn();
|
||||||
const isShiQz = getItem('roleList').find(item => item.roleCode == 'JS_777777') != undefined
|
const isShiQz = getItem('roleList').find(item => item.roleCode == 'JS_777777') != undefined
|
||||||
if (isShiQz) isShiQzDelet.value = true
|
if (isShiQz) isShiQzDelet.value = true
|
||||||
if (route.query.id) {
|
if (route.query.id) {
|
||||||
addEdit('x', {
|
addEdit('x', {
|
||||||
id: route.query.id
|
id: route.query.id
|
||||||
})
|
})
|
||||||
}else{
|
} else {
|
||||||
getList();
|
getList();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -198,7 +200,7 @@ const getList = () => {
|
|||||||
pageData.tableConfiger.loading = true;
|
pageData.tableConfiger.loading = true;
|
||||||
// 人员类型D_ZDRY_RYLX(01 重点 02 普通〉
|
// 人员类型D_ZDRY_RYLX(01 重点 02 普通〉
|
||||||
// rylx: '01',
|
// rylx: '01',
|
||||||
let data = {...pageData.pageConfiger, ...queryFrom.value,rylx: '01' };
|
let data = { ...pageData.pageConfiger, ...queryFrom.value, rylx: '01' };
|
||||||
qcckGet(data, "/mosty-gsxt/tbGsxtZdry/selectPage").then((res) => {
|
qcckGet(data, "/mosty-gsxt/tbGsxtZdry/selectPage").then((res) => {
|
||||||
pageData.tableData = res.records || [];
|
pageData.tableData = res.records || [];
|
||||||
pageData.total = res.total;
|
pageData.total = res.total;
|
||||||
@ -226,7 +228,14 @@ const handleremove = (id) => {
|
|||||||
});
|
});
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
const handleMoveToFocus = (id) => {
|
||||||
|
proxy.$confirm("确定要移至关注库?", "警告", { type: "warning" }).then(() => {
|
||||||
|
qcckPost({ id, rylx: '03' }, "/mosty-gsxt/tbGsxtZdry/rylxyd").then(() => {
|
||||||
|
proxy.$message({ type: "success", message: "移除成功" });
|
||||||
|
getList();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const chooseData = (data) => {
|
const chooseData = (data) => {
|
||||||
ids.value = Array.isArray(data) ? data.map((item) => item.id) : [];
|
ids.value = Array.isArray(data) ? data.map((item) => item.id) : [];
|
||||||
|
|||||||
@ -6,38 +6,26 @@
|
|||||||
<el-button type="primary" v-if="showBut" :disabled="disabled" @click="submit">保存</el-button>
|
<el-button type="primary" v-if="showBut" :disabled="disabled" @click="submit">保存</el-button>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<FormMessage :disabled="disabled" v-model="listQuery" :formList="formData" labelWidth="100px" ref="elform"
|
<FormMessage :disabled="disabled" v-model="listQuery" :formList="formData" labelWidth="130px" ref="elform"
|
||||||
:rules="rules">
|
:rules="rules">
|
||||||
<template #ryzp>
|
<template #ryzp>
|
||||||
<div style="width: 100%; padding-left: 50px">
|
<div style="width: 100%; padding-left: 50px">
|
||||||
<MOSTY.Upload :showBtn="false" :limit="1" v-model="listQuery.ryzp" />
|
<MOSTY.Upload :showBtn="false" :limit="1" v-model="listQuery.ryzp" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #ryLxdh>
|
<template #gkMjXm>
|
||||||
<div class="phone-input-container">
|
|
||||||
<div class="inputGroup" v-for="(item, index) in listQuery.ryLxdh" :key="index">
|
|
||||||
<el-input v-model="listQuery.ryLxdh[index]" class="group" placeholder="请输入电话号码" />
|
|
||||||
<div class="flex align-center but">
|
|
||||||
<el-button type="primary" :icon="Plus" circle @click="addPhone" title="添加电话号码"
|
|
||||||
v-if="listQuery.ryLxdh.length - 1 == index" />
|
|
||||||
<el-button type="success" :icon="Minus" circle @click="removePhone(index)" title="删除电话号码" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<template #gkmjxm>
|
|
||||||
<div>
|
<div>
|
||||||
<el-input v-model="listQuery.gkmjxm" class="group" placeholder="请输入管控民警姓名" readonly
|
<el-input v-model="listQuery.gkMjXm" class="group" placeholder="请输入管控民警姓名" readonly
|
||||||
@click="chooseMarksVisible = true" />
|
@click="chooseMarksVisible = true" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #gkmjsfzh>
|
<!-- <template #gkmjsfzh>
|
||||||
<div>
|
<div>
|
||||||
<el-input v-model="listQuery.gkmjsfzh" class="group" placeholder="请输入管控民警身份证号" readonly
|
<el-input v-model="listQuery.gkmjsfzh" class="group" placeholder="请输入管控民警身份证号" readonly
|
||||||
@click="chooseMarksVisible = true" />
|
@click="chooseMarksVisible = true" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template> -->
|
||||||
<!-- { label: "管控民警", prop: "gkmjxm", type: "slot" }, -->
|
<!-- { label: "管控民警", prop: "gkMjXm", type: "slot" }, -->
|
||||||
<!-- { label: "管控民警身份证号", prop: "gkmjsfzh", type: "slot" }, -->
|
<!-- { label: "管控民警身份证号", prop: "gkmjsfzh", type: "slot" }, -->
|
||||||
</FormMessage>
|
</FormMessage>
|
||||||
</div>
|
</div>
|
||||||
@ -48,8 +36,8 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import * as rule from "@/utils/rules.js";
|
import * as rule from "@/utils/rules.js";
|
||||||
|
import { IdCard } from "@/utils/validate.js";
|
||||||
import * as MOSTY from "@/components/MyComponents/index";
|
import * as MOSTY from "@/components/MyComponents/index";
|
||||||
import { Plus, Minus } from "@element-plus/icons-vue";
|
|
||||||
import FormMessage from "@/components/aboutTable/FormMessage.vue";
|
import FormMessage from "@/components/aboutTable/FormMessage.vue";
|
||||||
import ChooseUser from "@/components/ChooseList/ChooseUser/index.vue";
|
import ChooseUser from "@/components/ChooseList/ChooseUser/index.vue";
|
||||||
import { ref, reactive, onMounted, getCurrentInstance, watch } from "vue";
|
import { ref, reactive, onMounted, getCurrentInstance, watch } from "vue";
|
||||||
@ -73,57 +61,61 @@ const props = defineProps({
|
|||||||
const rules = reactive({
|
const rules = reactive({
|
||||||
ryXm: [{ required: true, message: "请输入姓名", trigger: "blur" }],
|
ryXm: [{ required: true, message: "请输入姓名", trigger: "blur" }],
|
||||||
...rule.identityCardRule({ validator: true }, 'rySfzh'), //身份证校验
|
...rule.identityCardRule({ validator: true }, 'rySfzh'), //身份证校验
|
||||||
...rule.phoneRule({ validator: true }, "ryLxdh"), // 是否必填 是否进行校验,
|
...rule.phoneRule({ validator: true }, "gkMjLxfs"), // 是否必填 是否进行校验,
|
||||||
rySfzh: [{ required: true, message: "请输入身份证号", trigger: "blur" }],
|
rySfzh: [{ required: true, message: "请输入身份证号", trigger: "blur" }],
|
||||||
ryLxdh: [{ required: true, message: "请输入联系电话", trigger: "blur" }],
|
|
||||||
ryXb: [{ required: true, message: "请选择性别", trigger: "change" }],
|
ryXb: [{ required: true, message: "请选择性别", trigger: "change" }],
|
||||||
ryMz: [{ required: true, message: "请选择民族", trigger: "change" }],
|
ryMz: [{ required: true, message: "请选择民族", trigger: "change" }],
|
||||||
ryCsrq: [{ required: true, message: "请选择出生日期", trigger: "change" }],
|
ryCsrq: [{ required: true, message: "请选择出生日期", trigger: "change" }],
|
||||||
zdrRyjb: [{ required: true, message: "请选择人员级别", trigger: "change" }],
|
|
||||||
zdrYjdj: [{ required: true, message: "请选择预警等级", trigger: "change" }],
|
zdrYjdj: [{ required: true, message: "请选择预警等级", trigger: "change" }],
|
||||||
zrSsbmdm: [{ required: true, message: "请选择责任单位", trigger: "change" }],
|
gxSsbmdm: [{ required: true, message: "请选择协管单位", trigger: "change" }],
|
||||||
// gkmjxm: [{ required: true, message: "请选择管控民警", trigger: "change" }],
|
zdrRkkssj: [{ required: true, message: "请选择入库开始时间", trigger: "change" }],
|
||||||
|
zdrRkjssj: [{ required: true, message: "请选择入库结束时间", trigger: "change" }],
|
||||||
|
gkMjLxfs: [{ required: true, message: "请输入民警联系方式", trigger: "blur" }],
|
||||||
|
// gkMjXm: [{ required: true, message: "请选择管控民警", trigger: "change" }],
|
||||||
// gkmjsfzh: [{ required: true, message: "请选择管控民警身份证号", trigger: "change" }],
|
// gkmjsfzh: [{ required: true, message: "请选择管控民警身份证号", trigger: "change" }],
|
||||||
// rylx: [{ required: true, message: "请选择人员类型", trigger: "change" }]
|
// rylx: [{ required: true, message: "请选择人员类型", trigger: "change" }]
|
||||||
});
|
});
|
||||||
const listQuery = ref({ ryLxdh: [""] }); //表单
|
const listQuery = ref({}); //表单
|
||||||
const chooseMarksVisible = ref(false); // 控制标签选择弹窗显示
|
const chooseMarksVisible = ref(false); // 控制标签选择弹窗显示
|
||||||
const roleIds = ref([]); // 已选择的标签ID
|
const roleIds = ref([]); // 已选择的标签ID
|
||||||
const formData = ref([
|
const formData = ref([
|
||||||
{ label: "人员照片", prop: "ryzp", type: "slot", width: "100%" },
|
{ label: "人员照片", prop: "ryzp", type: "slot", width: "100%" },
|
||||||
{ label: "姓名", prop: "ryXm", type: "input" },
|
{ label: "姓名", prop: "ryXm", type: "input", width: "30%" },
|
||||||
{ label: "性别", prop: "ryXb", type: "select", options: D_BZ_XB },
|
{ label: "身份证号", prop: "rySfzh", type: "input", width: "30%" },
|
||||||
{ label: "身份证号", prop: "rySfzh", type: "input" },
|
{ label: "性别", prop: "ryXb", type: "select", options: D_BZ_XB, width: "30%" },
|
||||||
{ label: "籍贯", prop: "ryJg", type: "select", options: D_BZ_XZQHDM },
|
{ label: "出生日期", prop: "ryCsrq", type: "date", width: "30%" },
|
||||||
{ label: "曾用名", prop: "cym", type: "input" },
|
{ label: "民族", prop: "ryMz", type: "select", options: D_BZ_MZ, width: "30%" },
|
||||||
{ label: "文化程度", prop: "whcdBm", type: "select", options: D_BZ_WHCD },
|
{ label: "协管单位", prop: "gxSsbmdm", depMc: 'gxSsbmmc', type: "department", width: "30%" },
|
||||||
{ label: "民族", prop: "ryMz", type: "select", options: D_BZ_MZ },
|
{ label: "预警等级", prop: "zdrYjdj", type: "select", options: D_GS_ZDR_YJDJ, width: "30%" },
|
||||||
{ label: "政治面貌", prop: "zzmm", type: "select", options: D_BZ_ZZMM },
|
{ label: "管控民警", prop: "gkMjXm", type: "slot", width: "30%" },
|
||||||
{ label: "职业", prop: "zyBm", type: "select", options: D_ZDRY_ZYLB },
|
{ label: "民警联系方式", prop: "gkMjLxfs", type: "input", width: "30%" },
|
||||||
{ label: "人员级别", prop: "zdrRyjb", type: "select", options: D_GS_ZDR_RYJB },
|
{ label: "入库开始时间", prop: "zdrRkkssj", type: "datetime", width: "30%" },
|
||||||
{ label: "预警等级", prop: "zdrYjdj", type: "select", options: D_GS_ZDR_YJDJ },
|
{ label: "入库结束时间", prop: "zdrRkjssj", type: "datetime", width: "30%" },
|
||||||
{ label: "出生日期", prop: "ryCsrq", type: "date" },
|
{ label: "重点人联系电话", prop: "ryLxdh", type: "input", width: "30%" },
|
||||||
{ label: "户籍地区划", prop: "hjdQh", type: "select", options: D_BZ_XZQHDM },
|
{ label: "籍贯", prop: "ryJg", type: "input", width: "30%" },
|
||||||
{ label: "户籍地详址", prop: "hjdXz", type: "input" },
|
{ label: "曾用名", prop: "cym", type: "input", width: "30%" },
|
||||||
{ label: "户籍地派出所", prop: "hjdPcsdm", depMc: "hjdPcsmc", type: "department" },
|
{ label: "文化程度", prop: "whcdBm", type: "select", options: D_BZ_WHCD, width: "30%" },
|
||||||
{ label: "现住地区划", prop: "xzdQh", type: "select", options: D_BZ_XZQHDM },
|
{ label: "政治面貌", prop: "zzmm", type: "select", options: D_BZ_ZZMM, width: "30%" },
|
||||||
{ label: "现住地详址", prop: "xzdXz", type: "input" },
|
{ label: "职业", prop: "zyBm", type: "input", width: "30%" },
|
||||||
{ label: "现住地派出所", prop: "xzdPcsdm", depMc: "xzdPcsmc", type: "department" },
|
{ label: "人员级别", prop: "zdrRyjb", type: "select", options: D_GS_ZDR_RYJB, width: "30%" },
|
||||||
{ label: "管控民警", prop: "gkmjxm", type: "slot" },
|
{ label: "户籍地区划", prop: "hjdQh", type: "input", width: "30%" },
|
||||||
{ label: "民警身份证", prop: "gkmjsfzh", type: "slot" },
|
{ label: "户籍地详址", prop: "hjdXz", type: "input", width: "30%" },
|
||||||
{ label: "管辖单位", prop: "gxSsbmdm", depMc: 'gxSsbmmc', type: "department" },
|
{ label: "户籍地派出所", prop: "hjdPcsmc", type: "input", width: "30%" },
|
||||||
{ label: "诉求单位", prop: "sqSsbmdm", depMc: 'sqSsbmmc', type: "department" },
|
{ label: "现住地区划", prop: "xzdQh", type: "input", width: "30%" },
|
||||||
{ label: "责任单位", prop: "zrSsbmdm", depMc: 'zrSsbmmc', type: "department" },
|
{ label: "现住地详址", prop: "xzdXz", type: "input", width: "30%" },
|
||||||
{ label: "所属警种", prop: "zdrSsjz", type: "select", options: D_GS_BK_SSJZ },
|
{ label: "现住地派出所", prop: "xzdPcsdm", depMc: "xzdPcsmc", type: "department", width: "30%" },
|
||||||
{ label: "涉及警种", prop: "zdrSjjz", type: "select", options: D_GS_BK_SSJZ, multiple: true },
|
|
||||||
{ label: "婚姻状态", prop: "hyzk", type: "select", options: D_BZ_HYZK },
|
// { label: "民警身份证", prop: "gkmjsfzh", type: "slot" },
|
||||||
// { label: "处置状态", prop: "zdrCzzt", type: "select", options: D_GS_ZDR_CZZT },
|
{ label: "诉求单位", prop: "sqSsbmmc", type: "input", width: "30%" },
|
||||||
// { label: "布控状态", prop: "zdrBkZt", type: "select", options: D_BZ_RCBKZT },
|
{ label: "责任单位", prop: "zrSsbmmc", type: "input", width: "30%" },
|
||||||
|
{ label: "所属警种", prop: "zdrSsjz", type: "select", options: D_GS_BK_SSJZ, width: "30%" },
|
||||||
|
{ label: "涉及警种", prop: "zdrSjjz", type: "select", options: D_GS_BK_SSJZ, multiple: true, width: "30%" },
|
||||||
|
{ label: "婚姻状态", prop: "hyzk", type: "select", options: D_BZ_HYZK, width: "30%" },
|
||||||
|
{ label: "处置状态", prop: "zdrCzzt", type: "select", options: D_GS_ZDR_CZZT, width: "30%" },
|
||||||
|
{ label: "布控状态", prop: "zdrBkZt", type: "select", options: D_BZ_RCBKZT, width: "30%" },
|
||||||
// { label: "人员类型", prop: "rylx", type: "select", options: D_ZDRY_RYLX },
|
// { label: "人员类型", prop: "rylx", type: "select", options: D_ZDRY_RYLX },
|
||||||
{ label: "入库开始时间", prop: "zdrRkkssj", type: "datetime" },
|
|
||||||
{ label: "入库结束时间", prop: "zdrRkjssj", type: "datetime" },
|
{ label: "Mac地址", prop: "macDz", type: "input", width: "30%" },
|
||||||
{ label: "Mac地址", prop: "macDz", type: "input" },
|
|
||||||
{ label: "联系电话", prop: "ryLxdh", type: "slot", width: "100%" },
|
|
||||||
// { label: "标签选择", prop: "tags", type: "slot", width: "100%" },
|
// { label: "标签选择", prop: "tags", type: "slot", width: "100%" },
|
||||||
{ label: "管控原因", prop: "zdrLkyy", type: "textarea", width: "100%" },
|
{ label: "管控原因", prop: "zdrLkyy", type: "textarea", width: "100%" },
|
||||||
]);
|
]);
|
||||||
@ -150,9 +142,22 @@ const deepClone = (obj) => {
|
|||||||
}
|
}
|
||||||
return clonedObj;
|
return clonedObj;
|
||||||
};
|
};
|
||||||
|
// 监听身份证号变化,自动填充性别、出生日期和民族
|
||||||
|
watch(() => listQuery.value.rySfzh, (val) => {
|
||||||
|
if (val && val.length === 18) {
|
||||||
|
// 使用IdCard方法提取出生日期
|
||||||
|
listQuery.value.ryCsrq = IdCard(val, 1);
|
||||||
|
// 使用IdCard方法提取性别
|
||||||
|
const genderText = IdCard(val, 2);
|
||||||
|
listQuery.value.ryXb = D_BZ_XB.value.find(item => item.zdmc === genderText).dm;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// 监听props.dataList变化,处理初始化数据
|
// 监听props.dataList变化,处理初始化数据
|
||||||
watch(() => props.dataList, (val) => {
|
watch(() => props.dataList, (val) => {
|
||||||
if (val) {
|
if (val) {
|
||||||
|
console.log(val);
|
||||||
|
|
||||||
// 使用深拷贝避免直接引用同一个对象
|
// 使用深拷贝避免直接引用同一个对象
|
||||||
listQuery.value = deepClone(val);
|
listQuery.value = deepClone(val);
|
||||||
// 处理照片数据
|
// 处理照片数据
|
||||||
@ -175,14 +180,9 @@ const submit = () => {
|
|||||||
};
|
};
|
||||||
//
|
//
|
||||||
const gettbGsxtZdryUpdate = () => {
|
const gettbGsxtZdryUpdate = () => {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const promes = {
|
const promes = {
|
||||||
...listQuery.value,
|
...listQuery.value,
|
||||||
ryzp: listQuery.value.ryzp.length > 0 ? listQuery.value.ryzp.toString() : "",
|
ryzp: listQuery.value.ryzp.length > 0 ? listQuery.value.ryzp.toString() : "",
|
||||||
ryLxdh: listQuery.value.ryLxdh,
|
|
||||||
zdrSjjz: JSON.stringify(listQuery.value.zdrSjjz),
|
zdrSjjz: JSON.stringify(listQuery.value.zdrSjjz),
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -200,28 +200,6 @@ const gettbGsxtZdryUpdate = () => {
|
|||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
// 添加电话号码
|
|
||||||
const addPhone = () => {
|
|
||||||
// 确保新添加的电话号码与现有数据结构一致
|
|
||||||
// 创建深拷贝以避免响应式更新问题
|
|
||||||
const newPhoneList = [...listQuery.value.ryLxdh];
|
|
||||||
newPhoneList.push('');
|
|
||||||
// 用全新数组替换现有数组,确保Vue正确检测到变化
|
|
||||||
listQuery.value.ryLxdh = newPhoneList;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 删除电话号码
|
|
||||||
const removePhone = (index) => {
|
|
||||||
if (listQuery.value.ryLxdh.length > 1) {
|
|
||||||
listQuery.value.ryLxdh.splice(index, 1);
|
|
||||||
} else {
|
|
||||||
// 清空输入但保留输入框
|
|
||||||
listQuery.value.ryLxdh[0] = '';
|
|
||||||
proxy.$message.warning('至少保留一个联系电话');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const throwData = () => {
|
const throwData = () => {
|
||||||
@ -229,32 +207,19 @@ const throwData = () => {
|
|||||||
if (elform.value && elform.value.validate) {
|
if (elform.value && elform.value.validate) {
|
||||||
elform.value.submit((data) => {
|
elform.value.submit((data) => {
|
||||||
// 过滤掉空的电话号码
|
// 过滤掉空的电话号码
|
||||||
const validPhones = listQuery.value.ryLxdh.filter(phone => phone && phone.trim());
|
|
||||||
if (validPhones.length === 0) {
|
|
||||||
proxy.$message.warning('请至少输入一个有效的联系电话');
|
|
||||||
reject(new Error('请至少输入一个有效的联系电话'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
resolve({
|
resolve({
|
||||||
...listQuery.value,
|
...listQuery.value,
|
||||||
ryzp: listQuery.value.ryzp && listQuery.value.ryzp.length > 0 ? listQuery.value.ryzp.toString() : '',
|
ryzp: listQuery.value.ryzp && listQuery.value.ryzp.length > 0 ? listQuery.value.ryzp.toString() : '',
|
||||||
ryLxdh: validPhones,
|
|
||||||
zdrSjjz: JSON.stringify(listQuery.value.zdrSjjz),
|
zdrSjjz: JSON.stringify(listQuery.value.zdrSjjz),
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
elform.value.submit((data) => {
|
elform.value.submit((data) => {
|
||||||
// 如果没有验证方法,直接返回数据
|
// 如果没有验证方法,直接返回数据
|
||||||
const validPhones = listQuery.value.ryLxdh.filter(phone => phone && phone.trim());
|
|
||||||
if (validPhones.length === 0) {
|
|
||||||
proxy.$message.warning('请至少输入一个有效的联系电话');
|
|
||||||
reject(new Error('请至少输入一个有效的联系电话'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
resolve({
|
resolve({
|
||||||
...listQuery.value,
|
...listQuery.value,
|
||||||
ryzp: listQuery.value.ryzp && listQuery.value.ryzp.length > 0 ? listQuery.value.ryzp.toString() : '',
|
ryzp: listQuery.value.ryzp && listQuery.value.ryzp.length > 0 ? listQuery.value.ryzp.toString() : '',
|
||||||
ryLxdh: validPhones,
|
|
||||||
zdrSjjz: JSON.stringify(listQuery.value.zdrSjjz),
|
zdrSjjz: JSON.stringify(listQuery.value.zdrSjjz),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -265,8 +230,9 @@ const throwData = () => {
|
|||||||
};
|
};
|
||||||
const choosed = (val) => {
|
const choosed = (val) => {
|
||||||
roleIds.value = [val[0].id]
|
roleIds.value = [val[0].id]
|
||||||
listQuery.value.gkmjxm = val[0].userName
|
listQuery.value.gkMjXm = val[0].userName
|
||||||
listQuery.value.gkmjsfzh = val[0].idEntityCard
|
listQuery.value.gkmjsfzh = val[0].idEntityCard
|
||||||
|
listQuery.value.gkMjLxfs = val[0].mobile
|
||||||
console.log(listQuery.value);
|
console.log(listQuery.value);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -96,48 +96,6 @@
|
|||||||
|
|
||||||
<!-- 操作 -->
|
<!-- 操作 -->
|
||||||
<template #controls="{ row }">
|
<template #controls="{ row }">
|
||||||
<el-popover placement="left" :visible="row.visible" :width="400" trigger="manual">
|
|
||||||
<template #reference>
|
|
||||||
<el-link size="small" type="warning" v-if="row.zdrZt == '02'"
|
|
||||||
@click="row.visible = !row.visible, chooseRow.id = row.id">审核</el-link>
|
|
||||||
</template>
|
|
||||||
<el-form :model="chooseRow" ref="elRowForm" :inline="true" label-width="100px" :rules="rules">
|
|
||||||
<el-form-item label="是否通过" prop="sftg" class="mt10 mb10" style="width: 100%;">
|
|
||||||
<MOSTY.Select filterable v-model="chooseRow.sftg" :dictEnum="D_BZ_SF" width="100%" clearable
|
|
||||||
placeholder="请选择是否通过" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="不通过原因" prop="shBtgyy" v-if="chooseRow.sftg == 0" style="width: 100%;">
|
|
||||||
<MOSTY.Other style="width: 100%;" clearable v-model="chooseRow.shBtgyy" type="textarea"
|
|
||||||
placeholder="请输入不通过原因" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
<div class="flex just-center mt10">
|
|
||||||
<el-button @click.stop="cancelRow(row)">取消</el-button>
|
|
||||||
<el-button type="primary" @click.stop="handleSend(row)" v-loading="btnloading">确定</el-button>
|
|
||||||
</div>
|
|
||||||
</el-popover>
|
|
||||||
|
|
||||||
<el-popover placement="left" :visible="row.visible1" :width="400" trigger="manual">
|
|
||||||
<template #reference>
|
|
||||||
<el-link size="small" type="primary" v-if="row.zdrZt == '04'"
|
|
||||||
@click="row.visible1 = !row.visible1, chooseRow.id = row.id">审批</el-link>
|
|
||||||
</template>
|
|
||||||
<el-form :model="chooseRow" ref="elRowForm1" :inline="true" label-width="100px" :rules="rules">
|
|
||||||
<el-form-item label="是否通过" prop="sftg" class="mt10 mb10" style="width: 100%;">
|
|
||||||
<MOSTY.Select filterable v-model="chooseRow.sftg" :dictEnum="D_BZ_SF" width="100%" clearable
|
|
||||||
placeholder="请选择是否通过" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="不通过原因" prop="spBtgyy" v-if="chooseRow.sftg == 0" style="width: 100%;">
|
|
||||||
<MOSTY.Other style="width: 100%;" clearable v-model="chooseRow.spBtgyy" type="textarea"
|
|
||||||
placeholder="请输入不通过原因" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
<div class="flex just-center mt10">
|
|
||||||
<el-button @click.stop="cancelRowSp(row)">取消</el-button>
|
|
||||||
<el-button type="primary" @click.stop="handleSendSp(row)" v-loading="btnloading">确定</el-button>
|
|
||||||
</div>
|
|
||||||
</el-popover>
|
|
||||||
|
|
||||||
<el-link size="small" type="primary" @click="addEdit('detail', row)">详情</el-link>
|
<el-link size="small" type="primary" @click="addEdit('detail', row)">详情</el-link>
|
||||||
</template>
|
</template>
|
||||||
</MyTable>
|
</MyTable>
|
||||||
@ -147,19 +105,18 @@
|
|||||||
}"></Pages>
|
}"></Pages>
|
||||||
</div>
|
</div>
|
||||||
<!-- 详情 -->
|
<!-- 详情 -->
|
||||||
<AddForm ref="addFormDiloag" @updateDate="getList"
|
<AddForm ref="addFormDiloag" @updateDate="getList" :showButData="true"
|
||||||
:dic="{ D_GS_ZDR_RYJB, D_BZ_XB, D_BZ_MZ, D_BZ_XZQHDM, D_GS_ZDR_BK_ZT, D_GS_ZDR_CZZT, D_GS_BQ_ZL, D_GS_BQ_LB, D_GS_BQ_LX, D_GS_ZDR_YJDJ, D_GS_BK_SSJZ }" />
|
:dic="{ D_GS_ZDR_RYJB, D_BZ_XB, D_BZ_MZ, D_BZ_XZQHDM, D_GS_ZDR_BK_ZT, D_GS_ZDR_CZZT, D_GS_BQ_ZL, D_GS_BQ_LB, D_GS_BQ_LX, D_GS_ZDR_YJDJ, D_GS_BK_SSJZ }" />
|
||||||
<!-- 选择用户 -->
|
<!-- 选择用户 -->
|
||||||
<ChooseUser v-model="chooseUserVisible" @choosedUsers="handleUserSelected" :roleIds="roleIds" />
|
<ChooseUser v-model="chooseUserVisible" @choosedUsers="handleUserSelected" :roleIds="roleIds" />
|
||||||
<!-- 转线索 -->
|
<!-- 转线索 -->
|
||||||
<ZxsForm v-if="showzxs" ref="zxsDilof" @change="getList"
|
<ZxsForm v-if="showzxs" ref="zxsDilof" @change="getList"
|
||||||
:dic="{ D_BZ_SF, D_BZ_XB, D_GS_XS_LY, D_BZ_SSZT, D_GS_XS_LX, D_GS_XS_QTLX }"></ZxsForm>
|
:dic="{ D_BZ_SF, D_BZ_XB, D_GS_XS_LY, D_BZ_SSZT, D_GS_XS_LX, D_GS_XS_QTLX }"></ZxsForm>
|
||||||
<Ypdolog v-model="showYpdolog" :dataList="ids"/>
|
<Ypdolog v-model="showYpdolog" :dataList="ids" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import * as MOSTY from "@/components/MyComponents/index";
|
|
||||||
import { ElMessage } from "element-plus";
|
import { ElMessage } from "element-plus";
|
||||||
import ChooseUser from "@/components/ChooseList/ChooseUser/index.vue";
|
import ChooseUser from "@/components/ChooseList/ChooseUser/index.vue";
|
||||||
import ZxsForm from "../mpvPeo/components/zxsForm.vue";
|
import ZxsForm from "../mpvPeo/components/zxsForm.vue";
|
||||||
@ -184,15 +141,6 @@ const ids = ref([]);
|
|||||||
const choosList = ref([]);
|
const choosList = ref([]);
|
||||||
const visible = ref(false);
|
const visible = ref(false);
|
||||||
const visiblefp = ref(false);
|
const visiblefp = ref(false);
|
||||||
const chooseRow = ref({})
|
|
||||||
const btnloading = ref(false)
|
|
||||||
const elRowForm = ref()
|
|
||||||
const elRowForm1 = ref()
|
|
||||||
const rules = reactive({
|
|
||||||
sftg: [{ required: true, message: "请选择是否通过", trigger: "change" }],
|
|
||||||
shBtgyy: [{ required: true, message: "请输入不通过原因", trigger: "blur" }],
|
|
||||||
spBtgyy: [{ required: true, message: "请输入不通过原因", trigger: "blur" }]
|
|
||||||
});
|
|
||||||
|
|
||||||
const searchConfiger = ref([
|
const searchConfiger = ref([
|
||||||
{
|
{
|
||||||
@ -346,50 +294,7 @@ const handleZxs = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const cancelRow = (row) => {
|
const showYpdolog = ref(false)
|
||||||
row.visible = false;
|
|
||||||
chooseRow.value = {};
|
|
||||||
btnloading.value = false;
|
|
||||||
elRowForm.value.resetFields()
|
|
||||||
};
|
|
||||||
|
|
||||||
// 审核
|
|
||||||
const handleSend = (val) => {
|
|
||||||
elRowForm.value.validate((valid) => {
|
|
||||||
if (!valid) return;
|
|
||||||
btnloading.value = true;
|
|
||||||
qcckPost(chooseRow.value, "/mosty-gsxt/tbGsxtZdry/updateSh").then(() => {
|
|
||||||
proxy.$message({ type: "success", message: "审核成功" });
|
|
||||||
cancelRow(val)
|
|
||||||
getList();
|
|
||||||
}).catch(() => {
|
|
||||||
btnloading.value = false;
|
|
||||||
});
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 审批
|
|
||||||
const cancelRowSp = (row) => {
|
|
||||||
row.visible1 = false;
|
|
||||||
chooseRow.value = {};
|
|
||||||
btnloading.value = false;
|
|
||||||
elRowForm1.value.resetFields()
|
|
||||||
}
|
|
||||||
// 审批
|
|
||||||
const handleSendSp = (val) => {
|
|
||||||
elRowForm1.value.validate((valid) => {
|
|
||||||
if (!valid) return;
|
|
||||||
btnloading.value = true;
|
|
||||||
qcckPost(chooseRow.value, "/mosty-gsxt/tbGsxtZdry/updateSp").then(() => {
|
|
||||||
proxy.$message({ type: "success", message: "审批成功" });
|
|
||||||
cancelRowSp(val);
|
|
||||||
getList();
|
|
||||||
}).catch(() => {
|
|
||||||
btnloading.value = false;
|
|
||||||
});
|
|
||||||
})
|
|
||||||
}
|
|
||||||
const showYpdolog=ref(false)
|
|
||||||
|
|
||||||
//新增编辑
|
//新增编辑
|
||||||
const addEdit = (type, row) => {
|
const addEdit = (type, row) => {
|
||||||
|
|||||||
@ -3,7 +3,8 @@
|
|||||||
<div class="head_box">
|
<div class="head_box">
|
||||||
<span class="title">{{ title }}临安码线索</span>
|
<span class="title">{{ title }}临安码线索</span>
|
||||||
<div>
|
<div>
|
||||||
<el-button type="primary" v-if="!listQuery.gzlid&&title!=='详情'" :loading="loading" @click="submit">保存</el-button>
|
<el-button type="primary" v-if="!listQuery.gzlid && title !== '详情'" :loading="loading"
|
||||||
|
@click="submit">保存</el-button>
|
||||||
<el-button @click="close">关闭</el-button>
|
<el-button @click="close">关闭</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -11,7 +12,7 @@
|
|||||||
|
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
|
|
||||||
<div class="form_cnt" :class="listQuery.gzlid&&title=='详情' ? 'ww80' : 'ww100'">
|
<div class="form_cnt" :class="listQuery.gzlid && title == '详情' ? 'ww80' : 'ww100'">
|
||||||
<FormMessage v-model="listQuery" :formList="formData" ref="elform" :rules="rules" :disabled="title == '详情'">
|
<FormMessage v-model="listQuery" :formList="formData" ref="elform" :rules="rules" :disabled="title == '详情'">
|
||||||
<template #gapdive>
|
<template #gapdive>
|
||||||
<div style="width: 100%;height: 10px;" class="mb20">
|
<div style="width: 100%;height: 10px;" class="mb20">
|
||||||
@ -31,7 +32,8 @@
|
|||||||
</template>
|
</template>
|
||||||
</FormMessage>
|
</FormMessage>
|
||||||
<el-divider content-position="left"><span class="mr20">相关人员</span>
|
<el-divider content-position="left"><span class="mr20">相关人员</span>
|
||||||
<el-button type="primary" size="small" @click="addEdit('add', null)" :disabled="title == '详情'">添加人员</el-button>
|
<el-button type="primary" size="small" @click="addEdit('add', null)"
|
||||||
|
:disabled="title == '详情'">添加人员</el-button>
|
||||||
</el-divider>
|
</el-divider>
|
||||||
<MyTable :tableData="pageForm.tableData" :tableColumn="pageForm.tableColumn" :tableHeight="pageForm.tableHeight"
|
<MyTable :tableData="pageForm.tableData" :tableColumn="pageForm.tableColumn" :tableHeight="pageForm.tableHeight"
|
||||||
:key="pageForm.keyCount" :tableConfiger="pageForm.tableConfiger" :controlsWidth="pageForm.controlsWidth">
|
:key="pageForm.keyCount" :tableConfiger="pageForm.tableConfiger" :controlsWidth="pageForm.controlsWidth">
|
||||||
@ -50,7 +52,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</MyTable>
|
</MyTable>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="listQuery.gzlid&&title=='详情'" class="ww20">
|
<div v-if="listQuery.gzlid && title == '详情'" class="ww20">
|
||||||
<ApprovalEcho ref="approvalEcho" />
|
<ApprovalEcho ref="approvalEcho" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -67,8 +69,11 @@ import AddPeo from '@/components/addPerson/index.vue'
|
|||||||
import MyTable from "@/components/aboutTable/MyTable.vue";
|
import MyTable from "@/components/aboutTable/MyTable.vue";
|
||||||
import FormMessage from "@/components/aboutTable/FormMessage.vue";
|
import FormMessage from "@/components/aboutTable/FormMessage.vue";
|
||||||
import { qcckGet, qcckPost, qcckPut } from "@/api/qcckApi.js";
|
import { qcckGet, qcckPost, qcckPut } from "@/api/qcckApi.js";
|
||||||
import { ref, defineExpose, reactive, onMounted, defineEmits, getCurrentInstance, nextTick,watch } from "vue";
|
import { ref, defineExpose, reactive, onMounted, defineEmits, getCurrentInstance, nextTick, watch } from "vue";
|
||||||
import ApprovalEcho from "@/components/flowPath/ApprovalEcho.vue";
|
import ApprovalEcho from "@/components/flowPath/ApprovalEcho.vue";
|
||||||
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
|
const router = useRouter()
|
||||||
|
const route = useRoute()
|
||||||
const emit = defineEmits(["change"]);
|
const emit = defineEmits(["change"]);
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
dic: Object
|
dic: Object
|
||||||
@ -147,10 +152,10 @@ const approvalEcho = ref()
|
|||||||
watch(() => approvalEcho.value, (val) => {
|
watch(() => approvalEcho.value, (val) => {
|
||||||
if (val) {
|
if (val) {
|
||||||
console.log(approvalEcho.value);
|
console.log(approvalEcho.value);
|
||||||
approvalEcho.value.getWorkflow(listQuery.value.gzlid)
|
approvalEcho.value.getWorkflow(listQuery.value.gzlid)
|
||||||
}
|
}
|
||||||
|
|
||||||
},{deep:true})
|
}, { deep: true })
|
||||||
|
|
||||||
// 打开弹窗
|
// 打开弹窗
|
||||||
const addEdit = (type, row, index) => {
|
const addEdit = (type, row, index) => {
|
||||||
@ -205,6 +210,11 @@ const close = () => {
|
|||||||
listQuery.value = {};
|
listQuery.value = {};
|
||||||
dialogForm.value = false;
|
dialogForm.value = false;
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
|
if (route.query.id) {
|
||||||
|
const query = { ...route.query };
|
||||||
|
delete query.id;
|
||||||
|
router.replace({ query });
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 表格高度计算
|
// 表格高度计算
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
<div>
|
<div>
|
||||||
|
|
||||||
<!-- 搜索 -->
|
<!-- 搜索 -->
|
||||||
<div ref="searchBox" class="mt10">
|
<div ref="searchBox" class="mt10">
|
||||||
<Search :searchArr="searchConfiger" @submit="onSearch" :key="pageData.keyCount">
|
<Search :searchArr="searchConfiger" @submit="onSearch" :key="pageData.keyCount">
|
||||||
<el-button type="danger" size="small" @click="plDelDictItem">
|
<el-button type="danger" size="small" @click="plDelDictItem">
|
||||||
<el-icon style="vertical-align: middle">
|
<el-icon style="vertical-align: middle">
|
||||||
@ -39,7 +39,7 @@
|
|||||||
<el-link size="small" type="primary" @click.stop="createProcess(row)">审核</el-link>
|
<el-link size="small" type="primary" @click.stop="createProcess(row)">审核</el-link>
|
||||||
<el-link size="small" type="danger" @click="delDictItem(row.id)">删除</el-link>
|
<el-link size="small" type="danger" @click="delDictItem(row.id)">删除</el-link>
|
||||||
</template>
|
</template>
|
||||||
<el-link size="small" type="warning" @click="openXsxf( row)">线索下发</el-link>
|
<el-link size="small" type="warning" @click="openXsxf(row)">线索下发</el-link>
|
||||||
</template>
|
</template>
|
||||||
</MyTable>
|
</MyTable>
|
||||||
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="pageData.tableHeight" :pageConfiger="{
|
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="pageData.tableHeight" :pageConfiger="{
|
||||||
@ -53,7 +53,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<SubmissionProcess v-model="showSp" :data="rowData"
|
<SubmissionProcess v-model="showSp" :data="rowData"
|
||||||
:userData="{ ajmc: '线索数据采集审批', flowType: 'XSSJCJSP', modelName: '线索' }" :path="fixedValue" @getList="getList" />
|
:userData="{ ajmc: '线索数据采集审批', flowType: 'XSSJCJSP', modelName: '线索' }" :path="fixedValue" @getList="getList" />
|
||||||
<Xsxf v-model="xsxfShow" :dataList="rowData"/>
|
<Xsxf v-model="xsxfShow" :dataList="rowData" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
@ -66,10 +66,12 @@ import { qcckGet, qcckPost } from "@/api/qcckApi.js";
|
|||||||
import { reactive, ref, onMounted, getCurrentInstance, nextTick } from "vue";
|
import { reactive, ref, onMounted, getCurrentInstance, nextTick } from "vue";
|
||||||
import { useRouter } from "vue-router";
|
import { useRouter } from "vue-router";
|
||||||
import Xsxf from "./components/xsxf.vue";
|
import Xsxf from "./components/xsxf.vue";
|
||||||
|
import { useRoute } from 'vue-router'
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
const route = useRoute()
|
||||||
const { proxy } = getCurrentInstance();
|
const { proxy } = getCurrentInstance();
|
||||||
const { D_GS_XS_XSCZZT, D_GS_XS_LY, D_BZ_SSZT, D_BZ_SF, D_GS_XS_LX, D_GS_XS_QTLX, D_BZ_XB, D_BZ_XSSHZT } = proxy.$dict("D_GS_XS_XSCZZT", "D_GS_XS_LY", "D_BZ_SSZT", "D_BZ_SF", "D_GS_XS_LX", "D_GS_XS_QTLX", "D_BZ_XB", "D_BZ_XSSHZT"); //获取字典数据
|
const { D_GS_XS_XSCZZT, D_GS_XS_LY, D_BZ_SSZT, D_BZ_SF, D_GS_XS_LX, D_GS_XS_QTLX, D_BZ_XB, D_BZ_XSSHZT } = proxy.$dict("D_GS_XS_XSCZZT", "D_GS_XS_LY", "D_BZ_SSZT", "D_BZ_SF", "D_GS_XS_LX", "D_GS_XS_QTLX", "D_BZ_XB", "D_BZ_XSSHZT"); //获取字典数据
|
||||||
const detailDiloag = ref();
|
const detailDiloag = ref(null);
|
||||||
const searchBox = ref(); //搜索框
|
const searchBox = ref(); //搜索框
|
||||||
const isShow = ref(false)
|
const isShow = ref(false)
|
||||||
const searchConfiger = ref([
|
const searchConfiger = ref([
|
||||||
@ -109,6 +111,11 @@ const pageData = reactive({
|
|||||||
const queryFrom = ref({});
|
const queryFrom = ref({});
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
if (route.query.id) {
|
||||||
|
addEdit('detail', {
|
||||||
|
id: route.query.id
|
||||||
|
})
|
||||||
|
}
|
||||||
getList()
|
getList()
|
||||||
tabHeightFn();
|
tabHeightFn();
|
||||||
});
|
});
|
||||||
@ -205,7 +212,7 @@ const createProcess = (row) => {
|
|||||||
const xsxfShow = ref(false)
|
const xsxfShow = ref(false)
|
||||||
const openXsxf = (row) => {
|
const openXsxf = (row) => {
|
||||||
xsxfShow.value = true
|
xsxfShow.value = true
|
||||||
rowData.value = {...row}
|
rowData.value = { ...row }
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -2,8 +2,8 @@
|
|||||||
<div>
|
<div>
|
||||||
<!-- 搜索 -->
|
<!-- 搜索 -->
|
||||||
<div ref="searchBox" class="mt10">
|
<div ref="searchBox" class="mt10">
|
||||||
<Search :searchArr="searchConfiger" @submit="onSearch" :key="pageData.keyCount" >
|
<Search :searchArr="searchConfiger" @submit="onSearch" :key="pageData.keyCount">
|
||||||
<el-button type="primary" size="small" @click="getDataById('add', '')">
|
<el-button type="primary" size="small" @click="getDataById('add', '')">
|
||||||
<el-icon style="vertical-align: middle">
|
<el-icon style="vertical-align: middle">
|
||||||
<CirclePlus />
|
<CirclePlus />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
@ -51,7 +51,6 @@ import { reactive, ref, onMounted, getCurrentInstance, watch, computed } from "v
|
|||||||
import AddForm from "./addForm.vue";
|
import AddForm from "./addForm.vue";
|
||||||
const { proxy } = getCurrentInstance();
|
const { proxy } = getCurrentInstance();
|
||||||
const { D_BZ_YPFS, D_BZ_YPLX } = proxy.$dict("D_BZ_YPFS", "D_BZ_YPLX")
|
const { D_BZ_YPFS, D_BZ_YPLX } = proxy.$dict("D_BZ_YPFS", "D_BZ_YPLX")
|
||||||
const detailDiloag = ref();
|
|
||||||
const searchBox = ref(); //搜索框
|
const searchBox = ref(); //搜索框
|
||||||
|
|
||||||
const userInfo = ref({})
|
const userInfo = ref({})
|
||||||
@ -59,7 +58,7 @@ onMounted(() => {
|
|||||||
userInfo.value = getItem('deptId') ? getItem('deptId')[0] : {}
|
userInfo.value = getItem('deptId') ? getItem('deptId')[0] : {}
|
||||||
tabHeightFn()
|
tabHeightFn()
|
||||||
if (route.query.id) {
|
if (route.query.id) {
|
||||||
detailDiloag.value.init('edit', {
|
addForm.value.init('detail', {
|
||||||
id: route.query.id
|
id: route.query.id
|
||||||
});
|
});
|
||||||
return
|
return
|
||||||
@ -77,7 +76,7 @@ const isShiQingBaoZhongXin = computed(() => {
|
|||||||
|
|
||||||
const searchConfiger = ref([
|
const searchConfiger = ref([
|
||||||
{ label: "约稿时间", prop: 'startTime', placeholder: "请输入约稿时间", showType: "datetimerange" },
|
{ label: "约稿时间", prop: 'startTime', placeholder: "请输入约稿时间", showType: "datetimerange" },
|
||||||
{ label: "约稿要求", prop: 'ypyq', placeholder: "请输入约稿要求", showType: "input" },
|
{ label: "约稿要求", prop: 'ypyq', placeholder: "请输入约稿要求", showType: "input" },
|
||||||
// { label: "研判方式", prop: 'ypfs', placeholder: "请输入研判方式", showType: "radio",options:D_BZ_YPFS },
|
// { label: "研判方式", prop: 'ypfs', placeholder: "请输入研判方式", showType: "radio",options:D_BZ_YPFS },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|||||||
@ -12,9 +12,10 @@
|
|||||||
<el-option label="人像预警" value="人像预警" />
|
<el-option label="人像预警" value="人像预警" />
|
||||||
<el-option label="车辆预警" value="车辆预警" />
|
<el-option label="车辆预警" value="车辆预警" />
|
||||||
<el-option label="区域预警" value="区域预警" />
|
<el-option label="区域预警" value="区域预警" />
|
||||||
|
<el-option label="布控预警" value="布控预警" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-popover>
|
</el-popover>
|
||||||
<el-popover placement="right" :width="240" style='height: 300px;' trigger="click" v-else-if ="item == '标签预警'">
|
<el-popover placement="right" :width="240" style='height: 300px;' trigger="click" v-else-if="item == '标签预警'">
|
||||||
<template #reference>
|
<template #reference>
|
||||||
<el-button :type="BqbutStylChange(qh) ? 'primary' : 'default'" size="small">{{ item }}</el-button>
|
<el-button :type="BqbutStylChange(qh) ? 'primary' : 'default'" size="small">{{ item }}</el-button>
|
||||||
</template>
|
</template>
|
||||||
@ -62,7 +63,7 @@ import Cs from '@/views/backOfficeSystem/ces/index.vue'
|
|||||||
import { onMounted, ref } from "vue";
|
import { onMounted, ref } from "vue";
|
||||||
// "人像预警", "车辆预警",, "区域预警","无人机预警"
|
// "人像预警", "车辆预警",, "区域预警","无人机预警"
|
||||||
const butList = ref(["七类重点", '政保预警', "布控预警", "预警整合"])
|
const butList = ref(["七类重点", '政保预警', "布控预警", "预警整合"])
|
||||||
const qh = ref('预警整合')
|
const qh = ref('七类重点')
|
||||||
const value = ref('人像预警')
|
const value = ref('人像预警')
|
||||||
const Bqvalue = ref('身份预警')
|
const Bqvalue = ref('身份预警')
|
||||||
const butStyle = ref()
|
const butStyle = ref()
|
||||||
|
|||||||
203
src/views/backOfficeSystem/luntan/components/ChangeAvatar.vue
Normal file
203
src/views/backOfficeSystem/luntan/components/ChangeAvatar.vue
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog :model-value="modelValue" center width="500px" :destroy-on-close="true" :title="title" @close="close"
|
||||||
|
:close-on-click-modal="false">
|
||||||
|
<div class="avatar-upload-container">
|
||||||
|
<div class="avatar-preview">
|
||||||
|
<img v-if="avatarUrl" :src="avatarUrl" alt="预览头像" class="preview-image">
|
||||||
|
<div v-else class="preview-placeholder">
|
||||||
|
<el-icon class="placeholder-icon">
|
||||||
|
<User />
|
||||||
|
</el-icon>
|
||||||
|
<span>请上传头像</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="upload-section">
|
||||||
|
<el-upload class="avatar-uploader" :auto-upload="false" :show-file-list="false"
|
||||||
|
:on-change="handleAvatarChange" :before-upload="beforeAvatarUpload" accept="image/*">
|
||||||
|
<el-button size="small" type="primary">选择图片</el-button>
|
||||||
|
</el-upload>
|
||||||
|
<div class="upload-tips">
|
||||||
|
<p>• 支持 JPG、PNG 格式</p>
|
||||||
|
<p>• 图片大小不超过 2MB</p>
|
||||||
|
<p>• 建议尺寸为 200x200 像素</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="close">取消</el-button>
|
||||||
|
<el-button type="primary" @click="confirmUpload" :loading="uploading" :disabled="!avatarUrl || uploading">
|
||||||
|
{{ uploading ? '上传中...' : '确认更换' }}
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, watch } from "vue";
|
||||||
|
import { ElMessage } from 'element-plus';
|
||||||
|
import { User } from '@element-plus/icons-vue';
|
||||||
|
import { upImageUploadId } from '@/api/commit';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
default: "更换头像"
|
||||||
|
},
|
||||||
|
heightNumber: {
|
||||||
|
type: Number,
|
||||||
|
default: 250
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const emits = defineEmits(["update:modelValue", "avatarUpdated"]);
|
||||||
|
|
||||||
|
// 头像相关状态
|
||||||
|
const avatarUrl = ref('');
|
||||||
|
const uploading = ref(false);
|
||||||
|
|
||||||
|
// 监听对话框显示状态,重置头像预览
|
||||||
|
watch(() => props.modelValue, (newVal) => {
|
||||||
|
if (!newVal) {
|
||||||
|
// 对话框关闭时重置头像预览
|
||||||
|
avatarUrl.value = '';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 当前选择的文件
|
||||||
|
const selectedFile = ref(null);
|
||||||
|
|
||||||
|
// 处理头像选择
|
||||||
|
const handleAvatarChange = (file) => {
|
||||||
|
selectedFile.value = file.raw;
|
||||||
|
// 创建临时预览URL
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.onload = (e) => {
|
||||||
|
avatarUrl.value = e.target.result;
|
||||||
|
};
|
||||||
|
reader.readAsDataURL(file.raw);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 上传前检查
|
||||||
|
const beforeAvatarUpload = (file) => {
|
||||||
|
const isJPG = file.type === 'image/jpeg';
|
||||||
|
const isPNG = file.type === 'image/png';
|
||||||
|
const isLt2M = file.size / 1024 / 1024 < 2;
|
||||||
|
|
||||||
|
if (!isJPG && !isPNG) {
|
||||||
|
ElMessage.error('请上传 JPG 或 PNG 格式的图片!');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!isLt2M) {
|
||||||
|
ElMessage.error('图片大小不能超过 2MB!');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 确认上传头像
|
||||||
|
const confirmUpload = async () => {
|
||||||
|
if (!avatarUrl.value || !selectedFile.value) {
|
||||||
|
ElMessage.warning('请先选择头像图片');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uploading.value = true;
|
||||||
|
try {
|
||||||
|
// 创建FormData对象
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append('file', selectedFile.value);
|
||||||
|
// 调用实际的上传接口
|
||||||
|
const response = await upImageUploadId(formData);
|
||||||
|
console.log(response);
|
||||||
|
emits('avatarUpdated', response);
|
||||||
|
// 关闭对话框
|
||||||
|
close();
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('上传头像失败:', error);
|
||||||
|
ElMessage.error('上传头像失败,请重试');
|
||||||
|
} finally {
|
||||||
|
uploading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 关闭对话框
|
||||||
|
const close = () => {
|
||||||
|
emits("update:modelValue", false);
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.avatar-upload-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar-preview {
|
||||||
|
width: 160px;
|
||||||
|
height: 160px;
|
||||||
|
border-radius: 50%;
|
||||||
|
overflow: hidden;
|
||||||
|
border: 2px solid #e8e8e8;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
|
||||||
|
.preview-image {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-placeholder {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
color: #909399;
|
||||||
|
|
||||||
|
.placeholder-icon {
|
||||||
|
font-size: 48px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-section {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar-uploader {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-tips {
|
||||||
|
width: 100%;
|
||||||
|
padding: 12px;
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #909399;
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin: 4px 0;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
488
src/views/backOfficeSystem/luntan/components/CommentList.vue
Normal file
488
src/views/backOfficeSystem/luntan/components/CommentList.vue
Normal file
@ -0,0 +1,488 @@
|
|||||||
|
<template>
|
||||||
|
<div class="comment-list">
|
||||||
|
<div v-for="comment in comments" :key="comment.id" class="comment-item">
|
||||||
|
<!-- 一级评论 -->
|
||||||
|
<div class="comment-main">
|
||||||
|
<el-avatar :size="40" :src="comment.userAvatar" class="comment-avatar">
|
||||||
|
<img src="@/assets/images/mr.png" />
|
||||||
|
</el-avatar>
|
||||||
|
|
||||||
|
<div class="comment-content">
|
||||||
|
<div class="comment-header">
|
||||||
|
<div class="user-info">
|
||||||
|
<span class="user-name">{{ comment.userName }}</span>
|
||||||
|
<div v-if="comment.ssbm" class="author-tag">
|
||||||
|
{{ comment.ssbm }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="comment-text">{{ comment.content }}</div>
|
||||||
|
|
||||||
|
<div class="comment-footer">
|
||||||
|
<span class="comment-time">{{ comment.publishTime }}</span>
|
||||||
|
<div class="comment-actions">
|
||||||
|
<!-- <div class="action-btn" :class="{ active: comment.isLiked }" @click="handleLike(comment)">
|
||||||
|
<el-icon>
|
||||||
|
<Promotion />
|
||||||
|
</el-icon>
|
||||||
|
<span>{{ comment.likeCount || 0 }}</span>
|
||||||
|
</div> -->
|
||||||
|
<div class="action-btn" @click="handleReply(comment)">
|
||||||
|
回复
|
||||||
|
</div>
|
||||||
|
<div v-if="comment.replies && comment.replies.length > 0" class="action-btn toggle-btn"
|
||||||
|
@click="toggleReplies(comment)">
|
||||||
|
{{ comment.showReplies ? '收起' : `展开${comment.replies.length}条回复` }}
|
||||||
|
<el-icon :class="{ 'rotate-icon': comment.showReplies }">
|
||||||
|
<ArrowDown />
|
||||||
|
</el-icon>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 回复输入框 -->
|
||||||
|
<transition name="slide-fade">
|
||||||
|
<div v-if="activeReplyId === comment.id" class="reply-input-box">
|
||||||
|
<div class="reply-label">回复 {{ comment.userName }}</div>
|
||||||
|
<el-input v-model="replyContent" type="textarea" :rows="3" placeholder="输入回复内容..."
|
||||||
|
class="reply-textarea" />
|
||||||
|
<div class="reply-actions">
|
||||||
|
<V3Emoji :options-name="optionsName" @click-emoji="onEmojiClick" :recent="true" style="width: 40px;" />
|
||||||
|
<div class="reply-buttons">
|
||||||
|
<el-button size="small" @click="cancelReply">取消</el-button>
|
||||||
|
<el-button size="small" type="primary" @click="submitReply(comment)">
|
||||||
|
回复
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
|
|
||||||
|
<!-- 二级评论列表 -->
|
||||||
|
<div v-if="comment.replies && comment.replies.length > 0 && comment.showReplies" class="replies-list">
|
||||||
|
<div v-for="reply in comment.replies" :key="reply.id" class="reply-item">
|
||||||
|
<el-avatar :size="32" :src="reply.userAvatar" class="reply-avatar">
|
||||||
|
<img src="@/assets/images/mr.png" />
|
||||||
|
</el-avatar>
|
||||||
|
|
||||||
|
<div class="reply-content">
|
||||||
|
<div class="reply-header">
|
||||||
|
<span class="user-name">{{ reply.userName }}</span>
|
||||||
|
<div v-if="reply.ssbm" class="author-tag">
|
||||||
|
{{ reply.ssbm }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="reply-text">
|
||||||
|
<span v-if="reply.replyToUser" class="reply-to">
|
||||||
|
回复 {{ reply.replyToUser }}:
|
||||||
|
</span>
|
||||||
|
{{ reply.content }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="reply-footer">
|
||||||
|
<span class="reply-time">{{ reply.publishTime }}</span>
|
||||||
|
<div class="reply-actions">
|
||||||
|
<!-- <div class="action-btn" :class="{ active: reply.isLiked }" @click="handleLike(reply)">
|
||||||
|
<el-icon>
|
||||||
|
<Promotion />
|
||||||
|
</el-icon>
|
||||||
|
<span v-if="reply.likeCount">{{ reply.likeCount }}</span>
|
||||||
|
</div> -->
|
||||||
|
<div class="action-btn" @click="handleReplyToReply(reply, comment)">
|
||||||
|
回复
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 二级回复输入框 -->
|
||||||
|
<transition name="slide-fade">
|
||||||
|
<div v-if="activeReplyId === reply.id" class="reply-input-box">
|
||||||
|
<div class="reply-label">回复 {{ reply.userName }}</div>
|
||||||
|
<el-input v-model="replyContent" type="textarea" :rows="3" placeholder="输入回复内容..."
|
||||||
|
class="reply-textarea" />
|
||||||
|
<div class="reply-actions">
|
||||||
|
<V3Emoji :options-name="optionsName" @click-emoji="onEmojiClick" :recent="true"
|
||||||
|
style="width: 40px;" />
|
||||||
|
<div class="reply-buttons">
|
||||||
|
<el-button size="small" @click="cancelReply">取消</el-button>
|
||||||
|
<el-button size="small" type="primary" @click="submitReply(comment, reply)">
|
||||||
|
回复
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { Promotion, ArrowDown } from '@element-plus/icons-vue'
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
import V3Emoji from 'vue3-emoji'
|
||||||
|
import { tbGsxtXxltHfid, tbGsxtXxltHfSave, tbGsxtXxltHfSelectList } from '@/api/tbGsxtXxltHf.js'
|
||||||
|
import { getItem } from '@/utils/storage.js'
|
||||||
|
import { setAddress } from '@/utils/tools'
|
||||||
|
|
||||||
|
const optionsName = {
|
||||||
|
'Smileys & Emotion': '笑脸&表情',
|
||||||
|
'Food & Drink': '食物&饮料',
|
||||||
|
'Animals & Nature': '动物&自然',
|
||||||
|
'Travel & Places': '旅行&地点',
|
||||||
|
'People & Body': '人物&身体',
|
||||||
|
Objects: '物品',
|
||||||
|
Symbols: '符号',
|
||||||
|
Flags: '旗帜',
|
||||||
|
Activities: '活动'
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
comments: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
}, replyTo: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits(['reply', 'like'])
|
||||||
|
|
||||||
|
const activeReplyId = ref(null)
|
||||||
|
const replyContent = ref('')
|
||||||
|
|
||||||
|
const getTagType = (tag) => {
|
||||||
|
const tagMap = {
|
||||||
|
'户外活动部': 'success',
|
||||||
|
'校长': 'warning',
|
||||||
|
'校本部': 'info'
|
||||||
|
}
|
||||||
|
return tagMap[tag] || 'info'
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleLike = (comment) => {
|
||||||
|
emit('like', comment)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleReply = (comment) => {
|
||||||
|
emit('reply')
|
||||||
|
activeReplyId.value = comment.id
|
||||||
|
replyContent.value = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleReplyToReply = (reply, parentComment) => {
|
||||||
|
emit('reply')
|
||||||
|
activeReplyId.value = reply.id
|
||||||
|
replyContent.value = `@${reply.userName}:`
|
||||||
|
}
|
||||||
|
|
||||||
|
const onEmojiClick = (emoji) => {
|
||||||
|
replyContent.value += emoji
|
||||||
|
}
|
||||||
|
|
||||||
|
const cancelReply = () => {
|
||||||
|
activeReplyId.value = null
|
||||||
|
replyContent.value = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
// 切换回复列表的展开/收起
|
||||||
|
const toggleReplies = (comment) => {
|
||||||
|
if (!comment.showReplies) {
|
||||||
|
comment.showReplies = true
|
||||||
|
} else {
|
||||||
|
comment.showReplies = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const formatReplyItem = (reply) => {
|
||||||
|
return {
|
||||||
|
...reply,
|
||||||
|
id: reply.id,
|
||||||
|
userName: reply.hfrxm || '匿名用户',
|
||||||
|
userAvatar: reply.userAvatar || (reply.hfrtx ? setAddress(reply.hfrtx) : ''),
|
||||||
|
userTag: reply.userTag || '',
|
||||||
|
content: reply.content || reply.hfnr || '',
|
||||||
|
publishTime: reply.publishTime || reply.hfsj || '',
|
||||||
|
likeCount: reply.likeCount || 0,
|
||||||
|
isLiked: reply.isLiked || false,
|
||||||
|
ssbm: reply.ssbm || '',
|
||||||
|
replyToUser: reply.replyToUser || reply.sjhfrxm || ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const submitReply = async (parentComment, replyToComment = null) => {
|
||||||
|
console.log(parentComment);
|
||||||
|
|
||||||
|
if (!replyContent.value.trim()) {
|
||||||
|
ElMessage.warning('请输入回复内容')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const ltmasg = getItem("ltmasg")
|
||||||
|
let pureContent = replyContent.value
|
||||||
|
if (pureContent.startsWith('@') && pureContent.includes(':')) {
|
||||||
|
const colonIndex = pureContent.indexOf(':')
|
||||||
|
if (colonIndex !== -1 && colonIndex < pureContent.length - 1) {
|
||||||
|
pureContent = pureContent.substring(colonIndex + 1).trim()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!pureContent) {
|
||||||
|
ElMessage.warning('请输入回复内容')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const targetReply = replyToComment || null
|
||||||
|
const newReply = {
|
||||||
|
hfnr: pureContent,
|
||||||
|
hfrsfzh: ltmasg.sfzh,
|
||||||
|
hfrtx: ltmasg.tx,
|
||||||
|
hfrxm: ltmasg.xm,
|
||||||
|
ltid: props.replyTo.id,
|
||||||
|
sfyjhf: 0,
|
||||||
|
sjhfid: parentComment.id,
|
||||||
|
sjhfrxm: targetReply ? targetReply.userName : ''
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const res = await tbGsxtXxltHfSave(newReply)
|
||||||
|
if (res) {
|
||||||
|
const dataxhf = await tbGsxtXxltHfSelectList({ sjhfid: parentComment.id })
|
||||||
|
const replyList = Array.isArray(dataxhf) ? dataxhf : (dataxhf?.records || [])
|
||||||
|
parentComment.replies = replyList.map(formatReplyItem)
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
// if (!parentComment.replies) {
|
||||||
|
// parentComment.replies = []
|
||||||
|
// }
|
||||||
|
// parentComment.replies.push(newReply)
|
||||||
|
|
||||||
|
// 自动展开回复列表
|
||||||
|
parentComment.showReplies = true
|
||||||
|
ElMessage.success('回复成功')
|
||||||
|
cancelReply()
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
|
||||||
|
ElMessage.error('回复失败')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.comment-list {
|
||||||
|
.comment-item {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.comment-main {
|
||||||
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comment-avatar {
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comment-content {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
padding-top: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comment-header {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-name {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #303133;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comment-text {
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.6;
|
||||||
|
color: #606266;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comment-footer {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comment-time {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #909399;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comment-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #909399;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #409eff;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
color: #409eff;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.toggle-btn {
|
||||||
|
.el-icon {
|
||||||
|
transition: transform 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rotate-icon {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.reply-input-box {
|
||||||
|
margin-top: 12px;
|
||||||
|
padding: 12px;
|
||||||
|
background: #f5f7fa;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reply-label {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #606266;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reply-textarea {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reply-actions {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reply-buttons {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.replies-list {
|
||||||
|
margin-top: 16px;
|
||||||
|
padding-left: 12px;
|
||||||
|
border-left: 2px solid #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reply-item {
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
align-items: flex-start;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.reply-avatar {
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reply-content {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
padding-top: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reply-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reply-text {
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 1.6;
|
||||||
|
color: #606266;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reply-to {
|
||||||
|
color: #409eff;
|
||||||
|
margin-right: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reply-footer {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reply-time {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #909399;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reply-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slide-fade-enter-active {
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slide-fade-leave-active {
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slide-fade-enter-from,
|
||||||
|
.slide-fade-leave-to {
|
||||||
|
transform: translateY(-10px);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.author-tag {
|
||||||
|
padding: 2px 8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: #409EFF;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 18px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
471
src/views/backOfficeSystem/luntan/components/PostDetail.vue
Normal file
471
src/views/backOfficeSystem/luntan/components/PostDetail.vue
Normal file
@ -0,0 +1,471 @@
|
|||||||
|
<template>
|
||||||
|
<div class="post-detail">
|
||||||
|
<!-- 头部 -->
|
||||||
|
<div class="detail-header">
|
||||||
|
<el-button text @click="handleBack">
|
||||||
|
<el-icon>
|
||||||
|
<ArrowLeft />
|
||||||
|
</el-icon>
|
||||||
|
返回
|
||||||
|
</el-button>
|
||||||
|
<div class="header-title">帖子详情</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 帖子内容 -->
|
||||||
|
<div class="post-main">
|
||||||
|
<div class="premium-badge" v-if="postData.isPremium">精品</div>
|
||||||
|
|
||||||
|
<div class="post-author">
|
||||||
|
<el-avatar :size="50" :src="postData.userAvatar">
|
||||||
|
<img src="@/assets/images/mr.png" />
|
||||||
|
</el-avatar>
|
||||||
|
<div class="author-info">
|
||||||
|
<div class="author-name-row">
|
||||||
|
<span class="author-name">{{ postData.userName }}</span>
|
||||||
|
<div v-if="postData.ssbm" class="author-tag">
|
||||||
|
{{ postData.ssbm }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="publish-time">{{ postData.publishTime }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="post-content-text">{{ postData.content }}</div>
|
||||||
|
|
||||||
|
<!-- 图片展示 -->
|
||||||
|
<div class="post-images" v-if="postData.images && postData.images.length > 0">
|
||||||
|
<div v-for="(img, index) in postData.images" :key="index" class="image-item">
|
||||||
|
<el-image :src="img" fit="cover" :preview-src-list="postData.images" :initial-index="index">
|
||||||
|
<template #error>
|
||||||
|
<div class="image-error">
|
||||||
|
<el-icon>
|
||||||
|
<Picture />
|
||||||
|
</el-icon>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-image>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 统计信息 -->
|
||||||
|
<div class="post-stats">
|
||||||
|
<div class="stat-item">
|
||||||
|
<el-icon>
|
||||||
|
<ChatDotRound />
|
||||||
|
</el-icon>
|
||||||
|
<span>{{ postData.commentCount || 0 }}</span>
|
||||||
|
</div>
|
||||||
|
<!-- <div class="stat-item" :class="{ active: postData.isLiked }" @click="handleLike">
|
||||||
|
<el-icon>
|
||||||
|
<Promotion />
|
||||||
|
</el-icon>
|
||||||
|
<span>{{ postData.likeCount || 0 }}</span>
|
||||||
|
</div> -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 评论区 -->
|
||||||
|
<div class="comment-section">
|
||||||
|
<!-- Tab切换 -->
|
||||||
|
<div class="comment-tabs">
|
||||||
|
<div class="tab-item" :class="{ active: activeTab === 'all' }" @click="activeTab = 'all'">
|
||||||
|
全部回复({{ comments.length }})
|
||||||
|
</div>
|
||||||
|
<!-- <div class="tab-item" :class="{ active: activeTab === 'author' }" @click="activeTab = 'author'">
|
||||||
|
只看楼主
|
||||||
|
</div> -->
|
||||||
|
|
||||||
|
<!-- <div class="sort-buttons">
|
||||||
|
<el-button text size="small">热门</el-button>
|
||||||
|
<el-button text size="small">正序</el-button>
|
||||||
|
<el-button text size="small">倒序</el-button>
|
||||||
|
</div> -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 顶部输入框 - 点击打开弹窗 -->
|
||||||
|
<div class="top-input" @click="replyToData">
|
||||||
|
<el-input placeholder="发点干货 文明第一步" readonly />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 评论列表 -->
|
||||||
|
|
||||||
|
<CommentList :comments="filteredComments" @reply="handleReply" :replyTo="replyTo" @like="handleCommentLike" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 回复弹窗 -->
|
||||||
|
<ReplyDialog v-model="showReplyDialog" :reply-to="replyTo" @success="handleReplySuccess" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, computed, onMounted } from 'vue'
|
||||||
|
import { ArrowLeft, ChatDotRound, Promotion, Picture } from '@element-plus/icons-vue'
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
import CommentList from './CommentList.vue'
|
||||||
|
import ReplyDialog from './ReplyDialog.vue'
|
||||||
|
import { tbGsxtXxltHfid } from '@/api/tbGsxtXxltHf'
|
||||||
|
import { setAddress } from '@/utils/tools'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
postId: {
|
||||||
|
type: [String, Number],
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits(['back'])
|
||||||
|
|
||||||
|
const activeTab = ref('all')
|
||||||
|
const showReplyDialog = ref(false)
|
||||||
|
const replyTo = ref(null)
|
||||||
|
const loading = ref(false)
|
||||||
|
|
||||||
|
// 帖子数据
|
||||||
|
const postData = ref({
|
||||||
|
id: null,
|
||||||
|
userName: '',
|
||||||
|
userAvatar: '',
|
||||||
|
userTag: '',
|
||||||
|
publishTime: '',
|
||||||
|
content: '',
|
||||||
|
images: [],
|
||||||
|
commentCount: 0,
|
||||||
|
likeCount: 0,
|
||||||
|
isPremium: false,
|
||||||
|
isLiked: false
|
||||||
|
})
|
||||||
|
|
||||||
|
// 评论数据
|
||||||
|
const comments = ref([])
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
loadPostDetail()
|
||||||
|
})
|
||||||
|
|
||||||
|
const loadPostDetail = async () => {
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
const res = await tbGsxtXxltHfid(props.postId)
|
||||||
|
|
||||||
|
// 设置帖子数据
|
||||||
|
postData.value = {
|
||||||
|
id: res.id,
|
||||||
|
userName: res.fbrxm || '匿名用户',
|
||||||
|
userAvatar: res.fbrtx ? setAddress(res.fbrtx) : '',
|
||||||
|
userTag: res.userTag || '',
|
||||||
|
publishTime: res.time || '',
|
||||||
|
content: res.content || '',
|
||||||
|
images: res.tp ? res.tp.split(',').map(img => setAddress(img)) : [],
|
||||||
|
commentCount: res.commentCount || 0,
|
||||||
|
likeCount: res.likeCount || 0,
|
||||||
|
isPremium: res.sfzd === 1,
|
||||||
|
isLiked: false,
|
||||||
|
ssbm: res.ssbm,
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置评论数据
|
||||||
|
if (res.replyList && res.replyList.length > 0) {
|
||||||
|
comments.value = res.replyList.map(item => ({
|
||||||
|
id: item.id,
|
||||||
|
userName: item.hfrxm || '匿名用户',
|
||||||
|
userAvatar: item.hfrtx ? setAddress(item.hfrtx) : '',
|
||||||
|
userTag: item.userTag || '',
|
||||||
|
content: item.hfnr || '',
|
||||||
|
publishTime: item.hfsj || '',
|
||||||
|
likeCount: item.likeCount || 0,
|
||||||
|
isLiked: false,
|
||||||
|
showReplies: false,
|
||||||
|
ssbm: item.ssbm,
|
||||||
|
replies: item.xjfhList ? item.xjfhList.map(reply => ({
|
||||||
|
id: reply.id,
|
||||||
|
userName: reply.hfrxm || '匿名用户',
|
||||||
|
userAvatar: reply.hfrtx ? setAddress(reply.hfrtx) : '',
|
||||||
|
userTag: reply.userTag || '',
|
||||||
|
content: reply.hfnr || '',
|
||||||
|
publishTime: reply.hfsj || '',
|
||||||
|
likeCount: reply.likeCount || 0,
|
||||||
|
isLiked: false,
|
||||||
|
replyToUser: reply.sjhfrxm || '',
|
||||||
|
ssbm: reply.ssbm,
|
||||||
|
})) : []
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('加载详情失败', error)
|
||||||
|
ElMessage.error('加载详情失败')
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const filteredComments = computed(() => {
|
||||||
|
if (activeTab.value === 'author') {
|
||||||
|
return comments.value.filter(c => c.userName === postData.value.userName)
|
||||||
|
}
|
||||||
|
console.log(comments.value);
|
||||||
|
|
||||||
|
return comments.value
|
||||||
|
})
|
||||||
|
|
||||||
|
const getTagType = (tag) => {
|
||||||
|
const tagMap = {
|
||||||
|
'户外活动部': 'success',
|
||||||
|
'校长': 'warning',
|
||||||
|
'校本部': 'info'
|
||||||
|
}
|
||||||
|
return tagMap[tag] || 'info'
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleBack = () => {
|
||||||
|
emit('back')
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleLike = () => {
|
||||||
|
postData.value.isLiked = !postData.value.isLiked
|
||||||
|
postData.value.likeCount += postData.value.isLiked ? 1 : -1
|
||||||
|
ElMessage.success(postData.value.isLiked ? '点赞成功' : '取消点赞')
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleReply = () => {
|
||||||
|
replyTo.value = {
|
||||||
|
...postData.value,
|
||||||
|
}
|
||||||
|
// showReplyDialog.value = true
|
||||||
|
}
|
||||||
|
const replyToData = () => {
|
||||||
|
replyTo.value = {
|
||||||
|
...postData.value,
|
||||||
|
}
|
||||||
|
showReplyDialog.value = true
|
||||||
|
}
|
||||||
|
const handleCommentLike = (comment) => {
|
||||||
|
comment.isLiked = !comment.isLiked
|
||||||
|
comment.likeCount += comment.isLiked ? 1 : -1
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleReplySuccess = () => {
|
||||||
|
ElMessage.success('回复成功')
|
||||||
|
loadPostDetail()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.post-detail {
|
||||||
|
background: #f5f7fa;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-header {
|
||||||
|
background: #fff;
|
||||||
|
padding: 16px 20px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
border-bottom: 1px solid #f0f0f0;
|
||||||
|
flex-shrink: 0;
|
||||||
|
|
||||||
|
.header-title {
|
||||||
|
flex: 1;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #303133;
|
||||||
|
margin-right: 60px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-main {
|
||||||
|
background: #fff;
|
||||||
|
padding: 20px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
position: relative;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comment-section {
|
||||||
|
background: #fff;
|
||||||
|
padding: 16px 20px 40px 20px;
|
||||||
|
flex: 1;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-main {
|
||||||
|
background: #fff;
|
||||||
|
padding: 20px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
position: relative;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.premium-badge {
|
||||||
|
position: absolute;
|
||||||
|
top: 20px;
|
||||||
|
right: 20px;
|
||||||
|
background: linear-gradient(135deg, #ff9a56 0%, #ff6b6b 100%);
|
||||||
|
color: #fff;
|
||||||
|
padding: 4px 12px;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-author {
|
||||||
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.author-info {
|
||||||
|
flex: 1;
|
||||||
|
padding-top: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.author-name-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.author-name {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #303133;
|
||||||
|
}
|
||||||
|
|
||||||
|
.author-tag {
|
||||||
|
padding: 2px 8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: #409EFF;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.publish-time {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #909399;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-content-text {
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.8;
|
||||||
|
color: #303133;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-images {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-item {
|
||||||
|
width: 200px;
|
||||||
|
height: 140px;
|
||||||
|
border-radius: 8px;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
:deep(.el-image) {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-error {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: #f5f7fa;
|
||||||
|
color: #c0c4cc;
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-stats {
|
||||||
|
display: flex;
|
||||||
|
gap: 24px;
|
||||||
|
padding-top: 16px;
|
||||||
|
border-top: 1px solid #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
color: #909399;
|
||||||
|
font-size: 14px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #409eff;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
color: #409eff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-icon {
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.comment-section {
|
||||||
|
background: #fff;
|
||||||
|
padding: 16px 20px 40px 20px;
|
||||||
|
flex: 1;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comment-tabs {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
border-bottom: 1px solid #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-item {
|
||||||
|
padding: 12px 16px;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #606266;
|
||||||
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
color: #409eff;
|
||||||
|
font-weight: 500;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
height: 2px;
|
||||||
|
background: #409eff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.sort-buttons {
|
||||||
|
margin-left: auto;
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-input {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
:deep(.el-input__wrapper) {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
235
src/views/backOfficeSystem/luntan/components/PostItem.vue
Normal file
235
src/views/backOfficeSystem/luntan/components/PostItem.vue
Normal file
@ -0,0 +1,235 @@
|
|||||||
|
<template>
|
||||||
|
<div class="post-item" @click="handleClick">
|
||||||
|
<!-- 精品标签 -->
|
||||||
|
<div class="premium-badge" v-if="post.isPremium">精品</div>
|
||||||
|
<div class="post-main-content">
|
||||||
|
<el-avatar :size="50" :src="post.userAvatar" class="post-avatar">
|
||||||
|
<img src="@/assets/images/mr.png" />
|
||||||
|
</el-avatar>
|
||||||
|
|
||||||
|
<div class="post-right">
|
||||||
|
<div class="post-header">
|
||||||
|
<div class="user-name-row">
|
||||||
|
<span class="user-name">{{ post.userName }}</span>
|
||||||
|
<div v-if="post.ssbm" class="author-tag">
|
||||||
|
{{ post.ssbm }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="post-time">{{ post.publishTime }}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="post-content">
|
||||||
|
<div class="post-text">{{ post.content }}</div>
|
||||||
|
|
||||||
|
<!-- 图片展示 -->
|
||||||
|
<div class="post-images" v-if="post.images && post.images.length > 0">
|
||||||
|
<div v-for="(img, index) in post.images" :key="index" class="image-item" @click.stop>
|
||||||
|
<el-image :src="img" fit="cover" :preview-src-list="post.images" :initial-index="index">
|
||||||
|
<template #error>
|
||||||
|
<div class="image-error">
|
||||||
|
<el-icon>
|
||||||
|
<Picture />
|
||||||
|
</el-icon>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-image>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="post-footer">
|
||||||
|
<div class="action-item">
|
||||||
|
<el-icon>
|
||||||
|
<ChatDotRound />
|
||||||
|
</el-icon>
|
||||||
|
<span>{{ post.commentCount || 0 }}</span>
|
||||||
|
</div>
|
||||||
|
<!-- <div class="action-item" :class="{ active: post.isLiked }" @click.stop="handleLike">
|
||||||
|
<el-icon>
|
||||||
|
<Promotion />
|
||||||
|
</el-icon>
|
||||||
|
<span>{{ post.likeCount || 0 }}</span>
|
||||||
|
</div> -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ChatDotRound, Promotion, Picture } from '@element-plus/icons-vue'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
post: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits(['like', 'click'])
|
||||||
|
|
||||||
|
const getTagType = (tag) => {
|
||||||
|
const tagMap = {
|
||||||
|
'已动态': 'success',
|
||||||
|
'校长': 'warning',
|
||||||
|
'校本部': 'info'
|
||||||
|
}
|
||||||
|
return 'warning'
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleLike = () => {
|
||||||
|
emit('like', props.post)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleClick = () => {
|
||||||
|
emit('click', props.post)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.post-item {
|
||||||
|
background: #fff !important;
|
||||||
|
border-radius: 8px !important;
|
||||||
|
padding: 20px !important;
|
||||||
|
margin-bottom: 16px !important;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08) !important;
|
||||||
|
position: relative !important;
|
||||||
|
transition: all 0.3s ease !important;
|
||||||
|
cursor: pointer !important;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12) !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.premium-badge {
|
||||||
|
position: absolute !important;
|
||||||
|
top: 16px !important;
|
||||||
|
right: 16px !important;
|
||||||
|
background: linear-gradient(135deg, #ff9a56 0%, #ff6b6b 100%) !important;
|
||||||
|
color: #fff !important;
|
||||||
|
padding: 4px 12px !important;
|
||||||
|
border-radius: 4px !important;
|
||||||
|
font-size: 12px !important;
|
||||||
|
font-weight: 500 !important;
|
||||||
|
box-shadow: 0 2px 4px rgba(255, 107, 107, 0.3) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-main-content {
|
||||||
|
display: flex !important;
|
||||||
|
gap: 12px !important;
|
||||||
|
align-items: flex-start !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-avatar {
|
||||||
|
flex-shrink: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-right {
|
||||||
|
flex: 1 !important;
|
||||||
|
min-width: 0 !important;
|
||||||
|
padding-top: 2px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-header {
|
||||||
|
margin-bottom: 12px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-name-row {
|
||||||
|
display: flex !important;
|
||||||
|
align-items: center !important;
|
||||||
|
gap: 8px !important;
|
||||||
|
margin-bottom: 4px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-name {
|
||||||
|
font-size: 16px !important;
|
||||||
|
font-weight: 500 !important;
|
||||||
|
color: #303133 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-time {
|
||||||
|
font-size: 12px !important;
|
||||||
|
color: #909399 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-content {
|
||||||
|
margin-bottom: 16px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-text {
|
||||||
|
font-size: 14px !important;
|
||||||
|
line-height: 1.6 !important;
|
||||||
|
color: #606266 !important;
|
||||||
|
margin-bottom: 12px !important;
|
||||||
|
word-break: break-word !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-images {
|
||||||
|
display: flex !important;
|
||||||
|
gap: 8px !important;
|
||||||
|
flex-wrap: wrap !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-item {
|
||||||
|
width: 200px !important;
|
||||||
|
height: 140px !important;
|
||||||
|
border-radius: 8px !important;
|
||||||
|
overflow: hidden !important;
|
||||||
|
cursor: pointer !important;
|
||||||
|
|
||||||
|
:deep(.el-image) {
|
||||||
|
width: 100% !important;
|
||||||
|
height: 100% !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-error {
|
||||||
|
display: flex !important;
|
||||||
|
align-items: center !important;
|
||||||
|
justify-content: center !important;
|
||||||
|
width: 100% !important;
|
||||||
|
height: 100% !important;
|
||||||
|
background: #f5f7fa !important;
|
||||||
|
color: #c0c4cc !important;
|
||||||
|
font-size: 24px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-footer {
|
||||||
|
display: flex !important;
|
||||||
|
gap: 24px !important;
|
||||||
|
padding-top: 12px !important;
|
||||||
|
border-top: 1px solid #f0f0f0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-item {
|
||||||
|
display: flex !important;
|
||||||
|
align-items: center !important;
|
||||||
|
gap: 6px !important;
|
||||||
|
color: #909399 !important;
|
||||||
|
font-size: 14px !important;
|
||||||
|
cursor: pointer !important;
|
||||||
|
transition: all 0.3s ease !important;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #409eff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
color: #409eff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-icon {
|
||||||
|
font-size: 18px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.author-tag {
|
||||||
|
padding: 2px 8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: #409EFF;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 18px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
186
src/views/backOfficeSystem/luntan/components/PostList.vue
Normal file
186
src/views/backOfficeSystem/luntan/components/PostList.vue
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
<template>
|
||||||
|
<div class="post-list">
|
||||||
|
<!-- 发布按钮 -->
|
||||||
|
<div class="publish-section">
|
||||||
|
<el-button type="primary" @click="showPublishDialog = true">
|
||||||
|
<el-icon>
|
||||||
|
<Edit />
|
||||||
|
</el-icon>
|
||||||
|
发布帖子
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 帖子列表 -->
|
||||||
|
<div class="posts-container" v-loading="loading" v-infinite-scroll="loadMore"
|
||||||
|
:infinite-scroll-disabled="scrollDisabled" :infinite-scroll-distance="100">
|
||||||
|
<PostItem v-for="post in postList" :key="post.id" :post="post" @like="handleLike"
|
||||||
|
@click="handlePostClick(post)" />
|
||||||
|
|
||||||
|
<!-- 加载更多提示 -->
|
||||||
|
<div v-if="loadingMore" class="loading-more">
|
||||||
|
<el-icon class="is-loading">
|
||||||
|
<Loading />
|
||||||
|
</el-icon>
|
||||||
|
<span>加载中...</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 没有更多数据提示 -->
|
||||||
|
<div v-if="noMore && postList.length > 0" class="no-more">
|
||||||
|
没有更多数据了
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 空状态 -->
|
||||||
|
<el-empty v-if="!loading && postList.length === 0" description="暂无帖子" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 发布对话框 -->
|
||||||
|
<PublishDialog v-model="showPublishDialog" @success="handlePublishSuccess" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted, computed } from 'vue'
|
||||||
|
import { Edit, Loading } from '@element-plus/icons-vue'
|
||||||
|
import PostItem from './PostItem.vue'
|
||||||
|
import PublishDialog from './PublishDialog.vue'
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
import { tbGsxtXxltSelectPage } from '@/api/tbGsxtXxltHf'
|
||||||
|
import { setAddress } from '@/utils/tools'
|
||||||
|
|
||||||
|
const loading = ref(false)
|
||||||
|
const loadingMore = ref(false)
|
||||||
|
const postList = ref([])
|
||||||
|
const showPublishDialog = ref(false)
|
||||||
|
|
||||||
|
const listQuery = ref({
|
||||||
|
pageCurrent: 1,
|
||||||
|
pageSize: 10
|
||||||
|
})
|
||||||
|
|
||||||
|
const total = ref(0)
|
||||||
|
|
||||||
|
// 计算是否禁用滚动加载
|
||||||
|
const scrollDisabled = computed(() => {
|
||||||
|
return loadingMore.value || noMore.value
|
||||||
|
})
|
||||||
|
|
||||||
|
// 计算是否没有更多数据
|
||||||
|
const noMore = computed(() => {
|
||||||
|
return postList.value.length >= total.value && total.value > 0
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
loadPosts()
|
||||||
|
})
|
||||||
|
|
||||||
|
const loadPosts = async (isLoadMore = false) => {
|
||||||
|
if (isLoadMore) {
|
||||||
|
loadingMore.value = true
|
||||||
|
} else {
|
||||||
|
loading.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await tbGsxtXxltSelectPage(listQuery.value)
|
||||||
|
const data = (res.records || []).map(item => ({
|
||||||
|
id: item.id,
|
||||||
|
userName: item.fbrxm || '匿名用户',
|
||||||
|
userAvatar: item.fbrtx ? setAddress(item.fbrtx) : '',
|
||||||
|
userTag: item.userTag || '',
|
||||||
|
publishTime: item.time || '',
|
||||||
|
content: item.content || '',
|
||||||
|
images: item.tp ? item.tp.split(',').map(img => setAddress(img)) : [],
|
||||||
|
commentCount: item.hfsl || 0,
|
||||||
|
likeCount: item.likeCount || 0,
|
||||||
|
isPremium: item.sfzd === 1,
|
||||||
|
isLiked: false,
|
||||||
|
ssbm: item.ssbm,
|
||||||
|
// 保存原始数据
|
||||||
|
rawData: item
|
||||||
|
}))
|
||||||
|
|
||||||
|
if (isLoadMore) {
|
||||||
|
postList.value = [...postList.value, ...data]
|
||||||
|
} else {
|
||||||
|
postList.value = data
|
||||||
|
}
|
||||||
|
|
||||||
|
total.value = res.total || 0
|
||||||
|
} catch (error) {
|
||||||
|
console.error('加载失败', error)
|
||||||
|
ElMessage.error('加载失败')
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
loadingMore.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加载更多
|
||||||
|
const loadMore = () => {
|
||||||
|
if (postList.value.length >= total.value) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
listQuery.value.pageCurrent++
|
||||||
|
loadPosts(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleLike = (post) => {
|
||||||
|
post.isLiked = !post.isLiked
|
||||||
|
post.likeCount += post.isLiked ? 1 : -1
|
||||||
|
ElMessage.success(post.isLiked ? '点赞成功' : '取消点赞')
|
||||||
|
}
|
||||||
|
|
||||||
|
const handlePublishSuccess = () => {
|
||||||
|
// 重置分页并重新加载
|
||||||
|
listQuery.value.pageCurrent = 1
|
||||||
|
loadPosts()
|
||||||
|
}
|
||||||
|
|
||||||
|
const emit = defineEmits(['openDetail'])
|
||||||
|
|
||||||
|
const handlePostClick = (post) => {
|
||||||
|
emit('openDetail', post)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.post-list {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.publish-section {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
background: #fff;
|
||||||
|
padding: 16px 20px;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
.posts-container {
|
||||||
|
min-height: 400px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-more {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 20px;
|
||||||
|
color: #909399;
|
||||||
|
font-size: 14px;
|
||||||
|
gap: 8px;
|
||||||
|
|
||||||
|
.el-icon {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-more {
|
||||||
|
text-align: center;
|
||||||
|
padding: 20px;
|
||||||
|
color: #c0c4cc;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
147
src/views/backOfficeSystem/luntan/components/PublishDialog.vue
Normal file
147
src/views/backOfficeSystem/luntan/components/PublishDialog.vue
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog v-model="dialogVisible" title="发布帖子" width="600px" :before-close="handleClose">
|
||||||
|
<el-form :model="form" :rules="rules" ref="formRef" label-width="80px">
|
||||||
|
<el-form-item label="标题" prop="title">
|
||||||
|
<el-input v-model="form.title" placeholder="请输入帖子标题" maxlength="50" show-word-limit />
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="内容" prop="content">
|
||||||
|
<el-input v-model="form.content" type="textarea" :rows="6" placeholder="请输入帖子内容" maxlength="500"
|
||||||
|
show-word-limit />
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="表情">
|
||||||
|
<V3Emoji
|
||||||
|
:options-name="optionsName"
|
||||||
|
@click-emoji="onEmojiClick"
|
||||||
|
:recent="true"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="图片">
|
||||||
|
<Upload v-model="imageIds" :limit="9" :isImg="true" :isAll="true" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="handleClose">取消</el-button>
|
||||||
|
<el-button type="primary" @click="handleSubmit" :loading="submitting">
|
||||||
|
发布
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, watch } from 'vue'
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
import V3Emoji from 'vue3-emoji'
|
||||||
|
import { tbGsxtXxltSave } from '@/api/tbGsxtXxltHf'
|
||||||
|
import { getItem } from '@/utils/storage.js'
|
||||||
|
import Upload from '@/components/MyComponents/Upload/index.vue'
|
||||||
|
|
||||||
|
const optionsName = {
|
||||||
|
'Smileys & Emotion': '笑脸&表情',
|
||||||
|
'Food & Drink': '食物&饮料',
|
||||||
|
'Animals & Nature': '动物&自然',
|
||||||
|
'Travel & Places': '旅行&地点',
|
||||||
|
'People & Body': '人物&身体',
|
||||||
|
Objects: '物品',
|
||||||
|
Symbols: '符号',
|
||||||
|
Flags: '旗帜',
|
||||||
|
Activities: '活动'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits(['update:modelValue', 'success'])
|
||||||
|
|
||||||
|
const dialogVisible = ref(false)
|
||||||
|
const formRef = ref()
|
||||||
|
const submitting = ref(false)
|
||||||
|
const imageIds = ref([])
|
||||||
|
|
||||||
|
const form = ref({
|
||||||
|
title: '',
|
||||||
|
content: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
const rules = {
|
||||||
|
title: [
|
||||||
|
{ required: true, message: '请输入标题', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
content: [
|
||||||
|
{ required: true, message: '请输入内容', trigger: 'blur' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(() => props.modelValue, (val) => {
|
||||||
|
dialogVisible.value = val
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(dialogVisible, (val) => {
|
||||||
|
emit('update:modelValue', val)
|
||||||
|
if (!val) {
|
||||||
|
resetForm()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const onEmojiClick = (emoji) => {
|
||||||
|
form.value.content += emoji
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleClose = () => {
|
||||||
|
dialogVisible.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleSubmit = async () => {
|
||||||
|
if (!formRef.value) return
|
||||||
|
|
||||||
|
await formRef.value.validate(async (valid) => {
|
||||||
|
if (valid) {
|
||||||
|
submitting.value = true
|
||||||
|
try {
|
||||||
|
const ltmasg = getItem('ltmasg')
|
||||||
|
|
||||||
|
const postData = {
|
||||||
|
title: form.value.title,
|
||||||
|
content: form.value.content,
|
||||||
|
tp: imageIds.value.join(','),
|
||||||
|
fbrsfzh: ltmasg?.sfzh || '',
|
||||||
|
fbrxm: ltmasg?.xm || '',
|
||||||
|
fbrtx: ltmasg?.tx || ''
|
||||||
|
}
|
||||||
|
|
||||||
|
await tbGsxtXxltSave(postData)
|
||||||
|
|
||||||
|
ElMessage.success('发布成功')
|
||||||
|
emit('success')
|
||||||
|
handleClose()
|
||||||
|
} catch (error) {
|
||||||
|
console.error('发布失败', error)
|
||||||
|
ElMessage.error('发布失败')
|
||||||
|
} finally {
|
||||||
|
submitting.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const resetForm = () => {
|
||||||
|
form.value = {
|
||||||
|
title: '',
|
||||||
|
content: ''
|
||||||
|
}
|
||||||
|
imageIds.value = []
|
||||||
|
formRef.value?.resetFields()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
// 样式已由Upload组件内部处理</style>
|
||||||
157
src/views/backOfficeSystem/luntan/components/ReplyDialog.vue
Normal file
157
src/views/backOfficeSystem/luntan/components/ReplyDialog.vue
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog
|
||||||
|
v-model="dialogVisible"
|
||||||
|
title="发表回复"
|
||||||
|
width="600px"
|
||||||
|
:before-close="handleClose"
|
||||||
|
>
|
||||||
|
<el-form :model="form" :rules="rules" ref="formRef">
|
||||||
|
<el-form-item prop="content">
|
||||||
|
<el-input
|
||||||
|
v-model="form.content"
|
||||||
|
type="textarea"
|
||||||
|
:rows="8"
|
||||||
|
placeholder="发点干货 文明第一步"
|
||||||
|
maxlength="500"
|
||||||
|
show-word-limit
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<div class="emoji-row">
|
||||||
|
<V3Emoji
|
||||||
|
:options-name="optionsName"
|
||||||
|
@click-emoji="onEmojiClick"
|
||||||
|
:recent="true"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="handleClose">取消</el-button>
|
||||||
|
<el-button type="primary" @click="handleSubmit" :loading="submitting">
|
||||||
|
回复
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, watch } from "vue";
|
||||||
|
import { ElMessage } from "element-plus";
|
||||||
|
import V3Emoji from "vue3-emoji";
|
||||||
|
import { getItem } from "@/utils/storage.js";
|
||||||
|
import {
|
||||||
|
tbGsxtXxltHfid,
|
||||||
|
tbGsxtXxltHfSave,
|
||||||
|
tbGsxtXxltHfSelectList
|
||||||
|
} from "@/api/tbGsxtXxltHf.js";
|
||||||
|
|
||||||
|
const optionsName = {
|
||||||
|
"Smileys & Emotion": "笑脸&表情",
|
||||||
|
"Food & Drink": "食物&饮料",
|
||||||
|
"Animals & Nature": "动物&自然",
|
||||||
|
"Travel & Places": "旅行&地点",
|
||||||
|
"People & Body": "人物&身体",
|
||||||
|
Objects: "物品",
|
||||||
|
Symbols: "符号",
|
||||||
|
Flags: "旗帜",
|
||||||
|
Activities: "活动"
|
||||||
|
};
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
replyTo: {
|
||||||
|
type: Object,
|
||||||
|
default: null
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const emit = defineEmits(["update:modelValue", "success"]);
|
||||||
|
|
||||||
|
const dialogVisible = ref(false);
|
||||||
|
const formRef = ref();
|
||||||
|
const submitting = ref(false);
|
||||||
|
|
||||||
|
const form = ref({
|
||||||
|
content: ""
|
||||||
|
});
|
||||||
|
|
||||||
|
const rules = {
|
||||||
|
content: [{ required: true, message: "请输入回复内容", trigger: "blur" }]
|
||||||
|
};
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.modelValue,
|
||||||
|
(val) => {
|
||||||
|
dialogVisible.value = val;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
watch(dialogVisible, (val) => {
|
||||||
|
emit("update:modelValue", val);
|
||||||
|
if (!val) {
|
||||||
|
resetForm();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const onEmojiClick = (emoji) => {
|
||||||
|
form.value.content += emoji;
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleClose = () => {
|
||||||
|
dialogVisible.value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmit = async () => {
|
||||||
|
if (!formRef.value) return;
|
||||||
|
await formRef.value.validate(async (valid) => {
|
||||||
|
if (valid) {
|
||||||
|
submitting.value = true;
|
||||||
|
try {
|
||||||
|
const ltmasg = getItem("ltmasg");
|
||||||
|
const promes = {
|
||||||
|
hfnr: form.value.content,
|
||||||
|
hfrsfzh: ltmasg.sfzh,
|
||||||
|
hfrtx: ltmasg.tx,
|
||||||
|
hfrxm: ltmasg.xm,
|
||||||
|
ltid: props.replyTo.id,
|
||||||
|
sfyjhf: "1"
|
||||||
|
// hftp: hfrsfzh.value.hftp ? hfrsfzh.value.hftp.join(',') : ''
|
||||||
|
};
|
||||||
|
|
||||||
|
// 这里替换为实际的API调用
|
||||||
|
await tbGsxtXxltHfSave(promes);
|
||||||
|
// await new Promise(resolve => setTimeout(resolve, 1000))
|
||||||
|
ElMessage.success("回复成功");
|
||||||
|
emit("success", form.value);
|
||||||
|
handleClose();
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
|
||||||
|
ElMessage.error("回复失败");
|
||||||
|
} finally {
|
||||||
|
submitting.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const resetForm = () => {
|
||||||
|
form.value = {
|
||||||
|
content: ""
|
||||||
|
};
|
||||||
|
formRef.value?.resetFields();
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.emoji-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
295
src/views/backOfficeSystem/luntan/components/UserCard.vue
Normal file
295
src/views/backOfficeSystem/luntan/components/UserCard.vue
Normal file
@ -0,0 +1,295 @@
|
|||||||
|
<template>
|
||||||
|
<div class="user-card">
|
||||||
|
<div class="user-avatar">
|
||||||
|
<div class="avatar-wrapper" @click="showAvatarDialog = true">
|
||||||
|
<el-avatar :size="80" :src="avatarUrl">
|
||||||
|
<img src="@/assets/images/mr.png" />
|
||||||
|
</el-avatar>
|
||||||
|
<div class="avatar-overlay">
|
||||||
|
<el-icon class="upload-icon">
|
||||||
|
<Camera />
|
||||||
|
</el-icon>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="user-info">
|
||||||
|
<div class="info-item clickable" @click="showNicknameDialog = true">
|
||||||
|
<span class="label">昵称:</span>
|
||||||
|
<span class="value">{{ userInfo.nickname || '-' }}</span>
|
||||||
|
<el-icon class="edit-icon">
|
||||||
|
<Edit />
|
||||||
|
</el-icon>
|
||||||
|
</div>
|
||||||
|
<div class="info-item">
|
||||||
|
<span class="label">账号:</span>
|
||||||
|
<span class="value">{{ userInfo.account || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="info-item">
|
||||||
|
<span class="label">姓名:</span>
|
||||||
|
<span class="value">{{ userInfo.name || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="info-item">
|
||||||
|
<span class="label">部门:</span>
|
||||||
|
<span class="value">{{ userInfo.department || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 更换头像对话框 -->
|
||||||
|
<ChangeAvatar v-model="showAvatarDialog" title="更换头像" @avatarUpdated="handleAvatarUpdated" />
|
||||||
|
|
||||||
|
<!-- 编辑昵称对话框 -->
|
||||||
|
<el-dialog v-model="showNicknameDialog" title="编辑昵称" width="400px" center :close-on-click-modal="false">
|
||||||
|
<el-form ref="nicknameFormRef" :model="nicknameForm" :rules="nicknameRules" label-width="80px">
|
||||||
|
<el-form-item label="昵称" prop="nickname">
|
||||||
|
<el-input v-model="nicknameForm.nickname" placeholder="请输入昵称" maxlength="20" show-word-limit />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="showNicknameDialog = false">取消</el-button>
|
||||||
|
<el-button type="primary" @click="handleSaveNickname">保存</el-button>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, reactive, computed, onMounted } from 'vue'
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
import { Camera, Edit } from '@element-plus/icons-vue'
|
||||||
|
import { getItem, setItem, removeItem } from '@/utils/storage.js'
|
||||||
|
import { setAddress } from '@/utils/tools'
|
||||||
|
import { tbGsxtXxltTxTxQueryBySfzh, tbGsxtXxltTxTxSave } from '@/api/tbGsxtXxltHf.js'
|
||||||
|
import ChangeAvatar from './ChangeAvatar.vue'
|
||||||
|
|
||||||
|
const showAvatarDialog = ref(false)
|
||||||
|
const showNicknameDialog = ref(false)
|
||||||
|
const nicknameFormRef = ref()
|
||||||
|
|
||||||
|
const userInfo = ref({
|
||||||
|
avatar: '',
|
||||||
|
account: '',
|
||||||
|
name: '',
|
||||||
|
department: '',
|
||||||
|
nickname: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
const nicknameForm = reactive({
|
||||||
|
nickname: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
const nicknameRules = {
|
||||||
|
nickname: [
|
||||||
|
{ required: true, message: '请输入昵称', trigger: 'blur' },
|
||||||
|
{ min: 2, max: 20, message: '昵称长度在 2 到 20 个字符', trigger: 'blur' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
const avatarUrl = computed(() => {
|
||||||
|
return userInfo.value.avatar ? setAddress(userInfo.value.avatar) : ''
|
||||||
|
})
|
||||||
|
|
||||||
|
// 加载用户信息
|
||||||
|
const loadUserInfo = async () => {
|
||||||
|
const sfzh = getItem('idEntityCard')
|
||||||
|
let ltmasg = getItem('ltmasg')
|
||||||
|
|
||||||
|
if (!ltmasg) {
|
||||||
|
try {
|
||||||
|
const res = await tbGsxtXxltTxTxQueryBySfzh({ sfzh: sfzh })
|
||||||
|
console.log(res);
|
||||||
|
|
||||||
|
const deptId = getItem('deptId')?.[0]
|
||||||
|
ltmasg = {
|
||||||
|
...res,
|
||||||
|
deptName: deptId?.deptName || ''
|
||||||
|
}
|
||||||
|
setItem('ltmasg', ltmasg)
|
||||||
|
} catch (error) {
|
||||||
|
console.error('加载用户信息失败:', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ltmasg) {
|
||||||
|
userInfo.value = {
|
||||||
|
avatar: ltmasg.tx || '',
|
||||||
|
account: ltmasg.sfzh || '',
|
||||||
|
name: ltmasg.xm || '',
|
||||||
|
department: ltmasg.deptName || ltmasg.bm || '',
|
||||||
|
nickname: ltmasg.nc || ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理头像更新
|
||||||
|
const handleAvatarUpdated = async (newAvatar) => {
|
||||||
|
try {
|
||||||
|
const ltmasg = getItem('ltmasg')
|
||||||
|
const updateData = {
|
||||||
|
...ltmasg,
|
||||||
|
tx: newAvatar
|
||||||
|
}
|
||||||
|
|
||||||
|
await tbGsxtXxltTxTxSave(updateData)
|
||||||
|
removeItem('ltmasg')
|
||||||
|
await loadUserInfo()
|
||||||
|
ElMessage.success('头像更新成功')
|
||||||
|
} catch (error) {
|
||||||
|
console.error('更新头像失败:', error)
|
||||||
|
ElMessage.error('头像更新失败,请重试')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理保存昵称
|
||||||
|
const handleSaveNickname = async () => {
|
||||||
|
if (!nicknameFormRef.value) return
|
||||||
|
|
||||||
|
await nicknameFormRef.value.validate(async (valid) => {
|
||||||
|
if (valid) {
|
||||||
|
try {
|
||||||
|
const ltmasg = getItem('ltmasg')
|
||||||
|
const updateData = {
|
||||||
|
...ltmasg,
|
||||||
|
nc: nicknameForm.nickname
|
||||||
|
}
|
||||||
|
|
||||||
|
await tbGsxtXxltTxTxSave(updateData)
|
||||||
|
removeItem('ltmasg')
|
||||||
|
await loadUserInfo()
|
||||||
|
showNicknameDialog.value = false
|
||||||
|
ElMessage.success('昵称保存成功')
|
||||||
|
} catch (error) {
|
||||||
|
console.error('保存昵称失败:', error)
|
||||||
|
ElMessage.error('昵称保存失败,请重试')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听昵称对话框打开,初始化表单
|
||||||
|
const openNicknameDialog = () => {
|
||||||
|
nicknameForm.nickname = userInfo.value.nickname
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听对话框显示状态
|
||||||
|
const unwatchNickname = () => {
|
||||||
|
if (showNicknameDialog.value) {
|
||||||
|
openNicknameDialog()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
loadUserInfo()
|
||||||
|
})
|
||||||
|
|
||||||
|
// 监听昵称对话框
|
||||||
|
const stopWatch = () => {
|
||||||
|
if (showNicknameDialog.value) {
|
||||||
|
nicknameForm.nickname = userInfo.value.nickname
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用 watch 监听对话框状态
|
||||||
|
import { watch } from 'vue'
|
||||||
|
watch(showNicknameDialog, (newVal) => {
|
||||||
|
if (newVal) {
|
||||||
|
nicknameForm.nickname = userInfo.value.nickname
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.user-card {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 24px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-avatar {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
|
||||||
|
.avatar-wrapper {
|
||||||
|
position: relative;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 50%;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
&:hover .avatar-overlay {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar-overlay {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.3s ease;
|
||||||
|
border-radius: 50%;
|
||||||
|
|
||||||
|
.upload-icon {
|
||||||
|
font-size: 24px;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-info {
|
||||||
|
.info-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
font-size: 14px;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.clickable {
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 4px 8px;
|
||||||
|
margin-left: -8px;
|
||||||
|
margin-right: -8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
transition: background-color 0.3s ease;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
|
||||||
|
.edit-icon {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
color: #909399;
|
||||||
|
min-width: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value {
|
||||||
|
color: #303133;
|
||||||
|
flex: 1;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
|
||||||
|
.edit-icon {
|
||||||
|
margin-left: 8px;
|
||||||
|
color: #409eff;
|
||||||
|
font-size: 14px;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.3s ease;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
82
src/views/backOfficeSystem/luntan/index.vue
Normal file
82
src/views/backOfficeSystem/luntan/index.vue
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
<template>
|
||||||
|
<div class="luntan-container">
|
||||||
|
<!-- 列表页 -->
|
||||||
|
<template v-if="!showDetail">
|
||||||
|
<div class="luntan-left">
|
||||||
|
<UserCard />
|
||||||
|
</div>
|
||||||
|
<div class="luntan-center">
|
||||||
|
<PostList @openDetail="handleOpenDetail" />
|
||||||
|
</div>
|
||||||
|
<div class="luntan-right">
|
||||||
|
<!-- 右侧留白区域,可以后续添加其他内容 -->
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 详情页 -->
|
||||||
|
<template v-else>
|
||||||
|
<div class="luntan-left"></div>
|
||||||
|
<div class="luntan-detail">
|
||||||
|
<PostDetail :post-id="currentPostId" @back="handleBack" />
|
||||||
|
</div>
|
||||||
|
<div class="luntan-right"></div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import UserCard from './components/UserCard.vue'
|
||||||
|
import PostList from './components/PostList.vue'
|
||||||
|
import PostDetail from './components/PostDetail.vue'
|
||||||
|
|
||||||
|
const showDetail = ref(false)
|
||||||
|
const currentPostId = ref(null)
|
||||||
|
|
||||||
|
const handleOpenDetail = (post) => {
|
||||||
|
currentPostId.value = post.id
|
||||||
|
showDetail.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleBack = () => {
|
||||||
|
showDetail.value = false
|
||||||
|
currentPostId.value = null
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.luntan-container {
|
||||||
|
display: flex;
|
||||||
|
gap: 20px;
|
||||||
|
padding: 20px;
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
min-height: calc(100vh - 60px);
|
||||||
|
max-height: calc(100vh - 60px);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.luntan-left {
|
||||||
|
width: 240px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.luntan-center {
|
||||||
|
flex: 1;
|
||||||
|
overflow-y: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.luntan-right {
|
||||||
|
width: 240px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.luntan-detail {
|
||||||
|
height: 83vh;
|
||||||
|
flex: 1;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 8px;
|
||||||
|
overflow-y: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -113,6 +113,11 @@ const props = defineProps({
|
|||||||
default: () => ({})
|
default: () => ({})
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
const dialogForm = ref(false); //弹窗
|
||||||
|
|
||||||
|
const title = ref("回复帖子");
|
||||||
|
const listQuery = ref({});
|
||||||
|
const ListData = ref([])
|
||||||
const optionsName = {
|
const optionsName = {
|
||||||
'Smileys & Emotion': '笑脸&表情',
|
'Smileys & Emotion': '笑脸&表情',
|
||||||
'Food & Drink': '食物&饮料',
|
'Food & Drink': '食物&饮料',
|
||||||
@ -124,11 +129,6 @@ const optionsName = {
|
|||||||
Flags: '旗帜',
|
Flags: '旗帜',
|
||||||
Activities: '活动'
|
Activities: '活动'
|
||||||
};
|
};
|
||||||
const dialogForm = ref(false); //弹窗
|
|
||||||
|
|
||||||
const title = ref("回复帖子");
|
|
||||||
const listQuery = ref({});
|
|
||||||
const ListData = ref([])
|
|
||||||
// 初始化数据
|
// 初始化数据
|
||||||
const init = (row) => {
|
const init = (row) => {
|
||||||
dialogForm.value = true;
|
dialogForm.value = true;
|
||||||
|
|||||||
@ -6,8 +6,13 @@
|
|||||||
<template #content>
|
<template #content>
|
||||||
<el-input type="textarea" placeholder="请输入内容" v-model="hfrsfzh.hfnr"></el-input>
|
<el-input type="textarea" placeholder="请输入内容" v-model="hfrsfzh.hfnr"></el-input>
|
||||||
<div style="width: 100%;border-bottom: 1px solid #eee;margin-top: 10px">
|
<div style="width: 100%;border-bottom: 1px solid #eee;margin-top: 10px">
|
||||||
<V3Emoji :options-name="optionsName" width="40px" title="表情" @click-emoji="onVue3Emoje"
|
<V3Emoji
|
||||||
:recent="true" ></V3Emoji>
|
:options-name="optionsName"
|
||||||
|
width="40px"
|
||||||
|
title="表情"
|
||||||
|
@click-emoji="onVue3Emoje"
|
||||||
|
:recent="true"
|
||||||
|
></V3Emoji>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</FormMessage>
|
</FormMessage>
|
||||||
@ -21,24 +26,12 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import "@wangeditor/editor/dist/css/style.css";
|
import "@wangeditor/editor/dist/css/style.css";
|
||||||
import V3Emoji from "vue3-emoji";
|
|
||||||
import FormMessage from "@/components/aboutTable/FormMessage.vue";
|
import FormMessage from "@/components/aboutTable/FormMessage.vue";
|
||||||
|
import V3Emoji from 'vue3-emoji'
|
||||||
import { getItem } from '@/utils/storage.js'
|
import { getItem } from '@/utils/storage.js'
|
||||||
import { tbGsxtXxltHfSave } from '@/api/tbGsxtXxltHf'
|
import { tbGsxtXxltHfSave } from '@/api/tbGsxtXxltHf'
|
||||||
import { ElMessage } from 'element-plus';
|
import { ElMessage } from 'element-plus';
|
||||||
import { ref, defineEmits, defineProps, watch, reactive ,computed} from "vue";
|
import { ref, defineEmits, defineProps, watch, reactive ,computed} from "vue";
|
||||||
const optionsName = {
|
|
||||||
'Smileys & Emotion': '笑脸&表情',
|
|
||||||
'Food & Drink': '食物&饮料',
|
|
||||||
'Animals & Nature': '动物&自然',
|
|
||||||
'Travel & Places': '旅行&地点',
|
|
||||||
'People & Body': '人物&身体',
|
|
||||||
Objects: '物品',
|
|
||||||
Symbols: '符号',
|
|
||||||
Flags: '旗帜',
|
|
||||||
Activities: '活动'
|
|
||||||
};
|
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: {
|
modelValue: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
@ -80,6 +73,18 @@ const rules = reactive({
|
|||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const optionsName = {
|
||||||
|
'Smileys & Emotion': '笑脸&表情',
|
||||||
|
'Food & Drink': '食物&饮料',
|
||||||
|
'Animals & Nature': '动物&自然',
|
||||||
|
'Travel & Places': '旅行&地点',
|
||||||
|
'People & Body': '人物&身体',
|
||||||
|
Objects: '物品',
|
||||||
|
Symbols: '符号',
|
||||||
|
Flags: '旗帜',
|
||||||
|
Activities: '活动'
|
||||||
|
};
|
||||||
|
|
||||||
const onVue3Emoje = (val) => {
|
const onVue3Emoje = (val) => {
|
||||||
hfrsfzh.value.hfnr += val
|
hfrsfzh.value.hfnr += val
|
||||||
}
|
}
|
||||||
|
|||||||
@ -110,6 +110,9 @@
|
|||||||
<div class="jqxq-value">{{ fieldValue("bkryqksm") }}</div>
|
<div class="jqxq-value">{{ fieldValue("bkryqksm") }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="flex just-center">
|
||||||
|
<el-button @click="closeDialog">关闭</el-button>
|
||||||
|
</div>
|
||||||
</DialogDragger>
|
</DialogDragger>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
|
|||||||
@ -34,6 +34,9 @@
|
|||||||
<div class="jqxq-value">{{ fieldValue("czjg") }}</div>
|
<div class="jqxq-value">{{ fieldValue("czjg") }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="flex just-center">
|
||||||
|
<el-button @click="closeDialog">关闭</el-button>
|
||||||
|
</div>
|
||||||
</DialogDragger>
|
</DialogDragger>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
|
|||||||
@ -39,7 +39,6 @@
|
|||||||
<el-date-picker style="width: 100%;" v-model="timeRange" type="datetimerange" start-placeholder="开始时间" end-placeholder="结束时间"
|
<el-date-picker style="width: 100%;" v-model="timeRange" type="datetimerange" start-placeholder="开始时间" end-placeholder="结束时间"
|
||||||
format="YYYY-MM-DD HH:mm:ss" @change="handleTimeRangeChange" />
|
format="YYYY-MM-DD HH:mm:ss" @change="handleTimeRangeChange" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</el-popover>
|
</el-popover>
|
||||||
<el-popover v-else-if="value.label === '事件' && value.onChage" placement="top" :width="480" trigger="click"
|
<el-popover v-else-if="value.label === '事件' && value.onChage" placement="top" :width="480" trigger="click"
|
||||||
@ -195,8 +194,6 @@ getZdsj()
|
|||||||
const changeBut = (row) => {
|
const changeBut = (row) => {
|
||||||
|
|
||||||
if (row.label == '清除') {
|
if (row.label == '清除') {
|
||||||
emitter.emit('deletePointArea', 'sj_flash')
|
|
||||||
emitter.emit('deletePointArea', 'jq_flash')
|
|
||||||
emitter.emit('deletePointArea', 'jq')
|
emitter.emit('deletePointArea', 'jq')
|
||||||
emitter.emit('deletePointArea', 'sj')
|
emitter.emit('deletePointArea', 'sj')
|
||||||
return
|
return
|
||||||
@ -402,16 +399,16 @@ const updetDz = (row) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const clickJq = (row) => {
|
const clickJq = (row) => {
|
||||||
emitter.emit('deletePointArea', 'sj_flash')
|
emitter.emit('deletePointArea', 'sj')
|
||||||
emitter.emit('deletePointArea', 'jq_flash')
|
emitter.emit('deletePointArea', 'jq')
|
||||||
if (changeState.value) {
|
if (changeState.value) {
|
||||||
// 添加新的闪烁点位
|
// 添加新的闪烁点位
|
||||||
emitter.emit('addPointArea', { flag: 'jq_flash', coords: [{ jd: row.fxdwjd, wd: row.fxdwwd }], flash: true, offset: [-1, 28] })
|
emitter.emit('addPointArea', { flag: 'jq', coords: [{...row, jd: row.fxdwjd, wd: row.fxdwwd }], flash: true, offset: [-1, 28] })
|
||||||
// 定位到该点
|
// 定位到该点
|
||||||
emitter.emit('setMapCenter', { location: [row.fxdwjd, row.fxdwwd], zoomLevel: 15 })
|
emitter.emit('setMapCenter', { location: [row.fxdwjd, row.fxdwwd], zoomLevel: 15 })
|
||||||
} else {
|
} else {
|
||||||
// 添加新的闪烁点位
|
// 添加新的闪烁点位
|
||||||
emitter.emit('addPointArea', { flag: 'sj_flash', coords: [{ jd: row.jd, wd: row.wd }], flash: true, offset: [-1, 28] })
|
emitter.emit('addPointArea', { flag: 'sj', coords: [{ ...row,jd: row.jd, wd: row.wd }], flash: true, offset: [-1, 28] })
|
||||||
// 定位到该点
|
// 定位到该点
|
||||||
emitter.emit('setMapCenter', { location: [row.jd, row.wd], zoomLevel: 15 })
|
emitter.emit('setMapCenter', { location: [row.jd, row.wd], zoomLevel: 15 })
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,6 +22,7 @@ module.exports = {
|
|||||||
publicPath: "./",
|
publicPath: "./",
|
||||||
outputDir: "gsxt",
|
outputDir: "gsxt",
|
||||||
assetsDir: "static",
|
assetsDir: "static",
|
||||||
|
transpileDependencies: ["vue-router"],
|
||||||
lintOnSave: false, //process.env.NODE_ENV === 'development',
|
lintOnSave: false, //process.env.NODE_ENV === 'development',
|
||||||
productionSourceMap: false,
|
productionSourceMap: false,
|
||||||
devServer: {
|
devServer: {
|
||||||
|
|||||||
Reference in New Issue
Block a user