标签更改

xuhongjie
严飞永 6 days ago
parent ae17144781
commit b855c71e0b

@ -31,6 +31,7 @@
"admin-template", "admin-template",
"management-system" "management-system"
], ],
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://gitee.com/y_project/RuoYi-Vue.git" "url": "https://gitee.com/y_project/RuoYi-Vue.git"

@ -74,7 +74,7 @@ export default {
], ],
currentPage: 1, currentPage: 1,
pageSize: 10, pageSize: 10,
total: 40, total: 0,
} }
}, },
methods: { methods: {

@ -242,6 +242,7 @@ export default {
.content { .content {
padding: 1rem; padding: 1rem;
display: flex; display: flex;
width: 100%;
} }
.containertop { .containertop {
@ -284,13 +285,13 @@ export default {
} }
.descriptionsdiv { .descriptionsdiv {
width: 20rem; width: 24rem;
margin-left: 10rem; margin-left: 5rem;
height: 25.31rem; height: 25.31rem;
} }
.descriptionsdivtwo { .descriptionsdivtwo {
width: 24rem; width: 27rem;
margin-left: 3rem; margin-left: 3rem;
height: 25.31rem; height: 25.31rem;
} }

@ -5,35 +5,56 @@
<img style="width: 1.2rem;height: 1.13rem;" src="@/assets/images/标签管理.png" alt=""> <img style="width: 1.2rem;height: 1.13rem;" src="@/assets/images/标签管理.png" alt="">
<span style="margin-top: -0.1rem;">标签管理</span> <span style="margin-top: -0.1rem;">标签管理</span>
</div> </div>
<div class="headright" @click="showAddTagModal"> <div class="headright" @click="showAddTagModal" v-if="(action === 'fill' || !action || action === 'okay') && checkRole(['admin', 'common'])">
添加标签 添加标签
</div> </div>
</div> </div>
<!-- 按照type分组显示 --> <!-- 按照type分组显示 -->
<div class="type-group" v-for="group in groupedTags" :key="group.type"> <div class="type-group" v-for="group in groupedTags" :key="group.type">
<div class="group-title"> <div class="group-title" @click="toggleGroup(group.type)">
<!-- 下拉展示 --> <div>
<i class="el-icon-arrow-down"></i> <i :class="isGroupOpen(group.type) ? 'el-icon-arrow-up' : 'el-icon-arrow-down'"></i>
<!-- 上拉收起 --> {{ TypeMap[group.type] }}
<i class="el-icon-arrow-up"></i> </div>
类型 {{ group.type }}</div> <div v-if="(action === 'fill' || !action || action === 'okay') && checkRole(['admin', 'common'])">
<div class="tablebody"> <el-button size="mini" type="text" icon="el-icon-delete" style="color: #F25353;"
<el-table :data="group.list" style="width: 100%" v-loading="loading"> @click.stop="handleDeleteType(group.type)" :disabled="isSaving">删除</el-button>
<el-table-column prop="name" label="标签名称" width="220"></el-table-column> </div>
<el-table-column label="操作" width="160"> </div>
<div class="tablebody" v-if="isGroupOpen(group.type)">
<el-table :data="group.list" style="width: 100%;" v-loading="loading">
<el-table-column prop="name" label="标签名称" width="260">
<template slot-scope="scope">
<div v-if="!scope.row.editing">{{ scope.row.name }}</div>
<el-input v-else v-model="scope.row.editName" size="small"
@keyup.enter.native="saveEdit(scope.row)" @blur="saveEdit(scope.row)"></el-input>
</template>
</el-table-column>
<el-table-column label="操作" width="155">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button size="mini" @click="handleEdit(scope.row)"></el-button> <div
<el-button size="mini" type="danger" @click="handleDelete(scope.row)"></el-button> v-if="(action === 'fill' || !action || action === 'okay') && checkRole(['admin', 'common'])">
<el-button size="mini" @click="startEdit(scope.row)" v-if="!scope.row.editing"
:disabled="isSaving">编辑</el-button>
<el-button size="mini" type="success" @click="saveEdit(scope.row)" v-else
:loading="isSaving">保存</el-button>
<el-button size="mini" type="danger" @click="handleDelete(scope.row)"
:disabled="scope.row.editing || isSaving">删除</el-button>
</div>
<div v-else style="color: #ccc;">
当前不可操作
</div>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
</div> </div>
</div> </div>
<!-- 添加/编辑标签弹窗 --> <!-- 添加标签弹窗 -->
<el-dialog :title="isEdit ? '编辑标签' : '添加标签'" :visible.sync="tagModalVisible" width="30%" <el-dialog title="添加标签" :visible.sync="tagModalVisible" width="30%" :close-on-click-modal="false"
:close-on-click-modal="false" @closed="resetForm"> @closed="resetForm">
<el-form :model="tagForm" :rules="rules" ref="tagForm" label-width="100px"> <el-form :model="tagForm" :rules="rules" ref="tagForm" label-width="100px">
<el-form-item label="标签类型" prop="type"> <el-form-item label="标签类型" prop="type">
<el-select v-model="tagForm.type" placeholder="请选择标签类型" style="width: 27.2rem;"> <el-select v-model="tagForm.type" placeholder="请选择标签类型" style="width: 27.2rem;">
@ -43,7 +64,7 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="标签名称" prop="name"> <el-form-item label="标签名称" prop="name">
<el-input v-model="tagForm.name" placeholder="请输入标签名称"></el-input> <el-input v-model="tagForm.name" placeholder="请输入标签名称" style="width: 27.2rem;"></el-input>
</el-form-item> </el-form-item>
</el-form> </el-form>
<span slot="footer" class="dialog-footer"> <span slot="footer" class="dialog-footer">
@ -56,6 +77,7 @@
<script> <script>
import { getallspan, addspan, updatspan, deletespan } from '@/api/manageApitwo/index'; import { getallspan, addspan, updatspan, deletespan } from '@/api/manageApitwo/index';
import { checkPermi, checkRole } from "@/utils/permission";
export default { export default {
dicts: ['bqlx'], dicts: ['bqlx'],
@ -63,15 +85,18 @@ export default {
xmId: { xmId: {
type: Number, type: Number,
required: true required: true
},
action: {
type: String,
required: true
} }
}, },
data() { data() {
return { return {
loading: false, loading: false,
groupedTags: [], // groupedTags: [],
isSaving: false,
tagModalVisible: false, tagModalVisible: false,
isEdit: false,
currentTagId: null,
tagForm: { tagForm: {
type: '', type: '',
name: '', name: '',
@ -87,11 +112,21 @@ export default {
rules: { rules: {
type: [{ required: true, message: '请选择标签类型', trigger: 'change' }], type: [{ required: true, message: '请选择标签类型', trigger: 'change' }],
name: [{ required: true, message: '请输入标签名称', trigger: 'blur' }] name: [{ required: true, message: '请输入标签名称', trigger: 'blur' }]
} },
//
TypeMap: {
1: "新一代信息技术",
2: "高端装备制造",
3: "生物医药及大健康",
4: "纳米技术应用及新材料",
5: "人工智能及数字产业",
6: "新能源及绿色产业"
},
openGroups: []
} }
}, },
computed: { computed: {
// / //
tagList() { tagList() {
return this.groupedTags.flatMap(group => group.list); return this.groupedTags.flatMap(group => group.list);
} }
@ -107,14 +142,44 @@ export default {
} }
}, },
methods: { methods: {
checkPermi,
checkRole,
//
isGroupOpen(type) {
return this.openGroups.includes(type);
},
//
toggleGroup(type) {
const index = this.openGroups.indexOf(type);
if (index >= 0) {
this.openGroups.splice(index, 1);
} else {
this.openGroups.push(type);
}
},
// //
async fetchTags() { async fetchTags() {
this.loading = true; this.loading = true;
try { try {
const res = await getallspan({ xmId: this.xmId }); const res = await getallspan({ xmId: this.xmId });
// 使 //
this.groupedTags = res.data || []; this.groupedTags = (res.data || []).map(group => {
console.log('分组标签数据:', this.groupedTags); return {
...group,
list: group.list.map(item => ({
...item,
editing: false,
editName: item.name
}))
};
});
//
if (this.groupedTags.length > 0 && this.openGroups.length === 0) {
this.openGroups.push(this.groupedTags[0].type);
}
} catch (error) { } catch (error) {
console.error('获取标签列表失败:', error); console.error('获取标签列表失败:', error);
this.$message.error('获取标签列表失败'); this.$message.error('获取标签列表失败');
@ -123,35 +188,73 @@ export default {
} }
}, },
// ...
showAddTagModal() { showAddTagModal() {
this.isEdit = false;
this.currentTagId = null;
this.tagModalVisible = true; this.tagModalVisible = true;
this.$nextTick(() => { this.$nextTick(() => {
this.$refs.tagForm && this.$refs.tagForm.clearValidate(); this.$refs.tagForm && this.$refs.tagForm.clearValidate();
}); });
}, },
handleEdit(row) { //
this.isEdit = true; startEdit(row) {
this.currentTagId = row.id; //
this.tagForm = { if (this.isSaving) return;
type: row.type,
name: row.name, //
xmId: this.xmId, this.groupedTags.forEach(group => {
createBy: row.createBy || '', group.list.forEach(item => {
createTime: row.createTime || '', if (item.editing && item.id !== row.id) {
createId: row.createId || 0, item.editing = false;
id: row.id || 0, }
updateBy: row.updateBy || '', });
updateTime: row.updateTime || '',
updateId: row.updateId || 0
};
this.tagModalVisible = true;
this.$nextTick(() => {
this.$refs.tagForm && this.$refs.tagForm.clearValidate();
}); });
row.editing = true;
row.editName = row.name;
},
//
async saveEdit(row) {
//
if (this.isSaving) return;
if (!row.editName || row.editName.trim() === '') {
this.$message.warning('标签名称不能为空');
return;
}
if (row.editName === row.name) {
row.editing = false;
return;
}
//
this.isSaving = true;
try {
const now = new Date();
const formattedTime = now.toISOString().replace('T', ' ').substring(0, 19);
const submitData = {
...row,
name: row.editName,
updateTime: formattedTime,
updateBy: this.$store.state.user.name || '',
updateId: this.$store.state.user.id || 0
};
await updatspan(submitData);
this.$message.success('标签更新成功');
//
row.name = row.editName;
row.editing = false;
} catch (error) {
console.error('更新失败:', error);
this.$message.error('标签更新失败');
} finally {
this.isSaving = false;
}
}, },
submitForm() { submitForm() {
@ -161,32 +264,25 @@ export default {
try { try {
const now = new Date(); const now = new Date();
const formattedTime = now.toISOString().replace('T', ' ').substring(0, 19); const formattedTime = now.toISOString().replace('T', ' ').substring(0, 19);
const submitData = { const submitData = {
...this.tagForm, ...this.tagForm,
createTime: this.isEdit ? this.tagForm.createTime : formattedTime, createTime: formattedTime,
updateTime: formattedTime, updateTime: formattedTime,
createBy: this.isEdit ? this.tagForm.createBy : this.$store.state.user.name || '', createBy: this.$store.state.user.name || '',
updateBy: this.$store.state.user.name || '', updateBy: this.$store.state.user.name || '',
createId: this.isEdit ? this.tagForm.createId : this.$store.state.user.id || 0, createId: this.$store.state.user.id || 0,
updateId: this.$store.state.user.id || 0 updateId: this.$store.state.user.id || 0
}; };
console.log('准备提交的完整数据:', JSON.stringify(submitData, null, 2)); await addspan(submitData);
this.$message.success('标签添加成功');
if (this.isEdit) {
await updatspan(submitData);
this.$message.success('标签更新成功');
} else {
await addspan(submitData);
this.$message.success('标签添加成功');
}
this.tagModalVisible = false; this.tagModalVisible = false;
this.fetchTags(); this.fetchTags();
} catch (error) { } catch (error) {
console.error('操作失败:', error); console.error('添加失败:', error);
this.$message.error(this.isEdit ? '标签更新失败' : '标签添加失败'); this.$message.error('标签添加失败');
} }
}); });
}, },
@ -205,9 +301,39 @@ export default {
console.error('删除失败:', error); console.error('删除失败:', error);
this.$message.error('删除失败'); this.$message.error('删除失败');
} }
}).catch(() => { }).catch(() => { });
this.$message.info('已取消删除'); },
}); //
async handleDeleteType(type) {
//
const group = this.groupedTags.find(g => g.type === type);
if (!group || group.list.length === 0) {
this.$message.warning('该类型下没有标签');
return;
}
this.$confirm(`确定要删除"${this.TypeMap[type]}"类型及其所有标签吗?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(async () => {
this.isSaving = true;
try {
// ID
const tagIds = group.list.map(tag => tag.id);
//
await deletespan(tagIds);
this.$message.success('删除成功');
this.fetchTags(); //
} catch (error) {
console.error('删除失败:', error);
this.$message.error('删除失败');
} finally {
this.isSaving = false;
}
}).catch(() => { });
}, },
resetForm() { resetForm() {
@ -231,14 +357,16 @@ export default {
<style scoped> <style scoped>
.descriptionsdivtwo { .descriptionsdivtwo {
width: 24rem; width: 27rem;
padding: 0 0.5rem 0 0;
margin-left: 3rem; margin-left: 3rem;
height: auto; /* 改为自动高度 */ height: auto;
min-height: 25.31rem; min-height: 25.31rem;
overflow: auto;
} }
.tablehead { .tablehead {
width: 100%; width: 90%;
height: 2.38rem; height: 2.38rem;
display: flex; display: flex;
align-items: center; align-items: center;
@ -273,13 +401,25 @@ export default {
} }
.group-title { .group-title {
font-weight: bold;
margin: 1rem 0 0.5rem 0; margin: 1rem 0 0.5rem 0;
font-size: 1rem; /* font-size: 1rem; */
font-family: alimedium;
color: #333; color: #333;
font-weight: bold;
cursor: pointer;
display: flex;
align-items: center;
gap: 0.5rem;
width: 90%;
justify-content: space-between;
} }
.tablebody { .tablebody {
margin-top: 0.5rem; margin-top: 0.5rem;
overflow: hidden;
}
.el-input {
width: 180px;
} }
</style> </style>

@ -19,9 +19,9 @@
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<div v-if="tableData.length === 0" class="no-data"> <!-- <div v-if="tableData.length === 0" class="no-data">
暂无数据 暂无数据
</div> </div> -->
<!-- 详情弹窗 --> <!-- 详情弹窗 -->
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="40%"> <el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="40%">

@ -19,9 +19,9 @@
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<div v-if="tableData.length === 0" class="no-data"> <!-- <div v-if="tableData.length === 0" class="no-data">
暂无数据 暂无数据
</div> </div> -->
<!-- 详情弹窗 --> <!-- 详情弹窗 -->
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="40%"> <el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="40%">

@ -199,7 +199,7 @@ export default {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
border: 1px solid #ccc; border: 1px solid #ccc;
margin: 0 1rem 0 0; margin: 0 1rem 0.5rem 0;
} }
.itemleft { .itemleft {

Loading…
Cancel
Save