Merge remote-tracking branch 'origin/master'

This commit is contained in:
M_Kececi
2026-03-15 22:59:42 +03:00
parent 9c76a521c5
commit e2c04fab5d
3 changed files with 213 additions and 49 deletions

View File

@@ -37,6 +37,78 @@ func normalizeDimParam(v string) string {
return s
}
func uniqueNonEmpty(items ...string) []string {
out := make([]string, 0, len(items))
seen := make(map[string]struct{}, len(items))
for _, it := range items {
v := normalizeDimParam(it)
if v == "" {
continue
}
if _, ok := seen[v]; ok {
continue
}
seen[v] = struct{}{}
out = append(out, v)
}
return out
}
func buildNameLikePatterns(token string) []string {
t := strings.ToUpper(strings.TrimSpace(token))
if t == "" {
return nil
}
return []string{
"% " + t + " %",
"%-" + t + "-%",
"%-" + t + "_%",
"%_" + t + "_%",
"%(" + t + ")%",
t + " %",
}
}
func resolveDimvalFromFileNameToken(pg *sql.DB, column, token string) string {
patterns := buildNameLikePatterns(token)
if len(patterns) == 0 {
return ""
}
query := fmt.Sprintf(`
SELECT x.dimv
FROM (
SELECT COALESCE(%s::text, '') AS dimv, COUNT(*) AS cnt
FROM dfblob
WHERE src_table='mmitem'
AND typ='img'
AND COALESCE(%s::text, '') <> ''
AND (
UPPER(COALESCE(file_name,'')) LIKE $1 OR
UPPER(COALESCE(file_name,'')) LIKE $2 OR
UPPER(COALESCE(file_name,'')) LIKE $3 OR
UPPER(COALESCE(file_name,'')) LIKE $4 OR
UPPER(COALESCE(file_name,'')) LIKE $5 OR
UPPER(COALESCE(file_name,'')) LIKE $6
)
GROUP BY COALESCE(%s::text, '')
) x
ORDER BY x.cnt DESC, x.dimv
LIMIT 1
`, column, column, column)
var v string
if err := pg.QueryRow(query,
patterns[0],
patterns[1],
patterns[2],
patterns[3],
patterns[4],
patterns[5],
).Scan(&v); err != nil {
return ""
}
return normalizeDimParam(v)
}
func extractImageUUID(storagePath, fileName string) string {
if m := uuidPattern.FindString(storagePath); m != "" {
return strings.ToLower(m)
@@ -112,20 +184,8 @@ LIMIT 1
return
}
// Rule:
// dim1!=0 && dim3!=0 => dimval1=dim1 AND dimval3=dim3
// dim1!=0 && dim3==0 => dimval1=dim1
// dim1==0 && dim3==0 => generic photos
dim1Filter := normalizeDimParam(dim1ID)
if dim1Filter == "" {
dim1Filter = normalizeDimParam(dim1)
}
dim3Filter := normalizeDimParam(dim3ID)
if dim3Filter == "" {
dim3Filter = normalizeDimParam(dim3)
}
query := `
runQuery := func(dim1Filter, dim3Filter string) ([]ProductImageItem, error) {
query := `
SELECT
id,
COALESCE(file_name,'') AS file_name,
@@ -135,26 +195,110 @@ FROM dfblob
WHERE typ='img'
AND src_table='mmitem'
AND src_id=$1`
args := []interface{}{mmItemID}
argPos := 2
if dim1Filter != "" {
query += fmt.Sprintf(" AND COALESCE(dimval1::text,'') = $%d", argPos)
args = append(args, dim1Filter)
argPos++
if dim3Filter != "" {
query += fmt.Sprintf(" AND COALESCE(dimval3::text,'') = $%d", argPos)
args = append(args, dim3Filter)
args := []interface{}{mmItemID}
argPos := 2
if dim1Filter != "" {
query += fmt.Sprintf(" AND COALESCE(dimval1::text,'') = $%d", argPos)
args = append(args, dim1Filter)
argPos++
if dim3Filter != "" {
query += fmt.Sprintf(" AND COALESCE(dimval3::text,'') = $%d", argPos)
args = append(args, dim3Filter)
argPos++
}
}
}
query += `
query += `
ORDER BY
COALESCE(sort_order,999999),
zlins_dttm DESC,
id DESC`
rows, err := pg.Query(query, args...)
if err != nil {
rows, err := pg.Query(query, args...)
if err != nil {
return nil, err
}
defer rows.Close()
items := make([]ProductImageItem, 0, 16)
for rows.Next() {
var it ProductImageItem
if err := rows.Scan(&it.ID, &it.FileName, &it.FileSize, &it.Storage); err != nil {
continue
}
it.ContentURL = fmt.Sprintf("/api/product-images/%d/content", it.ID)
if u := extractImageUUID(it.Storage, it.FileName); u != "" {
it.UUID = u
it.ThumbURL = "/uploads/image/t300/" + u + ".jpg"
it.FullURL = "/uploads/image/" + u + ".jpg"
}
items = append(items, it)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
// Rule:
// dim1!=0 && dim3!=0 => dimval1=dim1 AND dimval3=dim3
// dim1!=0 && dim3==0 => dimval1=dim1
// dim1==0 && dim3==0 => generic photos
//
// Frontend'den yanlis dim id gelebildigi icin:
// 1) once *_id ile deneriz
// 2) sonuc yoksa kod degeriyle fallback deneriz.
resolvedDim1ID := normalizeDimParam(dim1ID)
if resolvedDim1ID == "" && normalizeDimParam(dim1) != "" {
resolvedDim1ID = resolveDimvalFromFileNameToken(pg, "dimval1", dim1)
}
resolvedDim3ID := normalizeDimParam(dim3ID)
if resolvedDim3ID == "" && normalizeDimParam(dim3) != "" {
resolvedDim3ID = resolveDimvalFromFileNameToken(pg, "dimval3", dim3)
}
dim1Candidates := uniqueNonEmpty(resolvedDim1ID, dim1ID, dim1)
if len(dim1Candidates) == 0 {
dim1Candidates = []string{""}
}
dim3Candidates := uniqueNonEmpty(resolvedDim3ID, dim3ID, dim3)
items := make([]ProductImageItem, 0, 16)
selectedDim1 := ""
selectedDim3 := ""
var queryErr error
for _, d1 := range dim1Candidates {
localDim3Candidates := []string{""}
if d1 != "" {
if len(dim3Candidates) > 0 {
localDim3Candidates = append([]string{}, dim3Candidates...)
localDim3Candidates = append(localDim3Candidates, "")
}
}
for _, d3 := range localDim3Candidates {
var runErr error
items, runErr = runQuery(d1, d3)
if runErr != nil {
queryErr = runErr
continue
}
if len(items) > 0 {
selectedDim1 = d1
selectedDim3 = d3
break
}
if selectedDim1 == "" && selectedDim3 == "" {
selectedDim1 = d1
selectedDim3 = d3
}
}
if len(items) > 0 {
break
}
}
if queryErr != nil && len(items) == 0 {
slog.Error("product_images.list.query_failed",
"req_id", reqID,
"code", code,
@@ -162,35 +306,23 @@ ORDER BY
"dim1_id", dim1ID,
"dim3", dim3,
"dim3_id", dim3ID,
"err", err.Error(),
"err", queryErr.Error(),
)
http.Error(w, "Gorsel sorgu hatasi: "+err.Error(), http.StatusInternalServerError)
http.Error(w, "Gorsel sorgu hatasi: "+queryErr.Error(), http.StatusInternalServerError)
return
}
defer rows.Close()
items := make([]ProductImageItem, 0, 16)
for rows.Next() {
var it ProductImageItem
if err := rows.Scan(&it.ID, &it.FileName, &it.FileSize, &it.Storage); err != nil {
continue
}
it.ContentURL = fmt.Sprintf("/api/product-images/%d/content", it.ID)
if u := extractImageUUID(it.Storage, it.FileName); u != "" {
it.UUID = u
it.ThumbURL = "/uploads/image/t300/" + u + ".jpg"
it.FullURL = "/uploads/image/" + u + ".jpg"
}
items = append(items, it)
}
slog.Info("product_images.list.ok",
"req_id", reqID,
"code", code,
"dim1", dim1,
"dim1_id", dim1ID,
"resolved_dim1_id", resolvedDim1ID,
"dim3", dim3,
"dim3_id", dim3ID,
"resolved_dim3_id", resolvedDim3ID,
"selected_dim1", selectedDim1,
"selected_dim3", selectedDim3,
"count", len(items),
)

View File

@@ -486,7 +486,15 @@ function resolvePhotoDim3(item, secondColorDisplay = '') {
}
function resolvePhotoDim1ID(item) {
const candidates = [item?.ItemDim1Code, item?.itemDim1Code, item?.ITEMDIM1CODE, item?.Beden]
const candidates = [
item?.PhotoDim1ID,
item?.photoDim1ID,
item?.Dim1ID,
item?.dim1ID,
item?.ColorID,
item?.colorID,
item?.RenkID
]
for (const value of candidates) {
const s = String(value || '').trim()
if (/^\d+$/.test(s)) return s
@@ -495,7 +503,15 @@ function resolvePhotoDim1ID(item) {
}
function resolvePhotoDim3ID(item) {
const candidates = [item?.ItemDim3Code, item?.itemDim3Code, item?.ITEMDIM3CODE, item?.Renk2]
const candidates = [
item?.PhotoDim3ID,
item?.photoDim3ID,
item?.Dim3ID,
item?.dim3ID,
item?.SecondColorID,
item?.secondColorID,
item?.Renk2ID
]
for (const value of candidates) {
const s = String(value || '').trim()
if (/^\d+$/.test(s)) return s

View File

@@ -479,7 +479,15 @@ function resolvePhotoDim3(item, secondColorDisplay = '') {
}
function resolvePhotoDim1ID(item) {
const candidates = [item?.ItemDim1Code, item?.itemDim1Code, item?.ITEMDIM1CODE, item?.Beden]
const candidates = [
item?.PhotoDim1ID,
item?.photoDim1ID,
item?.Dim1ID,
item?.dim1ID,
item?.ColorID,
item?.colorID,
item?.RenkID
]
for (const value of candidates) {
const s = String(value || '').trim()
if (/^\d+$/.test(s)) return s
@@ -488,7 +496,15 @@ function resolvePhotoDim1ID(item) {
}
function resolvePhotoDim3ID(item) {
const candidates = [item?.ItemDim3Code, item?.itemDim3Code, item?.ITEMDIM3CODE, item?.Renk2]
const candidates = [
item?.PhotoDim3ID,
item?.photoDim3ID,
item?.Dim3ID,
item?.dim3ID,
item?.SecondColorID,
item?.secondColorID,
item?.Renk2ID
]
for (const value of candidates) {
const s = String(value || '').trim()
if (/^\d+$/.test(s)) return s