分享一套锋哥原创的基于Spring AI 2.0的带AI智能客服的商城系统(支付宝沙箱模拟支付+SprnigBoot4+Vue3)

0 阅读3分钟

大家好,我是java1234_小锋老师,分享一套基于Spring AI 2.0的带AI智能客服的商城系统(支付宝沙箱模拟支付+SprnigBoot4+Vue3)  。

1.jpg

项目简介

随着移动互联网与人工智能技术的飞速发展,电子商务已经成为人们日常生活中不可或缺的一部分。传统的商城系统虽然在商品展示、订单管理、在线支付等方面较为成熟,但是在用户服务方面仍然过度依赖人工客服,存在响应速度慢、服务时间受限、人力成本高等问题。近年来以大语言模型为代表的生成式人工智能取得重大突破,为构建智能化的电商客服系统提供了全新的技术路径。本课题以本科毕业设计为目标,设计并实现了一个基于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

相关截图

2.jpg

3.jpg

4.jpg

5.jpg

6.jpg

7.jpg

8.jpg

9.jpg

11.jpg

12.jpg

核心代码


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>