1. 前端代码
curd.vue
<template>
<div class="wraps">
<div>
<el-input v-model="search.keyWord" style="width: 300px"></el-input>
<el-button @click="init" style="margin-left: 10px">搜索</el-button>
<el-button @click="openDialog" type="primary" style="margin-left: 10px">添加</el-button>
</div>
<el-table border :data="tableData" style="width: 100%; margin-top: 30px">
<el-table-column prop="name" label="名字" />
<el-table-column prop="desc" label="描述" />
<el-table-column prop="id" label="id" />
<el-table-column>
<template #default="scope">
<el-button @click="edit(scope.row)">编辑</el-button>
<el-button @click="deleteRow(scope.row)">删除</el-button>
<el-button @click=";(isShowTag = true), (row = scope.row)">添加tag</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination
@current-change="change"
style="float: right; margin-top: 10px"
background
layout="prev, pager, next"
:total="total"
/>
</div>
<el-dialog v-model="dialogVisible" title="弹框" width="50%">
<el-form :model="form">
<el-form-item prop="name" label="名称">
<el-input v-model="form.name" placeholder="名称" />
</el-form-item>
<el-form-item prop="desc" label="描述">
<el-input v-model="form.desc" placeholder="描述"> </el-input>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="close">关闭</el-button>
<el-button type="primary" @click="save"> 保存 </el-button>
</span>
</template>
</el-dialog>
<el-dialog v-model="isShowTag" title="添加tag">
<el-select style="width: 100%" v-model="tags" multiple>
<el-option value="tag1">tag1</el-option>
<el-option value="tag2">tag2</el-option>
<el-option value="tag3">tag3</el-option>
</el-select>
<template #footer>
<el-button @click="addTa" type="primary">确定</el-button>
</template>
</el-dialog>
</template>
<script setup>
import { ref, reactive } from 'vue'
import { addUser, updateUser, delUser, getList, addTags } from '../apis'
const isShowTag = ref(false)
const tags = ref([])
const total = ref(0)
const row = ref({})
const addTa = async () => {
const res = await addTags({
tags: tags.value,
userId: row.value.id
})
isShowTag.value = false
tags.value = []
}
//搜索框
const search = reactive({
keyWord: '',
page: 1,
pageSize: 10
})
//表单
const form = reactive({
name: '',
desc: '',
id: 0
})
//清空数据
const resetForm = reactive({ ...form })
//表格数据
const tableData = ref([])
//弹框开关
const dialogVisible = ref(false)
const openDialog = () => {
dialogVisible.value = true
Object.assign(form, resetForm)
}
//初始化表格数据
const init = async () => {
const list = await getList(search)
tableData.value = list?.data ?? []
total.value = list?.total ?? 0
}
init()
const change = page => {
search.page = page
init()
}
//保存 和修改 表格数据
const save = async () => {
if (form.id) {
await updateUser(form)
} else {
await addUser(form)
}
close()
init()
}
//删除表格数据
const deleteRow = async row => {
await delUser({ id: row.id })
init()
}
//获取 详情
const edit = row => {
dialogVisible.value = true
Object.assign(form, row)
}
//关闭弹框
const close = () => {
dialogVisible.value = false
}
</script>
<style>
* {
padding: 0;
margin: 0;
}
html,
body {
width: 100%;
background: #ccc;
}
.wraps {
display: flex;
flex-direction: column;
height: 100vh;
padding: 30px;
}
</style>
api
import axios from 'axios'
axios.defaults.baseURL = 'http://localhost:3000'
//添加tag
export const addTags = (data) => axios.post(`/user/add/tags`,data).then(res => res.data)
2. 后端
整体流程:
- 新建一个tags.entity.ts
import {
Column,
Entity,
PrimaryGeneratedColumn,
JoinColumn,
ManyToOne,
} from 'typeorm';
import { User } from './user.entity';
@Entity()
export class Tags {
@PrimaryGeneratedColumn()
id: number;
@Column()
tags: string;
@ManyToOne(() => User, (user) => user.tags)
@JoinColumn()
user: User;
}
- 修改user.entity.ts
import {
PrimaryGeneratedColumn,
Column,
Generated,
CreateDateColumn,
Entity,
OneToMany,
} from 'typeorm';
import { Tags } from './tags.entity';
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column({ type: 'varchar', length: 255 })
name: string;
@Column({ type: 'text' })
desc: string;
@Generated('uuid')
uuid: string;
@CreateDateColumn({ type: 'timestamp' })
createTime: Date;
@OneToMany(() => Tags, (tags) => tags.user)
tags: Tags[];
}
- 在user.module.ts的imports中加入Tags的实体
import { Module } from '@nestjs/common';
import { UserService } from './user.service';
import { UserController } from './user.controller';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './entities/user.entity';
import { Tags } from './entities/tags.entity';
@Module({
imports: [TypeOrmModule.forFeature([User, Tags])],
controllers: [UserController],
providers: [UserService],
})
export class UserModule {}
- user.controller.ts 中写添加标签的代码
@Post('/add/tags')
addTags(@Body() params: { tags: string[]; userId: number }) {
return this.userService.addTags(params);
}
- user.service.ts 写存入tag数据库的操作,表格进行连表查询使用relation进行关联
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Like, Repository } from 'typeorm';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';
import { Tags } from './entities/tags.entity';
import { User } from './entities/user.entity';
@Injectable()
export class UserService {
constructor(
@InjectRepository(User) private readonly user: Repository<User>,
@InjectRepository(Tags) private readonly tag: Repository<Tags>,
) {}
//通过前端传入的userId 查到当前id 的用户信息,然后拿到前端传入的tags [tag1,tag2,tag3]
// 进行遍历 给tag实例进行赋值 然后调用保存方法添加tag 添加完之后 通过 tagList 保存该tag类
// 最后把tagList 赋给 user类的tags属性 然后重新调用save 进行更新
async addTags(params: { tags: string[]; userId: number }) {
const userInfo = await this.user.findOne({ where: { id: params.userId } });
const tagList: Tags[] = [];
for (let i = 0; i < params.tags.length; i++) {
const T = new Tags();
T.tags = params.tags[i];
await this.tag.save(T);
tagList.push(T);
}
userInfo.tags = tagList;
console.log(userInfo, 1);
return this.user.save(userInfo);
}
async findAll(query: { keyWord: string; page: number; pageSize: number }) {
const data = await this.user.find({
//查询的时候如果需要联合查询需要增加 relations
relations: ['tags'],
where: {
name: Like(`%${query.keyWord}%`),
},
order: {
id: 'DESC',
},
skip: (query.page - 1) * query.pageSize,
take: query.pageSize,
});
const total = await this.user.count({
where: {
name: Like(`% ${query.keyWord} %`),
},
});
return {
data,
total,
};
}
}
tag 表
user表
结果