database.sql
-- 创建数据库
CREATE DATABASE IF NOT EXISTS product_management;
USE product_management;
-- 创建表
CREATE TABLE IF NOT EXISTS product_data (
id INT AUTO_INCREMENT PRIMARY KEY,
product_info JSON NOT NULL,
status TINYINT DEFAULT 1 COMMENT '数据状态,1 表示正常,0 表示删除',
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '添加时间',
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
delete_time DATETIME NULL COMMENT '删除时间'
);
-- 插入示例数据
INSERT INTO product_data (product_info)
VALUES ('[
{
"stockname": "总 店",
"total": "1",
"goodsname": "B042700000006637",
"goodsid": "B0427",
"type": "B",
"types": "镜架",
"brands": "爱 阿玛尼200-03",
"brand": "爱 阿玛尼",
"model": "200-03",
"sph": null,
"cyl": null,
"addlight": null,
"stockid": "01",
"unit": "副",
"price": "2",
"amount": 2,
"batch": "2025-04-06+24",
"expiry": "2025-04-30",
"production": "2025-04-06",
"shelflife": "24",
"batchno": "微信"
},
{
"stockname": "总 店",
"total": "2",
"goodsname": "B042700000006638",
"goodsid": "B0427",
"type": "B",
"types": "镜架",
"brands": "爱 阿玛尼201-02",
"brand": "爱 阿玛尼",
"model": "201-02",
"sph": null,
"cyl": null,
"addlight": null,
"stockid": "01",
"unit": "副",
"price": "0",
"amount": 0,
"batch": "2025-04-06+24",
"expiry": "2025-04-30",
"production": "2025-04-06",
"shelflife": "24",
"batchno": "微信"
},
{
"stockname": "总 店",
"total": "1",
"goodsname": "B042700000006639",
"goodsid": "B0427",
"type": "B",
"types": "镜架",
"brands": "爱 阿玛尼202-01",
"brand": "爱 阿玛尼",
"model": "202-01",
"sph": null,
"cyl": null,
"addlight": null,
"stockid": "01",
"unit": "副",
"price": "0",
"amount": 0,
"batch": "2025-04-06+24",
"expiry": "2025-04-30",
"production": "2025-04-06",
"shelflife": "24",
"batchno": "微信"
},
{
"stockname": "总 店",
"total": "12",
"goodsname": "C0071-00.25-1.00",
"goodsid": "C0071",
"type": "C",
"types": "隐形眼镜",
"brands": "博士伦睛莹年抛(水蓝片)-0.25-1.00",
"brand": "博士伦睛莹年抛(水蓝片)",
"model": null,
"sph": "-0.25",
"cyl": "-1.00",
"addlight": null,
"stockid": "01",
"unit": "片",
"price": "0",
"amount": 0,
"batch": "2025-04-06+270",
"expiry": "2026-01-01",
"production": "2025-04-06",
"shelflife": "270",
"batchno": "银联"
},
{
"stockname": "总 店",
"total": "2",
"goodsname": "C0071-01.00-1.00",
"goodsid": "C0071",
"type": "C",
"types": "隐形眼镜",
"brands": "博士伦睛莹年抛(水蓝片)-1.00-1.00",
"brand": "博士伦睛莹年抛(水蓝片)",
"model": null,
"sph": "-1.00",
"cyl": "-1.00",
"addlight": null,
"stockid": "01",
"unit": "片",
"price": "0",
"amount": 0,
"batch": "2025-04-06+270",
"expiry": "2026-01-01",
"production": "2025-04-06",
"shelflife": "270",
"batchno": "银联"
},
{
"stockname": "总 店",
"total": "313",
"goodsname": "C0071-01.25-1.50",
"goodsid": "C0071",
"type": "C",
"types": "隐形眼镜",
"brands": "博士伦睛莹年抛(水蓝片)-1.25-1.50",
"brand": "博士伦睛莹年抛(水蓝片)",
"model": null,
"sph": "-1.25",
"cyl": "-1.50",
"addlight": null,
"stockid": "01",
"unit": "片",
"price": "0",
"amount": 0,
"batch": "2025-04-06+270",
"expiry": "2026-01-01",
"production": "2025-04-06",
"shelflife": "270",
"batchno": "银联"
}
]'); HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>产品数据管理</title>
<!-- 引入 Layui CSS -->
<link rel="stylesheet" href="https://cdn.staticfile.org/layui/2.8.12/css/layui.min.css">
<!-- 引入 Tailwind CSS -->
<script src="https://unpkg.com/@tailwindcss/browser@4"></script>
<!-- 引入 Font Awesome -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css" rel="stylesheet">
</head>
<body class="bg-gray-100 p-8">
<!-- 页面标题 -->
<h1 class="text-2xl font-bold mb-4">产品数据管理</h1>
<!-- 新增按钮 -->
<button id="addBtn" class="layui-btn layui-btn-normal mb-4">新增</button>
<!-- 表格容器 -->
<table id="productTable" lay-filter="productTable"></table>
<!-- 弹出层表单 -->
<div id="formPopup" class="layui-layer" style="display: none;">
<form class="layui-form" lay-filter="formFilter">
<!-- 隐藏的 ID 输入框,用于修改时传递 ID -->
<input type="hidden" name="id">
<!-- 产品信息输入框 -->
<div class="layui-form-item">
<label class="layui-form-label">产品信息</label>
<div class="layui-input-block">
<textarea name="product_info" placeholder="请输入 JSON 格式的产品信息" class="layui-textarea"></textarea>
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<!-- 提交按钮 -->
<button class="layui-btn" lay-submit lay-filter="formSubmit">提交</button>
<!-- 取消按钮 -->
<button type="button" class="layui-btn layui-btn-primary" id="cancelBtn">取消</button>
</div>
</div>
</form>
</div>
<!-- 引入 Layui JS -->
<script src="https://cdn.staticfile.org/layui/2.8.12/layui.min.js"></script>
<script>
layui.use(['table', 'form', 'layer'], function () {
var table = layui.table;
var form = layui.form;
var layer = layui.layer;
// 渲染表格
table.render({
elem: '#productTable',
url: '/product/query', // 后端查询数据接口
cols: [[
{ field: 'id', title: 'ID', width: 80 },
{ field: 'product_info', title: '产品信息', width: 400, templet: function (d) {
return JSON.stringify(d.product_info);
} },
{ title: '操作', width: 200, templet: function (d) {
return '<button class="layui-btn layui-btn-xs layui-btn-normal" onclick="editData(' + d.id + ')">编辑</button>' +
'<button class="layui-btn layui-btn-xs layui-btn-danger" onclick="deleteData(' + d.id + ')">删除</button>';
} }
]],
page: true
});
// 新增按钮点击事件
document.getElementById('addBtn').addEventListener('click', function () {
// 清空表单数据
form.val('formFilter', {
id: '',
product_info: ''
});
// 弹出表单层
layer.open({
title: '新增产品数据',
type: 1,
content: document.getElementById('formPopup'),
area: ['600px', '400px']
});
});
// 取消按钮点击事件
document.getElementById('cancelBtn').addEventListener('click', function () {
layer.closeAll();
});
// 提交表单事件
form.on('submit(formSubmit)', function (data) {
var url = data.field.id ? '/product/update/' + data.field.id : '/product/save';
// 发送 AJAX 请求
$.ajax({
url: url,
type: 'POST',
data: data.field,
success: function (res) {
if (res.code === 0) {
layer.msg(res.msg, { icon: 1 });
layer.closeAll();
table.reload('productTable');
} else {
layer.msg(res.msg, { icon: 2 });
}
},
error: function () {
layer.msg('网络错误', { icon: 2 });
}
});
return false;
});
// 编辑数据函数
window.editData = function (id) {
// 发送 AJAX 请求获取数据
$.ajax({
url: '/product/query',
type: 'GET',
data: { id: id },
success: function (res) {
if (res.code === 0) {
var data = res.data.find(item => item.id === id);
if (data) {
// 填充表单数据
form.val('formFilter', {
id: id,
product_info: JSON.stringify(data.product_info)
});
// 弹出表单层
layer.open({
title: '编辑产品数据',
type: 1,
content: document.getElementById('formPopup'),
area: ['600px', '400px']
});
} else {
layer.msg('未找到该数据', { icon: 2 });
}
} else {
layer.msg('获取数据失败', { icon: 2 });
}
},
error: function () {
layer.msg('网络错误', { icon: 2 });
}
});
};
// 删除数据函数
window.deleteData = function (id) {
layer.confirm('确定要删除这条数据吗?', {
icon: 3,
title: '提示'
}, function (index) {
// 发送 AJAX 请求删除数据
$.ajax({
url: '/product/delete/' + id,
type: 'POST',
success: function (res) {
if (res.code === 0) {
layer.msg(res.msg, { icon: 1 });
table.reload('productTable');
} else {
layer.msg(res.msg, { icon: 2 });
}
},
error: function () {
layer.msg('网络错误', { icon: 2 });
}
});
layer.close(index);
});
};
});
</script>
</body>
</html> ProductDataController.php
<?php
namespace app\controller;
use app\model\ProductData;
use think\facade\Request;
use think\facade\Db;
class ProductDataController
{
/**
* 查询产品数据
*
* @return \think\response\Json
*/
public function queryProductData()
{
// 查询正常状态的数据
$data = ProductData::getNormalData();
return json([
'code' => 0,
'msg' => '',
'count' => count($data),
'data' => $data
]);
}
/**
* 保存产品数据
*
* @return \think\response\Json
*/
public function saveProductData()
{
$productData = Request::post('product_info');
$model = new ProductData();
$model->product_info = $productData;
$result = $model->save();
if ($result) {
return json([
'code' => 0,
'msg' => '数据保存成功'
]);
} else {
return json([
'code' => 1,
'msg' => '数据保存失败'
]);
}
}
/**
* 更新产品数据
*
* @param int $id
* @return \think\response\Json
*/
public function updateProductData($id)
{
$productData = Request::post('product_info');
$model = ProductData::find($id);
if ($model && $model->status == 1) {
$model->product_info = $productData;
$result = $model->save();
if ($result) {
return json([
'code' => 0,
'msg' => '数据更新成功'
]);
}
}
return json([
'code' => 1,
'msg' => '数据更新失败'
]);
}
/**
* 删除产品数据(软删除)
*
* @param int $id
* @return \think\response\Json
*/
public function deleteProductData($id)
{
$result = ProductData::softDelete($id);
if ($result) {
return json([
'code' => 0,
'msg' => '数据删除成功'
]);
} else {
return json([
'code' => 1,
'msg' => '数据删除失败'
]);
}
}
} 用DB实现
<?php
namespace app\controller;
use think\facade\Db;
use think\facade\Request;
class ProductDataController
{
/**
* 查询产品数据
*
* @return \think\response\Json
*/
public function queryProductData()
{
// 查询正常状态的数据
$data = Db::name('product_data')
->where('status', 1)
->select();
// 将 JSON 数据解码
foreach ($data as &$item) {
$item['product_info'] = json_decode($item['product_info'], true);
}
return json([
'code' => 0,
'msg' => '',
'count' => count($data),
'data' => $data
]);
}
/**
* 保存产品数据
*
* @return \think\response\Json
*/
public function saveProductData()
{
$productData = Request::post('product_info');
$productJson = json_encode($productData, JSON_UNESCAPED_UNICODE);
// 插入数据到数据库
$result = Db::name('product_data')->insert([
'product_info' => $productJson
]);
if ($result) {
return json([
'code' => 0,
'msg' => '数据保存成功'
]);
} else {
return json([
'code' => 1,
'msg' => '数据保存失败'
]);
}
}
/**
* 更新产品数据
*
* @param int $id
* @return \think\response\Json
*/
public function updateProductData($id)
{
$productData = Request::post('product_info');
$productJson = json_encode($productData, JSON_UNESCAPED_UNICODE);
// 更新数据库中的数据
$result = Db::name('product_data')
->where('id', $id)
->where('status', 1)
->update([
'product_info' => $productJson
]);
if ($result) {
return json([
'code' => 0,
'msg' => '数据更新成功'
]);
} else {
return json([
'code' => 1,
'msg' => '数据更新失败'
]);
}
}
/**
* 删除产品数据(软删除)
*
* @param int $id
* @return \think\response\Json
*/
public function deleteProductData($id)
{
// 更新数据状态为删除,并记录删除时间
$result = Db::name('product_data')
->where('id', $id)
->where('status', 1)
->update([
'status' => 0,
'delete_time' => date('Y-m-d H:i:s')
]);
if ($result) {
return json([
'code' => 0,
'msg' => '数据删除成功'
]);
} else {
return json([
'code' => 1,
'msg' => '数据删除失败'
]);
}
}
} 模型ProductData.php
<?php
namespace app\model;
use think\Model;
class ProductData extends Model
{
// 指定表名
protected $table = 'product_data';
// 指定 JSON 类型的字段
protected $json = ['product_info'];
/**
* 获取正常状态的数据
*
* @return \think\model\collection\Collection
*/
public static function getNormalData()
{
return self::where('status', 1)->select();
}
/**
* 软删除数据
*
* @param int $id
* @return bool
*/
public static function softDelete($id)
{
return self::where('id', $id)
->where('status', 1)
->update([
'status' => 0,
'delete_time' => date('Y-m-d H:i:s')
]);
}
} 代码说明
执行
database.sql脚本创建数据库和表。确保项目中安装了 ThinkPHP 8 框架。
将上述代码文件放置到对应的目录下。
数据库脚本(
database.sql):创建product_management数据库和product_data表,用于存储产品数据。模型(
app/model/ProductData.php):$table:指定模型对应的表名。$json:指定product_info字段为 JSON 类型。getNormalData方法:获取正常状态的数据。softDelete方法:软删除数据。
控制器(
app/controller/ProductDataController.php):queryProductData方法:查询产品数据。saveProductData方法:保存产品数据。updateProductData方法:更新产品数据。deleteProductData方法:删除产品数据(软删除)。
前端页面(
public/index.html):使用 Layui 框架实现产品数据的增删改查交互。使用 Layui 框架实现表格的展示和增删改查操作。
通过 AJAX 请求与后端控制器进行数据交互。
入口文件(
public/index.php):引入 ThinkPHP 引导文件,实例化控制器并调用saveTableData方法,最后输出结果。
使用步骤
执行
database.sql脚本创建数据库和表。将上述代码文件放置到对应的目录下。
配置 ThinkPHP 8 的路由,将
/product/query、/product/save、/product/update/:id和/product/delete/:id路由到对应的控制器方法。访问
public/index.html页面,即可进行产品数据的增删改查操作。
评论区