批量操作弹窗画面

main
zhufu 2025-04-10 10:05:38 +08:00
parent 5b3588782b
commit 40a02e6ec7
8 changed files with 1476 additions and 1 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 396 B

View File

@ -0,0 +1,423 @@
<template>
<div class="item-content">
<div class="show-content-div" v-if="step == 0">
<div class="subtitle">
<div style="border-radius: 20px 0px 0px 0px;" :class="`${selectType == 0? 'active': ''}`" @click="selectType = 0">条件</div>
<div style="border-radius: 0px 20px 0px 0px;" :class="`${selectType == 1? 'active': ''}`" @click="selectType = 1">SQL</div>
</div>
<div class="condition-div" v-if="selectType == 0">
<div class="filter-div" v-for="(item, index) in filterList">
<div class="filter-title">
<div class="filter-item-title" style="position: relative;">
字段
<div class="mark">{{ `条件${index+1}` }}</div>
</div>
<div class="filter-item-title">类型</div>
<div class="filter-item-title">条件</div>
<div class="filter-item-title">内容</div>
</div>
<div class="filter-value">
<div class="filter-item-value">
<a-select
class="item-value-select"
v-model:value="item.fields"
:options="options1"
style="width: 190px;height: 43px;"
placeholder="请选择相关字段"
/>
</div>
<div class="filter-item-value">String</div>
<div class="filter-item-value">
<a-select
class="item-value-select"
v-model:value="item.conditions"
:options="options1"
style="width: 190px;height: 43px;"
placeholder="请选择相关条件"
/>
</div>
<div class="filter-item-value">
<a-input v-model:value="item.value" placeholder="请输入相关内容" style="width: 300px;height: 43px;" />
</div>
</div>
</div>
<div style="display: flex;justify-content: center;padding-top: 46px;">
<a-button class="insert-filter-button" :icon="h(PlusOutlined)" @click="insertFilter"></a-button>
</div>
</div>
<div class="condition-div" v-if="selectType == 1">
<a-textarea v-model:value="sqlValue" placeholder="请输入SQL" :rows="8" />
</div>
</div>
<div class="show-content-div" v-if="step == 1">
<a-table :row-selection="rowSelection" :dataSource="dataSource" :columns="columns" :pagination="{ pageSize: 50 }"
:scroll="{ y: 490 }" :footer="null"/>
</div>
<div class="footer">
<a-button class="operation-button">关闭</a-button>
<a-button type="primary" class="operation-button" @click="nextStep"></a-button>
</div>
</div>
<a-modal
v-model:open="submitModal"
title="内容替换"
okText="提交"
>
<div style="padding: 30px">
<div style="display: flex;align-items: center;margin-bottom: 10px;justify-content: center;">
<div style="width: 100px;">选择字段</div>
<a-select
:options="options1"
style="width: 190px;"
placeholder="请选择字段"
/>
</div>
<div style="display: flex;align-items: center;margin-bottom: 10px;justify-content: center;">
<div style="width: 100px;">替换内容</div>
<a-select
:options="options1"
style="width: 190px;"
placeholder="请选择相内容"
/>
</div>
<div style="display: flex;align-items: center;margin-bottom: 10px;justify-content: center;">
<div style="width: 100px;">新内容</div>
<a-input
style="width: 190px;"
placeholder="输入内容"
/>
</div>
</div>
</a-modal>
</template>
<script setup lang="ts">
import { ref, h } from "vue"
import { PlusOutlined } from '@ant-design/icons-vue';
const step = ref(0)
const selectType = ref(0)
const submitModal = ref(false)
const options1 = ref([
{
value: 'userName',
label: 'userName',
},
{
value: 'addresss',
label: 'addresss',
},
{
value: 'id',
label: 'id',
},
{
value: 'year',
label: 'year',
},
]);
const sqlValue = ref('')
const filterList:any = ref([])
const dataSource = ref([
{
key: '1',
name: '胡彦斌',
age: 32,
address: '西湖区湖底公园1号',
},
{
key: '2',
name: '胡彦祖',
age: 42,
address: '西湖区湖底公园1号',
},
{
key: '1',
name: '胡彦斌',
age: 32,
address: '西湖区湖底公园1号',
},
{
key: '2',
name: '胡彦祖',
age: 42,
address: '西湖区湖底公园1号',
},
{
key: '1',
name: '胡彦斌',
age: 32,
address: '西湖区湖底公园1号',
},
{
key: '2',
name: '胡彦祖',
age: 42,
address: '西湖区湖底公园1号',
},
{
key: '1',
name: '胡彦斌',
age: 32,
address: '西湖区湖底公园1号',
},
{
key: '2',
name: '胡彦祖',
age: 42,
address: '西湖区湖底公园1号',
},
{
key: '1',
name: '胡彦斌',
age: 32,
address: '西湖区湖底公园1号',
},
{
key: '2',
name: '胡彦祖',
age: 42,
address: '西湖区湖底公园1号',
},
{
key: '1',
name: '胡彦斌',
age: 32,
address: '西湖区湖底公园1号',
},
{
key: '2',
name: '胡彦祖',
age: 42,
address: '西湖区湖底公园1号',
},
{
key: '1',
name: '胡彦斌',
age: 32,
address: '西湖区湖底公园1号',
},
{
key: '2',
name: '胡彦祖',
age: 42,
address: '西湖区湖底公园1号',
},
{
key: '1',
name: '胡彦斌',
age: 32,
address: '西湖区湖底公园1号',
},
{
key: '2',
name: '胡彦祖',
age: 42,
address: '西湖区湖底公园1号',
},
])
const columns = ref([
{
title: '姓名',
dataIndex: 'name',
key: 'name',
},
{
title: '年龄',
dataIndex: 'age',
key: 'age',
},
{
title: '住址',
dataIndex: 'address',
key: 'address',
},
])
const nextStep = () => {
if(step.value == 1){
submitModal.value = true
return
}
step.value ++
}
const insertFilter = () => {
filterList.value.push({
fields: '',
conditions: '',
value: ''
})
}
const rowSelection = {
onChange: (selectedRowKeys, selectedRows) => {
console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows);
},
getCheckboxProps: (record) => ({
disabled: record.name === 'Disabled User',
name: record.name,
}),
};
</script>
<style lang="scss" scoped>
.item-content{
width: 100%;
height: 100%;
.show-content-div{
height: 590px;
padding-top: 24px;
margin-bottom: 31px;
.subtitle{
display: flex;
height: 79px;
border-radius: 20px 20px 0px 0px;
border: 1px solid #CCCCCC;
border-bottom: 0px;
div{
flex: 1;
display: flex;
align-items: center;
justify-content: center;
font-family: PingFangSC-Regular;
font-weight: 400;
font-size: 24px;
color: #2F3033;
line-height: 33px;
cursor: pointer;
}
.active{
color: #0464D2;
background: #EFF0F0;
}
}
.condition-div{
height: calc(100% - 80px);
background: #E5E6E6;
border-left: 1px solid #CCCCCC;
border-right: 1px solid #CCCCCC;
border-bottom: 1px solid #CCCCCC;
padding: 29px;
overflow: auto;
::v-deep(.ant-input) {
font-family: PingFangSC-Regular;
font-weight: 400;
font-size: 18px;
color: #2F3033;
line-height: 25px;
}
.filter-div{
height: 112px;
background: #FFFFFF;
border-radius: 11px;
border: 1px solid #DEDEDE;
margin-bottom: 13px;
.filter-title{
height: 43px;
border-bottom: 1px solid #CCCCCC;
display: flex;
.filter-item-title{
flex: 1;
display: flex;
align-items: center;
justify-content: center;
font-family: PingFangSC-Regular;
font-weight: 400;
font-size: 18px;
color: #2F3033;
line-height: 25px;
border-right: 1px solid #CCCCCC;
.mark{
position: absolute;
top: 0px;
left: 0px;
width: 76px;
height: 43px;
background: linear-gradient( 226deg, #0464D2 0%, #3932D2 100%);
border-radius: 11px 0px 11px 0px;
font-family: PingFangSC-Regular;
font-weight: 400;
font-size: 18px;
color: #FFFFFF;
line-height: 25px;
display: flex;
align-items: center;
justify-content: center;
}
}
.filter-item-title:last-child{
border-right: 0px;
}
}
.filter-value{
height: 68px;
display: flex;
.filter-item-value{
flex: 1;
border-right: 1px solid #CCCCCC;
display: flex;
align-items: center;
justify-content: center;
.item-value-select{
:deep(.ant-select-selector){
height: 43px !important;
align-items: center; /* 垂直居中 */
}
:deep(.ant-select-selection-search-input){
height: 100% !important;
}
}
::v-deep(.ant-select-selection-placeholder) {
color: #2F3033;
font-family: PingFangSC-Regular;
font-weight: 400;
font-size: 18px;
}
::v-deep(.ant-input::placeholder) {
color: #2F3033;
font-family: PingFangSC-Regular;
font-weight: 400;
font-size: 18px;
}
::v-deep(.ant-select-selection-item) {
font-family: PingFangSC-Regular;
font-weight: 400;
font-size: 18px;
color: #2F3033;
line-height: 25px;
}
}
.filter-item-value:last-child{
border-right: 0px;
}
}
}
.insert-filter-button{
width: 302px;
height: 64px;
background: linear-gradient( 270deg, #3338D2 0%, #0563D2 100%);
border-radius: 10px;
font-family: PingFangSC-Regular;
font-weight: 400;
font-size: 24px;
color: #FFFFFF;
line-height: 33px;
}
}
}
.footer{
width: 100%;
height: 60px;
display: flex;
align-items: center;
justify-content: end;
.operation-button{
width: 169px;
height: 60px;
margin-right: 16px;
font-family: PingFangSC-Regular;
font-weight: 400;
font-size: 24px;
line-height: 33px;
}
}
}
</style>

View File

@ -0,0 +1,271 @@
<template>
<div class="item-content">
<div class="show-content-div">
<div class="subtitle">
<div style="border-radius: 20px 0px 0px 0px;" :class="`${selectType == 0? 'active': ''}`" @click="selectType = 0">条件</div>
<div style="border-radius: 0px 20px 0px 0px;" :class="`${selectType == 1? 'active': ''}`" @click="selectType = 1">SQL</div>
</div>
<div class="condition-div" v-if="selectType == 0">
<div class="filter-div" v-for="(item, index) in filterList">
<div class="filter-title">
<div class="filter-item-title" style="position: relative;">
字段
<div class="mark">{{ `条件${index+1}` }}</div>
</div>
<div class="filter-item-title">类型</div>
<div class="filter-item-title">条件</div>
<div class="filter-item-title">内容</div>
</div>
<div class="filter-value">
<div class="filter-item-value">
<a-select
class="item-value-select"
v-model:value="item.fields"
:options="options1"
style="width: 190px;height: 43px;"
placeholder="请选择相关字段"
/>
</div>
<div class="filter-item-value">String</div>
<div class="filter-item-value">
<a-select
class="item-value-select"
v-model:value="item.conditions"
:options="options1"
style="width: 190px;height: 43px;"
placeholder="请选择相关条件"
/>
</div>
<div class="filter-item-value">
<a-input v-model:value="item.value" placeholder="请输入相关内容" style="width: 300px;height: 43px;" />
</div>
</div>
</div>
<div style="display: flex;justify-content: center;padding-top: 46px;">
<a-button class="insert-filter-button" :icon="h(PlusOutlined)" @click="insertFilter"></a-button>
</div>
</div>
<div class="condition-div" v-if="selectType == 1">
<a-textarea v-model:value="sqlValue" placeholder="请输入SQL" :rows="8" />
</div>
</div>
<div class="footer">
<a-button class="operation-button">关闭</a-button>
<a-button type="primary" class="operation-button" @click="firstSubmit"></a-button>
</div>
</div>
<a-modal
v-model:open="submitModal"
title="选择字段"
>
<div style="padding: 30px 30px 10px 30px;">
<a-checkbox-group :options="options1" style="margin-bottom: 20px;"/>
<div style="display: flex;">
<a-checkbox>全选</a-checkbox>
<a-checkbox>反选</a-checkbox>
</div>
</div>
</a-modal>
</template>
<script setup lang="ts">
import { ref, h } from "vue"
import { PlusOutlined } from '@ant-design/icons-vue';
const selectType = ref(0)
const submitModal = ref(false)
const options1 = ref([
{
value: 'userName',
label: 'userName',
},
{
value: 'addresss',
label: 'addresss',
},
{
value: 'id',
label: 'id',
},
{
value: 'year',
label: 'year',
},
]);
const sqlValue = ref('')
const filterList:any = ref([])
const firstSubmit = () => {
submitModal.value = true
}
const insertFilter = () => {
filterList.value.push({
fields: '',
conditions: '',
value: ''
})
}
</script>
<style lang="scss" scoped>
.item-content{
width: 100%;
height: 100%;
.show-content-div{
height: 590px;
padding-top: 24px;
margin-bottom: 31px;
.subtitle{
display: flex;
height: 79px;
border-radius: 20px 20px 0px 0px;
border: 1px solid #CCCCCC;
border-bottom: 0px;
div{
flex: 1;
display: flex;
align-items: center;
justify-content: center;
font-family: PingFangSC-Regular;
font-weight: 400;
font-size: 24px;
color: #2F3033;
line-height: 33px;
cursor: pointer;
}
.active{
color: #0464D2;
background: #EFF0F0;
}
}
.condition-div{
height: calc(100% - 80px);
background: #E5E6E6;
border-left: 1px solid #CCCCCC;
border-right: 1px solid #CCCCCC;
border-bottom: 1px solid #CCCCCC;
padding: 29px;
overflow: auto;
::v-deep(.ant-input) {
font-family: PingFangSC-Regular;
font-weight: 400;
font-size: 18px;
color: #2F3033;
line-height: 25px;
}
.filter-div{
height: 112px;
background: #FFFFFF;
border-radius: 11px;
border: 1px solid #DEDEDE;
margin-bottom: 13px;
.filter-title{
height: 43px;
border-bottom: 1px solid #CCCCCC;
display: flex;
.filter-item-title{
flex: 1;
display: flex;
align-items: center;
justify-content: center;
font-family: PingFangSC-Regular;
font-weight: 400;
font-size: 18px;
color: #2F3033;
line-height: 25px;
border-right: 1px solid #CCCCCC;
.mark{
position: absolute;
top: 0px;
left: 0px;
width: 76px;
height: 43px;
background: linear-gradient( 226deg, #0464D2 0%, #3932D2 100%);
border-radius: 11px 0px 11px 0px;
font-family: PingFangSC-Regular;
font-weight: 400;
font-size: 18px;
color: #FFFFFF;
line-height: 25px;
display: flex;
align-items: center;
justify-content: center;
}
}
.filter-item-title:last-child{
border-right: 0px;
}
}
.filter-value{
height: 68px;
display: flex;
.filter-item-value{
flex: 1;
border-right: 1px solid #CCCCCC;
display: flex;
align-items: center;
justify-content: center;
.item-value-select{
:deep(.ant-select-selector){
height: 43px !important;
align-items: center; /* 垂直居中 */
}
:deep(.ant-select-selection-search-input){
height: 100% !important;
}
}
::v-deep(.ant-select-selection-placeholder) {
color: #2F3033;
font-family: PingFangSC-Regular;
font-weight: 400;
font-size: 18px;
}
::v-deep(.ant-input::placeholder) {
color: #2F3033;
font-family: PingFangSC-Regular;
font-weight: 400;
font-size: 18px;
}
::v-deep(.ant-select-selection-item) {
font-family: PingFangSC-Regular;
font-weight: 400;
font-size: 18px;
color: #2F3033;
line-height: 25px;
}
}
.filter-item-value:last-child{
border-right: 0px;
}
}
}
.insert-filter-button{
width: 302px;
height: 64px;
background: linear-gradient( 270deg, #3338D2 0%, #0563D2 100%);
border-radius: 10px;
font-family: PingFangSC-Regular;
font-weight: 400;
font-size: 24px;
color: #FFFFFF;
line-height: 33px;
}
}
}
.footer{
width: 100%;
height: 60px;
display: flex;
align-items: center;
justify-content: end;
.operation-button{
width: 169px;
height: 60px;
margin-right: 16px;
font-family: PingFangSC-Regular;
font-weight: 400;
font-size: 24px;
line-height: 33px;
}
}
}
</style>

View File

@ -0,0 +1,224 @@
<template>
<div class="title">
批量操作
<div class="close-button" @click="emits('closemergeSourceModal')"></div>
</div>
<div class="modal-content">
<div class="cue-span">检测到以下数据存在冲突</div>
<div class="comparison-div">
<div style="flex: 1;padding-right: 10px;" >
<div class="table-title">原数据</div>
<a-table ref="oldTable" :dataSource="dataSource" :columns="columns" :pagination="{ pageSize: 50 }"
:scroll="{ y: 472 }" :footer="null" />
</div>
<div style="flex: 1;padding-left: 10px;" >
<div class="table-title">新数据</div>
<a-table ref="newTable" :dataSource="dataSource" :columns="columns" :pagination="{ pageSize: 50 }"
:scroll="{ y: 472 }" :footer="null" />
</div>
</div>
<div class="footer">
<a-button type="primary" class="operation-button">手动修改</a-button>
<a-button type="primary" class="operation-button">保留原数据</a-button>
<a-button type="primary" class="operation-button">使用新数据覆盖</a-button>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, nextTick, onMounted, onUnmounted, defineEmits } from "vue"
const emits = defineEmits(['closemergeSourceModal'])
const control = ref(0)
const oldTable = ref()
const newTable = ref()
const dataSource = ref([
{
key: '1',
name: '胡彦斌',
age: 32,
address: '西湖区湖底公园1号',
},
{
key: '2',
name: '胡彦祖',
age: 42,
address: '西湖区湖底公园1号',
},
{
key: '1',
name: '胡彦斌',
age: 32,
address: '西湖区湖底公园1号',
},
{
key: '2',
name: '胡彦祖',
age: 42,
address: '西湖区湖底公园1号',
},
{
key: '1',
name: '胡彦斌',
age: 32,
address: '西湖区湖底公园1号',
},
{
key: '2',
name: '胡彦祖',
age: 42,
address: '西湖区湖底公园1号',
},
{
key: '1',
name: '胡彦斌',
age: 32,
address: '西湖区湖底公园1号',
},
{
key: '2',
name: '胡彦祖',
age: 42,
address: '西湖区湖底公园1号',
},
{
key: '1',
name: '胡彦斌',
age: 32,
address: '西湖区湖底公园1号',
},
{
key: '2',
name: '胡彦祖',
age: 42,
address: '西湖区湖底公园1号',
},
{
key: '1',
name: '胡彦斌',
age: 32,
address: '西湖区湖底公园1号',
},
{
key: '2',
name: '胡彦祖',
age: 42,
address: '西湖区湖底公园1号',
},
{
key: '1',
name: '胡彦斌',
age: 32,
address: '西湖区湖底公园1号',
},
{
key: '2',
name: '胡彦祖',
age: 42,
address: '西湖区湖底公园1号',
},
{
key: '1',
name: '胡彦斌',
age: 32,
address: '西湖区湖底公园1号',
},
{
key: '2',
name: '胡彦祖',
age: 42,
address: '西湖区湖底公园1号',
},
])
const columns = ref([
{
title: '姓名',
dataIndex: 'name',
key: 'name',
},
{
title: '年龄',
dataIndex: 'age',
key: 'age',
},
{
title: '住址',
dataIndex: 'address',
key: 'address',
},
])
onMounted(() => {
nextTick(() => {
const oldTableBody = oldTable.value?.$el.querySelector('.ant-table-body')
const newTableBody = newTable.value?.$el.querySelector('.ant-table-body')
if (oldTableBody && oldTableBody) {
oldTableBody.addEventListener('scroll', (e) => {
newTableBody.scrollTop = e.target.scrollTop
})
newTableBody.addEventListener('scroll', (e) => {
oldTableBody.scrollTop = e.target.scrollTop
})
}
})
})
onUnmounted(() => {
})
</script>
<style lang="scss" scoped>
.title{
height: 86px;
padding-left: 43px;
padding-right: 43px;
display: flex;
justify-content: space-between;
align-items: center;
font-family: PingFangSC-Regular;
font-weight: 400;
font-size: 36px;
color: #1E1E20;
line-height: 50px;
user-select: none;
border-bottom: 1px solid #E4E4E7;
.close-button{
width: 30px;
height: 30px;
background-image: url('/public/components/BatchProcessingModal/close_icon.png');
background-size: 100% 100%;
cursor: pointer;
}
}
.modal-content{
width: 100%;
height: 790px;
padding: 28px 44px 27px 34px;
.cue-span{
font-size: 20px;
margin-bottom: 10px;
}
.comparison-div{
display: flex;
.table-title{
font-size: 20px;
margin-bottom: 10px;
}
}
.footer{
width: 100%;
height: 60px;
display: flex;
align-items: center;
justify-content: end;
.operation-button{
width: 220px;
height: 60px;
margin-right: 16px;
font-family: PingFangSC-Regular;
font-weight: 400;
font-size: 24px;
line-height: 33px;
}
}
}
</style>

View File

@ -0,0 +1,235 @@
<template>
<div class="item-content">
<div class="procedure-div">
<div class="procedure-0" v-if="procedure == 0">
<div>
<div class="upload-image"></div>
<div class="upload-span">上传shp/Excel文件</div>
<div class="upload-button-div">
<a-button type="primary" class="upload-button" :icon="h(PlusOutlined)" @click="procedure++"></a-button>
</div>
</div>
</div>
<div class="procedure-1" v-if="procedure == 1">
<a-table :dataSource="dataSource" :columns="columns" :pagination="{ pageSize: 50 }"
:scroll="{ y: 490 }" :footer="null"/>
</div>
</div>
<div class="footer">
<a-button v-if="procedure == 1" type="primary" class="operation-button"></a-button>
<a-button class="operation-button">关闭</a-button>
<a-button v-if="procedure == 0" class="operation-button"></a-button>
<a-button v-if="procedure == 1" type="primary" class="operation-button" @click="submit"></a-button>
</div>
</div>
<a-modal
class="BatchProcessingModal"
width="1660px"
v-model:open="mergeSourceModal"
:footer="null"
:closable="false"
:destroyOnClose="true"
style="top: 50px"
>
<MergeSourceModal @closemergeSourceModal="closemergeSourceModal"/>
</a-modal>
</template>
<script setup lang="ts">
import { ref, h, } from "vue"
import { PlusOutlined } from '@ant-design/icons-vue';
import MergeSourceModal from './MergeSourceModal/index.vue'
const procedure = ref(0)
const mergeSourceModal = ref(false)
const dataSource = ref([
{
key: '1',
name: '胡彦斌',
age: 32,
address: '西湖区湖底公园1号',
},
{
key: '2',
name: '胡彦祖',
age: 42,
address: '西湖区湖底公园1号',
},
{
key: '1',
name: '胡彦斌',
age: 32,
address: '西湖区湖底公园1号',
},
{
key: '2',
name: '胡彦祖',
age: 42,
address: '西湖区湖底公园1号',
},
{
key: '1',
name: '胡彦斌',
age: 32,
address: '西湖区湖底公园1号',
},
{
key: '2',
name: '胡彦祖',
age: 42,
address: '西湖区湖底公园1号',
},
{
key: '1',
name: '胡彦斌',
age: 32,
address: '西湖区湖底公园1号',
},
{
key: '2',
name: '胡彦祖',
age: 42,
address: '西湖区湖底公园1号',
},
{
key: '1',
name: '胡彦斌',
age: 32,
address: '西湖区湖底公园1号',
},
{
key: '2',
name: '胡彦祖',
age: 42,
address: '西湖区湖底公园1号',
},
{
key: '1',
name: '胡彦斌',
age: 32,
address: '西湖区湖底公园1号',
},
{
key: '2',
name: '胡彦祖',
age: 42,
address: '西湖区湖底公园1号',
},
{
key: '1',
name: '胡彦斌',
age: 32,
address: '西湖区湖底公园1号',
},
{
key: '2',
name: '胡彦祖',
age: 42,
address: '西湖区湖底公园1号',
},
{
key: '1',
name: '胡彦斌',
age: 32,
address: '西湖区湖底公园1号',
},
{
key: '2',
name: '胡彦祖',
age: 42,
address: '西湖区湖底公园1号',
},
])
const columns = ref([
{
title: '姓名',
dataIndex: 'name',
key: 'name',
},
{
title: '年龄',
dataIndex: 'age',
key: 'age',
},
{
title: '住址',
dataIndex: 'address',
key: 'address',
},
])
const submit = () => {
mergeSourceModal.value = true
}
const closemergeSourceModal = () => {
mergeSourceModal.value = false
}
</script>
<style lang="scss" scoped>
.item-content{
width: 100%;
height: 100%;
.procedure-div{
height: 590px;
.procedure-0{
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
.upload-image{
width: 200px;
height: 200px;
background-color: red;
margin: auto;
margin-bottom: 10px;
}
.upload-span{
display: flex;
justify-content: center;
margin-bottom: 10px;
font-family: PingFangSC-Regular;
font-weight: 400;
font-size: 24px;
}
.upload-button-div{
display: flex;
justify-content: center;
.upload-button{
width: 200px;
margin-right: 10px;
background: linear-gradient( 270deg, #3338D2 0%, #0563D2 100%);
border-radius: 10px;
height: 64px;
font-family: PingFangSC-Regular;
font-weight: 400;
font-size: 24px;
color: #FFFFFF;
line-height: 33px;
}
}
}
.procedure-1{
padding-top: 10px;
}
}
.footer{
width: 100%;
height: 91px;
padding-top: 31px;
display: flex;
align-items: center;
justify-content: end;
.operation-button{
width: 169px;
height: 60px;
margin-right: 10px;
font-family: PingFangSC-Regular;
font-weight: 400;
font-size: 24px;
line-height: 33px;
}
}
}
</style>

View File

@ -0,0 +1,214 @@
<template>
<div class="item-content">
<div class="procedure-div">
<div class="procedure-0" v-if="procedure == 0">
<div>
<div class="upload-image"></div>
<div class="upload-span">上传shp/Excel文件</div>
<div class="upload-button-div">
<a-button type="primary" class="upload-button" :icon="h(PlusOutlined)" @click="procedure++"></a-button>
</div>
</div>
</div>
<div class="procedure-1" v-if="procedure == 1">
<a-table :dataSource="dataSource" :columns="columns" :pagination="{ pageSize: 50 }"
:scroll="{ y: 490 }" :footer="null"/>
</div>
</div>
<div class="footer">
<a-button v-if="procedure == 1" type="primary" class="operation-button"></a-button>
<a-button class="operation-button">关闭</a-button>
<a-button v-if="procedure == 0" class="operation-button"></a-button>
<a-button v-if="procedure == 1" type="primary" class="operation-button"></a-button>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, h, } from "vue"
import { PlusOutlined } from '@ant-design/icons-vue';
const procedure = ref(0)
const dataSource = ref([
{
key: '1',
name: '胡彦斌',
age: 32,
address: '西湖区湖底公园1号',
},
{
key: '2',
name: '胡彦祖',
age: 42,
address: '西湖区湖底公园1号',
},
{
key: '1',
name: '胡彦斌',
age: 32,
address: '西湖区湖底公园1号',
},
{
key: '2',
name: '胡彦祖',
age: 42,
address: '西湖区湖底公园1号',
},
{
key: '1',
name: '胡彦斌',
age: 32,
address: '西湖区湖底公园1号',
},
{
key: '2',
name: '胡彦祖',
age: 42,
address: '西湖区湖底公园1号',
},
{
key: '1',
name: '胡彦斌',
age: 32,
address: '西湖区湖底公园1号',
},
{
key: '2',
name: '胡彦祖',
age: 42,
address: '西湖区湖底公园1号',
},
{
key: '1',
name: '胡彦斌',
age: 32,
address: '西湖区湖底公园1号',
},
{
key: '2',
name: '胡彦祖',
age: 42,
address: '西湖区湖底公园1号',
},
{
key: '1',
name: '胡彦斌',
age: 32,
address: '西湖区湖底公园1号',
},
{
key: '2',
name: '胡彦祖',
age: 42,
address: '西湖区湖底公园1号',
},
{
key: '1',
name: '胡彦斌',
age: 32,
address: '西湖区湖底公园1号',
},
{
key: '2',
name: '胡彦祖',
age: 42,
address: '西湖区湖底公园1号',
},
{
key: '1',
name: '胡彦斌',
age: 32,
address: '西湖区湖底公园1号',
},
{
key: '2',
name: '胡彦祖',
age: 42,
address: '西湖区湖底公园1号',
},
])
const columns = ref([
{
title: '姓名',
dataIndex: 'name',
key: 'name',
},
{
title: '年龄',
dataIndex: 'age',
key: 'age',
},
{
title: '住址',
dataIndex: 'address',
key: 'address',
},
])
</script>
<style lang="scss" scoped>
.item-content{
width: 100%;
height: 100%;
.procedure-div{
height: 590px;
.procedure-0{
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
.upload-image{
width: 200px;
height: 200px;
background-color: red;
margin: auto;
margin-bottom: 10px;
}
.upload-span{
display: flex;
justify-content: center;
margin-bottom: 10px;
font-family: PingFangSC-Regular;
font-weight: 400;
font-size: 24px;
}
.upload-button-div{
display: flex;
justify-content: center;
.upload-button{
width: 200px;
margin-right: 10px;
background: linear-gradient( 270deg, #3338D2 0%, #0563D2 100%);
border-radius: 10px;
height: 64px;
font-family: PingFangSC-Regular;
font-weight: 400;
font-size: 24px;
color: #FFFFFF;
line-height: 33px;
}
}
}
.procedure-1{
padding-top: 10px;
}
}
.footer{
width: 100%;
height: 91px;
padding-top: 31px;
display: flex;
align-items: center;
justify-content: end;
.operation-button{
width: 169px;
height: 60px;
margin-right: 10px;
font-family: PingFangSC-Regular;
font-weight: 400;
font-size: 24px;
line-height: 33px;
}
}
}
</style>

View File

@ -0,0 +1,92 @@
<template>
<div class="title">
批量操作
<div class="close-button" @click="emits('changeBatchProcessingModal')"></div>
</div>
<div class="modal-content">
<div class="control-button-div">
<div :class="`control-button ${control == 0? 'active': ''}`" @click="changeControl(0)"></div>
<div :class="`control-button ${control == 1? 'active': ''}`" @click="changeControl(1)"></div>
<div :class="`control-button ${control == 2? 'active': ''}`" @click="changeControl(2)"></div>
<div :class="`control-button ${control == 3? 'active': ''}`" @click="changeControl(3)"></div>
</div>
<div class="content">
<ImportComponent v-if="control == 0"/>
<UpdateComponent v-if="control == 1"/>
<ExportComponent v-if="control == 2"/>
<BatchOperationsComponent v-if="control == 3"/>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, defineEmits } from "vue"
import ImportComponent from './ImportComponent/index.vue'
import UpdateComponent from './UpdateComponent/index.vue'
import ExportComponent from './ExportComponent/index.vue'
import BatchOperationsComponent from './BatchOperationsComponent/index.vue'
const emits = defineEmits(['changeBatchProcessingModal'])
const control = ref(0)
const changeControl = (type) => {
control.value = type
}
</script>
<style lang="scss" scoped>
.title{
height: 86px;
padding-left: 43px;
padding-right: 43px;
display: flex;
justify-content: space-between;
align-items: center;
font-family: PingFangSC-Regular;
font-weight: 400;
font-size: 36px;
color: #1E1E20;
line-height: 50px;
user-select: none;
border-bottom: 1px solid #E4E4E7;
.close-button{
width: 30px;
height: 30px;
background-image: url('/public/components/BatchProcessingModal/close_icon.png');
background-size: 100% 100%;
cursor: pointer;
}
}
.modal-content{
width: 100%;
height: 790px;
padding: 28px 44px 27px 34px;
.control-button-div{
display: flex;
border-bottom: 2px solid #E9E9EC;
.control-button{
width: 169px;
height: 54px;
background: #F2F3F6;
border-radius: 16px 16px 0px 0px;
display: flex;
align-items: center;
justify-content: center;
font-family: PingFangSC-Regular;
font-weight: 400;
font-size: 24px;
color: #191A1B;
line-height: 33px;
margin-right: 4px;
cursor: pointer;
user-select: none;
}
.active{
background-color: #0464D2;
color: #fff;
}
}
}
.content{
height: 707px;
}
</style>

View File

@ -19,7 +19,7 @@
/>
<a-button type="primary" @click="handleCreate"> </a-button>
<a-button type="primary" @click="handleItem"> </a-button>
<a-button type="primary" @click="handleItem"> </a-button>
<a-button type="primary" @click="changeBatchProcessingModal(true)"> </a-button>
<a-button type="primary" @click="styleHandle"> </a-button>
</div>
<div class="close-icon" @click="tableVisible = false">
@ -147,6 +147,17 @@
</div>
<AddModel @register="registerAddModal" :treeData="treeData" @success="handleSuccess" />
<EditorModel @register="registerEditorModal" />
<a-modal
class="BatchProcessingModal"
width="1660px"
v-model:open="batchProcessingModalOpen"
:footer="null"
:closable="false"
:destroyOnClose="true"
style="top: 50px"
>
<BatchProcessingModal @changeBatchProcessingModal="changeBatchProcessingModal"/>
</a-modal>
</PageWrapper>
</template>
<script setup lang="ts">
@ -162,6 +173,7 @@
import { useMessage } from '@/hooks/web/useMessage';
import { uploadFile, fun_Delete } from '@/api/demo/files';
import { getAppEnvConfig } from '@/utils/env';
import BatchProcessingModal from './BatchProcessingModal/index.vue';
const { VITE_GLOB_API_URL } = getAppEnvConfig();
const { createConfirm, createMessage } = useMessage();
@ -170,6 +182,7 @@
const selectVal = ref();
const columnVal = ref(1);
const fileList = ref([]);
const batchProcessingModalOpen = ref(false)
const [registerAddModal, { openModal: openAddModal }] = useModal();
const [registerEditorModal, { openModal: openEditorModal }] = useModal();
@ -358,6 +371,9 @@
urlData: fileUrlView.value,
});
};
const changeBatchProcessingModal = (type: boolean) => {
batchProcessingModalOpen.value = type
}
</script>
<style lang="less" scoped>