diff --git a/apps/wpmw/views.py b/apps/wpmw/views.py index f8582c9d..60c51b69 100644 --- a/apps/wpmw/views.py +++ b/apps/wpmw/views.py @@ -1,3 +1,4 @@ +import re from rest_framework.decorators import action from apps.utils.viewsets import CustomModelViewSet, CustomGenericViewSet from apps.utils.mixins import CustomListModelMixin, CustomRetrieveModelMixin, ComplexQueryMixin, BulkUpdateModelMixin @@ -101,18 +102,19 @@ class WprViewSet(BulkUpdateModelMixin, CustomListModelMixin, CustomRetrieveModel with_unsubmit = request.query_params.get("with_unsubmit", "yes") # wpr_qs_last = Wpr.objects.filter(number_out__startswith=prefix).order_by("number_out").last() # 使用原始sql + # 编号格式为"前缀+补零数字"(无分隔符,如 'FS01'/'FS00025',前端也按此规则拼接)。 + # 用 ^[0-9]+$ 约束前缀后必须紧跟纯数字,避免 'FS' 误命中 'FSM00027' 这类更长前缀; + # 并按尾部数字的数值(而非字符串)排序取最大,避免补零位数不一致时取错。 query = """ - SELECT id, number_out FROM wpmw_wpr + SELECT id, number_out FROM wpmw_wpr WHERE number_out LIKE %s - AND translate( - substring(number_out FROM LENGTH(%s) + 2), - '0123456789', - '' - ) = '' - order by number_out desc limit 1 + AND substring(number_out FROM LENGTH(%s) + 1) ~ '^[0-9]+$' + ORDER BY (substring(number_out FROM LENGTH(%s) + 1))::bigint DESC + LIMIT 1 """ params = ( - f"{prefix}-%", + f"{prefix}%", + prefix, prefix ) number_outs = [] @@ -127,25 +129,23 @@ class WprViewSet(BulkUpdateModelMixin, CustomListModelMixin, CustomRetrieveModel select mioitemw.id, mioitemw.number_out from inm_mioitemw mioitemw left join inm_mioitem mioitem on mioitem.id = mioitemw.mioitem_id left join inm_mio mio on mio.id = mioitem.mio_id where mio.submit_time is null and mioitemw.number_out LIKE %s - AND translate( - substring(mioitemw.number_out FROM LENGTH(%s) + 2), - '0123456789', - '' - ) = '' - order by mioitemw.number_out desc limit 1 + AND substring(mioitemw.number_out FROM LENGTH(%s) + 1) ~ '^[0-9]+$' + ORDER BY (substring(mioitemw.number_out FROM LENGTH(%s) + 1))::bigint DESC + LIMIT 1 """ mioitemw_last = query_one_dict(query2, params) if mioitemw_last: number_outs.append(mioitemw_last["number_out"]) if number_outs: - number_outs.sort() + # 按尾部数字的数值取最大(与前端一致:去掉非数字字符后作为流水号) + number_outs.sort(key=lambda n: int(re.sub(r"\D", "", n))) number_out_last = number_outs[-1] - number_int_last = number_out_last.lstrip(prefix).lstrip("0") + number_int_last = re.sub(r"\D", "", number_out_last) try: number_int_last = int(number_int_last) except ValueError: - raise ParseError(f"找到 {number_int_last}, 请检查前缀格式") - return Response({"number_out_last": number_out_last, "number_out_int_last": int(number_int_last)}) + raise ParseError(f"找到 {number_out_last}, 请检查前缀格式") + return Response({"number_out_last": number_out_last, "number_out_int_last": number_int_last}) else: return Response({"number_out_last": None})