You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
fu-hsi-web/src/views/ruleEngine/atomicIndex/index.vue

448 lines
13 KiB
Vue

<!--
* @description: 原子指标
* @fileName: index
* @author: 17076
* @date: 2024/6/28-上午10:03
* @version: V1.0.0
-->
<template>
<div class="content">
<cs-search title="原子指标" :data="searchData" :span="8" direction="row" @onSearch="onSearch" @getData="onSearch" />
<div class="main-content">
<div :class="[detailFlag?'table-content-open':'table-content-closed']">
<div class="header">
<el-button style="margin: 16px 16px 0 0;" type="primary" icon="el-icon-circle-plus-outline" @click="handleAdd"></el-button>
</div>
<vxe-grid v-bind="gridOptions" style="margin-top: 20px;padding: 0 16px;">
<template #operate="{row}">
<el-button type="text" icon="el-icon-edit" @click="handleEdit(row)" />
<!-- <el-button type="text" icon="el-icon-view" title="查看明细" @click="handleView(row)" /> -->
<el-button type="text" style="color: red" icon="el-icon-delete" @click="handleDel(row)" />
</template>
<template #name="{row}">
<el-link type="primary" @click="opendetails(row)">{{ row.name }}</el-link>
</template>
</vxe-grid>
<div style="text-align: center">
<cs-page
:page.sync="queryForm.page"
:limit.sync="queryForm.size"
:total="queryForm.total"
@pagination="fetchData"
/>
</div>
</div>
<div v-if="detailFlag" class="details">
<div class="title">原子指标详情</div>
<div class="details-item">
<span class="circle" />
{{ datailsInfo.name }}</div>
<div class="details-item">
<div class="label">指标算法:</div>
<div class="value">{{ datailsInfo.indexSourceName }}</div>
</div>
<div v-if="datailsInfo['indexSource'] !=='1'" class="details-item">
<div class="label">查询语句:</div>
<div v-if="['2','3'].includes(datailsInfo['indexSource'])" class="value">{{ datailsInfo.queryLang }}</div>
<div v-if="datailsInfo['indexSource'] ==='5'" class="value">
<div v-if="datailsInfo.promptName" class="sel-name">{{ `已选:${datailsInfo.promptName}` }}</div>
<div v-if="datailsInfo['indexSource'] === '5' && datailsInfo.extractAttributes.length > 0" class="select-model-list">
<div v-for="(item,index) in datailsInfo.extractAttributes" :key="index" class="model-list-item">
<span>{{ item }}</span>
</div>
</div>
</div>
</div>
<div class="contract" @click="detailFlag=false">
<i class="el-icon-d-arrow-right contract-icon" />
</div>
<div class="details-item">
<div class="label">指标说明:</div>
<div class="value">{{ datailsInfo.remark }}</div>
</div>
</div>
</div>
<el-dialog
:visible.sync="dialogVisible"
width="500px"
append-to-body
:before-close="handleClose"
>
<template>
<div class="del-folder">
<div class="header">
<img src="@/assets/record/error.png" alt="">
<span>确认删除原子指标?</span>
</div>
<div v-if="atomicList.length > 0" class="content-text">存在关联的案件模型指标,继续永久删除原子指标点击【确定】,取消可直接关闭弹窗。</div>
<div v-if="atomicList.length === 0" class="content-text">
无关联案件模型,确定永久删除?
</div>
<div class="atomic-list">
<span v-for="(item,index) in atomicList" :key="index">
{{ `${item.modelName} ${item.atomicIndexName}` }}
</span>
</div>
<div class="footer-btns">
<div class="btn" @click="delItem"></div>
<div class="reset_btn" @click="handleClose"></div>
</div>
</div>
</template>
</el-dialog>
<!--编辑弹窗-->
<edit-atomic ref="edit" @reloadData="fetchData" />
</div>
</div></template>
<script>
import ChangeRules from '@/views/ruleEngine/indexRule/components/ChangeRules.vue'
import IndexAtlas from '@/views/ruleEngine/indexRule/components/IndexAtlas.vue'
import mixin from '@/views/mixin'
import EditAtomic from '@/views/ruleEngine/atomicIndex/components/EditAtomic.vue'
import { queryAtomicIndex, delAtomicIndex } from '@/api/atomicIndex'
import { queryAtomicUsed } from '@/api/indexRule/index'
export default {
name: 'Index',
components: { EditAtomic, IndexAtlas, ChangeRules },
mixins: [mixin],
data() {
return {
// 筛选数据
searchData: [
{ label: '原子指标', model: 'name', type: 'input' },
// { label: '指标分类', model: 'indexType', type: 'select', option: JSON.parse(sessionStorage.getItem('index_type')) },
{ label: '指标来源', model: 'indexSource', type: 'select', option: JSON.parse(sessionStorage.getItem('index_source')) },
{ label: '最新时间', model: 'updateTime', type: 'datetimerange' }
],
detailFlag: false,
dialogVisible: false,
atomicList: [],
datailsInfo: {
name: '',
remark: ''
},
selectAtomic: '',
// 表格配置
gridOptions: {
...mixin.data().gridOptions,
// 指标名称单元格添加样式
cellClassName: ({ column }) => {
if (column.field === 'indexName') {
return 'text-blue'
}
return null
},
columns: [
{ title: '序号', type: 'seq', width: '50px' },
{ title: '原子指标', field: 'name', slots: { default: 'name' }},
// { title: '案件类型', field: 'caseTypeName', sortable: true },
{ title: '指标来源', field: 'indexSourceName', sortable: true },
// { title: '状态', field: 'connectStatus' },
{ title: '最新时间', field: 'updateTime', sortable: true },
{ title: '操作', slots: { default: 'operate' }, fixed: 'right', width: '150px' }
],
data: []
}
}
},
mounted() {
this.tableHeight(390)
},
methods: {
// 原子指标查询
fetchData() {
const params = JSON.parse(JSON.stringify(this.searchFormData))
if (this.searchFormData.updateTime) {
this.$set(params, 'updateStartTime', this.searchFormData.updateTime[0])
this.$set(params, 'updateEndTime', this.searchFormData.updateTime[1])
delete params['updateTime']
}
queryAtomicIndex(params, this.queryForm.page, this.queryForm.size).then(res => {
this.gridOptions.data = res.data.result
this.queryForm.total = res.data.total
})
},
async delItem() {
const { code, msg } = await delAtomicIndex(this.selectAtomic)
code === 200 ? this.$baseMessage.success(msg || '删除成功!') : this.$baseMessage.error(msg || '删除失败!')
this.fetchData()
this.dialogVisible = false
},
handleClose() {
this.dialogVisible = false
},
// 新增
handleAdd() {
this.$refs.edit.show()
},
// 变更
handleChange() {
this.$refs.change.show()
},
// 编辑
handleEdit(row) {
this.$refs.edit.show(row, true)
},
// 查看明细
handleView(row) {
this.$refs.edit.show(row, false)
},
// 查询原子指标被使用情况
async getAtomicUsed(val) {
const res = await queryAtomicUsed({ atomicIndexId: val })
if (res.code === 200) {
this.atomicList = res.data
}
},
// 删除
handleDel(row) {
this.dialogVisible = true
this.getAtomicUsed(row.id)
this.selectAtomic = row.id
// this.$baseConfirm('确定要删除吗?', null, async() => {
// const { code, msg } = await delAtomicIndex(row.id)
// code === 200 ? this.$baseMessage.success(msg || '删除成功!') : this.$baseMessage.error(msg || '删除失败!')
// this.fetchData()
// })
},
opendetails(item) {
this.datailsInfo = { ...item }
this.datailsInfo.extractAttributes = item.properties ? item.properties.split(',') : []
this.detailFlag = true
},
// 筛选
onSearch(data, callback) {
this.searchFormData = Object.assign({}, data)
this.queryForm.page = 1
this.fetchData()
if (callback) callback(true)
}
}
}
</script>
<style scoped lang="scss">
.content {
height: 100%;
.main-content {
border-radius: 8px;
box-sizing: border-box;
margin-top: 10px;
display: flex;
.table-content-open {
width: calc(100% - 480px);
background: #FFFFFF;
}
.table-content-closed {
width: 100%;
background: #FFFFFF;
}
.details {
width: 408px;
background: #FFFFFF;
border-radius: 6px 6px 6px 6px;
margin-left: 16px;
padding: 24px;
// margin-top: 10px;
position: relative;
.contract {
position: absolute;
top: 50%;
left: -18px;
cursor: pointer;
width: 20px;
border-bottom: 10px solid #fff;
border-left: 3px solid transparent;
border-right: 3px solid transparent;
height: 0;
transform: rotate(-90deg);
/* 向左旋转 90 度 */
transform-origin: center center;
.contract-icon {
transform: rotate(90deg);
cursor: pointer;
padding-left:5px ;
}
}
.title {
font-size: 16px;
color: #333333;
margin-bottom: 16px;
}
.circle {
width: 8px;
height: 8px;
background: #666666;
border-radius: 50%;
margin-top: 2px;
margin-right: 8px;
}
.details-item {
display: flex;
font-size: 16px;
color: #666666;
margin-bottom: 16px;
// align-items: center;
.label {
margin-right: 8px;
width: 90px;
}
.value {
flex: 1;
}
}
.sel-name {
font-size: 16px;
color: #3763FF;
}
.sel-desc {
margin-top: 8px;font-size: 16px;
color: #333333
}
.sql_btn {
position: absolute;
right: 16px;
bottom: 16px;width: 112px;
height: 42px;
background: #FFFFFF;
border-radius: 6px 6px 6px 6px;
border: 1px solid #3763FF;
font-size: 16px;
color: #3763FF;
text-align: center;
line-height: 42px;
cursor: pointer;
}
.select-model-list {
display: flex;
margin-top: 16px;
flex-wrap: wrap;
.model-list-item {
padding: 0 12px;
height: 32px;
margin:0 8px 8px 0;
background: #F0F0F0;
border-radius: 6px 6px 6px 6px;font-size: 14px;
color: #333333;
display: flex;
align-items: center;
cursor: pointer;
span {
// margin-right: 16px;
}
}
}
}
}
.expand-details {
background: #F6F6F6;
padding: 8px 20px;
box-sizing: border-box;
}
.header {
display: flex;
flex-direction: row-reverse;
align-items: center;
}
}
::v-deep {
.text-blue {
color: #005AA8;
}
.header-blue {
background: #F2F6FA;
}
}
</style>
<style lang="scss" scoped>
.dialog-content {
border-radius: 5px;
padding: 20px;
box-sizing: border-box;
}
::v-deep .el-dialog__header {
padding: 0;
}
::v-deep .el-dialog__body {
padding: 0 !important;
}
::v-deep .el-dialog {
// background: linear-gradient(to bottom, #E1ECFE, #FFFFFF);
margin-top: 30vh !important
}
.del-folder {
padding: 24px;
.header {
display: flex;
img {
width: 28px;
height: 28px;
margin-right: 16px;
}
font-weight: bold;
font-size: 20px;
color: #333333;
}
.content-text {
margin-top: 12px;
font-weight: 400;
font-size: 16px;
color: #666666;
line-height: 25px;
padding-left: 45px;
}
.atomic-list {
display: flex;
flex-direction: column;
padding-left: 45px;
margin-top: 8px;
span {
font-size: 14px;
color: #666666;
margin-top: 4px;
}
}
.footer-btns {
padding-top: 24px;
display: flex;
flex-direction: row-reverse;
.btn {
padding: 8px 24px;
background: #3763FF;
box-shadow: 0px 2px 0px 0px rgba(0,0,0,0.04);
border-radius: 6px 6px 6px 6px;
text-align: center;
font-size: 16px;
color: #FFFFFF;
cursor: pointer;
margin-left: 16px;
}
.reset_btn {
padding: 8px 24px;
background: #FFFFFF;
box-shadow: 0px 2px 0px 0px rgba(0,0,0,0.04);
border-radius: 6px 6px 6px 6px;
border: 1px solid #3763FF;
text-align: center;
font-size: 16px;
color: #3763FF;
cursor: pointer;
margin-left: 16px;
}
}
}
</style>