大家好,我是java1234_小锋老师,分享一套基于Spring AI 2.0的带AI智能客服的商城系统(支付宝沙箱模拟支付+SprnigBoot4+Vue3) 。
项目简介
随着移动互联网与人工智能技术的飞速发展,电子商务已经成为人们日常生活中不可或缺的一部分。传统的商城系统虽然在商品展示、订单管理、在线支付等方面较为成熟,但是在用户服务方面仍然过度依赖人工客服,存在响应速度慢、服务时间受限、人力成本高等问题。近年来以大语言模型为代表的生成式人工智能取得重大突破,为构建智能化的电商客服系统提供了全新的技术路径。本课题以本科毕业设计为目标,设计并实现了一个基于Spring AI 2.0的带智能客服的商城系统。系统采用前后端分离架构,后端使用Spring Boot框架开发并集成Spring AI 2.0实现智能对话能力,通过向量数据库存储和检索商品知识库与FAQ语料,以支持检索增强生成(RAG)模式,使智能客服能够基于商城自身知识进行准确、个性化的问答。系统在功能上覆盖了用户注册登录、商品浏览搜索、购物车管理、订单管理、智能客服对话以及完整的支付宝沙盒在线支付流程等核心功能。前端基于Vue 3和Element Plus构建,后端持久层使用MyBatis-Plus,数据库选用MySQL 8.0。本文从需求分析、总体设计、详细设计、编码实现到系统测试,完整描述了系统的开发过程,并通过实际运行验证了系统的可用性与稳定性。系统能够有效降低客服人力成本、提升用户体验,对中小型电商企业引入AI客服具有一定的参考意义。
源码下载
链接: pan.baidu.com/s/1ZJN1IUWt…
提取码: 1234
相关截图
核心代码
package com.java1234.server.controller.admin;
import com.java1234.server.common.R;
import com.java1234.server.entity.Category;
import com.java1234.server.service.CategoryService;
import com.java1234.server.vo.CategoryTreeVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 管理端分类控制器
*/
@RestController
@RequestMapping("/api/admin/category")
public class AdminCategoryController {
@Autowired
private CategoryService categoryService;
@GetMapping
public R<List<CategoryTreeVO>> tree() {
return R.ok(categoryService.treeList());
}
@PostMapping
public R<Void> add(@RequestBody Category category) {
categoryService.add(category);
return R.ok();
}
@PutMapping
public R<Void> update(@RequestBody Category category) {
categoryService.update(category);
return R.ok();
}
@DeleteMapping("/{id}")
public R<Void> delete(@PathVariable Long id) {
categoryService.delete(id);
return R.ok();
}
}
<template>
<div class="page-container">
<div class="page-toolbar">
<el-input v-model="query.keyword" placeholder="用户名/姓名" clearable style="width: 200px" />
<el-button type="primary" @click="loadList">查询</el-button>
<el-button type="success" @click="openDialog()">新增管理员</el-button>
</div>
<div class="table-wrapper">
<el-table v-loading="loading" :data="tableData" border stripe height="100%" style="width: 100%">
<el-table-column prop="id" label="ID" min-width="70" />
<el-table-column prop="username" label="用户名" min-width="120" />
<el-table-column prop="realName" label="真实姓名" min-width="120" />
<el-table-column label="状态" min-width="90">
<template #default="{ row }">
<el-tag :type="row.status === 1 ? 'success' : 'danger'">{{ row.status === 1 ? '正常' : '禁用' }}</el-tag>
</template>
</el-table-column>
<el-table-column label="创建时间" min-width="170">
<template #default="{ row }">{{ formatDateTime(row.createTime) }}</template>
</el-table-column>
<el-table-column label="操作" min-width="150" fixed="right">
<template #default="{ row }">
<el-button type="primary" link @click="openDialog(row)">编辑</el-button>
<el-button type="danger" link @click="handleDelete(row)">删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
<div class="page-pagination">
<el-pagination
v-model:current-page="query.pageNum"
v-model:page-size="query.pageSize"
:total="total"
:page-sizes="[10, 20, 50]"
layout="total, sizes, prev, pager, next"
@size-change="loadList"
@current-change="loadList"
/>
</div>
<el-dialog v-model="dialogVisible" :title="form.id ? '编辑管理员' : '新增管理员'" width="480px" destroy-on-close>
<el-form ref="formRef" :model="form" :rules="formRules" label-width="90px">
<el-form-item label="用户名" prop="username">
<el-input v-model="form.username" :disabled="!!form.id" />
</el-form-item>
<el-form-item v-if="!form.id" label="密码" prop="password">
<el-input v-model="form.password" type="password" show-password />
</el-form-item>
<el-form-item label="真实姓名" prop="realName">
<el-input v-model="form.realName" />
</el-form-item>
<el-form-item label="状态">
<el-radio-group v-model="form.status">
<el-radio :value="1">正常</el-radio>
<el-radio :value="0">禁用</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" :loading="submitLoading" @click="handleSubmit">确定</el-button>
</template>
</el-dialog>
</div>
</template>
<script setup>
import { ref, reactive, computed, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { formatDateTime } from '@/utils/date'
import { getAdminList, addAdmin, updateAdmin, deleteAdmin } from '@/api/admin'
const loading = ref(false)
const submitLoading = ref(false)
const tableData = ref([])
const total = ref(0)
const dialogVisible = ref(false)
const formRef = ref()
const query = reactive({
pageNum: 1,
pageSize: 10,
keyword: '',
})
const defaultForm = () => ({
id: null,
username: '',
password: '',
realName: '',
status: 1,
})
const form = reactive(defaultForm())
const formRules = computed(() => ({
username: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
password: form.id ? [] : [{ required: true, message: '请输入密码', trigger: 'blur' }],
realName: [{ required: true, message: '请输入真实姓名', trigger: 'blur' }],
}))
async function loadList() {
loading.value = true
try {
const res = await getAdminList(query)
tableData.value = res.data?.list || []
total.value = res.data?.total || 0
} finally {
loading.value = false
}
}
function openDialog(row) {
Object.assign(form, defaultForm(), row || {})
if (row) form.password = ''
dialogVisible.value = true
}
async function handleSubmit() {
await formRef.value.validate()
submitLoading.value = true
try {
const payload = { ...form }
if (form.id && !payload.password) delete payload.password
if (form.id) {
await updateAdmin(payload)
} else {
await addAdmin(payload)
}
ElMessage.success('保存成功')
dialogVisible.value = false
loadList()
} finally {
submitLoading.value = false
}
}
function handleDelete(row) {
ElMessageBox.confirm('确定删除该管理员吗?', '提示', { type: 'warning' })
.then(async () => {
await deleteAdmin(row.id)
ElMessage.success('删除成功')
loadList()
})
.catch(() => {})
}
onMounted(loadList)
</script>