|
@@ -0,0 +1,540 @@
|
|
|
+<template>
|
|
|
+ <div>
|
|
|
+ <!-- 弹窗 -->
|
|
|
+ <hc-dialog
|
|
|
+ v-model="dialogVisible"
|
|
|
+ title="参数信息"
|
|
|
+ widths="60%"
|
|
|
+ @close="closeParamDialog"
|
|
|
+ >
|
|
|
+ <div>
|
|
|
+ <div class="sub-title">{{ props.params.paramName }}</div>
|
|
|
+ <!-- 搜索栏 -->
|
|
|
+ <div class="search-container">
|
|
|
+ <div>
|
|
|
+ <el-form :inline="true" :model="searchForm" class="demo-form-inline">
|
|
|
+ <el-form-item prop="projectName">
|
|
|
+ <el-select
|
|
|
+ v-model="searchForm.projectName"
|
|
|
+ placeholder="项目名称"
|
|
|
+ clearable
|
|
|
+ style="width: 200px;"
|
|
|
+ @change="changeProject"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in projectList"
|
|
|
+ :key="item.id"
|
|
|
+ :label="item.projectName"
|
|
|
+ :value="item.projectId"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item prop="contractSection">
|
|
|
+ <el-select
|
|
|
+ v-model="searchForm.contractId"
|
|
|
+ placeholder="合同段"
|
|
|
+ clearable
|
|
|
+ style="width: 200px;"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in contractList"
|
|
|
+ :key="item.id"
|
|
|
+ :label="item.contractName"
|
|
|
+ :value="item.id"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item>
|
|
|
+ <el-input
|
|
|
+ v-model="searchForm.elementName"
|
|
|
+ placeholder="元素名称"
|
|
|
+ clearable
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item>
|
|
|
+ <el-button hc-btn type="primary" @click="searchElement">搜索</el-button>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 操作按钮 -->
|
|
|
+ <div>
|
|
|
+ <el-button hc-btn type="success" @click="handleAdd">新增元素</el-button>
|
|
|
+ <el-button hc-btn type="primary" @click="handleEditParam">编辑参数</el-button>
|
|
|
+
|
|
|
+ <el-button v-del-com:[handleDelteParam] hc-btn type="danger">删除参数</el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 表格 -->
|
|
|
+ <hc-table
|
|
|
+ :column="tableColumn"
|
|
|
+ :datas="tableData"
|
|
|
+ :loading="tableLoading"
|
|
|
+ :index-style="{ width: 60 }"
|
|
|
+ >
|
|
|
+ <template #type="{ row }">
|
|
|
+ {{ row.type === 1 ? '是' : '否' }}
|
|
|
+ </template>
|
|
|
+ <template #action="{ row }">
|
|
|
+ <el-link type="primary" @click="handleEdit(row)">编辑</el-link>
|
|
|
+ <el-link v-del-com:[handleDelteEle]="row" type="danger" class="mg-l-10">删除</el-link>
|
|
|
+ </template>
|
|
|
+ </hc-table>
|
|
|
+ </div>
|
|
|
+ </hc-dialog>
|
|
|
+
|
|
|
+ <!-- 新增弹窗 -->
|
|
|
+ <hc-dialog
|
|
|
+ v-model="addDialogVisible"
|
|
|
+ :title="form.id ? '元素编辑' : '元素新增'"
|
|
|
+ widths="30%"
|
|
|
+ @close="closeDialog"
|
|
|
+ >
|
|
|
+ <el-form ref="formRef" :model="form" :rules="rules" label-position="left">
|
|
|
+ <el-form-item label="元素名称" label-width="120px">
|
|
|
+ <el-input v-model="form.elementName" :disabled="form.selectedElement.length > 0" />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item v-if="!isEdit" label="选择元素" label-width="120px">
|
|
|
+ <el-button v-if="form.selectedElement.length === 0" style="width: 100%;" :disabled="form.elementName.length > 0" @click="checkEle">点击选择元素</el-button>
|
|
|
+ <div v-else class="bottom-box" @click="checkEle">
|
|
|
+ <el-scrollbar height="100px">
|
|
|
+ <div class="tag-container">
|
|
|
+ <el-tag
|
|
|
+ v-for="item in form.selectedElement"
|
|
|
+ :key="item.id"
|
|
|
+ type="info"
|
|
|
+ closable
|
|
|
+ class="mb-5 mr-5"
|
|
|
+ @close="handleClose(tag)"
|
|
|
+ >
|
|
|
+ {{ item.eName }}
|
|
|
+ </el-tag>
|
|
|
+ </div>
|
|
|
+ </el-scrollbar>
|
|
|
+ </div>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="是否全局参数" label-width="120px" prop="type">
|
|
|
+ <el-radio-group v-model="form.type">
|
|
|
+ <el-radio :value="1">是</el-radio>
|
|
|
+ <el-radio :value="2">否</el-radio>
|
|
|
+ </el-radio-group>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <template v-if="form.type === 2">
|
|
|
+ <div v-for="(item, index) in proData" :key="index" class="form-container" :style="{ marginTop: index === 0 ? '40px' : '0' }">
|
|
|
+ <!-- 删除图标 -->
|
|
|
+ <el-button
|
|
|
+ v-if="index !== 0" type="danger" size="mini"
|
|
|
+ icon="el-icon-delete"
|
|
|
+ circle
|
|
|
+ class="delete-icon"
|
|
|
+ @click="removeProData(index)"
|
|
|
+ />
|
|
|
+ <el-form-item label="选择项目" prop="contractSection" label-width="120px">
|
|
|
+ <el-select v-model="item.projectName" placeholder="请选择项目" clearable style="width: 100%;" @change="changeProject">
|
|
|
+ <el-option
|
|
|
+ v-for="item1 in projectList1"
|
|
|
+ :key="item1.id"
|
|
|
+ :label="item1.projectName"
|
|
|
+ :value="item1.id"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="选择合同段" prop="contractSection" label-width="120px">
|
|
|
+ <el-select v-model="item.contractSection" placeholder="请选择合同段" clearable multiple class="multiple-select">
|
|
|
+ <el-option
|
|
|
+ v-for="item2 in contractList"
|
|
|
+ :key="item2.id"
|
|
|
+ :label="item2.contractName"
|
|
|
+ :value="item2.id"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-form>
|
|
|
+ <template #footer>
|
|
|
+ <span class="dialog-footer">
|
|
|
+ <el-button @click="addDialogVisible = false">取 消</el-button>
|
|
|
+ <el-button type="primary" :loading="submitLoading" @click="confirmAdd">确 定</el-button>
|
|
|
+ </span>
|
|
|
+ </template>
|
|
|
+ </hc-dialog>
|
|
|
+
|
|
|
+ <!-- 选择元素弹窗 -->
|
|
|
+ <checkEleDialog ref="checkEleDialogRef" @confirm-check="confirmCheck" />
|
|
|
+ <!-- 编辑参数弹窗 -->
|
|
|
+ <addParamDialog ref="addParamDialogRef" :params="params" @add-parameter="addCardFinish" />
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup>
|
|
|
+import { nextTick, reactive, ref } from 'vue'
|
|
|
+
|
|
|
+import projectApi from '~api/project/project'
|
|
|
+import contractApi from '~api/project/contract'
|
|
|
+import { getArrValue } from 'js-fast-way'
|
|
|
+import paramApi from '~api/paramter/parmter'
|
|
|
+import checkEleDialog from './checkEleDialog.vue'
|
|
|
+import addParamDialog from './addParamDialog.vue'
|
|
|
+
|
|
|
+// 定义props
|
|
|
+const props = defineProps({
|
|
|
+ params: {
|
|
|
+ type: Object,
|
|
|
+ default: () => ({}),
|
|
|
+ },
|
|
|
+})
|
|
|
+
|
|
|
+// 定义emit
|
|
|
+const emit = defineEmits(['finshDetail'])
|
|
|
+
|
|
|
+// 数据定义
|
|
|
+const dialogVisible = ref(false)
|
|
|
+const projectList = ref([])
|
|
|
+const projectList1 = ref([])
|
|
|
+const contractList = ref([])
|
|
|
+const searchForm = reactive({
|
|
|
+ projectName: '',
|
|
|
+ contractId: '',
|
|
|
+ elementName: '',
|
|
|
+})
|
|
|
+const tableData = ref([])
|
|
|
+const tableLoading = ref(false)
|
|
|
+const addDialogVisible = ref(false)
|
|
|
+const formRef = ref(null)
|
|
|
+const isEdit = ref(false)
|
|
|
+const form = ref({
|
|
|
+ elementName: '',
|
|
|
+ selectedElement: [],
|
|
|
+ type: false,
|
|
|
+})
|
|
|
+const proData = ref([{}])
|
|
|
+const rules = {
|
|
|
+ type: [
|
|
|
+ { required: true, message: '请选择是否全局参数', trigger: 'change' },
|
|
|
+ ],
|
|
|
+}
|
|
|
+const editDialogVisible = ref(false)
|
|
|
+const paramId = ref('')
|
|
|
+const addParamDialogRef = ref(null)
|
|
|
+
|
|
|
+// 在 script setup 中添加
|
|
|
+const tableColumn = ref([
|
|
|
+ { key: 'elementName', name: '元素名称' },
|
|
|
+ { key: 'type', name: '是否全局参数', width: 120, align: 'center' },
|
|
|
+ { key: 'projectName', name: '项目名称', width: 180 },
|
|
|
+ { key: 'contractName', name: '合同段', width: 180 },
|
|
|
+ { key: 'action', name: '操作', width: 150, align: 'center' },
|
|
|
+])
|
|
|
+
|
|
|
+// 获取项目列表
|
|
|
+const getProjectListData = async (id) => {
|
|
|
+ if (!id) {
|
|
|
+ const res = await projectApi.page({ current: 1, size: 999 })
|
|
|
+ projectList.value = getArrValue(res.data.data.records ) || []
|
|
|
+ } else {
|
|
|
+ const res = await paramApi.getProjectContractByParam({ parameterId: id })
|
|
|
+ projectList.value = getArrValue(res.data) || []
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+// 获取项目列表
|
|
|
+const getProjectListData1 = async () => {
|
|
|
+ const { data } = await projectApi.page({ current: 1, size: 999 })
|
|
|
+ projectList1.value = getArrValue( data?.records)
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+// 项目变化
|
|
|
+const changeProject = async (val) => {
|
|
|
+ try {
|
|
|
+ const res = await contractApi.getList(val)
|
|
|
+ contractList.value = getArrValue( res.data)
|
|
|
+ } catch (error) {
|
|
|
+ console.error('获取合同段列表失败:', error)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 搜索元素
|
|
|
+const searchElement = () => {
|
|
|
+ getTableData()
|
|
|
+}
|
|
|
+
|
|
|
+// 获取表格数据
|
|
|
+const getTableData = async () => {
|
|
|
+ tableLoading.value = true
|
|
|
+
|
|
|
+ const { res, data, code } = await paramApi.getParameterElementList({
|
|
|
+ parameterId: props.params.id,
|
|
|
+ contractId: searchForm.contractId,
|
|
|
+ projectId: searchForm.projectName,
|
|
|
+ elementName: searchForm.elementName,
|
|
|
+ })
|
|
|
+
|
|
|
+ if (code === 200) {
|
|
|
+ tableData.value = getArrValue( data) || []
|
|
|
+ } else {
|
|
|
+ tableData.value = []
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+const handleDelteParam = async ({ item }, resolve) => {
|
|
|
+ const { isRes } = await paramApi.remove({ id: props.params.id })
|
|
|
+ resolve() //关闭弹窗
|
|
|
+ if (!isRes) return
|
|
|
+ window.$message.success('删除成功')
|
|
|
+ dialogVisible.value = false
|
|
|
+ emit('finshDetail')
|
|
|
+}
|
|
|
+
|
|
|
+// 关闭弹窗
|
|
|
+const closeParamDialog = () => {
|
|
|
+ dialogVisible.value = false
|
|
|
+ emit('finshDetail')
|
|
|
+ addDialogVisible.value = false
|
|
|
+ projectList.value = []
|
|
|
+ projectList1.value = []
|
|
|
+ contractList.value = []
|
|
|
+}
|
|
|
+
|
|
|
+// 显示弹窗
|
|
|
+const show = (id) => {
|
|
|
+ paramId.value = id
|
|
|
+
|
|
|
+
|
|
|
+ nextTick(() => {
|
|
|
+ dialogVisible.value = true
|
|
|
+ getTableData(id)
|
|
|
+ getProjectListData(id)
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+// 新增元素
|
|
|
+const handleAdd = () => {
|
|
|
+ addDialogVisible.value = true
|
|
|
+ getProjectListData1()
|
|
|
+ isEdit.value = false
|
|
|
+ form.value = {
|
|
|
+ elementName: '',
|
|
|
+ selectedElement: [],
|
|
|
+ type: false,
|
|
|
+ }
|
|
|
+ proData.value = [{}]
|
|
|
+}
|
|
|
+
|
|
|
+// 关闭新增弹窗
|
|
|
+const closeDialog = () => {
|
|
|
+ addDialogVisible.value = false
|
|
|
+ isEdit.value = false
|
|
|
+ contractList.value = []
|
|
|
+}
|
|
|
+
|
|
|
+// 编辑参数
|
|
|
+const handleEditParam = () => {
|
|
|
+ addParamDialogRef.value?.show(props.params)
|
|
|
+}
|
|
|
+
|
|
|
+// 添加卡完成
|
|
|
+const addCardFinish = () => {
|
|
|
+ console.log('编辑完成')
|
|
|
+ closeParamDialog()
|
|
|
+}
|
|
|
+
|
|
|
+// 编辑元素
|
|
|
+const handleEdit = (row) => {
|
|
|
+
|
|
|
+ getProjectListData1()
|
|
|
+ changeProject(row.projectId)
|
|
|
+ isEdit.value = true
|
|
|
+ form.value = row
|
|
|
+ let arr = [{
|
|
|
+ projectName: row.projectId,
|
|
|
+ contractSection: row.contractId ? row.contractId.split(',') : [],
|
|
|
+ }]
|
|
|
+ proData.value = arr
|
|
|
+ form.value.selectedElement = []
|
|
|
+ nextTick(() => {
|
|
|
+ addDialogVisible.value = true
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+const handleDelteEle = async ({ item }, resolve) => {
|
|
|
+ const { isRes } = await paramApi.removeElement({ id: item.id })
|
|
|
+ resolve() //关闭弹窗
|
|
|
+ if (!isRes) return
|
|
|
+ window.$message.success('删除成功')
|
|
|
+ getTableData().then()
|
|
|
+}
|
|
|
+/**
|
|
|
+ * 确认添加元素
|
|
|
+ * @returns {Promise<void>}
|
|
|
+ */
|
|
|
+const submitLoading = ref(false)
|
|
|
+const confirmAdd = async () => {
|
|
|
+
|
|
|
+ const { selectedElement } = form.value
|
|
|
+ if (!form.value.elementName && (!selectedElement || selectedElement.length === 0)) {
|
|
|
+ window.$message.error('请选择元素或者完善元素名称')
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ const subArr = []
|
|
|
+ const projectList = []
|
|
|
+
|
|
|
+ // 检查是否需要添加项目数据
|
|
|
+ if (form.value.type === 2) {
|
|
|
+ if (!proData.value?.[0]?.projectName) {
|
|
|
+ window.$message.warning('请先选择项目')
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ proData.value.forEach(item => {
|
|
|
+ if (!item.contractSection) {
|
|
|
+ window.$message.warning('请选择合同段')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ projectList.push({
|
|
|
+ projectId: item.projectName,
|
|
|
+ contractId: Array.isArray(item.contractSection)
|
|
|
+ ? item.contractSection.join(',')
|
|
|
+ : item.contractSection,
|
|
|
+ })
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ // 构建提交数据
|
|
|
+ if (selectedElement?.length > 0) {
|
|
|
+ selectedElement.forEach(item => {
|
|
|
+ subArr.push({
|
|
|
+ id: form.value.id,
|
|
|
+ parameterId: props.params.id,
|
|
|
+ type: form.value.type,
|
|
|
+ elementName: item.eName,
|
|
|
+ projectList: form.value.type === 2 ? projectList : [],
|
|
|
+ })
|
|
|
+ })
|
|
|
+ } else if (form.value.elementName) {
|
|
|
+ subArr.push({
|
|
|
+ id: form.value.id,
|
|
|
+ parameterId: props.params.id,
|
|
|
+ type: form.value.type,
|
|
|
+ elementName: form.value.elementName,
|
|
|
+ projectList: form.value.type === 2 ? projectList : [],
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ if (subArr.length === 0) {
|
|
|
+ window.$message.error('提交数据不能为空')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ submitLoading.value = true
|
|
|
+
|
|
|
+ const { code, msg } = await paramApi.submitElement(subArr)
|
|
|
+ submitLoading.value = false
|
|
|
+ if (code === 200) {
|
|
|
+ window.$message.success(msg)
|
|
|
+ addDialogVisible.value = false
|
|
|
+ await getTableData()
|
|
|
+ } else {
|
|
|
+ window.$message.error(msg || '操作失败')
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+// 添加项目数据
|
|
|
+const addProData = () => {
|
|
|
+ proData.value.push({})
|
|
|
+}
|
|
|
+
|
|
|
+// 移除项目数据
|
|
|
+const removeProData = (index) => {
|
|
|
+ proData.value.splice(index, 1)
|
|
|
+}
|
|
|
+const checkEleDialogRef = ref(null)// 选择元素
|
|
|
+const checkEle = () => {
|
|
|
+ checkEleDialogRef.value.show(form.value.selectedElement)
|
|
|
+}
|
|
|
+
|
|
|
+// 确认检查
|
|
|
+const confirmCheck = (selectedData) => {
|
|
|
+ form.value.selectedElement = selectedData
|
|
|
+ console.log('选择的元素1111111111:', selectedData)
|
|
|
+}
|
|
|
+
|
|
|
+// 处理关闭
|
|
|
+const handleClose = (tag) => {
|
|
|
+ form.value.selectedElement.splice(form.value.selectedElement.indexOf(tag), 1)
|
|
|
+}
|
|
|
+
|
|
|
+// 暴露方法给父组件
|
|
|
+defineExpose({
|
|
|
+ show,
|
|
|
+})
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+.form-container1 {
|
|
|
+ position: relative;
|
|
|
+ max-height: 400px;
|
|
|
+ overflow-y: auto;
|
|
|
+}
|
|
|
+.form-container {
|
|
|
+ border: 1px solid #ccc; /* 淡灰色边框 */
|
|
|
+ padding: 20px 40px 0px 20px;
|
|
|
+ margin-bottom: 15px;
|
|
|
+ position: relative;
|
|
|
+}
|
|
|
+.delete-icon {
|
|
|
+ position: absolute;
|
|
|
+ top: 5px;
|
|
|
+ right:5px;
|
|
|
+ z-index: 1000;
|
|
|
+}
|
|
|
+.add-button {
|
|
|
+ margin-left: 20px;
|
|
|
+ position: absolute;
|
|
|
+ top: 0px;
|
|
|
+ right: 5px;
|
|
|
+ z-index: 1000;
|
|
|
+}
|
|
|
+.multiple-select {
|
|
|
+ width: 100%;
|
|
|
+}
|
|
|
+.search-container {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between; /* 使子元素两端对齐 */
|
|
|
+ align-items: center; /* 垂直居中对齐 */
|
|
|
+}
|
|
|
+.bottom-box {
|
|
|
+ width: 100%;
|
|
|
+ height: 120px;
|
|
|
+ border: 1px solid var(--el-border-color);
|
|
|
+ margin-top: 10px;
|
|
|
+ cursor: pointer;
|
|
|
+}
|
|
|
+.tag-container {
|
|
|
+ padding: 10px;
|
|
|
+}
|
|
|
+.mr-5 {
|
|
|
+ margin-right: 5px;
|
|
|
+}
|
|
|
+.mb-5 {
|
|
|
+ margin-bottom: 5px;
|
|
|
+}
|
|
|
+.sub-title{
|
|
|
+ margin-bottom: 15px;
|
|
|
+ font-weight: bold;
|
|
|
+ font-size: 16px
|
|
|
+}
|
|
|
+.mg-l-10 {
|
|
|
+ margin-left: 10px;
|
|
|
+}
|
|
|
+</style>
|