채번 자동생성기능

This commit is contained in:
kjs
2025-11-04 17:35:02 +09:00
parent b8e30c9557
commit 198f678b68
14 changed files with 808 additions and 171 deletions

View File

@@ -84,7 +84,7 @@ export const EnhancedInteractiveScreenViewer: React.FC<EnhancedInteractiveScreen
// 자동값 생성 함수
const generateAutoValue = useCallback(
(autoValueType: string): string => {
async (autoValueType: string, ruleId?: string): Promise<string> => {
const now = new Date();
switch (autoValueType) {
case "current_datetime":
@@ -99,6 +99,20 @@ export const EnhancedInteractiveScreenViewer: React.FC<EnhancedInteractiveScreen
return crypto.randomUUID();
case "sequence":
return `SEQ_${Date.now()}`;
case "numbering_rule":
// 채번 규칙 사용
if (ruleId) {
try {
const { generateNumberingCode } = await import("@/lib/api/numberingRule");
const response = await generateNumberingCode(ruleId);
if (response.success && response.data) {
return response.data.generatedCode;
}
} catch (error) {
console.error("채번 규칙 코드 생성 실패:", error);
}
}
return "";
default:
return "";
}
@@ -129,24 +143,32 @@ export const EnhancedInteractiveScreenViewer: React.FC<EnhancedInteractiveScreen
// 자동값 설정
useEffect(() => {
const widgetComponents = allComponents.filter((c) => c.type === "widget") as WidgetComponent[];
const autoValueUpdates: Record<string, any> = {};
const loadAutoValues = async () => {
const autoValueUpdates: Record<string, any> = {};
for (const widget of widgetComponents) {
const fieldName = widget.columnName || widget.id;
const currentValue = finalFormData[fieldName];
for (const widget of widgetComponents) {
const fieldName = widget.columnName || widget.id;
const currentValue = finalFormData[fieldName];
// 자동값이 설정되어 있고 현재 값이 없는 경우
if (widget.inputType === "auto" && widget.autoValueType && !currentValue) {
const autoValue = generateAutoValue(widget.autoValueType);
if (autoValue) {
autoValueUpdates[fieldName] = autoValue;
// 자동값이 설정되어 있고 현재 값이 없는 경우
if (widget.inputType === "auto" && widget.autoValueType && !currentValue) {
const autoValue = await generateAutoValue(
widget.autoValueType,
(widget as any).numberingRuleId // 채번 규칙 ID
);
if (autoValue) {
autoValueUpdates[fieldName] = autoValue;
}
}
}
}
if (Object.keys(autoValueUpdates).length > 0) {
setLocalFormData((prev) => ({ ...prev, ...autoValueUpdates }));
}
if (Object.keys(autoValueUpdates).length > 0) {
setLocalFormData((prev) => ({ ...prev, ...autoValueUpdates }));
}
};
loadAutoValues();
}, [allComponents, finalFormData, generateAutoValue]);
// 향상된 저장 핸들러

View File

@@ -136,7 +136,7 @@ export const InteractiveScreenViewer: React.FC<InteractiveScreenViewerProps> = (
: null;
// 자동값 생성 함수
const generateAutoValue = useCallback((autoValueType: string): string => {
const generateAutoValue = useCallback(async (autoValueType: string, ruleId?: string): Promise<string> => {
const now = new Date();
switch (autoValueType) {
case "current_datetime":
@@ -152,6 +152,20 @@ export const InteractiveScreenViewer: React.FC<InteractiveScreenViewerProps> = (
return crypto.randomUUID();
case "sequence":
return `SEQ_${Date.now()}`;
case "numbering_rule":
// 채번 규칙 사용
if (ruleId) {
try {
const { generateNumberingCode } = await import("@/lib/api/numberingRule");
const response = await generateNumberingCode(ruleId);
if (response.success && response.data) {
return response.data.generatedCode;
}
} catch (error) {
console.error("채번 규칙 코드 생성 실패:", error);
}
}
return "";
default:
return "";
}

View File

@@ -7,6 +7,8 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@
import { Checkbox } from "@/components/ui/checkbox";
import { Textarea } from "@/components/ui/textarea";
import { TextTypeConfig } from "@/types/screen";
import { getAvailableNumberingRules } from "@/lib/api/numberingRule";
import { NumberingRuleConfig } from "@/types/numbering-rule";
interface TextTypeConfigPanelProps {
config: TextTypeConfig;
@@ -26,9 +28,14 @@ export const TextTypeConfigPanel: React.FC<TextTypeConfigPanelProps> = ({ config
autoInput: false,
autoValueType: "current_datetime" as const,
customValue: "",
numberingRuleId: "",
...config,
};
// 채번 규칙 목록 상태
const [numberingRules, setNumberingRules] = useState<NumberingRuleConfig[]>([]);
const [loadingRules, setLoadingRules] = useState(false);
// 로컬 상태로 실시간 입력 관리
const [localValues, setLocalValues] = useState({
minLength: safeConfig.minLength?.toString() || "",
@@ -41,8 +48,33 @@ export const TextTypeConfigPanel: React.FC<TextTypeConfigPanelProps> = ({ config
autoInput: safeConfig.autoInput,
autoValueType: safeConfig.autoValueType,
customValue: safeConfig.customValue,
numberingRuleId: safeConfig.numberingRuleId,
});
// 채번 규칙 목록 로드
useEffect(() => {
const loadRules = async () => {
setLoadingRules(true);
try {
// TODO: 현재 메뉴 objid를 화면 정보에서 가져와야 함
// 지금은 menuObjid 없이 호출 (global 규칙만 조회)
const response = await getAvailableNumberingRules();
if (response.success && response.data) {
setNumberingRules(response.data);
}
} catch (error) {
console.error("채번 규칙 목록 로드 실패:", error);
} finally {
setLoadingRules(false);
}
};
// autoValueType이 numbering_rule일 때만 로드
if (localValues.autoValueType === "numbering_rule") {
loadRules();
}
}, [localValues.autoValueType]);
// config가 변경될 때 로컬 상태 동기화
useEffect(() => {
setLocalValues({
@@ -56,6 +88,7 @@ export const TextTypeConfigPanel: React.FC<TextTypeConfigPanelProps> = ({ config
autoInput: safeConfig.autoInput,
autoValueType: safeConfig.autoValueType,
customValue: safeConfig.customValue,
numberingRuleId: safeConfig.numberingRuleId,
});
}, [
safeConfig.minLength,
@@ -68,6 +101,7 @@ export const TextTypeConfigPanel: React.FC<TextTypeConfigPanelProps> = ({ config
safeConfig.autoInput,
safeConfig.autoValueType,
safeConfig.customValue,
safeConfig.numberingRuleId,
]);
const updateConfig = (key: keyof TextTypeConfig, value: any) => {
@@ -90,16 +124,10 @@ export const TextTypeConfigPanel: React.FC<TextTypeConfigPanelProps> = ({ config
autoInput: key === "autoInput" ? value : localValues.autoInput,
autoValueType: key === "autoValueType" ? value : localValues.autoValueType,
customValue: key === "customValue" ? value : localValues.customValue,
numberingRuleId: key === "numberingRuleId" ? value : localValues.numberingRuleId,
};
const newConfig = JSON.parse(JSON.stringify(currentValues));
// console.log("📝 TextTypeConfig 업데이트:", {
// key,
// value,
// oldConfig: safeConfig,
// newConfig,
// localValues,
// });
setTimeout(() => {
onConfigChange(newConfig);
@@ -236,11 +264,45 @@ export const TextTypeConfigPanel: React.FC<TextTypeConfigPanelProps> = ({ config
<SelectItem value="current_user"> </SelectItem>
<SelectItem value="uuid"> ID (UUID)</SelectItem>
<SelectItem value="sequence"></SelectItem>
<SelectItem value="numbering_rule"> </SelectItem>
<SelectItem value="custom"> </SelectItem>
</SelectContent>
</Select>
</div>
{localValues.autoValueType === "numbering_rule" && (
<div>
<Label htmlFor="numberingRuleId" className="text-sm font-medium">
<span className="text-destructive">*</span>
</Label>
<Select
value={localValues.numberingRuleId}
onValueChange={(value) => updateConfig("numberingRuleId", value)}
disabled={loadingRules}
>
<SelectTrigger className="mt-1 h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}>
<SelectValue placeholder={loadingRules ? "규칙 로딩 중..." : "채번 규칙 선택"} />
</SelectTrigger>
<SelectContent>
{numberingRules.length === 0 ? (
<SelectItem value="no-rules" disabled>
</SelectItem>
) : (
numberingRules.map((rule) => (
<SelectItem key={rule.ruleId} value={rule.ruleId}>
{rule.ruleName} ({rule.ruleId})
</SelectItem>
))
)}
</SelectContent>
</Select>
<p className="text-muted-foreground mt-1 text-[10px]">
</p>
</div>
)}
{localValues.autoValueType === "custom" && (
<div>
<Label htmlFor="customValue" className="text-sm font-medium">