You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
220 lines
6.1 KiB
220 lines
6.1 KiB
package db |
|
|
|
import ( |
|
"changeme/model" |
|
"database/sql" |
|
"errors" |
|
"fmt" |
|
"reflect" |
|
"strings" |
|
"sync" |
|
|
|
"github.com/gogf/gf/v2/util/gconv" |
|
_ "github.com/mattn/go-sqlite3" |
|
) |
|
|
|
// DB 结构体 |
|
type DB struct { |
|
*sql.DB |
|
} |
|
|
|
var ( |
|
instance *DB |
|
once sync.Once |
|
) |
|
var TableName = "photo_studio_shoot_order" |
|
// GetInstance 返回数据库单例实例 |
|
func GetInstance() *DB { |
|
once.Do(func() { |
|
db, err := sql.Open("sqlite3", "test.db") |
|
if err != nil { |
|
panic(err) |
|
} |
|
instance = &DB{db} |
|
//检测表是否存在 |
|
checkTableSQL := `SELECT count(*) FROM sqlite_master WHERE type='table' AND name='`+TableName+`';` |
|
var count int |
|
if err := instance.QueryRow(checkTableSQL).Scan(&count); err != nil { |
|
panic(err) |
|
} |
|
if count > 0 { |
|
return |
|
} |
|
// 创建表 |
|
createTableSQL := `CREATE TABLE "`+TableName+`" ( |
|
"id" INTEGER NOT NULL, |
|
"pid" INTEGER NOT NULL, |
|
"customer_id" INTEGER NOT NULL, |
|
"customer_name" TEXT NOT NULL, |
|
"status" INTEGER NOT NULL, |
|
"order_id" INTEGER NOT NULL, |
|
"digital_order_id" INTEGER NOT NULL, |
|
"digital_type" INTEGER NOT NULL, |
|
"cover_path" TEXT NOT NULL, |
|
"cover_rotate_deg" INTEGER NOT NULL, |
|
"shoot_at_count" INTEGER NOT NULL, |
|
"shoot_done_count" INTEGER NOT NULL, |
|
"upload_cover_count" INTEGER NOT NULL, |
|
"upload_highmode_count" INTEGER NOT NULL, |
|
"upload_yuv_count" INTEGER NOT NULL, |
|
"first_shoot_at" DATETIME NULL, |
|
"first_shoot_done_at" DATETIME NULL, |
|
"last_shoot_at" DATETIME NULL, |
|
"last_shoot_done_at" DATETIME NULL, |
|
"check_status" INTEGER NOT NULL, |
|
"check_fail_reason" TEXT NOT NULL, |
|
"check_at" DATETIME NULL, |
|
"shop_id" INTEGER NOT NULL, |
|
"eq_id" INTEGER NOT NULL, |
|
"master_ver" TEXT NOT NULL, |
|
"eq_type" INTEGER NOT NULL, |
|
"created_at" DATETIME NULL, |
|
"upload_done_at" DATETIME NULL, |
|
"minipreview_upload_done_at" DATETIME NULL, |
|
"updated_at" DATETIME NULL, |
|
"is_privary" INTEGER NOT NULL, |
|
"cancel_at" DATETIME NULL, |
|
PRIMARY KEY ("id") |
|
);` |
|
if _, err = instance.Exec(createTableSQL); err != nil { |
|
panic(err) |
|
} |
|
}) |
|
return instance |
|
} |
|
|
|
|
|
//Add 新增数据 |
|
func (db *DB) Add(addData *model.AddData) error { |
|
v := reflect.ValueOf(addData) |
|
// 确保传入的参数是指向结构体的指针 |
|
if v.Kind() != reflect.Ptr || v.Elem().Kind() != reflect.Struct { |
|
return errors.New("invalid input") |
|
} |
|
// 获取结构体的类型和字段 |
|
t := v.Elem().Type() |
|
fields := []string{} |
|
placeholders := []string{} |
|
values := []interface{}{} |
|
|
|
for i := 0; i < v.Elem().NumField(); i++ { |
|
field := t.Field(i) |
|
value := v.Elem().Field(i) |
|
// 使用 db 标签作为字段名 |
|
dbTag := field.Tag.Get("json") |
|
fields = append(fields, dbTag) |
|
placeholders = append(placeholders, "?") |
|
values = append(values, value.Interface()) |
|
} |
|
// 生成 SQL 语句 |
|
sqlStatement := fmt.Sprintf("INSERT INTO %s (%s) VALUES (%s)", |
|
TableName, |
|
strings.Join(fields, ", "), |
|
strings.Join(placeholders, ", ")) |
|
// 执行 SQL 语句 |
|
_, err := db.Exec(sqlStatement, values...) |
|
return err |
|
} |
|
|
|
//根据查询列表数据 |
|
// List 方法 |
|
func (db *DB) List(req *model.PageReqData) (list []*model.Data, err error) { |
|
// 基本的 SQL 查询语句 |
|
query := "SELECT cover_path,pid,customer_name FROM "+TableName+" WHERE 1=1" |
|
var args []interface{} |
|
|
|
// 根据请求参数动态构建查询条件 |
|
if req.Pid > 0 { |
|
query += " AND pid = ?" |
|
args = append(args, req.Pid) |
|
} |
|
if req.CustomerId > 0 { |
|
query += " AND customer_id = ?" |
|
args = append(args, req.CustomerId) |
|
} |
|
if req.CustomerName != "" { |
|
query += " AND customer_name LIKE ?" |
|
args = append(args, "%"+req.CustomerName+"%") |
|
} |
|
if req.Status > 0 { |
|
query += " AND status = ?" |
|
args = append(args, req.Status) |
|
} |
|
|
|
// 添加分页条件 |
|
if req.Page <= 0 { |
|
req.Page = 1 |
|
} |
|
if req.Size <= 0 { |
|
req.Size = 20 |
|
} |
|
offset := (req.Page - 1) * req.Size |
|
query += fmt.Sprintf(" LIMIT %d OFFSET %d", req.Size, offset) |
|
// 执行查询 |
|
rows, err := db.Query(query, args...) |
|
if err != nil { |
|
return nil, err |
|
} |
|
defer rows.Close() |
|
|
|
// 读取查询结果 |
|
for rows.Next() { |
|
var addData model.Data |
|
if err := rows.Scan(&addData.CoverPath, &addData.Pid, &addData.CustomerName); err != nil { |
|
return nil, err |
|
} |
|
list = append(list, &addData) |
|
} |
|
return list, nil |
|
} |
|
|
|
func (db *DB) Delete(req *model.DeleteReqData) (err error) { |
|
if req.Pid == 0 && req.Id == 0 { |
|
return errors.New("参数不能为空") |
|
} |
|
query := "DELETE FROM "+TableName+" WHERE 1=1" |
|
var args []interface{} |
|
if req.Pid > 0 { |
|
query += " AND pid = ?" |
|
args = append(args, req.Pid) |
|
} |
|
if req.Id > 0 { |
|
query += " AND id = ?" |
|
args = append(args, req.Id) |
|
} |
|
_, err = db.Exec(query, args...) |
|
return err |
|
} |
|
|
|
func (db *DB) Update(addData *model.Data) error { |
|
v := reflect.ValueOf(addData) |
|
// 确保传入的参数是指向结构体的指针 |
|
if v.Kind() != reflect.Ptr || v.Elem().Kind() != reflect.Struct { |
|
return errors.New("invalid input") |
|
} |
|
|
|
// 获取结构体的类型和字段 |
|
t := v.Elem().Type() |
|
fields := []string{} |
|
values := []interface{}{} |
|
|
|
for i := 0; i < v.Elem().NumField(); i++ { |
|
field := t.Field(i) |
|
value := v.Elem().Field(i) |
|
// 使用 db 标签作为字段名 |
|
dbTag := field.Tag.Get("json") |
|
if gconv.String(value.Interface()) != "" && gconv.String(value.Interface()) != "0" && dbTag != "id" { |
|
fields = append(fields, fmt.Sprintf("%s = ?", dbTag)) |
|
values = append(values, value.Interface()) |
|
} |
|
} |
|
// 生成 Update SQL 语句 |
|
sqlStatement := fmt.Sprintf("UPDATE %s SET %s WHERE id = %s", |
|
TableName, |
|
strings.Join(fields, ", "), |
|
gconv.String(addData.Id), |
|
) |
|
// 执行 SQL 语句 |
|
_, err := db.Exec(sqlStatement, values...) |
|
return err |
|
} |