chore: initialize wygj monorepo
This commit is contained in:
@@ -0,0 +1,723 @@
|
||||
<template>
|
||||
<div class="demo-home">
|
||||
<section class="toolbar-meta">
|
||||
<span class="snapshot-time">数据截至:2026-07-02 10:00:00</span>
|
||||
<el-button text :icon="Refresh">刷新</el-button>
|
||||
</section>
|
||||
|
||||
<section class="hero-grid">
|
||||
<article v-for="item in heroEntries" :key="item.title" class="entry-card">
|
||||
<div class="entry-main">
|
||||
<div class="entry-icon">
|
||||
<el-icon><component :is="item.icon" /></el-icon>
|
||||
</div>
|
||||
<div>
|
||||
<h2>{{ item.title }}</h2>
|
||||
<p>{{ item.desc }}</p>
|
||||
<span class="status-pill" :class="`pill-${item.type}`">{{ item.status }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="entry-actions">
|
||||
<el-button type="danger" :disabled="!item.path" @click="goFeature(item.path)">进入功能</el-button>
|
||||
<el-button>查看样例</el-button>
|
||||
</div>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<section class="content-grid">
|
||||
<article class="panel progress-panel">
|
||||
<div class="panel-title">
|
||||
<h2>选 用 育 留 案例沉淀 流程进度</h2>
|
||||
</div>
|
||||
<div class="stage-track">
|
||||
<div v-for="stage in stages" :key="stage.name" class="stage-item" :class="stage.state">
|
||||
<div class="stage-node">
|
||||
<el-icon v-if="stage.state === 'done'"><Check /></el-icon>
|
||||
<span v-else>{{ stage.step }}</span>
|
||||
</div>
|
||||
<div class="stage-copy">
|
||||
<strong>{{ stage.name }}</strong>
|
||||
<span>{{ stage.desc }}</span>
|
||||
<span class="status-pill" :class="`pill-${stage.tagType}`">{{ stage.label }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<article class="panel risk-panel">
|
||||
<div class="panel-title">
|
||||
<h2>演示待办与风险</h2>
|
||||
</div>
|
||||
<ul class="risk-list">
|
||||
<li v-for="risk in risks" :key="risk.name">
|
||||
<div class="risk-icon">
|
||||
<el-icon><component :is="risk.icon" /></el-icon>
|
||||
</div>
|
||||
<span class="risk-name">{{ risk.name }}</span>
|
||||
<span class="risk-owner">负责人:{{ risk.owner }}</span>
|
||||
<span class="status-pill risk-status" :class="`pill-${risk.type}`">{{ risk.status }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<section class="bottom-grid">
|
||||
<article class="panel record-panel">
|
||||
<div class="panel-title compact">
|
||||
<h2>最近训练记录</h2>
|
||||
</div>
|
||||
<el-table :data="records" size="small" class="record-table">
|
||||
<el-table-column prop="name" label="人员" min-width="92" />
|
||||
<el-table-column prop="scene" label="场景" min-width="118" />
|
||||
<el-table-column prop="score" label="得分" width="68" />
|
||||
<el-table-column label="状态" width="88">
|
||||
<template #default="{ row }">
|
||||
<span class="status-dot" :class="row.state"></span>
|
||||
{{ row.status }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="time" label="时间" width="112" />
|
||||
</el-table>
|
||||
<div class="panel-link">
|
||||
查看更多 <el-icon><ArrowRight /></el-icon>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<article class="panel pipeline-panel">
|
||||
<div class="panel-title compact">
|
||||
<h2>案例沉淀 Pipeline</h2>
|
||||
</div>
|
||||
<div class="pipeline-steps">
|
||||
<div v-for="(step, index) in pipeline" :key="step.name" class="pipeline-step">
|
||||
<div class="pipeline-icon">
|
||||
<el-icon><component :is="step.icon" /></el-icon>
|
||||
</div>
|
||||
<strong>{{ step.name }}</strong>
|
||||
<span>{{ step.count }}</span>
|
||||
<el-icon v-if="index < pipeline.length - 1" class="pipeline-arrow"><ArrowRight /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pipeline-summary">
|
||||
<span>今日新增:12 条</span>
|
||||
<span>待审核:2 条</span>
|
||||
<span>已入库:128 条</span>
|
||||
</div>
|
||||
<div class="panel-link">
|
||||
进入案例沉淀 <el-icon><ArrowRight /></el-icon>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<article class="panel metrics-panel">
|
||||
<div class="panel-title compact">
|
||||
<h2>验收指标</h2>
|
||||
</div>
|
||||
<div class="metric-grid">
|
||||
<div v-for="metric in metrics" :key="metric.label" class="metric-card">
|
||||
<el-icon><component :is="metric.icon" /></el-icon>
|
||||
<div>
|
||||
<span>{{ metric.label }}</span>
|
||||
<strong>{{ metric.value }}</strong>
|
||||
<small>{{ metric.target }}</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-link">
|
||||
查看指标详情 <el-icon><ArrowRight /></el-icon>
|
||||
</div>
|
||||
</article>
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="Index" lang="ts">
|
||||
import {
|
||||
ArrowRight,
|
||||
Check,
|
||||
Cpu,
|
||||
DataLine,
|
||||
DocumentChecked,
|
||||
Finished,
|
||||
FolderChecked,
|
||||
Headset,
|
||||
Histogram,
|
||||
Microphone,
|
||||
Notebook,
|
||||
Operation,
|
||||
Reading,
|
||||
Refresh,
|
||||
Switch,
|
||||
Tickets,
|
||||
TrendCharts,
|
||||
UserFilled,
|
||||
VideoCamera
|
||||
} from '@element-plus/icons-vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const heroEntries = [
|
||||
{
|
||||
title: 'AI面试出题',
|
||||
desc: '基于岗位画像与 JD,一键生成面试题目',
|
||||
status: '可演示',
|
||||
type: 'success',
|
||||
icon: DocumentChecked,
|
||||
path: '/recruit/interview'
|
||||
},
|
||||
{
|
||||
title: '三角色对练',
|
||||
desc: '简历生成 + 面试对象 + 结果评估闭环',
|
||||
status: '可演示',
|
||||
type: 'success',
|
||||
icon: UserFilled,
|
||||
path: '/train/practice'
|
||||
},
|
||||
{
|
||||
title: '案例语音整理',
|
||||
desc: '语音上传,AI 整理为结构化案例',
|
||||
status: '样片兜底',
|
||||
type: 'warning',
|
||||
icon: Microphone,
|
||||
path: '/knowledge/cases'
|
||||
},
|
||||
{
|
||||
title: 'SOP知识库',
|
||||
desc: '知识库检索 + RAG问答,支持员工赋能',
|
||||
status: '可演示',
|
||||
type: 'success',
|
||||
icon: Reading,
|
||||
path: '/knowledge/sop'
|
||||
}
|
||||
] as const;
|
||||
|
||||
const goFeature = (path?: string) => {
|
||||
if (!path) return;
|
||||
router.push(path);
|
||||
};
|
||||
|
||||
const stages = [
|
||||
{ step: 1, name: '选:AI面试', desc: '题目与评估', label: '已完成', state: 'done', tagType: 'success' },
|
||||
{ step: 2, name: '用:岗位适配', desc: '与录用评估', label: '已完成', state: 'done', tagType: 'success' },
|
||||
{ step: 3, name: '育:三角色对练', desc: '实战陪练', label: '进行中', state: 'active', tagType: 'danger' },
|
||||
{ step: 4, name: '留:成长追踪', desc: '与能力提升', label: '待启动', state: 'idle', tagType: 'info' },
|
||||
{ step: 5, name: '案例沉淀', desc: '知识与复用', label: '待启动', state: 'idle', tagType: 'info' }
|
||||
] as const;
|
||||
|
||||
const risks = [
|
||||
{ name: '住宅 SOP 素材', owner: '培训组', status: '待确认', type: 'danger', icon: Tickets },
|
||||
{ name: '方言 ASR', owner: '技术组', status: '样片兜底', type: 'warning', icon: Headset },
|
||||
{ name: 'PII 出境评估', owner: '合规组', status: '评估中', type: 'warning', icon: Finished },
|
||||
{ name: '录屏兜底方案', owner: '产品组', status: '已准备', type: 'primary', icon: VideoCamera }
|
||||
] as const;
|
||||
|
||||
const records = [
|
||||
{ name: '张三', scene: '客服应对投诉', score: 86, status: '已完成', state: 'done', time: '07-02 09:32' },
|
||||
{ name: '李四', scene: '催缴沟通技巧', score: 78, status: '已完成', state: 'done', time: '07-02 09:12' },
|
||||
{ name: '王五', scene: '突发事件处理', score: 72, status: '进行中', state: 'active', time: '07-02 08:47' },
|
||||
{ name: '赵六', scene: '业主沟通谈判', score: 90, status: '已完成', state: 'done', time: '07-02 08:15' },
|
||||
{ name: '孙七', scene: '服务礼仪规范', score: 65, status: '未达标', state: 'danger', time: '07-01 18:33' }
|
||||
];
|
||||
|
||||
const pipeline = [
|
||||
{ name: '语音上传', count: '12 条', icon: FolderChecked },
|
||||
{ name: 'ASR 转写', count: '12 条', icon: Histogram },
|
||||
{ name: 'AI 整理', count: '10 条', icon: Cpu },
|
||||
{ name: '审核入库', count: '8 条', icon: Tickets },
|
||||
{ name: '样片展示', count: '5 条', icon: VideoCamera }
|
||||
] as const;
|
||||
|
||||
const metrics = [
|
||||
{ label: '端到端路径', value: '1 条', target: '可完整演示', icon: Switch },
|
||||
{ label: 'RAG 可用率', value: '95%', target: '目标 > 90%', icon: Operation },
|
||||
{ label: '评分一致率', value: '92%', target: '目标 > 85%', icon: TrendCharts },
|
||||
{ label: '试点人数', value: '120 人', target: '目标 > 100 人', icon: DataLine }
|
||||
] as const;
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.demo-home {
|
||||
min-height: calc(100vh - 84px);
|
||||
padding: 22px;
|
||||
background: #f5f7fb;
|
||||
color: #162033;
|
||||
}
|
||||
|
||||
.toolbar-meta {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 12px;
|
||||
margin-bottom: 12px;
|
||||
color: #657184;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.status-pill {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: fit-content;
|
||||
min-height: 24px;
|
||||
padding: 0 10px;
|
||||
border-radius: 6px;
|
||||
font-size: 12px;
|
||||
line-height: 24px;
|
||||
font-weight: 700;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.pill-danger {
|
||||
color: #c80f1f;
|
||||
background: #ffe8e9;
|
||||
}
|
||||
|
||||
.pill-success {
|
||||
color: #15844a;
|
||||
background: #e5f8ee;
|
||||
}
|
||||
|
||||
.pill-warning {
|
||||
color: #c46b00;
|
||||
background: #fff2dc;
|
||||
}
|
||||
|
||||
.pill-primary {
|
||||
color: #1467bd;
|
||||
background: #e7f2ff;
|
||||
}
|
||||
|
||||
.pill-info {
|
||||
color: #64748b;
|
||||
background: #eef2f7;
|
||||
}
|
||||
|
||||
.hero-grid,
|
||||
.content-grid,
|
||||
.bottom-grid {
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.hero-grid {
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.content-grid {
|
||||
grid-template-columns: minmax(0, 1.25fr) minmax(360px, 0.75fr);
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.bottom-grid {
|
||||
grid-template-columns: minmax(350px, 1fr) minmax(420px, 1.1fr) minmax(330px, 0.9fr);
|
||||
}
|
||||
|
||||
.panel,
|
||||
.entry-card {
|
||||
border: 1px solid #e4e9f2;
|
||||
border-radius: 8px;
|
||||
background: #fff;
|
||||
box-shadow: 0 10px 24px rgba(21, 30, 45, 0.04);
|
||||
}
|
||||
|
||||
.entry-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
min-height: 188px;
|
||||
padding: 22px 22px 20px;
|
||||
}
|
||||
|
||||
.entry-main {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
align-items: flex-start;
|
||||
|
||||
h2 {
|
||||
margin: 2px 0 8px;
|
||||
font-size: 18px;
|
||||
line-height: 1.25;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
p {
|
||||
min-height: 40px;
|
||||
margin: 0 0 12px;
|
||||
color: #3f4b5f;
|
||||
font-size: 13px;
|
||||
line-height: 1.55;
|
||||
}
|
||||
}
|
||||
|
||||
.entry-icon {
|
||||
display: grid;
|
||||
width: 58px;
|
||||
height: 58px;
|
||||
flex: 0 0 58px;
|
||||
place-items: center;
|
||||
border-radius: 8px;
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, #ff6b72, #d90f20);
|
||||
font-size: 32px;
|
||||
box-shadow: 0 10px 20px rgba(216, 15, 32, 0.22);
|
||||
}
|
||||
|
||||
.entry-actions {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 12px;
|
||||
margin-top: 22px;
|
||||
|
||||
.el-button {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.panel {
|
||||
padding: 18px;
|
||||
}
|
||||
|
||||
.panel-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 18px;
|
||||
|
||||
&.compact {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin: 0;
|
||||
font-size: 17px;
|
||||
line-height: 1.35;
|
||||
font-weight: 700;
|
||||
}
|
||||
}
|
||||
|
||||
.stage-track {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(5, minmax(0, 1fr));
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.stage-item {
|
||||
position: relative;
|
||||
display: grid;
|
||||
justify-items: center;
|
||||
gap: 12px;
|
||||
min-height: 150px;
|
||||
text-align: center;
|
||||
|
||||
&:not(:last-child)::after {
|
||||
position: absolute;
|
||||
top: 22px;
|
||||
right: -50%;
|
||||
width: 100%;
|
||||
height: 0;
|
||||
border-top: 2px dashed #c7ced8;
|
||||
content: '';
|
||||
}
|
||||
|
||||
&.done:not(:last-child)::after {
|
||||
border-color: #31b367;
|
||||
}
|
||||
|
||||
&.active:not(:last-child)::after {
|
||||
border-color: #d70f20;
|
||||
}
|
||||
}
|
||||
|
||||
.stage-node {
|
||||
z-index: 1;
|
||||
display: grid;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
place-items: center;
|
||||
border: 2px solid #d3d9e3;
|
||||
border-radius: 50%;
|
||||
background: #fff;
|
||||
color: #69758a;
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.stage-item.done .stage-node {
|
||||
border-color: #31b367;
|
||||
color: #fff;
|
||||
background: #31b367;
|
||||
}
|
||||
|
||||
.stage-item.active .stage-node {
|
||||
border-color: #d70f20;
|
||||
color: #fff;
|
||||
background: #d70f20;
|
||||
}
|
||||
|
||||
.stage-copy {
|
||||
display: grid;
|
||||
justify-items: center;
|
||||
gap: 8px;
|
||||
|
||||
strong {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
span {
|
||||
min-height: 34px;
|
||||
color: #303b4c;
|
||||
font-size: 13px;
|
||||
line-height: 1.35;
|
||||
}
|
||||
}
|
||||
|
||||
.risk-list {
|
||||
display: grid;
|
||||
gap: 0;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
list-style: none;
|
||||
|
||||
li {
|
||||
display: grid;
|
||||
grid-template-columns: 34px minmax(110px, 1fr) minmax(120px, 0.8fr) 82px;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
min-height: 43px;
|
||||
border-bottom: 1px solid #edf0f5;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.risk-icon {
|
||||
color: #5d6878;
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
.risk-name {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.risk-owner {
|
||||
color: #637085;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.record-panel {
|
||||
:deep(.el-table__inner-wrapper::before) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.record-table {
|
||||
border: 1px solid #edf0f5;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.status-dot {
|
||||
display: inline-block;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
margin-right: 6px;
|
||||
border-radius: 50%;
|
||||
vertical-align: middle;
|
||||
|
||||
&.done {
|
||||
background: #31b367;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background: #e6a23c;
|
||||
}
|
||||
|
||||
&.danger {
|
||||
background: #d70f20;
|
||||
}
|
||||
}
|
||||
|
||||
.pipeline-steps {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(5, minmax(0, 1fr));
|
||||
gap: 12px;
|
||||
padding: 8px 0 18px;
|
||||
}
|
||||
|
||||
.pipeline-step {
|
||||
position: relative;
|
||||
display: grid;
|
||||
justify-items: center;
|
||||
gap: 8px;
|
||||
text-align: center;
|
||||
|
||||
strong {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
span {
|
||||
color: #0f7be8;
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
}
|
||||
}
|
||||
|
||||
.pipeline-icon {
|
||||
display: grid;
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
place-items: center;
|
||||
border: 1px solid #dce2ec;
|
||||
border-radius: 50%;
|
||||
background: #f8fafc;
|
||||
color: #1d2b3f;
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
.pipeline-arrow {
|
||||
position: absolute;
|
||||
top: 22px;
|
||||
right: -18px;
|
||||
color: #aab3c2;
|
||||
}
|
||||
|
||||
.pipeline-summary {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px 16px;
|
||||
padding-top: 14px;
|
||||
border-top: 1px solid #edf0f5;
|
||||
color: #526178;
|
||||
|
||||
span {
|
||||
position: relative;
|
||||
|
||||
&:not(:last-child)::after {
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
right: -9px;
|
||||
width: 1px;
|
||||
height: 12px;
|
||||
background: #cbd3df;
|
||||
content: '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.metric-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.metric-card {
|
||||
display: grid;
|
||||
grid-template-columns: 44px minmax(0, 1fr);
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
min-height: 86px;
|
||||
padding: 12px;
|
||||
border: 1px solid #e5eaf3;
|
||||
border-radius: 8px;
|
||||
|
||||
.el-icon {
|
||||
color: #d70f20;
|
||||
font-size: 34px;
|
||||
}
|
||||
|
||||
span,
|
||||
small {
|
||||
display: block;
|
||||
color: #5f6c80;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
strong {
|
||||
display: block;
|
||||
margin: 2px 0;
|
||||
color: #142033;
|
||||
font-size: 24px;
|
||||
line-height: 1.1;
|
||||
}
|
||||
}
|
||||
|
||||
.panel-link {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 4px;
|
||||
margin-top: 14px;
|
||||
color: #d70f20;
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
@media (max-width: 1360px) {
|
||||
.hero-grid {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.content-grid,
|
||||
.bottom-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.demo-home {
|
||||
padding: 14px;
|
||||
}
|
||||
|
||||
.page-heading {
|
||||
align-items: flex-start;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.hero-grid,
|
||||
.stage-track,
|
||||
.pipeline-steps,
|
||||
.metric-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.stage-item {
|
||||
justify-items: start;
|
||||
grid-template-columns: 48px minmax(0, 1fr);
|
||||
min-height: auto;
|
||||
text-align: left;
|
||||
|
||||
&::after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.stage-copy {
|
||||
justify-items: start;
|
||||
}
|
||||
|
||||
.risk-list li {
|
||||
grid-template-columns: 28px minmax(0, 1fr);
|
||||
}
|
||||
|
||||
.risk-owner,
|
||||
.risk-status {
|
||||
grid-column: 2;
|
||||
}
|
||||
|
||||
.pipeline-step {
|
||||
grid-template-columns: 56px minmax(0, 1fr);
|
||||
justify-items: start;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.pipeline-arrow {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.pipeline-summary span::after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user