Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -37,6 +37,78 @@ func normalizeDimParam(v string) string {
|
|||||||
return s
|
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 {
|
func extractImageUUID(storagePath, fileName string) string {
|
||||||
if m := uuidPattern.FindString(storagePath); m != "" {
|
if m := uuidPattern.FindString(storagePath); m != "" {
|
||||||
return strings.ToLower(m)
|
return strings.ToLower(m)
|
||||||
@@ -112,19 +184,7 @@ LIMIT 1
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rule:
|
runQuery := func(dim1Filter, dim3Filter string) ([]ProductImageItem, error) {
|
||||||
// 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 := `
|
query := `
|
||||||
SELECT
|
SELECT
|
||||||
id,
|
id,
|
||||||
@@ -155,17 +215,7 @@ ORDER BY
|
|||||||
|
|
||||||
rows, err := pg.Query(query, args...)
|
rows, err := pg.Query(query, args...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error("product_images.list.query_failed",
|
return nil, err
|
||||||
"req_id", reqID,
|
|
||||||
"code", code,
|
|
||||||
"dim1", dim1,
|
|
||||||
"dim1_id", dim1ID,
|
|
||||||
"dim3", dim3,
|
|
||||||
"dim3_id", dim3ID,
|
|
||||||
"err", err.Error(),
|
|
||||||
)
|
|
||||||
http.Error(w, "Gorsel sorgu hatasi: "+err.Error(), http.StatusInternalServerError)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
|
|
||||||
@@ -183,14 +233,96 @@ ORDER BY
|
|||||||
}
|
}
|
||||||
items = append(items, it)
|
items = append(items, it)
|
||||||
}
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return items, nil
|
||||||
|
}
|
||||||
|
|
||||||
slog.Info("product_images.list.ok",
|
// 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,
|
"req_id", reqID,
|
||||||
"code", code,
|
"code", code,
|
||||||
"dim1", dim1,
|
"dim1", dim1,
|
||||||
"dim1_id", dim1ID,
|
"dim1_id", dim1ID,
|
||||||
"dim3", dim3,
|
"dim3", dim3,
|
||||||
"dim3_id", dim3ID,
|
"dim3_id", dim3ID,
|
||||||
|
"err", queryErr.Error(),
|
||||||
|
)
|
||||||
|
http.Error(w, "Gorsel sorgu hatasi: "+queryErr.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
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),
|
"count", len(items),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -486,7 +486,15 @@ function resolvePhotoDim3(item, secondColorDisplay = '') {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function resolvePhotoDim1ID(item) {
|
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) {
|
for (const value of candidates) {
|
||||||
const s = String(value || '').trim()
|
const s = String(value || '').trim()
|
||||||
if (/^\d+$/.test(s)) return s
|
if (/^\d+$/.test(s)) return s
|
||||||
@@ -495,7 +503,15 @@ function resolvePhotoDim1ID(item) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function resolvePhotoDim3ID(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) {
|
for (const value of candidates) {
|
||||||
const s = String(value || '').trim()
|
const s = String(value || '').trim()
|
||||||
if (/^\d+$/.test(s)) return s
|
if (/^\d+$/.test(s)) return s
|
||||||
|
|||||||
@@ -479,7 +479,15 @@ function resolvePhotoDim3(item, secondColorDisplay = '') {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function resolvePhotoDim1ID(item) {
|
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) {
|
for (const value of candidates) {
|
||||||
const s = String(value || '').trim()
|
const s = String(value || '').trim()
|
||||||
if (/^\d+$/.test(s)) return s
|
if (/^\d+$/.test(s)) return s
|
||||||
@@ -488,7 +496,15 @@ function resolvePhotoDim1ID(item) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function resolvePhotoDim3ID(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) {
|
for (const value of candidates) {
|
||||||
const s = String(value || '').trim()
|
const s = String(value || '').trim()
|
||||||
if (/^\d+$/.test(s)) return s
|
if (/^\d+$/.test(s)) return s
|
||||||
|
|||||||
Reference in New Issue
Block a user