潘的第一次 commit
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import ElementPlus from 'element-plus'
|
||||
import Customer from '../index.vue'
|
||||
import * as customerApi from '@/api/customer'
|
||||
|
||||
vi.mock('@/api/customer', () => ({
|
||||
getCustomerList: vi.fn(),
|
||||
getCustomerDetail: vi.fn(),
|
||||
createCustomer: vi.fn(),
|
||||
updateCustomer: vi.fn(),
|
||||
deleteCustomer: vi.fn(),
|
||||
updateCustomerStatus: vi.fn()
|
||||
}))
|
||||
|
||||
describe('Customer 客户档案', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
vi.mocked(customerApi.getCustomerList).mockResolvedValue({ list: [], total: 0 })
|
||||
})
|
||||
|
||||
it('renders and loads list', async () => {
|
||||
vi.mocked(customerApi.getCustomerList).mockResolvedValue({
|
||||
list: [
|
||||
{
|
||||
clientId: 1,
|
||||
clientCode: 'C001',
|
||||
clientName: '客户A',
|
||||
clientNick: 'A',
|
||||
contact1: '张三',
|
||||
contact1Tel: '13800001111',
|
||||
address: '深圳',
|
||||
enableFlag: 'Y',
|
||||
createTime: '2026-01-25 10:00:00'
|
||||
}
|
||||
],
|
||||
total: 1
|
||||
})
|
||||
|
||||
const wrapper = mount(Customer, {
|
||||
global: {
|
||||
plugins: [ElementPlus],
|
||||
stubs: {
|
||||
ElPopconfirm: { template: '<div @click="$attrs.onConfirm?.()"><slot /></div>' }
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
await vi.waitFor(() => {
|
||||
expect(customerApi.getCustomerList).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
expect(wrapper.find('.search-card').exists()).toBe(true)
|
||||
expect(wrapper.find('.table-card').exists()).toBe(true)
|
||||
expect(wrapper.find('table').exists()).toBe(true)
|
||||
expect(wrapper.find('.pagination-wrapper').exists()).toBe(true)
|
||||
})
|
||||
|
||||
it('has query inputs and toolbar buttons', async () => {
|
||||
const wrapper = mount(Customer, {
|
||||
global: {
|
||||
plugins: [ElementPlus],
|
||||
stubs: {
|
||||
ElPopconfirm: { template: '<div><slot /></div>' }
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
await wrapper.vm.$nextTick()
|
||||
expect(wrapper.find('.search-card').exists()).toBe(true)
|
||||
expect(wrapper.text()).toMatch(/新增|刷新|导出|批量删除/)
|
||||
})
|
||||
})
|
||||
514
erp-frontend-vue/src/views/Sales/Customer/index.vue
Normal file
514
erp-frontend-vue/src/views/Sales/Customer/index.vue
Normal file
@@ -0,0 +1,514 @@
|
||||
<template>
|
||||
<div class="page-container">
|
||||
<!-- 查询区域 -->
|
||||
<el-card class="search-card" shadow="never">
|
||||
<el-form :model="queryParams" inline>
|
||||
<el-form-item label="客户编码">
|
||||
<el-input v-model="queryParams.clientCode" placeholder="请输入客户编码" clearable style="width: 160px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="客户名称">
|
||||
<el-input v-model="queryParams.clientName" placeholder="请输入客户名称" clearable style="width: 160px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="客户简称">
|
||||
<el-input v-model="queryParams.clientNick" placeholder="请输入客户简称" clearable style="width: 160px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="状态">
|
||||
<el-select v-model="queryParams.enableFlag" placeholder="全部" clearable style="width: 100px;">
|
||||
<el-option label="启用" value="Y" />
|
||||
<el-option label="停用" value="N" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleQuery">
|
||||
<el-icon><Search /></el-icon>查询
|
||||
</el-button>
|
||||
<el-button @click="handleReset">
|
||||
<el-icon><Refresh /></el-icon>重置
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<!-- 工具栏与表格 -->
|
||||
<el-card class="table-card" shadow="never">
|
||||
<div class="toolbar">
|
||||
<el-button type="primary" @click="handleAdd">
|
||||
<el-icon><Plus /></el-icon>新增
|
||||
</el-button>
|
||||
<el-button type="danger" :disabled="!selectedRows.length" @click="handleBatchDelete">
|
||||
<el-icon><Delete /></el-icon>批量删除
|
||||
</el-button>
|
||||
<el-button type="success" @click="handleExport">
|
||||
<el-icon><Download /></el-icon>导出
|
||||
</el-button>
|
||||
<el-button @click="handleRefresh">
|
||||
<el-icon><Refresh /></el-icon>刷新
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="tableData"
|
||||
stripe
|
||||
border
|
||||
style="width: 100%"
|
||||
@selection-change="handleSelectionChange"
|
||||
>
|
||||
<el-table-column type="selection" width="50" />
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="clientCode" label="客户编码" width="120" />
|
||||
<el-table-column prop="clientName" label="客户名称" min-width="160" show-overflow-tooltip />
|
||||
<el-table-column prop="clientNick" label="简称" width="100" />
|
||||
<el-table-column prop="contact1" label="联系人" width="100" />
|
||||
<el-table-column prop="contact1Tel" label="联系电话" width="120" />
|
||||
<el-table-column prop="address" label="地址" min-width="180" show-overflow-tooltip />
|
||||
<el-table-column prop="enableFlag" label="状态" width="80" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="row.enableFlag === 'Y' ? 'success' : 'info'">
|
||||
{{ row.enableFlag === 'Y' ? '启用' : '停用' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createTime" label="创建时间" width="160" />
|
||||
<el-table-column label="操作" width="180" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button type="primary" link @click="handleView(row)">查看</el-button>
|
||||
<el-button type="primary" link @click="handleEdit(row)">编辑</el-button>
|
||||
<el-popconfirm title="确定删除该客户吗?" @confirm="handleDelete(row)">
|
||||
<template #reference>
|
||||
<el-button type="danger" link>删除</el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="pagination-wrapper">
|
||||
<el-pagination
|
||||
v-model:current-page="queryParams.pageNum"
|
||||
v-model:page-size="queryParams.pageSize"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
:total="total"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
@size-change="loadData"
|
||||
@current-change="loadData"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:title="dialogTitle"
|
||||
width="800px"
|
||||
:close-on-click-modal="false"
|
||||
destroy-on-close
|
||||
>
|
||||
<el-form ref="formRef" :model="formData" :rules="formRules" label-width="100px">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="客户编码" prop="clientCode">
|
||||
<el-input v-model="formData.clientCode" placeholder="请输入客户编码" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="客户名称" prop="clientName">
|
||||
<el-input v-model="formData.clientName" placeholder="请输入客户名称" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="客户简称">
|
||||
<el-input v-model="formData.clientNick" placeholder="请输入简称" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="客户级别">
|
||||
<el-select v-model="formData.clientLevel" placeholder="请选择" clearable style="width: 100%;">
|
||||
<el-option label="A级" value="A" />
|
||||
<el-option label="B级" value="B" />
|
||||
<el-option label="C级" value="C" />
|
||||
<el-option label="D级" value="D" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="联系人1">
|
||||
<el-input v-model="formData.contact1" placeholder="请输入联系人" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="联系人1电话">
|
||||
<el-input v-model="formData.contact1Tel" placeholder="请输入电话" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="联系人2">
|
||||
<el-input v-model="formData.contact2" placeholder="请输入联系人" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="联系人2电话">
|
||||
<el-input v-model="formData.contact2Tel" placeholder="请输入电话" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="电话">
|
||||
<el-input v-model="formData.tel" placeholder="请输入电话" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="邮箱">
|
||||
<el-input v-model="formData.email" placeholder="请输入邮箱" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="网址">
|
||||
<el-input v-model="formData.website" placeholder="请输入网址" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="启用状态">
|
||||
<el-radio-group v-model="formData.enableFlag">
|
||||
<el-radio label="Y">启用</el-radio>
|
||||
<el-radio label="N">停用</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="24">
|
||||
<el-form-item label="地址">
|
||||
<el-input v-model="formData.address" placeholder="请输入地址" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-divider content-position="left">开票信息</el-divider>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="税号">
|
||||
<el-input v-model="formData.taxNo" placeholder="请输入税号" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="开户银行">
|
||||
<el-input v-model="formData.bankName" placeholder="请输入开户银行" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="银行账号">
|
||||
<el-input v-model="formData.bankAccount" placeholder="请输入银行账号" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="信用代码">
|
||||
<el-input v-model="formData.creditCode" placeholder="统一社会信用代码" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="24">
|
||||
<el-form-item label="开票地址">
|
||||
<el-input v-model="formData.invoiceAddress" placeholder="开票地址电话" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="24">
|
||||
<el-form-item label="备注">
|
||||
<el-input v-model="formData.remark" type="textarea" :rows="3" placeholder="请输入备注" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="submitLoading" @click="handleSubmit">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 查看弹窗 -->
|
||||
<el-dialog v-model="viewDialogVisible" title="客户详情" width="800px">
|
||||
<div v-loading="viewLoading">
|
||||
<el-descriptions :column="2" border>
|
||||
<el-descriptions-item label="客户编码">{{ viewData.clientCode }}</el-descriptions-item>
|
||||
<el-descriptions-item label="客户名称">{{ viewData.clientName }}</el-descriptions-item>
|
||||
<el-descriptions-item label="客户简称">{{ viewData.clientNick }}</el-descriptions-item>
|
||||
<el-descriptions-item label="客户级别">{{ viewData.clientLevel || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="联系人1">{{ viewData.contact1 || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="联系人1电话">{{ viewData.contact1Tel || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="联系人2">{{ viewData.contact2 || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="联系人2电话">{{ viewData.contact2Tel || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="电话">{{ viewData.tel || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="邮箱">{{ viewData.email || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="网址">{{ viewData.website || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="状态">
|
||||
<el-tag :type="viewData.enableFlag === 'Y' ? 'success' : 'info'">
|
||||
{{ viewData.enableFlag === 'Y' ? '启用' : '停用' }}
|
||||
</el-tag>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="地址" :span="2">{{ viewData.address || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="税号">{{ viewData.taxNo || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="开户银行">{{ viewData.bankName || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="银行账号">{{ viewData.bankAccount || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="信用代码">{{ viewData.creditCode || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="开票地址" :span="2">{{ viewData.invoiceAddress || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="创建时间">{{ viewData.createTime || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="更新时间">{{ viewData.updateTime || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="备注" :span="2">{{ viewData.remark || '-' }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</div>
|
||||
<template #footer>
|
||||
<el-button @click="viewDialogVisible = false">关闭</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { Search, Refresh, Plus, Download, Delete } from '@element-plus/icons-vue'
|
||||
import {
|
||||
getCustomerList,
|
||||
getCustomerDetail,
|
||||
createCustomer,
|
||||
updateCustomer,
|
||||
deleteCustomer,
|
||||
type Customer,
|
||||
type CustomerQuery
|
||||
} from '@/api/customer'
|
||||
|
||||
const queryParams = reactive<CustomerQuery & { pageNum: number; pageSize: number }>({
|
||||
clientCode: '',
|
||||
clientName: '',
|
||||
clientNick: '',
|
||||
enableFlag: undefined,
|
||||
pageNum: 1,
|
||||
pageSize: 10
|
||||
})
|
||||
|
||||
const total = ref(0)
|
||||
const loading = ref(false)
|
||||
const tableData = ref<Customer[]>([])
|
||||
const selectedRows = ref<Customer[]>([])
|
||||
|
||||
const dialogVisible = ref(false)
|
||||
const dialogTitle = ref('新增客户')
|
||||
const submitLoading = ref(false)
|
||||
const formRef = ref()
|
||||
const formData = reactive<Partial<Customer>>({
|
||||
clientCode: '',
|
||||
clientName: '',
|
||||
clientNick: '',
|
||||
clientLevel: 'B',
|
||||
contact1: '',
|
||||
contact1Tel: '',
|
||||
contact2: '',
|
||||
contact2Tel: '',
|
||||
tel: '',
|
||||
email: '',
|
||||
website: '',
|
||||
address: '',
|
||||
taxNo: '',
|
||||
bankName: '',
|
||||
bankAccount: '',
|
||||
creditCode: '',
|
||||
invoiceAddress: '',
|
||||
enableFlag: 'Y',
|
||||
remark: ''
|
||||
})
|
||||
|
||||
const formRules = {
|
||||
clientCode: [{ required: true, message: '请输入客户编码', trigger: 'blur' }],
|
||||
clientName: [{ required: true, message: '请输入客户名称', trigger: 'blur' }]
|
||||
}
|
||||
|
||||
const viewDialogVisible = ref(false)
|
||||
const viewLoading = ref(false)
|
||||
const viewData = ref<Customer>({} as Customer)
|
||||
|
||||
function resetForm() {
|
||||
Object.assign(formData, {
|
||||
clientId: undefined,
|
||||
clientCode: '',
|
||||
clientName: '',
|
||||
clientNick: '',
|
||||
clientLevel: 'B',
|
||||
contact1: '',
|
||||
contact1Tel: '',
|
||||
contact2: '',
|
||||
contact2Tel: '',
|
||||
tel: '',
|
||||
email: '',
|
||||
website: '',
|
||||
address: '',
|
||||
taxNo: '',
|
||||
bankName: '',
|
||||
bankAccount: '',
|
||||
creditCode: '',
|
||||
invoiceAddress: '',
|
||||
enableFlag: 'Y',
|
||||
remark: ''
|
||||
})
|
||||
}
|
||||
|
||||
async function loadData() {
|
||||
loading.value = true
|
||||
try {
|
||||
const res = await getCustomerList({
|
||||
clientCode: queryParams.clientCode || undefined,
|
||||
clientName: queryParams.clientName || undefined,
|
||||
clientNick: queryParams.clientNick || undefined,
|
||||
enableFlag: queryParams.enableFlag,
|
||||
pageNum: queryParams.pageNum,
|
||||
pageSize: queryParams.pageSize
|
||||
})
|
||||
tableData.value = res.list
|
||||
total.value = res.total
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function handleQuery() {
|
||||
queryParams.pageNum = 1
|
||||
loadData()
|
||||
}
|
||||
|
||||
function handleReset() {
|
||||
queryParams.clientCode = ''
|
||||
queryParams.clientName = ''
|
||||
queryParams.clientNick = ''
|
||||
queryParams.enableFlag = undefined
|
||||
queryParams.pageNum = 1
|
||||
handleQuery()
|
||||
}
|
||||
|
||||
function handleRefresh() {
|
||||
loadData()
|
||||
}
|
||||
|
||||
function handleAdd() {
|
||||
dialogTitle.value = '新增客户'
|
||||
resetForm()
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
function handleEdit(row: Customer) {
|
||||
dialogTitle.value = '编辑客户'
|
||||
Object.assign(formData, { ...row })
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
async function handleView(row: Customer) {
|
||||
viewDialogVisible.value = true
|
||||
viewData.value = {} as Customer
|
||||
viewLoading.value = true
|
||||
try {
|
||||
if (row.clientId != null) {
|
||||
const detail = await getCustomerDetail(row.clientId)
|
||||
viewData.value = detail
|
||||
} else {
|
||||
viewData.value = { ...row }
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
viewData.value = { ...row }
|
||||
} finally {
|
||||
viewLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function handleDelete(row: Customer) {
|
||||
if (row.clientId == null) return
|
||||
try {
|
||||
await deleteCustomer(row.clientId)
|
||||
ElMessage.success('删除成功')
|
||||
loadData()
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
|
||||
function handleSelectionChange(rows: Customer[]) {
|
||||
selectedRows.value = rows
|
||||
}
|
||||
|
||||
async function handleBatchDelete() {
|
||||
const ids = selectedRows.value.map((r) => r.clientId).filter((id): id is number => id != null)
|
||||
if (!ids.length) return
|
||||
try {
|
||||
await deleteCustomer(ids)
|
||||
ElMessage.success('删除成功')
|
||||
loadData()
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
|
||||
function handleExport() {
|
||||
ElMessage.info('导出功能开发中')
|
||||
}
|
||||
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
await formRef.value?.validate()
|
||||
submitLoading.value = true
|
||||
if (formData.clientId != null) {
|
||||
await updateCustomer(formData)
|
||||
ElMessage.success('更新成功')
|
||||
} else {
|
||||
await createCustomer(formData)
|
||||
ElMessage.success('新增成功')
|
||||
}
|
||||
dialogVisible.value = false
|
||||
loadData()
|
||||
} catch (e) {
|
||||
if (e !== false) console.error(e)
|
||||
} finally {
|
||||
submitLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
loadData()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.page-container {
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.search-card {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.search-card :deep(.el-card__body) {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.toolbar {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.pagination-wrapper {
|
||||
margin-top: 16px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user