对接预立案登记接口、对接立项登记接口
This commit is contained in:
43
src/api/calibration/conflictOfInterestSearch/index.ts
Normal file
43
src/api/calibration/conflictOfInterestSearch/index.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import request from '@/utils/request'
|
||||
const AUTH_BASE_URL = '/api2'
|
||||
|
||||
/*
|
||||
* 立项登记
|
||||
* */
|
||||
|
||||
// 新增立项登记
|
||||
export const BusinessProject = (data: any) => {
|
||||
const formData = new FormData()
|
||||
formData.append('type', data.type)
|
||||
formData.append('ContractNo', data.ContractNo)
|
||||
formData.append('times', data.times)
|
||||
formData.append('client_info', data.client_info)
|
||||
formData.append('party_info', data.party_info)
|
||||
formData.append('description', data.description)
|
||||
formData.append('responsiblefor', data.responsiblefor)
|
||||
formData.append('charge', data.charge)
|
||||
formData.append('contract', data.contract)
|
||||
return request({
|
||||
url: `${AUTH_BASE_URL}/business/project`,
|
||||
method: 'post',
|
||||
data: formData,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 审批分页接口
|
||||
export const UserRoxyexhibition = (data: any) => {
|
||||
const formData = new FormData()
|
||||
formData.append('page', data.pageNum)
|
||||
formData.append('per_page', data.pageSize)
|
||||
return request({
|
||||
url: `${AUTH_BASE_URL}/user/roxyexhibition`,
|
||||
method: 'post',
|
||||
data: formData,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
}
|
||||
})
|
||||
}
|
||||
46
src/api/calibration/preRegistration/index.ts
Normal file
46
src/api/calibration/preRegistration/index.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import request from '@/utils/request'
|
||||
const AUTH_BASE_URL = '/api2'
|
||||
|
||||
/*
|
||||
* 预立案登记
|
||||
* */
|
||||
|
||||
// 新增预立案登记
|
||||
export const BusinessRegister = (data: any) => {
|
||||
const formData = new FormData()
|
||||
formData.append('times', data.times)
|
||||
formData.append('client_username', data.client_username)
|
||||
formData.append('client_card', data.client_card)
|
||||
formData.append('party_username', data.party_username)
|
||||
formData.append('party_card', data.party_card)
|
||||
formData.append('description', data.description)
|
||||
formData.append('Undertaker', data.Undertaker)
|
||||
return request({
|
||||
url: `${AUTH_BASE_URL}/business/register`,
|
||||
method: 'post',
|
||||
data: formData,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 审批分页接口
|
||||
export const BusinessRegisterdetail = (data: any) => {
|
||||
const formData = new FormData()
|
||||
formData.append('page', data.pageNum)
|
||||
formData.append('per_page', data.pageSize)
|
||||
if (data.times && data.times.length) {
|
||||
formData.append('times', data.times[0])
|
||||
formData.append('end_time', data.times[1])
|
||||
}
|
||||
if (data.Undertaker) formData.append('Undertaker', data.Undertaker)
|
||||
return request({
|
||||
url: `${AUTH_BASE_URL}/business/registerdetail`,
|
||||
method: 'post',
|
||||
data: formData,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -175,17 +175,20 @@ export const constantRoutes: RouteRecordRaw[] = [
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: 'user',
|
||||
name: 'BusinessConflict',
|
||||
component: () => import('@/views/business/conflict/index.vue'),
|
||||
path: 'conflictOfInterestSearch',
|
||||
name: 'ConflictOfInterestSearch',
|
||||
component: () =>
|
||||
import('@/views/calibration/businessSystem/conflictOfInterestSearch/index.vue'),
|
||||
// component: () => import('@/views/business/conflict/index.vue'),
|
||||
meta: {
|
||||
title: '利益冲突检索'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'role',
|
||||
name: 'BusinessPreRegistration',
|
||||
component: () => import('@/views/business/preRegistration/index.vue'),
|
||||
path: 'preRegistration',
|
||||
name: 'PreRegistration',
|
||||
// component: () => import('@/views/business/preRegistration/index.vue'),
|
||||
component: () => import('@/views/calibration/businessSystem/preRegistration/index.vue'),
|
||||
meta: {
|
||||
title: '预立案登记'
|
||||
}
|
||||
|
||||
@@ -0,0 +1,409 @@
|
||||
<template>
|
||||
<div class="pre-registration-form">
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="formData"
|
||||
:rules="formRules"
|
||||
label-width="auto"
|
||||
label-position="top"
|
||||
>
|
||||
<el-form-item label="项目类型" prop="type">
|
||||
<el-select v-model="formData.type" placeholder="请选择项目类型">
|
||||
<el-option
|
||||
v-for="item in UndertakerList"
|
||||
:key="item.id"
|
||||
:label="item.username"
|
||||
:value="item.username"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="合同编号" prop="ContractNo">
|
||||
<el-input v-model="formData.ContractNo" disabled placeholder="选择项目类型生成" />
|
||||
</el-form-item>
|
||||
<el-form-item label="立项日期时间" prop="times">
|
||||
<el-date-picker
|
||||
v-model="formData.times"
|
||||
type="date"
|
||||
placeholder="请选择立项日期时间"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<div class="section">
|
||||
<h2>委托人信息</h2>
|
||||
<div class="table-actions">
|
||||
<el-button type="primary" @click="addClient">
|
||||
<el-icon><Plus /></el-icon>
|
||||
新增一项
|
||||
</el-button>
|
||||
<el-button type="danger" @click="batchDeleteClients">
|
||||
<el-icon><Delete /></el-icon>
|
||||
批量删除
|
||||
</el-button>
|
||||
</div>
|
||||
<el-table
|
||||
:data="formData.client_info"
|
||||
border
|
||||
style="width: 100%"
|
||||
class="client-table"
|
||||
@selection-change="handleClientSelectionChange"
|
||||
>
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column prop="index" label="序号" width="80" align="center" />
|
||||
<el-table-column prop="name" label="自然人姓名/法人名称" min-width="200">
|
||||
<template #default="scope">
|
||||
<el-form-item
|
||||
:prop="'client_info.' + scope.$index + '.name'"
|
||||
:rules="formRules.clientName"
|
||||
>
|
||||
<el-input v-model="scope.row.name" placeholder="请输入" style="width: 100%" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="idNumber" label="身份证号码/统一代码" min-width="250">
|
||||
<template #default="scope">
|
||||
<el-form-item
|
||||
:prop="'client_info.' + scope.$index + '.idNumber'"
|
||||
:rules="formRules.clientIdNumber"
|
||||
>
|
||||
<el-input v-model="scope.row.idNumber" placeholder="请输入" style="width: 100%" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="150" align="center">
|
||||
<template #default="scope">
|
||||
<el-button type="primary" size="small" @click="copyClient(scope.row)">复制</el-button>
|
||||
<el-button type="danger" size="small" @click="deleteClient(scope.$index)">
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<h2>相对方信息</h2>
|
||||
<div class="table-actions">
|
||||
<el-button type="primary" @click="addOpponent">
|
||||
<el-icon><Plus /></el-icon>
|
||||
新增一项
|
||||
</el-button>
|
||||
<el-button type="danger">
|
||||
<el-icon><Delete /></el-icon>
|
||||
批量删除
|
||||
</el-button>
|
||||
</div>
|
||||
<el-table
|
||||
:data="formData.party_info"
|
||||
border
|
||||
style="width: 100%"
|
||||
class="opponent-table"
|
||||
@selection-change="handleOpponentSelectionChange"
|
||||
>
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column prop="index" label="序号" width="80" align="center" />
|
||||
<el-table-column prop="name" label="自然人姓名/法人名称" min-width="200">
|
||||
<template #default="scope">
|
||||
<el-form-item
|
||||
:prop="'party_info.' + scope.$index + '.name'"
|
||||
:rules="formRules.opponentName"
|
||||
>
|
||||
<el-input v-model="scope.row.name" placeholder="请输入" style="width: 100%" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="idNumber" label="身份证号码/统一代码" min-width="250">
|
||||
<template #default="scope">
|
||||
<el-form-item
|
||||
:prop="'party_info.' + scope.$index + '.idNumber'"
|
||||
:rules="formRules.opponentIdNumber"
|
||||
>
|
||||
<el-input v-model="scope.row.idNumber" placeholder="请输入" style="width: 100%" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="150" align="center">
|
||||
<template #default="scope">
|
||||
<el-button type="primary" size="small" @click="copyOpponent(scope.row)">
|
||||
复制
|
||||
</el-button>
|
||||
<el-button type="danger" size="small" @click="deleteOpponent(scope.$index)">
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
|
||||
<el-form-item label="描述" prop="description">
|
||||
<el-input
|
||||
v-model="formData.description"
|
||||
type="textarea"
|
||||
placeholder="描述"
|
||||
:rows="4"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="负责人" prop="responsiblefor">
|
||||
<el-select v-model="formData.responsiblefor" placeholder="请选择负责人">
|
||||
<el-option
|
||||
v-for="item in UndertakerList"
|
||||
:key="item.id"
|
||||
:label="item.username"
|
||||
:value="item.username"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="收费情况" prop="charge">
|
||||
<el-input v-model="formData.charge" placeholder="请输入" />
|
||||
</el-form-item>
|
||||
<el-form-item label="合同" prop="AcademicResume">
|
||||
<el-upload
|
||||
class="avatar-uploader"
|
||||
action="#"
|
||||
:auto-upload="false"
|
||||
:show-file-list="false"
|
||||
:on-change="(file) => handleFileSelect(file, 'AcademicResume')"
|
||||
:before-upload="handleBeforeUpload"
|
||||
>
|
||||
<div v-if="formData.AcademicResume" class="upload-preview">
|
||||
<span>{{ formData.AcademicResume.name }}</span>
|
||||
<el-button type="danger" size="small" @click.stop="removeFile('AcademicResume')">
|
||||
删除
|
||||
</el-button>
|
||||
</div>
|
||||
<el-button v-else size="small" type="primary">点击选择文件</el-button>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
<!-- 提交按钮 -->
|
||||
<!-- <div class="form-actions">-->
|
||||
<!-- <el-button type="primary" @click="handleSubmit">提交</el-button>-->
|
||||
<!-- <el-button @click="handleSaveDraft">暂存</el-button>-->
|
||||
<!-- </div>-->
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { Delete, Plus } from '@element-plus/icons-vue'
|
||||
import { UserPersonneldisplay } from '@/api/calibration/personnelManagement'
|
||||
import { ElMessage } from 'element-plus'
|
||||
|
||||
const formRef = ref()
|
||||
// 表单数据
|
||||
const formData = reactive<any>({
|
||||
type: '',
|
||||
ContractNo: '',
|
||||
times: '',
|
||||
client_info: [{ index: 1, name: '', idNumber: '' }],
|
||||
party_info: [{ index: 1, name: '', idNumber: '' }],
|
||||
description: '',
|
||||
responsiblefor: '',
|
||||
charge: '',
|
||||
contract: undefined
|
||||
})
|
||||
|
||||
const UndertakerList = ref<any[]>([])
|
||||
|
||||
// 选择的委托人
|
||||
const selectedClients = ref<any[]>([])
|
||||
// 选择的相对方
|
||||
const selectedOpponents = ref<any[]>([])
|
||||
|
||||
const formRules = reactive<any>({
|
||||
times: [{ required: true, message: '请选择预立案日期', trigger: 'change' }],
|
||||
description: [{ required: true, message: '请填写项目简述/案由', trigger: 'blur' }],
|
||||
responsiblefor: [{ required: true, message: '请选择承办人员', trigger: 'change' }],
|
||||
clientName: [{ required: true, message: '请输入姓名/法人名称', trigger: 'blur' }],
|
||||
clientIdNumber: [{ required: true, message: '请输入身份证号码/统一代码', trigger: 'blur' }],
|
||||
opponentName: [{ required: true, message: '请输入姓名/法人名称', trigger: 'blur' }],
|
||||
opponentIdNumber: [{ required: true, message: '请输入身份证号码/统一代码', trigger: 'blur' }]
|
||||
})
|
||||
|
||||
// 处理委托人选择
|
||||
const handleClientSelectionChange = (selection: any[]) => {
|
||||
selectedClients.value = selection
|
||||
}
|
||||
|
||||
// 处理相对方选择
|
||||
const handleOpponentSelectionChange = (selection: any[]) => {
|
||||
selectedOpponents.value = selection
|
||||
}
|
||||
|
||||
// 新增委托人
|
||||
const addClient = () => {
|
||||
const newIndex = formData.client_info.length + 1
|
||||
formData.client_info.push({ index: newIndex, name: '', idNumber: '' })
|
||||
}
|
||||
|
||||
// 删除委托人
|
||||
const deleteClient = (index: number) => {
|
||||
if (formData.client_info.length > 1) {
|
||||
formData.client_info.splice(index, 1)
|
||||
// 更新序号
|
||||
formData.client_info.forEach((client: any, idx: number) => {
|
||||
client.index = idx + 1
|
||||
})
|
||||
} else if (formData.party_info.length === 0) {
|
||||
ElMessage.warning('委托方和相对方至少需要存在一个')
|
||||
} else {
|
||||
formData.client_info.splice(index, 1)
|
||||
}
|
||||
}
|
||||
|
||||
// 复制委托人
|
||||
const copyClient = (client: any) => {
|
||||
const newIndex = formData.client_info.length + 1
|
||||
formData.client_info.push({ ...client, index: newIndex })
|
||||
}
|
||||
|
||||
// 批量删除委托人
|
||||
const batchDeleteClients = () => {
|
||||
if (selectedClients.value.length === 0) {
|
||||
ElMessage.warning('请选择要删除的委托人')
|
||||
return
|
||||
}
|
||||
|
||||
// 检查是否删除后还剩至少一个(或相对方存在)
|
||||
if (
|
||||
formData.client_info.length - selectedClients.value.length === 0 &&
|
||||
formData.party_info.length === 0
|
||||
) {
|
||||
ElMessage.warning('委托方和相对方至少需要存在一个')
|
||||
return
|
||||
}
|
||||
|
||||
// 执行批量删除
|
||||
formData.client_info = formData.client_info.filter(
|
||||
(client: any) => !selectedClients.value.includes(client)
|
||||
)
|
||||
// 更新序号
|
||||
formData.client_info.forEach((client: any, idx: number) => {
|
||||
client.index = idx + 1
|
||||
})
|
||||
// 清空选择
|
||||
selectedClients.value = []
|
||||
ElMessage.success('批量删除成功')
|
||||
}
|
||||
|
||||
// 新增相对方
|
||||
const addOpponent = () => {
|
||||
const newIndex = formData.party_info.length + 1
|
||||
formData.party_info.push({ index: newIndex, name: '', idNumber: '' })
|
||||
}
|
||||
|
||||
// 删除相对方
|
||||
const deleteOpponent = (index: number) => {
|
||||
if (formData.party_info.length > 1) {
|
||||
formData.party_info.splice(index, 1)
|
||||
// 更新序号
|
||||
formData.party_info.forEach((opponent: any, idx: number) => {
|
||||
opponent.index = idx + 1
|
||||
})
|
||||
} else if (formData.client_info.length === 0) {
|
||||
ElMessage.warning('委托方和相对方至少需要存在一个')
|
||||
} else {
|
||||
formData.party_info.splice(index, 1)
|
||||
}
|
||||
}
|
||||
|
||||
// 复制相对方
|
||||
const copyOpponent = (opponent: any) => {
|
||||
const newIndex = formData.party_info.length + 1
|
||||
formData.party_info.push({ ...opponent, index: newIndex })
|
||||
}
|
||||
|
||||
function handleFileSelect(file: any, field: string): void {
|
||||
// 将文件对象保存到表单数据中
|
||||
formData[field] = file.raw // file.raw 是实际的 File 对象
|
||||
console.log(formData[field])
|
||||
formRef.value.clearValidate(field)
|
||||
ElMessage.success('文件选择成功')
|
||||
}
|
||||
|
||||
function handleBeforeUpload(file: File): boolean {
|
||||
// 可以在这里添加文件类型和大小的校验
|
||||
const isLt10M = file.size / 1024 / 1024 < 10
|
||||
if (!isLt10M) {
|
||||
ElMessage.error('上传文件大小不能超过 10MB!')
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
function removeFile(field: string): void {
|
||||
formData[field] = undefined
|
||||
ElMessage.success('文件已删除')
|
||||
}
|
||||
|
||||
const DepartmentList = () => {
|
||||
UserPersonneldisplay().then((res: any) => {
|
||||
UndertakerList.value = res.data
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
DepartmentList()
|
||||
})
|
||||
|
||||
const getForm = () => {
|
||||
return formData
|
||||
}
|
||||
|
||||
const submit = (): Promise<boolean> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
formRef.value?.validate((valid: boolean) => {
|
||||
if (valid) {
|
||||
// 验证委托方和相对方至少存在一个
|
||||
if (formData.client_info.length === 0 || formData.party_info.length === 0) {
|
||||
ElMessage.error('委托方和相对方至少需要存在一个')
|
||||
reject(false)
|
||||
return
|
||||
}
|
||||
resolve(true)
|
||||
} else {
|
||||
ElMessage.error('请完善必填信息')
|
||||
reject(false)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
defineExpose({
|
||||
submit,
|
||||
getForm
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.pre-registration-form {
|
||||
width: 100%;
|
||||
height: 600px;
|
||||
padding-right: 20px;
|
||||
overflow: hidden;
|
||||
overflow-y: auto;
|
||||
&::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb:hover {
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
}
|
||||
.section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,540 @@
|
||||
<!-- 用户管理 -->
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<!-- 搜索区域 -->
|
||||
<div class="search-container">
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="auto">
|
||||
<el-form-item label="委托人信息" prop="keywords">
|
||||
<el-input
|
||||
v-model="queryParams.keywords"
|
||||
placeholder="自然人姓名/身份证号码/法人机构名称/统一社会信用代码"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="相对方信息" prop="keywords">
|
||||
<el-input
|
||||
v-model="queryParams.keywords"
|
||||
placeholder="自然人姓名/身份证号码/法人机构名称/统一社会信用代码"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="search-buttons">
|
||||
<el-button type="primary" icon="search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="refresh" @click="handleResetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<el-button
|
||||
type="primary"
|
||||
icon="edit"
|
||||
style="margin-bottom: 20px"
|
||||
@click="handleOpenDialog('立项登记')"
|
||||
>
|
||||
立项登记
|
||||
</el-button>
|
||||
<el-button
|
||||
type="success"
|
||||
icon="Plus"
|
||||
style="margin-bottom: 20px"
|
||||
@click="handleOpenDialog('投标登记')"
|
||||
>
|
||||
投标登记
|
||||
</el-button>
|
||||
<el-card shadow="hover" class="data-table">
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="pageData"
|
||||
border
|
||||
stripe
|
||||
highlight-current-row
|
||||
class="data-table__content"
|
||||
row-key="id"
|
||||
@selection-change="handleSelectionChange"
|
||||
>
|
||||
<el-table-column label="案件名" prop="username" />
|
||||
<el-table-column label="委托人姓名" width="150" align="center" prop="nickname" />
|
||||
<el-table-column label="委托人身份证" width="120" align="center" prop="deptName" />
|
||||
<el-table-column label="相对方姓名" width="150" align="center" prop="mobile" />
|
||||
<el-table-column label="相对方身份证" align="center" prop="email" width="160" />
|
||||
<el-table-column label="主办律师" align="center" prop="createTime" width="150" />
|
||||
<el-table-column label="协办律师" align="center" prop="createTime" width="150" />
|
||||
<el-table-column label="律师助理" align="center" prop="createTime" width="150" />
|
||||
<el-table-column label="操作" align="center" width="220">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-hasPerm="'sys:user:reset-password'"
|
||||
type="primary"
|
||||
icon="RefreshLeft"
|
||||
size="small"
|
||||
link
|
||||
@click="handleResetPassword(scope.row)"
|
||||
>
|
||||
重置密码
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination
|
||||
v-if="total > 0"
|
||||
v-model:total="total"
|
||||
v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="fetchUserList"
|
||||
/>
|
||||
</el-card>
|
||||
<!-- 用户表单 -->
|
||||
<el-drawer
|
||||
v-model="dialog.visible"
|
||||
:title="dialog.title"
|
||||
append-to-body
|
||||
:size="drawerSize"
|
||||
@close="handleCloseDialog"
|
||||
>
|
||||
<el-form
|
||||
v-show="dialog.title === '立项登记'"
|
||||
ref="userFormRef"
|
||||
:model="formData"
|
||||
:rules="rules"
|
||||
label-width="80px"
|
||||
>
|
||||
<el-form-item label="用户名" prop="username">
|
||||
<el-input
|
||||
v-model="formData.username"
|
||||
:readonly="!!formData.id"
|
||||
placeholder="请输入用户名"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="用户昵称" prop="nickname">
|
||||
<el-input v-model="formData.nickname" placeholder="请输入用户昵称" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="所属部门" prop="deptId">
|
||||
<el-tree-select
|
||||
v-model="formData.deptId"
|
||||
placeholder="请选择所属部门"
|
||||
:data="deptOptions"
|
||||
filterable
|
||||
check-strictly
|
||||
:render-after-expand="false"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="性别" prop="gender">
|
||||
<Dict v-model="formData.gender" code="gender" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="角色" prop="roleIds">
|
||||
<el-select v-model="formData.roleIds" multiple placeholder="请选择">
|
||||
<el-option
|
||||
v-for="item in roleOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="手机号码" prop="mobile">
|
||||
<el-input v-model="formData.mobile" placeholder="请输入手机号码" maxlength="11" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="邮箱" prop="email">
|
||||
<el-input v-model="formData.email" placeholder="请输入邮箱" maxlength="50" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-switch
|
||||
v-model="formData.status"
|
||||
inline-prompt
|
||||
active-text="正常"
|
||||
inactive-text="禁用"
|
||||
:active-value="1"
|
||||
:inactive-value="0"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-form
|
||||
v-show="dialog.title === '投标登记'"
|
||||
ref="userFormRef"
|
||||
:model="formDataTender"
|
||||
:rules="rulesTender"
|
||||
label-width="80px"
|
||||
>
|
||||
<el-form-item label="案件名" prop="username">
|
||||
<el-input
|
||||
v-model="formData.username"
|
||||
:readonly="!!formData.id"
|
||||
placeholder="请输入案件名"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="handleSubmit">确 定</el-button>
|
||||
<el-button @click="handleCloseDialog">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
// ==================== 1. Vue 核心 API ====================
|
||||
import { computed, onMounted, reactive, ref } from 'vue'
|
||||
import { useDebounceFn } from '@vueuse/core'
|
||||
|
||||
// ==================== 2. Element Plus ====================
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
|
||||
// ==================== 3. 类型定义 ====================
|
||||
import type { UserForm, UserPageQuery, UserPageVO } from '@/api/system/user-api'
|
||||
// ==================== 4. API 服务 ====================
|
||||
import UserAPI from '@/api/system/user-api'
|
||||
|
||||
// ==================== 5. Store ====================
|
||||
import { useAppStore } from '@/store/modules/app-store'
|
||||
// import { useUserStore } from '@/store';
|
||||
|
||||
// ==================== 6. Enums ====================
|
||||
import { DeviceEnum } from '@/enums/settings/device-enum'
|
||||
|
||||
// ==================== 7. Composables ====================
|
||||
import { useAiAction, useTableSelection } from '@/composables'
|
||||
import { functionDialogBox } from '@/utils/functionDialogBox'
|
||||
import BusinessProjectForm from './components/BusinessProjectForm.vue'
|
||||
|
||||
// ==================== 8. 组件 ====================
|
||||
// import DeptTree from './components/DeptTree.vue';
|
||||
// import UserImport from './components/UserImport.vue';
|
||||
|
||||
// ==================== 组件配置 ====================
|
||||
defineOptions({
|
||||
name: 'SystemUser',
|
||||
inheritAttrs: false
|
||||
})
|
||||
|
||||
// ==================== Store 实例 ====================
|
||||
const appStore = useAppStore()
|
||||
// const userStore = useUserStore();
|
||||
|
||||
// ==================== 响应式状态 ====================
|
||||
|
||||
// DOM 引用
|
||||
const queryFormRef = ref()
|
||||
const userFormRef = ref()
|
||||
|
||||
// 列表查询参数
|
||||
const queryParams = reactive<UserPageQuery>({
|
||||
pageNum: 1,
|
||||
pageSize: 10
|
||||
})
|
||||
|
||||
// 列表数据
|
||||
const pageData = ref<UserPageVO[]>()
|
||||
const total = ref(0)
|
||||
const loading = ref(false)
|
||||
|
||||
// 弹窗状态
|
||||
const dialog = reactive({
|
||||
visible: false,
|
||||
title: '新增用户'
|
||||
})
|
||||
|
||||
// 表单数据
|
||||
const formData = reactive<UserForm>({
|
||||
status: 1
|
||||
})
|
||||
|
||||
// 登记表格数据
|
||||
const formDataTender = reactive<UserForm>({
|
||||
status: 1
|
||||
})
|
||||
|
||||
// 下拉选项数据
|
||||
const deptOptions = ref<OptionType[]>()
|
||||
const roleOptions = ref<OptionType[]>()
|
||||
|
||||
// 导入弹窗
|
||||
// const importDialogVisible = ref(false);
|
||||
|
||||
// ==================== 计算属性 ====================
|
||||
|
||||
/**
|
||||
* 抽屉尺寸(响应式)
|
||||
*/
|
||||
const drawerSize = computed(() => (appStore.device === DeviceEnum.DESKTOP ? '600px' : '90%'))
|
||||
|
||||
// ==================== 表单验证规则 ====================
|
||||
|
||||
const rules = reactive({
|
||||
username: [
|
||||
{
|
||||
required: true,
|
||||
message: '用户名不能为空',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
nickname: [
|
||||
{
|
||||
required: true,
|
||||
message: '用户昵称不能为空',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
deptId: [
|
||||
{
|
||||
required: true,
|
||||
message: '所属部门不能为空',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
roleIds: [
|
||||
{
|
||||
required: true,
|
||||
message: '用户角色不能为空',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
email: [
|
||||
{
|
||||
pattern: /\w[-\w.+]*@([A-Za-z0-9][-A-Za-z0-9]+\.)+[A-Za-z]{2,14}/,
|
||||
message: '请输入正确的邮箱地址',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
mobile: [
|
||||
{
|
||||
pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
|
||||
message: '请输入正确的手机号码',
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
const rulesTender = reactive({
|
||||
username: [
|
||||
{
|
||||
required: true,
|
||||
message: '案件名不能为空',
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
// ==================== 数据加载 ====================
|
||||
|
||||
/**
|
||||
* 获取用户列表数据
|
||||
*/
|
||||
async function fetchUserList(): Promise<void> {
|
||||
loading.value = true
|
||||
try {
|
||||
const data = await UserAPI.getPage(queryParams)
|
||||
pageData.value = data.list
|
||||
total.value = data.total
|
||||
} catch (error) {
|
||||
ElMessage.error('获取用户列表失败')
|
||||
console.error('获取用户列表失败:', error)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== 表格选择 ====================
|
||||
const { handleSelectionChange } = useTableSelection<UserPageVO>()
|
||||
|
||||
// ==================== 查询操作 ====================
|
||||
|
||||
/**
|
||||
* 查询用户列表
|
||||
*/
|
||||
function handleQuery(): Promise<void> {
|
||||
queryParams.pageNum = 1
|
||||
return fetchUserList()
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置查询条件
|
||||
*/
|
||||
function handleResetQuery(): void {
|
||||
queryFormRef.value.resetFields()
|
||||
queryParams.deptId = undefined
|
||||
queryParams.createTime = undefined
|
||||
handleQuery()
|
||||
}
|
||||
// ==================== 用户操作 ====================
|
||||
|
||||
/**
|
||||
* 重置用户密码
|
||||
* @param row 用户数据
|
||||
*/
|
||||
function handleResetPassword(row: UserPageVO): void {
|
||||
ElMessageBox.prompt(`请输入用户【${row.username}】的新密码`, '重置密码', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
inputPattern: /.{6,}/,
|
||||
inputErrorMessage: '密码至少需要6位字符'
|
||||
})
|
||||
.then(({ value }) => {
|
||||
return UserAPI.resetPassword(row.id, value)
|
||||
})
|
||||
.then(() => {
|
||||
ElMessage.success('密码重置成功')
|
||||
})
|
||||
.catch((error) => {
|
||||
if (error !== 'cancel') {
|
||||
ElMessage.error('密码重置失败')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// ==================== 弹窗操作 ====================
|
||||
|
||||
/**
|
||||
* 打开用户表单弹窗
|
||||
* @param id 用户ID(编辑时传入)
|
||||
*/
|
||||
async function handleOpenDialog(titleString: string, id?: string): Promise<void> {
|
||||
// dialog.visible = true
|
||||
// dialog.title = titleString
|
||||
//
|
||||
// // 并行加载下拉选项数据
|
||||
// try {
|
||||
// ;[roleOptions.value, deptOptions.value] = await Promise.all([
|
||||
// RoleAPI.getOptions(),
|
||||
// DeptAPI.getOptions()
|
||||
// ])
|
||||
// } catch (error) {
|
||||
// ElMessage.error('加载选项数据失败')
|
||||
// console.error('加载选项数据失败:', error)
|
||||
// }
|
||||
//
|
||||
// // 编辑:加载用户数据
|
||||
// if (id) {
|
||||
// try {
|
||||
// const data = await UserAPI.getFormData(id)
|
||||
// Object.assign(formData, data)
|
||||
// } catch (error) {
|
||||
// ElMessage.error('加载用户数据失败')
|
||||
// console.error('加载用户数据失败:', error)
|
||||
// }
|
||||
// }
|
||||
functionDialogBox(
|
||||
BusinessProjectForm,
|
||||
{},
|
||||
{
|
||||
title: '新增预立案登记',
|
||||
width: '900',
|
||||
ok(value: any) {
|
||||
console.log('value', value)
|
||||
handleSubmit(value)
|
||||
}
|
||||
// cancel() {
|
||||
// console.log("value");
|
||||
// },
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭用户表单弹窗
|
||||
*/
|
||||
function handleCloseDialog(): void {
|
||||
dialog.visible = false
|
||||
userFormRef.value.resetFields()
|
||||
userFormRef.value.clearValidate()
|
||||
|
||||
// 重置表单数据
|
||||
formData.id = undefined
|
||||
formData.status = 1
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交用户表单(防抖)
|
||||
*/
|
||||
const handleSubmit = useDebounceFn(async (data: any) => {
|
||||
const valid = await userFormRef.value.validate().catch(() => false)
|
||||
if (!valid) return
|
||||
|
||||
const userId = data.id
|
||||
loading.value = true
|
||||
|
||||
try {
|
||||
if (userId) {
|
||||
await UserAPI.update(userId, formData)
|
||||
ElMessage.success('修改用户成功')
|
||||
} else {
|
||||
// await UserAPI.create(data)
|
||||
console.log(data)
|
||||
ElMessage.success('新增用户成功')
|
||||
}
|
||||
handleCloseDialog()
|
||||
handleResetQuery()
|
||||
} catch (error) {
|
||||
ElMessage.error(userId ? '修改用户失败' : '新增用户失败')
|
||||
console.error('提交用户表单失败:', error)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}, 1000)
|
||||
|
||||
// ==================== AI 助手相关 ====================
|
||||
useAiAction({
|
||||
actionHandlers: {
|
||||
/**
|
||||
* AI 修改用户昵称
|
||||
* 使用配置对象方式:自动处理确认、执行、反馈
|
||||
*/
|
||||
updateUserNickname: {
|
||||
needConfirm: true,
|
||||
callBackendApi: true, // 自动调用后端 API
|
||||
confirmMessage: (args: any) =>
|
||||
`AI 助手将执行以下操作:<br/>
|
||||
<strong>修改用户:</strong> ${args.username}<br/>
|
||||
<strong>新昵称:</strong> ${args.nickname}<br/><br/>
|
||||
确认执行吗?`,
|
||||
successMessage: (args: any) => `已将用户 ${args.username} 的昵称修改为 ${args.nickname}`,
|
||||
execute: async () => {
|
||||
// callBackendApi=true 时,execute 可以为空
|
||||
// Composable 会自动调用后端 API
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* AI 查询用户
|
||||
* 使用配置对象方式:查询操作不需要确认
|
||||
*/
|
||||
queryUser: {
|
||||
needConfirm: false, // 查询操作无需确认
|
||||
successMessage: (args: any) => `已搜索:${args.keywords}`,
|
||||
execute: async (args: any) => {
|
||||
queryParams.keywords = args.keywords
|
||||
await handleQuery()
|
||||
}
|
||||
}
|
||||
},
|
||||
onRefresh: fetchUserList,
|
||||
onAutoSearch: (keywords: string) => {
|
||||
queryParams.keywords = keywords
|
||||
setTimeout(() => {
|
||||
handleQuery()
|
||||
ElMessage.success(`AI 助手已为您自动搜索:${keywords}`)
|
||||
}, 300)
|
||||
}
|
||||
})
|
||||
|
||||
// ==================== 生命周期 ====================
|
||||
|
||||
/**
|
||||
* 组件挂载时初始化数据
|
||||
*
|
||||
* 注意:这里会先加载列表数据,如果 URL 中有 AI 参数(如搜索关键字),
|
||||
* useAiAction 会在 nextTick 中再次执行搜索,这是预期行为
|
||||
*/
|
||||
onMounted(() => {
|
||||
handleQuery()
|
||||
})
|
||||
</script>
|
||||
@@ -0,0 +1,359 @@
|
||||
<template>
|
||||
<div class="pre-registration-form">
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="formData"
|
||||
:rules="formRules"
|
||||
label-width="auto"
|
||||
label-position="top"
|
||||
>
|
||||
<!-- 预立案日期 -->
|
||||
<el-form-item label="预立案日期" prop="times">
|
||||
<el-date-picker
|
||||
v-model="formData.times"
|
||||
type="date"
|
||||
placeholder="请选择预立案日期"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 委托人信息 -->
|
||||
<div class="section">
|
||||
<h2>委托人信息</h2>
|
||||
<div class="table-actions">
|
||||
<el-button type="primary" @click="addClient">
|
||||
<el-icon><Plus /></el-icon>
|
||||
新增一项
|
||||
</el-button>
|
||||
<el-button type="danger" @click="batchDeleteClients">
|
||||
<el-icon><Delete /></el-icon>
|
||||
批量删除
|
||||
</el-button>
|
||||
</div>
|
||||
<el-table
|
||||
:data="formData.client_username"
|
||||
border
|
||||
style="width: 100%"
|
||||
class="client-table"
|
||||
@selection-change="handleClientSelectionChange"
|
||||
>
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column prop="index" label="序号" width="80" align="center" />
|
||||
<el-table-column prop="name" label="自然人姓名/法人名称" min-width="200">
|
||||
<template #default="scope">
|
||||
<el-form-item
|
||||
:prop="'client_username.' + scope.$index + '.name'"
|
||||
:rules="formRules.clientName"
|
||||
>
|
||||
<el-input v-model="scope.row.name" placeholder="请输入" style="width: 100%" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="idNumber" label="身份证号码/统一代码" min-width="250">
|
||||
<template #default="scope">
|
||||
<el-form-item
|
||||
:prop="'client_username.' + scope.$index + '.idNumber'"
|
||||
:rules="formRules.clientIdNumber"
|
||||
>
|
||||
<el-input v-model="scope.row.idNumber" placeholder="请输入" style="width: 100%" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="150" align="center">
|
||||
<template #default="scope">
|
||||
<el-button type="primary" size="small" @click="copyClient(scope.row)">复制</el-button>
|
||||
<el-button type="danger" size="small" @click="deleteClient(scope.$index)">
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
|
||||
<!-- 相对方信息 -->
|
||||
<div class="section">
|
||||
<h2>相对方信息</h2>
|
||||
<div class="table-actions">
|
||||
<el-button type="primary" @click="addOpponent">
|
||||
<el-icon><Plus /></el-icon>
|
||||
新增一项
|
||||
</el-button>
|
||||
<el-button type="danger">
|
||||
<el-icon><Delete /></el-icon>
|
||||
批量删除
|
||||
</el-button>
|
||||
</div>
|
||||
<el-table
|
||||
:data="formData.party_username"
|
||||
border
|
||||
style="width: 100%"
|
||||
class="opponent-table"
|
||||
@selection-change="handleOpponentSelectionChange"
|
||||
>
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column prop="index" label="序号" width="80" align="center" />
|
||||
<el-table-column prop="name" label="自然人姓名/法人名称" min-width="200">
|
||||
<template #default="scope">
|
||||
<el-form-item
|
||||
:prop="'party_username.' + scope.$index + '.name'"
|
||||
:rules="formRules.opponentName"
|
||||
>
|
||||
<el-input v-model="scope.row.name" placeholder="请输入" style="width: 100%" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="idNumber" label="身份证号码/统一代码" min-width="250">
|
||||
<template #default="scope">
|
||||
<el-form-item
|
||||
:prop="'party_username.' + scope.$index + '.idNumber'"
|
||||
:rules="formRules.opponentIdNumber"
|
||||
>
|
||||
<el-input v-model="scope.row.idNumber" placeholder="请输入" style="width: 100%" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="150" align="center">
|
||||
<template #default="scope">
|
||||
<el-button type="primary" size="small" @click="copyOpponent(scope.row)">
|
||||
复制
|
||||
</el-button>
|
||||
<el-button type="danger" size="small" @click="deleteOpponent(scope.$index)">
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
|
||||
<!-- 项目简述/案由 -->
|
||||
<el-form-item label="项目简述/案由" prop="description">
|
||||
<el-input
|
||||
v-model="formData.description"
|
||||
type="textarea"
|
||||
placeholder="简要陈述项目情况"
|
||||
:rows="4"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 承办人员 -->
|
||||
<el-form-item label="承办人员" prop="Undertaker">
|
||||
<el-select v-model="formData.Undertaker" placeholder="请选择承办人员">
|
||||
<el-option
|
||||
v-for="item in UndertakerList"
|
||||
:key="item.id"
|
||||
:label="item.username"
|
||||
:value="item.username"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 提交按钮 -->
|
||||
<!-- <div class="form-actions">-->
|
||||
<!-- <el-button type="primary" @click="handleSubmit">提交</el-button>-->
|
||||
<!-- <el-button @click="handleSaveDraft">暂存</el-button>-->
|
||||
<!-- </div>-->
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { Delete, Plus } from '@element-plus/icons-vue'
|
||||
import { UserPersonneldisplay } from '@/api/calibration/personnelManagement'
|
||||
|
||||
const formRef = ref()
|
||||
// 表单数据
|
||||
const formData = reactive<any>({
|
||||
times: '',
|
||||
client_username: [{ index: 1, name: '', idNumber: '' }],
|
||||
party_username: [{ index: 1, name: '', idNumber: '' }],
|
||||
description: '',
|
||||
Undertaker: ''
|
||||
})
|
||||
|
||||
const UndertakerList = ref<any[]>([])
|
||||
|
||||
// 选择的委托人
|
||||
const selectedClients = ref<any[]>([])
|
||||
// 选择的相对方
|
||||
const selectedOpponents = ref<any[]>([])
|
||||
|
||||
const formRules = reactive<any>({
|
||||
times: [{ required: true, message: '请选择预立案日期', trigger: 'change' }],
|
||||
description: [{ required: true, message: '请填写项目简述/案由', trigger: 'blur' }],
|
||||
Undertaker: [{ required: true, message: '请选择承办人员', trigger: 'change' }],
|
||||
clientName: [{ required: true, message: '请输入姓名/法人名称', trigger: 'blur' }],
|
||||
clientIdNumber: [{ required: true, message: '请输入身份证号码/统一代码', trigger: 'blur' }],
|
||||
opponentName: [{ required: true, message: '请输入姓名/法人名称', trigger: 'blur' }],
|
||||
opponentIdNumber: [{ required: true, message: '请输入身份证号码/统一代码', trigger: 'blur' }]
|
||||
})
|
||||
|
||||
// 处理委托人选择
|
||||
const handleClientSelectionChange = (selection: any[]) => {
|
||||
selectedClients.value = selection
|
||||
}
|
||||
|
||||
// 处理相对方选择
|
||||
const handleOpponentSelectionChange = (selection: any[]) => {
|
||||
selectedOpponents.value = selection
|
||||
}
|
||||
|
||||
// 新增委托人
|
||||
const addClient = () => {
|
||||
const newIndex = formData.client_username.length + 1
|
||||
formData.client_username.push({ index: newIndex, name: '', idNumber: '' })
|
||||
}
|
||||
|
||||
// 删除委托人
|
||||
const deleteClient = (index: number) => {
|
||||
if (formData.client_username.length > 1) {
|
||||
formData.client_username.splice(index, 1)
|
||||
// 更新序号
|
||||
formData.client_username.forEach((client: any, idx: number) => {
|
||||
client.index = idx + 1
|
||||
})
|
||||
} else if (formData.party_username.length === 0) {
|
||||
ElMessage.warning('委托方和相对方至少需要存在一个')
|
||||
} else {
|
||||
formData.client_username.splice(index, 1)
|
||||
}
|
||||
}
|
||||
|
||||
// 复制委托人
|
||||
const copyClient = (client: any) => {
|
||||
const newIndex = formData.client_username.length + 1
|
||||
formData.client_username.push({ ...client, index: newIndex })
|
||||
}
|
||||
|
||||
// 批量删除委托人
|
||||
const batchDeleteClients = () => {
|
||||
if (selectedClients.value.length === 0) {
|
||||
ElMessage.warning('请选择要删除的委托人')
|
||||
return
|
||||
}
|
||||
|
||||
// 检查是否删除后还剩至少一个(或相对方存在)
|
||||
if (
|
||||
formData.client_username.length - selectedClients.value.length === 0 &&
|
||||
formData.party_username.length === 0
|
||||
) {
|
||||
ElMessage.warning('委托方和相对方至少需要存在一个')
|
||||
return
|
||||
}
|
||||
|
||||
// 执行批量删除
|
||||
formData.client_username = formData.client_username.filter(
|
||||
(client: any) => !selectedClients.value.includes(client)
|
||||
)
|
||||
// 更新序号
|
||||
formData.client_username.forEach((client: any, idx: number) => {
|
||||
client.index = idx + 1
|
||||
})
|
||||
// 清空选择
|
||||
selectedClients.value = []
|
||||
ElMessage.success('批量删除成功')
|
||||
}
|
||||
|
||||
// 新增相对方
|
||||
const addOpponent = () => {
|
||||
const newIndex = formData.party_username.length + 1
|
||||
formData.party_username.push({ index: newIndex, name: '', idNumber: '' })
|
||||
}
|
||||
|
||||
// 删除相对方
|
||||
const deleteOpponent = (index: number) => {
|
||||
if (formData.party_username.length > 1) {
|
||||
formData.party_username.splice(index, 1)
|
||||
// 更新序号
|
||||
formData.party_username.forEach((opponent: any, idx: number) => {
|
||||
opponent.index = idx + 1
|
||||
})
|
||||
} else if (formData.client_username.length === 0) {
|
||||
ElMessage.warning('委托方和相对方至少需要存在一个')
|
||||
} else {
|
||||
formData.party_username.splice(index, 1)
|
||||
}
|
||||
}
|
||||
|
||||
// 复制相对方
|
||||
const copyOpponent = (opponent: any) => {
|
||||
const newIndex = formData.party_username.length + 1
|
||||
formData.party_username.push({ ...opponent, index: newIndex })
|
||||
}
|
||||
|
||||
// 暂存表单
|
||||
// const handleSaveDraft = () => {
|
||||
// // 保存草稿逻辑
|
||||
// console.log('暂存表单数据:', formData)
|
||||
// ElMessage.success('表单暂存成功')
|
||||
// }
|
||||
const DepartmentList = () => {
|
||||
UserPersonneldisplay().then((res: any) => {
|
||||
UndertakerList.value = res.data
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
DepartmentList()
|
||||
})
|
||||
|
||||
const getForm = () => {
|
||||
return formData
|
||||
}
|
||||
|
||||
const submit = (): Promise<boolean> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
formRef.value?.validate((valid: boolean) => {
|
||||
if (valid) {
|
||||
// 验证委托方和相对方至少存在一个
|
||||
if (formData.client_username.length === 0 || formData.party_username.length === 0) {
|
||||
ElMessage.error('委托方和相对方至少需要存在一个')
|
||||
reject(false)
|
||||
return
|
||||
}
|
||||
resolve(true)
|
||||
} else {
|
||||
ElMessage.error('请完善必填信息')
|
||||
reject(false)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
defineExpose({
|
||||
submit,
|
||||
getForm
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.pre-registration-form {
|
||||
width: 100%;
|
||||
height: 600px;
|
||||
padding-right: 20px;
|
||||
overflow: hidden;
|
||||
overflow-y: auto;
|
||||
&::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb:hover {
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
}
|
||||
.section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
}
|
||||
</style>
|
||||
320
src/views/calibration/businessSystem/preRegistration/index.vue
Normal file
320
src/views/calibration/businessSystem/preRegistration/index.vue
Normal file
@@ -0,0 +1,320 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<!-- 搜索区域 -->
|
||||
<div class="search-container">
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||
<el-form-item prop="person" label="报销人">
|
||||
<el-input
|
||||
v-model="queryParams.person"
|
||||
placeholder="请输入报销人"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="创建时间" prop="times">
|
||||
<el-date-picker
|
||||
v-model="queryParams.times"
|
||||
type="daterange"
|
||||
value-format="YYYY-MM-DD"
|
||||
placeholder="请选择创建时间"
|
||||
range-separator="至"
|
||||
start-placeholder="开始时间"
|
||||
end-placeholder="结束时间"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="search-buttons">
|
||||
<el-button type="primary" icon="search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="refresh" @click="handleResetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<el-card shadow="hover" class="data-table">
|
||||
<div class="data-table__toolbar">
|
||||
<div class="data-table__toolbar--actions">
|
||||
<el-button type="success" icon="plus" @click="handleOpenDialog()">新增</el-button>
|
||||
<el-button
|
||||
type="danger"
|
||||
:disabled="ids.length === 0"
|
||||
icon="delete"
|
||||
@click="handleDelete()"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<el-table
|
||||
ref="dataTableRef"
|
||||
v-loading="loading"
|
||||
:data="roleList"
|
||||
highlight-current-row
|
||||
border
|
||||
class="data-table__content"
|
||||
@selection-change="handleSelectionChange"
|
||||
>
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="委托人信息" prop="client_username">
|
||||
<el-table-column v-slot="{ row }" prop="client_username" label="自然人姓名/法人名称">
|
||||
{{
|
||||
JSON.parse(row.client_username)
|
||||
.map((item: any) => item.name)
|
||||
.join(',')
|
||||
}}
|
||||
</el-table-column>
|
||||
<el-table-column v-slot="{ row }" prop="client_username" label="身份证号码/统一代码">
|
||||
{{
|
||||
JSON.parse(row.client_username)
|
||||
.map((item: any) => item.idNumber)
|
||||
.join(',')
|
||||
}}
|
||||
</el-table-column>
|
||||
</el-table-column>
|
||||
<el-table-column label="相对方信息" prop="party_username">
|
||||
<el-table-column v-slot="{ row }" prop="party_username" label="自然人姓名/法人名称">
|
||||
{{
|
||||
JSON.parse(row.party_username)
|
||||
.map((item: any) => item.name)
|
||||
.join(',')
|
||||
}}
|
||||
</el-table-column>
|
||||
<el-table-column v-slot="{ row }" prop="party_username" label="身份证号码/统一代码">
|
||||
{{
|
||||
JSON.parse(row.party_username)
|
||||
.map((item: any) => item.idNumber)
|
||||
.join(',')
|
||||
}}
|
||||
</el-table-column>
|
||||
</el-table-column>
|
||||
<el-table-column label="承办人员" prop="Undertaker" />
|
||||
<el-table-column label="描述" prop="description" />
|
||||
<el-table-column label="时间" prop="times" />
|
||||
<el-table-column fixed="right" label="操作" width="220">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
type="primary"
|
||||
size="small"
|
||||
link
|
||||
icon="edit"
|
||||
@click="handleOpenDialog(scope.row.id)"
|
||||
>
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
type="danger"
|
||||
size="small"
|
||||
link
|
||||
icon="delete"
|
||||
@click="onUserDeleteDepartment(scope.row.id)"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination
|
||||
v-if="total > 0"
|
||||
v-model:total="total"
|
||||
v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="fetchData"
|
||||
/>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import RoleAPI, { RolePageVO } from '@/api/system/role-api'
|
||||
import { UserDeleteDepartment } from '@/api/calibration/department'
|
||||
import { UserPersonneldisplay } from '@/api/calibration/personnelManagement'
|
||||
import { functionDialogBox } from '@/utils/functionDialogBox'
|
||||
import PreRegistrationForm from './components/PreRegistrationForm.vue'
|
||||
import { BusinessRegister, BusinessRegisterdetail } from '@/api/calibration/preRegistration'
|
||||
|
||||
defineOptions({
|
||||
name: 'Role',
|
||||
inheritAttrs: false
|
||||
})
|
||||
|
||||
const queryFormRef = ref()
|
||||
const permTreeRef = ref()
|
||||
|
||||
const loading = ref(false)
|
||||
const ids = ref<number[]>([])
|
||||
const total = ref(0)
|
||||
const personinchargeList = ref<any[]>([])
|
||||
|
||||
const queryParams = reactive<any>({
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
times: [],
|
||||
Undertaker: ''
|
||||
})
|
||||
|
||||
// 角色表格数据
|
||||
const roleList = ref<RolePageVO[]>()
|
||||
|
||||
// 弹窗
|
||||
const dialog = reactive({
|
||||
title: '',
|
||||
visible: false
|
||||
})
|
||||
|
||||
const permKeywords = ref('')
|
||||
|
||||
// 获取数据
|
||||
function fetchData() {
|
||||
loading.value = true
|
||||
BusinessRegisterdetail(queryParams)
|
||||
.then((res: any) => {
|
||||
roleList.value = res.data
|
||||
total.value = res.total
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
|
||||
// 查询(重置页码后获取数据)
|
||||
function handleQuery() {
|
||||
queryParams.pageNum = 1
|
||||
fetchData()
|
||||
}
|
||||
|
||||
// 重置查询
|
||||
function handleResetQuery() {
|
||||
if (queryFormRef.value) queryFormRef.value.resetFields()
|
||||
queryParams.pageNum = 1
|
||||
fetchData()
|
||||
}
|
||||
|
||||
// 行复选框选中
|
||||
function handleSelectionChange(selection: any) {
|
||||
ids.value = selection.map((item: any) => item.id)
|
||||
}
|
||||
|
||||
// 打开角色弹窗
|
||||
function handleOpenDialog(roleId?: string) {
|
||||
dialog.visible = true
|
||||
if (roleId) {
|
||||
functionDialogBox(
|
||||
PreRegistrationForm,
|
||||
{},
|
||||
{
|
||||
title: '编辑预立案登记',
|
||||
width: '900',
|
||||
ok(value: any) {
|
||||
console.log('value', value)
|
||||
}
|
||||
// cancel() {
|
||||
// console.log("value");
|
||||
// },
|
||||
}
|
||||
)
|
||||
} else {
|
||||
functionDialogBox(
|
||||
PreRegistrationForm,
|
||||
{},
|
||||
{
|
||||
title: '新增预立案登记',
|
||||
width: '900',
|
||||
ok(value: any) {
|
||||
console.log('value', value)
|
||||
handleSubmit(value)
|
||||
}
|
||||
// cancel() {
|
||||
// console.log("value");
|
||||
// },
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// 提交角色表单
|
||||
function handleSubmit(data: any) {
|
||||
loading.value = true
|
||||
const roleId = data.id
|
||||
if (roleId) {
|
||||
// RoleAPI.update(roleId, formData)
|
||||
// .then(() => {
|
||||
// ElMessage.success('修改成功')
|
||||
// handleCloseDialog()
|
||||
// handleResetQuery()
|
||||
// })
|
||||
// .finally(() => (loading.value = false))
|
||||
} else {
|
||||
BusinessRegister({
|
||||
...data,
|
||||
client_username: JSON.stringify(data.client_username),
|
||||
party_username: JSON.stringify(data.party_username)
|
||||
})
|
||||
.then(() => {
|
||||
ElMessage.success('新增成功')
|
||||
handleResetQuery()
|
||||
})
|
||||
.finally(() => (loading.value = false))
|
||||
}
|
||||
}
|
||||
|
||||
const onUserDeleteDepartment = (id: string) => {
|
||||
ElMessageBox.confirm('确认删除已选中的数据项?', '警告', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(
|
||||
() => {
|
||||
loading.value = true
|
||||
UserDeleteDepartment(id)
|
||||
.then(() => {
|
||||
ElMessage.success('删除成功')
|
||||
handleResetQuery()
|
||||
})
|
||||
.finally(() => (loading.value = false))
|
||||
},
|
||||
() => {
|
||||
ElMessage.info('已取消删除')
|
||||
}
|
||||
)
|
||||
}
|
||||
// 删除角色
|
||||
function handleDelete(roleId?: number) {
|
||||
const roleIds = [roleId || ids.value].join(',')
|
||||
if (!roleIds) {
|
||||
ElMessage.warning('请勾选删除项')
|
||||
return
|
||||
}
|
||||
|
||||
ElMessageBox.confirm('确认删除已选中的数据项?', '警告', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(
|
||||
() => {
|
||||
loading.value = true
|
||||
RoleAPI.deleteByIds(roleIds)
|
||||
.then(() => {
|
||||
ElMessage.success('删除成功')
|
||||
handleResetQuery()
|
||||
})
|
||||
.finally(() => (loading.value = false))
|
||||
},
|
||||
() => {
|
||||
ElMessage.info('已取消删除')
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
const DepartmentList = () => {
|
||||
UserPersonneldisplay().then((res: any) => {
|
||||
personinchargeList.value = res.data
|
||||
})
|
||||
}
|
||||
// 权限筛选
|
||||
watch(permKeywords, (val) => {
|
||||
permTreeRef.value!.filter(val)
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
handleQuery()
|
||||
DepartmentList()
|
||||
})
|
||||
</script>
|
||||
312
vite.config.ts
312
vite.config.ts
@@ -1,55 +1,55 @@
|
||||
import vue from "@vitejs/plugin-vue";
|
||||
import { type ConfigEnv, type UserConfig, loadEnv, defineConfig, type PluginOption } from "vite";
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
import { type ConfigEnv, type UserConfig, loadEnv, defineConfig, type PluginOption } from 'vite'
|
||||
|
||||
import AutoImport from "unplugin-auto-import/vite";
|
||||
import Components from "unplugin-vue-components/vite";
|
||||
import { ElementPlusResolver } from "unplugin-vue-components/resolvers";
|
||||
import AutoImport from 'unplugin-auto-import/vite'
|
||||
import Components from 'unplugin-vue-components/vite'
|
||||
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
|
||||
|
||||
import { mockDevServerPlugin } from "vite-plugin-mock-dev-server";
|
||||
import { mockDevServerPlugin } from 'vite-plugin-mock-dev-server'
|
||||
|
||||
import UnoCSS from "unocss/vite";
|
||||
import { resolve } from "path";
|
||||
import { name, version, engines, dependencies, devDependencies } from "./package.json";
|
||||
import UnoCSS from 'unocss/vite'
|
||||
import { resolve } from 'path'
|
||||
import { name, version, engines, dependencies, devDependencies } from './package.json'
|
||||
|
||||
// 平台的名称、版本、运行所需的 node 版本、依赖、构建时间的类型提示
|
||||
const __APP_INFO__ = {
|
||||
pkg: { name, version, engines, dependencies, devDependencies },
|
||||
buildTimestamp: Date.now(),
|
||||
};
|
||||
buildTimestamp: Date.now()
|
||||
}
|
||||
|
||||
const pathSrc = resolve(__dirname, "src");
|
||||
const pathSrc = resolve(__dirname, 'src')
|
||||
|
||||
// Vite配置 https://cn.vitejs.dev/config
|
||||
export default defineConfig(({ mode }: ConfigEnv) => {
|
||||
const env = loadEnv(mode, process.cwd());
|
||||
const isProduction = mode === "production";
|
||||
const env = loadEnv(mode, process.cwd())
|
||||
const isProduction = mode === 'production'
|
||||
|
||||
return {
|
||||
base: "./", // 设置为相对路径,支持直接打开index.html
|
||||
base: './', // 设置为相对路径,支持直接打开index.html
|
||||
resolve: {
|
||||
alias: {
|
||||
"@": pathSrc,
|
||||
},
|
||||
'@': pathSrc
|
||||
}
|
||||
},
|
||||
css: {
|
||||
preprocessorOptions: {
|
||||
// 定义全局 SCSS 变量
|
||||
scss: {
|
||||
additionalData: `@use "@/styles/variables.scss" as *;`,
|
||||
},
|
||||
},
|
||||
additionalData: `@use "@/styles/variables.scss" as *;`
|
||||
}
|
||||
}
|
||||
},
|
||||
server: {
|
||||
host: "0.0.0.0",
|
||||
host: '0.0.0.0',
|
||||
port: +(env.VITE_APP_PORT as string),
|
||||
open: true,
|
||||
proxy: {
|
||||
"/dev-api/api2": {
|
||||
'/dev-api/api2': {
|
||||
changeOrigin: true,
|
||||
target: "http://8.137.99.82:8006",
|
||||
target: 'http://192.168.31.69:8006',
|
||||
rewrite: (path: string) => {
|
||||
return path.replace(/^\/dev-api\/api2/, "");
|
||||
},
|
||||
return path.replace(/^\/dev-api\/api2/, '')
|
||||
}
|
||||
},
|
||||
// 代理 /dev-api 的请求
|
||||
[env.VITE_APP_BASE_API as string]: {
|
||||
@@ -57,163 +57,163 @@ export default defineConfig(({ mode }: ConfigEnv) => {
|
||||
// 代理目标地址:https://api.youlai.tech
|
||||
target: env.VITE_APP_API_URL as string,
|
||||
rewrite: (path: string) => {
|
||||
return path.replace(new RegExp("^" + (env.VITE_APP_BASE_API as string)), "");
|
||||
},
|
||||
},
|
||||
},
|
||||
return path.replace(new RegExp('^' + (env.VITE_APP_BASE_API as string)), '')
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins: [
|
||||
vue(),
|
||||
...(env.VITE_MOCK_DEV_SERVER === "true" ? [mockDevServerPlugin()] : []),
|
||||
...(env.VITE_MOCK_DEV_SERVER === 'true' ? [mockDevServerPlugin()] : []),
|
||||
UnoCSS(),
|
||||
// API 自动导入
|
||||
AutoImport({
|
||||
// 导入 Vue 函数,如:ref, reactive, toRef 等
|
||||
imports: ["vue", "@vueuse/core", "pinia", "vue-router", "vue-i18n"],
|
||||
imports: ['vue', '@vueuse/core', 'pinia', 'vue-router', 'vue-i18n'],
|
||||
resolvers: [
|
||||
// 导入 Element Plus函数,如:ElMessage, ElMessageBox 等
|
||||
ElementPlusResolver({ importStyle: "sass" }),
|
||||
ElementPlusResolver({ importStyle: 'sass' })
|
||||
],
|
||||
eslintrc: {
|
||||
enabled: false,
|
||||
filepath: "./.eslintrc-auto-import.json",
|
||||
globalsPropValue: true,
|
||||
filepath: './.eslintrc-auto-import.json',
|
||||
globalsPropValue: true
|
||||
},
|
||||
vueTemplate: true,
|
||||
// 导入函数类型声明文件路径 (false:关闭自动生成)
|
||||
dts: false,
|
||||
dts: false
|
||||
// dts: "src/types/auto-imports.d.ts",
|
||||
}),
|
||||
// 组件自动导入
|
||||
Components({
|
||||
resolvers: [
|
||||
// 导入 Element Plus 组件
|
||||
ElementPlusResolver({ importStyle: "sass" }),
|
||||
ElementPlusResolver({ importStyle: 'sass' })
|
||||
],
|
||||
// 指定自定义组件位置(默认:src/components)
|
||||
dirs: ["src/components", "src/**/components"],
|
||||
dirs: ['src/components', 'src/**/components'],
|
||||
// 导入组件类型声明文件路径 (false:关闭自动生成)
|
||||
dts: false,
|
||||
dts: false
|
||||
// dts: "src/types/components.d.ts",
|
||||
}),
|
||||
})
|
||||
],
|
||||
// 预加载项目必需的组件
|
||||
optimizeDeps: {
|
||||
include: [
|
||||
"vue",
|
||||
"vue-router",
|
||||
"element-plus",
|
||||
"pinia",
|
||||
"axios",
|
||||
"@vueuse/core",
|
||||
"codemirror-editor-vue3",
|
||||
"default-passive-events",
|
||||
"exceljs",
|
||||
"path-to-regexp",
|
||||
"echarts/core",
|
||||
"echarts/renderers",
|
||||
"echarts/charts",
|
||||
"echarts/components",
|
||||
"vue-i18n",
|
||||
"nprogress",
|
||||
"sortablejs",
|
||||
"qs",
|
||||
"path-browserify",
|
||||
"@stomp/stompjs",
|
||||
"@element-plus/icons-vue",
|
||||
"element-plus/es",
|
||||
"element-plus/es/locale/lang/en",
|
||||
"element-plus/es/locale/lang/zh-cn",
|
||||
"element-plus/es/components/alert/style/index",
|
||||
"element-plus/es/components/avatar/style/index",
|
||||
"element-plus/es/components/backtop/style/index",
|
||||
"element-plus/es/components/badge/style/index",
|
||||
"element-plus/es/components/base/style/index",
|
||||
"element-plus/es/components/breadcrumb-item/style/index",
|
||||
"element-plus/es/components/breadcrumb/style/index",
|
||||
"element-plus/es/components/button/style/index",
|
||||
"element-plus/es/components/card/style/index",
|
||||
"element-plus/es/components/cascader/style/index",
|
||||
"element-plus/es/components/checkbox-group/style/index",
|
||||
"element-plus/es/components/checkbox/style/index",
|
||||
"element-plus/es/components/col/style/index",
|
||||
"element-plus/es/components/color-picker/style/index",
|
||||
"element-plus/es/components/config-provider/style/index",
|
||||
"element-plus/es/components/date-picker/style/index",
|
||||
"element-plus/es/components/descriptions-item/style/index",
|
||||
"element-plus/es/components/descriptions/style/index",
|
||||
"element-plus/es/components/dialog/style/index",
|
||||
"element-plus/es/components/divider/style/index",
|
||||
"element-plus/es/components/drawer/style/index",
|
||||
"element-plus/es/components/dropdown-item/style/index",
|
||||
"element-plus/es/components/dropdown-menu/style/index",
|
||||
"element-plus/es/components/dropdown/style/index",
|
||||
"element-plus/es/components/empty/style/index",
|
||||
"element-plus/es/components/form-item/style/index",
|
||||
"element-plus/es/components/form/style/index",
|
||||
"element-plus/es/components/icon/style/index",
|
||||
"element-plus/es/components/image-viewer/style/index",
|
||||
"element-plus/es/components/image/style/index",
|
||||
"element-plus/es/components/input-number/style/index",
|
||||
"element-plus/es/components/input-tag/style/index",
|
||||
"element-plus/es/components/input/style/index",
|
||||
"element-plus/es/components/link/style/index",
|
||||
"element-plus/es/components/loading/style/index",
|
||||
"element-plus/es/components/menu-item/style/index",
|
||||
"element-plus/es/components/menu/style/index",
|
||||
"element-plus/es/components/message-box/style/index",
|
||||
"element-plus/es/components/message/style/index",
|
||||
"element-plus/es/components/notification/style/index",
|
||||
"element-plus/es/components/option/style/index",
|
||||
"element-plus/es/components/pagination/style/index",
|
||||
"element-plus/es/components/popover/style/index",
|
||||
"element-plus/es/components/progress/style/index",
|
||||
"element-plus/es/components/radio-button/style/index",
|
||||
"element-plus/es/components/radio-group/style/index",
|
||||
"element-plus/es/components/radio/style/index",
|
||||
"element-plus/es/components/row/style/index",
|
||||
"element-plus/es/components/scrollbar/style/index",
|
||||
"element-plus/es/components/select/style/index",
|
||||
"element-plus/es/components/skeleton-item/style/index",
|
||||
"element-plus/es/components/skeleton/style/index",
|
||||
"element-plus/es/components/step/style/index",
|
||||
"element-plus/es/components/steps/style/index",
|
||||
"element-plus/es/components/sub-menu/style/index",
|
||||
"element-plus/es/components/switch/style/index",
|
||||
"element-plus/es/components/tab-pane/style/index",
|
||||
"element-plus/es/components/table-column/style/index",
|
||||
"element-plus/es/components/table/style/index",
|
||||
"element-plus/es/components/tabs/style/index",
|
||||
"element-plus/es/components/tag/style/index",
|
||||
"element-plus/es/components/text/style/index",
|
||||
"element-plus/es/components/time-picker/style/index",
|
||||
"element-plus/es/components/time-select/style/index",
|
||||
"element-plus/es/components/timeline-item/style/index",
|
||||
"element-plus/es/components/timeline/style/index",
|
||||
"element-plus/es/components/tooltip/style/index",
|
||||
"element-plus/es/components/tree-select/style/index",
|
||||
"element-plus/es/components/tree/style/index",
|
||||
"element-plus/es/components/upload/style/index",
|
||||
"element-plus/es/components/watermark/style/index",
|
||||
"element-plus/es/components/checkbox-button/style/index",
|
||||
"element-plus/es/components/space/style/index",
|
||||
],
|
||||
'vue',
|
||||
'vue-router',
|
||||
'element-plus',
|
||||
'pinia',
|
||||
'axios',
|
||||
'@vueuse/core',
|
||||
'codemirror-editor-vue3',
|
||||
'default-passive-events',
|
||||
'exceljs',
|
||||
'path-to-regexp',
|
||||
'echarts/core',
|
||||
'echarts/renderers',
|
||||
'echarts/charts',
|
||||
'echarts/components',
|
||||
'vue-i18n',
|
||||
'nprogress',
|
||||
'sortablejs',
|
||||
'qs',
|
||||
'path-browserify',
|
||||
'@stomp/stompjs',
|
||||
'@element-plus/icons-vue',
|
||||
'element-plus/es',
|
||||
'element-plus/es/locale/lang/en',
|
||||
'element-plus/es/locale/lang/zh-cn',
|
||||
'element-plus/es/components/alert/style/index',
|
||||
'element-plus/es/components/avatar/style/index',
|
||||
'element-plus/es/components/backtop/style/index',
|
||||
'element-plus/es/components/badge/style/index',
|
||||
'element-plus/es/components/base/style/index',
|
||||
'element-plus/es/components/breadcrumb-item/style/index',
|
||||
'element-plus/es/components/breadcrumb/style/index',
|
||||
'element-plus/es/components/button/style/index',
|
||||
'element-plus/es/components/card/style/index',
|
||||
'element-plus/es/components/cascader/style/index',
|
||||
'element-plus/es/components/checkbox-group/style/index',
|
||||
'element-plus/es/components/checkbox/style/index',
|
||||
'element-plus/es/components/col/style/index',
|
||||
'element-plus/es/components/color-picker/style/index',
|
||||
'element-plus/es/components/config-provider/style/index',
|
||||
'element-plus/es/components/date-picker/style/index',
|
||||
'element-plus/es/components/descriptions-item/style/index',
|
||||
'element-plus/es/components/descriptions/style/index',
|
||||
'element-plus/es/components/dialog/style/index',
|
||||
'element-plus/es/components/divider/style/index',
|
||||
'element-plus/es/components/drawer/style/index',
|
||||
'element-plus/es/components/dropdown-item/style/index',
|
||||
'element-plus/es/components/dropdown-menu/style/index',
|
||||
'element-plus/es/components/dropdown/style/index',
|
||||
'element-plus/es/components/empty/style/index',
|
||||
'element-plus/es/components/form-item/style/index',
|
||||
'element-plus/es/components/form/style/index',
|
||||
'element-plus/es/components/icon/style/index',
|
||||
'element-plus/es/components/image-viewer/style/index',
|
||||
'element-plus/es/components/image/style/index',
|
||||
'element-plus/es/components/input-number/style/index',
|
||||
'element-plus/es/components/input-tag/style/index',
|
||||
'element-plus/es/components/input/style/index',
|
||||
'element-plus/es/components/link/style/index',
|
||||
'element-plus/es/components/loading/style/index',
|
||||
'element-plus/es/components/menu-item/style/index',
|
||||
'element-plus/es/components/menu/style/index',
|
||||
'element-plus/es/components/message-box/style/index',
|
||||
'element-plus/es/components/message/style/index',
|
||||
'element-plus/es/components/notification/style/index',
|
||||
'element-plus/es/components/option/style/index',
|
||||
'element-plus/es/components/pagination/style/index',
|
||||
'element-plus/es/components/popover/style/index',
|
||||
'element-plus/es/components/progress/style/index',
|
||||
'element-plus/es/components/radio-button/style/index',
|
||||
'element-plus/es/components/radio-group/style/index',
|
||||
'element-plus/es/components/radio/style/index',
|
||||
'element-plus/es/components/row/style/index',
|
||||
'element-plus/es/components/scrollbar/style/index',
|
||||
'element-plus/es/components/select/style/index',
|
||||
'element-plus/es/components/skeleton-item/style/index',
|
||||
'element-plus/es/components/skeleton/style/index',
|
||||
'element-plus/es/components/step/style/index',
|
||||
'element-plus/es/components/steps/style/index',
|
||||
'element-plus/es/components/sub-menu/style/index',
|
||||
'element-plus/es/components/switch/style/index',
|
||||
'element-plus/es/components/tab-pane/style/index',
|
||||
'element-plus/es/components/table-column/style/index',
|
||||
'element-plus/es/components/table/style/index',
|
||||
'element-plus/es/components/tabs/style/index',
|
||||
'element-plus/es/components/tag/style/index',
|
||||
'element-plus/es/components/text/style/index',
|
||||
'element-plus/es/components/time-picker/style/index',
|
||||
'element-plus/es/components/time-select/style/index',
|
||||
'element-plus/es/components/timeline-item/style/index',
|
||||
'element-plus/es/components/timeline/style/index',
|
||||
'element-plus/es/components/tooltip/style/index',
|
||||
'element-plus/es/components/tree-select/style/index',
|
||||
'element-plus/es/components/tree/style/index',
|
||||
'element-plus/es/components/upload/style/index',
|
||||
'element-plus/es/components/watermark/style/index',
|
||||
'element-plus/es/components/checkbox-button/style/index',
|
||||
'element-plus/es/components/space/style/index'
|
||||
]
|
||||
},
|
||||
// 构建配置
|
||||
build: {
|
||||
chunkSizeWarningLimit: 2000, // 消除打包大小超过500kb警告
|
||||
minify: isProduction ? ("terser" as const) : false, // 只在生产环境启用压缩
|
||||
minify: isProduction ? ('terser' as const) : false, // 只在生产环境启用压缩
|
||||
terserOptions: isProduction
|
||||
? {
|
||||
compress: {
|
||||
keep_infinity: true, // 防止 Infinity 被压缩成 1/0,这可能会导致 Chrome 上的性能问题
|
||||
drop_console: true, // 生产环境去除 console.log, console.warn, console.error 等
|
||||
drop_debugger: true, // 生产环境去除 debugger
|
||||
pure_funcs: ["console.log", "console.info"], // 移除指定的函数调用
|
||||
pure_funcs: ['console.log', 'console.info'] // 移除指定的函数调用
|
||||
},
|
||||
format: {
|
||||
comments: false, // 删除注释
|
||||
},
|
||||
comments: false // 删除注释
|
||||
}
|
||||
}
|
||||
: {},
|
||||
rollupOptions: {
|
||||
@@ -222,28 +222,28 @@ export default defineConfig(({ mode }: ConfigEnv) => {
|
||||
// "vue-i18n": ["vue-i18n"],
|
||||
// },
|
||||
// 用于从入口点创建的块的打包输出格式[name]表示文件名,[hash]表示该文件内容hash值
|
||||
entryFileNames: "js/[name].[hash].js",
|
||||
entryFileNames: 'js/[name].[hash].js',
|
||||
// 用于命名代码拆分时创建的共享块的输出命名
|
||||
chunkFileNames: "js/[name].[hash].js",
|
||||
chunkFileNames: 'js/[name].[hash].js',
|
||||
// 用于输出静态资源的命名,[ext]表示文件扩展名
|
||||
assetFileNames: (assetInfo: any) => {
|
||||
const info = assetInfo.name.split(".");
|
||||
let extType = info[info.length - 1];
|
||||
const info = assetInfo.name.split('.')
|
||||
let extType = info[info.length - 1]
|
||||
// console.log('文件信息', assetInfo.name)
|
||||
if (/\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/i.test(assetInfo.name)) {
|
||||
extType = "media";
|
||||
extType = 'media'
|
||||
} else if (/\.(png|jpe?g|gif|svg)(\?.*)?$/.test(assetInfo.name)) {
|
||||
extType = "img";
|
||||
extType = 'img'
|
||||
} else if (/\.(woff2?|eot|ttf|otf)(\?.*)?$/i.test(assetInfo.name)) {
|
||||
extType = "fonts";
|
||||
extType = 'fonts'
|
||||
}
|
||||
return `${extType}/[name].[hash].[ext]`;
|
||||
},
|
||||
},
|
||||
},
|
||||
return `${extType}/[name].[hash].[ext]`
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
define: {
|
||||
__APP_INFO__: JSON.stringify(__APP_INFO__),
|
||||
},
|
||||
};
|
||||
});
|
||||
__APP_INFO__: JSON.stringify(__APP_INFO__)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user