1. 设备管理界面完成
2. 用户管理界面完成
3. 会话列表完成
This commit is contained in:
Zy
2026-10-10 17:02:31 +08:00
parent 23703a66c2
commit 2ccce95d44
64 changed files with 5341 additions and 1254 deletions

View File

@@ -1,17 +1,41 @@
<script lang="ts" setup>
import FormItemTip from "@/components/FormItemTip/index.vue";
import cskbEditor from '@/components/Editor/cskb.vue'
import {FormInstance, FormRules} from "element-plus";
import {addCsKb} from "@/api/system/cskb";
import modal from "@/plugins/modal";
const formRef = ref<FormInstance>()
const router = useRouter();
const form = ref({
phone: "",
username: "",
sex: 1,
creatDay: '',
status: 1,
quickAction: [],
img: ''
"title": "",
"category": "",
"content": "",
"sort": 1,
"status": "1",
"buttons": []
})
// ========= 表单校验 rules =========
const rules: FormRules = {
title: [
{required: true, message: '请输入问题标题', trigger: 'blur'},
{max: 30, message: '标题最多30个字符', trigger: 'blur'}
],
category: [
{required: true, message: '请选择问题分类', trigger: 'change'}
],
content: [
{required: true, message: '请填写回复内容', trigger: 'blur'}
],
sort: [
{required: true, message: '请输入排序号', trigger: 'blur'},
{type: 'number', min: 0, message: '排序号不能小于0', trigger: 'blur'}
]
}
const actions = {
resolved: {"buttonCode": "resolved", "label": "已解决", "sort": 1, value: 'resolved'},
transfer_human: {"buttonCode": "transfer_human", "label": "转人工", "sort": 2, value: 'transfer_human'},
}
function handleBack() {
@@ -20,16 +44,43 @@ function handleBack() {
})
}
function submit() {
async function submit(isEnable = false) {
if (!formRef.value) return
console.log(form.value)
await formRef.value.validate((valid) => {
if (valid) {
// isEnable=true 代表保存并启用
form.value.buttons = form.value.buttons.map(item => {
return actions[item]
})
addCsKb(form.value).then(() => {
modal.msgSuccess('添加成功')
if (isEnable) {
handleBack()
}
})
}
})
}
function reset() {
form.value = {
"title": "",
"category": "",
"content": "",
"sort": 1,
"status": "1",
"buttons": []
}
}
</script>
<template>
<div class="edit">
<div class="flex justify-between">
<div class="flex justify-between" style="padding-top: 22px">
<pagecrumb></pagecrumb>
<el-button plain type="info" @click="handleBack"> 返回客服列表</el-button>
<el-button plain type="info" @click="handleBack"> 返回知识库管理</el-button>
</div>
<div class="tipBox">
<div class="tip1">新增的知识条目保存后需要「启用」才会在 APP 端展示
@@ -47,55 +98,41 @@ function submit() {
</div>
</div>
<div class="formbox">
<el-form label-position="top">
<el-form ref="formRef" :model="form" :rules="rules" label-position="top">
<div class="title">
基础信息
</div>
<el-row :gutter="24">
<el-col :span="12">
<FormItemTip
v-model="form.phone"
v-model.trim="form.title"
:inputAttrs="{ placeholder: '请输入问题标题,如「连不上 Wi-Fi」', showWordLimit:true ,maxlength:30}"
:required="true"
label="问题标题"
prop="phone"
prop="title"
tip="建议使用用户口语化问法,便于模糊匹配"
>
</FormItemTip>
</el-col>
<el-col :span="12">
<FormItemTip
v-model="form.username"
:inputAttrs="{ placeholder: '请选择问题分类'}"
:required="true"
v-model.trim="form.category"
:inputAttrs="{ placeholder: '请选择问题分类', maxlength:30}"
label="问题分类"
prop="username"
prop="category"
>
</FormItemTip>
</el-col>
</el-row>
<el-row :gutter="24">
<el-col :span="24">
<div>回复内容 <span>*</span></div>
<div>
<cskbEditor v-model="form.creatDay" :simple-toolbar="true"></cskbEditor>
</div>
</el-col>
</el-row>
<el-row :gutter="24">
<el-col :span="12">
<FormItemTip
v-model="form.status"
:inputAttrs="{ placeholder: '', disabled: false }"
:radioOptions="[
{label:'启用',value:1},
{label:'禁用',value:0},
]"
label="账号状态"
prop="status"
tip="禁用后该客服无法登录工作台,其接待中会话将转回排队"
type="radio"
label="回复内容"
prop="content"
type="default"
>
<template #default>
<cskbEditor v-model="form.content" :simple-toolbar="true" style="width: 100%"></cskbEditor>
</template>
</FormItemTip>
</el-col>
</el-row>
@@ -105,13 +142,10 @@ function submit() {
<el-row :gutter="24">
<el-col :span="12">
<FormItemTip
v-model="form.quickAction"
:radio-options="[
{label: '已解决',value:1},
{label: '转人工',value:0}
]"
v-model="form.buttons"
:radio-options="Object.values(actions)"
label="关联快捷按钮"
prop="phone"
prop="buttons"
tip="回复气泡下方展示的引导按钮,可多选"
type="checkBox"
>
@@ -119,11 +153,10 @@ function submit() {
</el-col>
<el-col :span="12">
<FormItemTip
v-model="form.username"
v-model.number="form.sort"
:inputAttrs="{ placeholder: '请输入排序'}"
:required="true"
label="排序号"
prop="username"
prop="sort"
tip="决定该条目在 APP 常见问题列表中的展示顺序"
type="inputNumber"
>
@@ -134,6 +167,11 @@ function submit() {
<el-row :gutter="24">
<el-col :span="12">
<FormItemTip
v-model="form.status"
:inputAttrs="{
activeValue: '1',
inactiveValue: '0',
}"
label="启用状态"
tip="关闭则保存为草稿,仅后台可见"
type="switch"
@@ -151,9 +189,9 @@ function submit() {
<div class="footer">
<div class="footer-tip">标题、分类与回复内容为必填项;排序号越小展示越靠前</div>
<div>
<el-button>取消</el-button>
<el-button plain type="primary" @click="submit">保存并继续新增</el-button>
<el-button type="primary" @click="submit">保存并启用</el-button>
<el-button @click="reset">取消</el-button>
<el-button plain type="primary" @click="submit(false)">保存并继续新增</el-button>
<el-button type="primary" @click="submit(true)">保存并启用</el-button>
</div>
</div>
</div>
@@ -161,7 +199,9 @@ function submit() {
<style lang="scss" scoped>
.edit {
overflow: auto;
overflow: hidden;
overflow-y: auto;
min-height: 100%;
padding-bottom: 50px;
.tipBox {