|
|
@@ -0,0 +1,241 @@
|
|
|
+<template>
|
|
|
+ <el-main>
|
|
|
+ <el-card shadow="never">
|
|
|
+ <template #header>
|
|
|
+ <div class="header-row">
|
|
|
+ <span>客服管理</span>
|
|
|
+ <el-button type="primary" @click="openCreate">添加客服</el-button>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <el-table v-loading="loading" :data="list">
|
|
|
+ <el-table-column prop="id" label="ID" width="80" />
|
|
|
+ <el-table-column prop="name" label="姓名" min-width="100" show-overflow-tooltip />
|
|
|
+ <el-table-column prop="wechat" label="微信号" min-width="120" show-overflow-tooltip />
|
|
|
+ <el-table-column prop="phone" label="手机号" width="130" />
|
|
|
+ <el-table-column label="二维码" width="100">
|
|
|
+ <template #default="{ row }">
|
|
|
+ <el-image
|
|
|
+ v-if="row.qrcode"
|
|
|
+ :src="row.qrcode"
|
|
|
+ :preview-src-list="[row.qrcode]"
|
|
|
+ fit="cover"
|
|
|
+ style="width: 48px; height: 48px; border-radius: 4px;"
|
|
|
+ preview-teleported
|
|
|
+ />
|
|
|
+ <span v-else>-</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="状态" width="120">
|
|
|
+ <template #default="{ row }">
|
|
|
+ <el-switch
|
|
|
+ :model-value="Number(row.status)"
|
|
|
+ :active-value="1"
|
|
|
+ :inactive-value="0"
|
|
|
+ inline-prompt
|
|
|
+ active-text="启用"
|
|
|
+ inactive-text="停用"
|
|
|
+ active-color="#13ce66"
|
|
|
+ inactive-color="#ff4949"
|
|
|
+ @change="(val) => changeStatus(row, val)"
|
|
|
+ />
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="操作" width="160" fixed="right">
|
|
|
+ <template #default="{ row }">
|
|
|
+ <el-button size="small" @click="openEdit(row)">编辑</el-button>
|
|
|
+ <el-button size="small" type="danger" @click="removeRow(row)">删除</el-button>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+
|
|
|
+ <div class="pager">
|
|
|
+ <el-pagination
|
|
|
+ background
|
|
|
+ layout="total, prev, pager, next, sizes"
|
|
|
+ :total="total"
|
|
|
+ :current-page="query.page"
|
|
|
+ :page-size="query.limit"
|
|
|
+ :page-sizes="[5, 10, 20, 50]"
|
|
|
+ @current-change="handlePageChange"
|
|
|
+ @size-change="handleSizeChange"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </el-card>
|
|
|
+
|
|
|
+ <el-dialog v-model="dialogVisible" :title="dialogTitle" width="520px" destroy-on-close>
|
|
|
+ <el-form ref="formRef" :model="form" :rules="rules" label-width="90px">
|
|
|
+ <el-form-item label="姓名" prop="name">
|
|
|
+ <el-input v-model="form.name" clearable maxlength="40" />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="微信号" prop="wechat">
|
|
|
+ <el-input v-model="form.wechat" clearable maxlength="60" />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="手机号" prop="phone">
|
|
|
+ <el-input v-model="form.phone" clearable maxlength="20" />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="二维码" prop="qrcode">
|
|
|
+ <div class="qrcode-row">
|
|
|
+ <sc-upload v-model="form.qrcode" title="上传" :api-obj="$API.common.upload" />
|
|
|
+ <el-input v-model="form.qrcode" placeholder="或填写图片地址" clearable class="qrcode-input" />
|
|
|
+ </div>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="备注" prop="aa">
|
|
|
+ <el-input v-model="form.aa" placeholder="与接口字段 aa 对应" maxlength="120" />
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ <template #footer>
|
|
|
+ <el-button @click="dialogVisible = false">取消</el-button>
|
|
|
+ <el-button type="primary" :loading="saving" @click="submitForm">保存</el-button>
|
|
|
+ </template>
|
|
|
+ </el-dialog>
|
|
|
+ </el-main>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+export default {
|
|
|
+ name: "KefuList",
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ loading: false,
|
|
|
+ saving: false,
|
|
|
+ list: [],
|
|
|
+ total: 0,
|
|
|
+ query: { page: 1, limit: 10 },
|
|
|
+ dialogVisible: false,
|
|
|
+ dialogTitle: "添加客服",
|
|
|
+ form: this.getDefaultForm(),
|
|
|
+ rules: {
|
|
|
+ name: [{ required: true, message: "请输入姓名", trigger: "blur" }],
|
|
|
+ wechat: [{ required: true, message: "请输入微信号", trigger: "blur" }],
|
|
|
+ phone: [{ required: true, message: "请输入手机号", trigger: "blur" }],
|
|
|
+ qrcode: [{ required: true, message: "请上传或填写二维码", trigger: "blur" }]
|
|
|
+ }
|
|
|
+ };
|
|
|
+ },
|
|
|
+ created() {
|
|
|
+ this.getList();
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ getDefaultForm() {
|
|
|
+ return { id: "", name: "", wechat: "", phone: "", qrcode: "", aa: "-" };
|
|
|
+ },
|
|
|
+ async getList() {
|
|
|
+ this.loading = true;
|
|
|
+ try {
|
|
|
+ const res = await this.$API.kefu.list.get(this.query);
|
|
|
+ if (res.code !== 1) {
|
|
|
+ this.$message.error(res.msg || "获取客服列表失败");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const data = res.data || {};
|
|
|
+ this.list = data.data || data.list || [];
|
|
|
+ this.total = Number(data.count || data.total || this.list.length || 0);
|
|
|
+ } finally {
|
|
|
+ this.loading = false;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ handlePageChange(page) {
|
|
|
+ this.query.page = page;
|
|
|
+ this.getList();
|
|
|
+ },
|
|
|
+ handleSizeChange(limit) {
|
|
|
+ this.query.limit = limit;
|
|
|
+ this.query.page = 1;
|
|
|
+ this.getList();
|
|
|
+ },
|
|
|
+ openCreate() {
|
|
|
+ this.dialogTitle = "添加客服";
|
|
|
+ this.form = this.getDefaultForm();
|
|
|
+ this.dialogVisible = true;
|
|
|
+ this.$nextTick(() => this.$refs.formRef?.clearValidate());
|
|
|
+ },
|
|
|
+ openEdit(row) {
|
|
|
+ this.dialogTitle = "编辑客服";
|
|
|
+ this.form = {
|
|
|
+ id: row.id,
|
|
|
+ name: row.name || "",
|
|
|
+ wechat: row.wechat || "",
|
|
|
+ phone: row.phone || "",
|
|
|
+ qrcode: row.qrcode || "",
|
|
|
+ aa: row.aa != null && row.aa !== "" ? String(row.aa) : "-"
|
|
|
+ };
|
|
|
+ this.dialogVisible = true;
|
|
|
+ this.$nextTick(() => this.$refs.formRef?.clearValidate());
|
|
|
+ },
|
|
|
+ submitForm() {
|
|
|
+ this.$refs.formRef.validate(async (valid) => {
|
|
|
+ if (!valid) return false;
|
|
|
+ this.saving = true;
|
|
|
+ try {
|
|
|
+ const payload = {
|
|
|
+ name: this.form.name,
|
|
|
+ wechat: this.form.wechat,
|
|
|
+ phone: this.form.phone,
|
|
|
+ qrcode: this.form.qrcode,
|
|
|
+ aa: this.form.aa || "-"
|
|
|
+ };
|
|
|
+ if (this.form.id) payload.id = String(this.form.id);
|
|
|
+ const res = await this.$API.kefu.save.post(payload);
|
|
|
+ if (res.code !== 1) {
|
|
|
+ this.$message.error(res.msg || "保存失败");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ this.$message.success(res.msg || "保存成功");
|
|
|
+ this.dialogVisible = false;
|
|
|
+ this.getList();
|
|
|
+ } finally {
|
|
|
+ this.saving = false;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ async removeRow(row) {
|
|
|
+ const confirm = await this.$confirm("确认删除该客服吗?", "提示", {
|
|
|
+ type: "warning",
|
|
|
+ confirmButtonText: "删除",
|
|
|
+ confirmButtonClass: "el-button--danger"
|
|
|
+ }).catch(() => {});
|
|
|
+ if (confirm !== "confirm") return;
|
|
|
+ const res = await this.$API.kefu.del.delete(row.id);
|
|
|
+ if (res.code !== 1) {
|
|
|
+ this.$message.error(res.msg || "删除失败");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ this.$message.success(res.msg || "删除成功");
|
|
|
+ this.getList();
|
|
|
+ },
|
|
|
+ async changeStatus(row, status) {
|
|
|
+ const res = await this.$API.kefu.setStatus.get(row.id, status);
|
|
|
+ if (res.code !== 1) {
|
|
|
+ this.$message.error(res.msg || "状态更新失败");
|
|
|
+ this.getList();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ this.$message.success(res.msg || "状态更新成功");
|
|
|
+ row.status = status;
|
|
|
+ }
|
|
|
+ }
|
|
|
+};
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+.header-row {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+}
|
|
|
+.pager {
|
|
|
+ margin-top: 16px;
|
|
|
+ display: flex;
|
|
|
+ justify-content: flex-end;
|
|
|
+}
|
|
|
+.qrcode-row {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap: 10px;
|
|
|
+ width: 100%;
|
|
|
+}
|
|
|
+.qrcode-input {
|
|
|
+ max-width: 360px;
|
|
|
+}
|
|
|
+</style>
|