20241019165800
This commit is contained in:
parent
11b7c0dc2f
commit
c2427efb42
112
main.py
112
main.py
|
@ -13,12 +13,12 @@ import pywintypes
|
||||||
import hashlib
|
import hashlib
|
||||||
import win32com.client
|
import win32com.client
|
||||||
import win32print
|
import win32print
|
||||||
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QLabel, QComboBox, QCheckBox, QLineEdit, QAction, QMenu, QMessageBox, QPushButton, QVBoxLayout, QHBoxLayout, QFileDialog
|
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QLabel, QComboBox, QCheckBox, QLineEdit, QAction, QMenu, \
|
||||||
from PyQt5.QtCore import Qt, QCoreApplication
|
QMessageBox, QPushButton, QVBoxLayout, QHBoxLayout, QFileDialog, QDialog
|
||||||
|
from PyQt5.QtCore import Qt, QCoreApplication, QTimer, QPropertyAnimation
|
||||||
from PyQt5.QtGui import QPixmap, QIntValidator
|
from PyQt5.QtGui import QPixmap, QIntValidator
|
||||||
from threading import RLock
|
from threading import RLock
|
||||||
|
|
||||||
|
|
||||||
sys.path.append(os.path.dirname(__file__))
|
sys.path.append(os.path.dirname(__file__))
|
||||||
clr.AddReference('BarTender')
|
clr.AddReference('BarTender')
|
||||||
try:
|
try:
|
||||||
|
@ -93,12 +93,14 @@ if os.name == 'nt':
|
||||||
|
|
||||||
PVOID = c_void_p
|
PVOID = c_void_p
|
||||||
|
|
||||||
|
|
||||||
class _OFFSET(Structure):
|
class _OFFSET(Structure):
|
||||||
_fields_ = [
|
_fields_ = [
|
||||||
('Offset', DWORD),
|
('Offset', DWORD),
|
||||||
('OffsetHigh', DWORD)
|
('OffsetHigh', DWORD)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class _OFFSET_UNION(Union):
|
class _OFFSET_UNION(Union):
|
||||||
_fields_ = [
|
_fields_ = [
|
||||||
('_offset', _OFFSET),
|
('_offset', _OFFSET),
|
||||||
|
@ -106,6 +108,7 @@ if os.name == 'nt':
|
||||||
]
|
]
|
||||||
_anonymous_ = ['_offset']
|
_anonymous_ = ['_offset']
|
||||||
|
|
||||||
|
|
||||||
class OVERLAPPED(Structure):
|
class OVERLAPPED(Structure):
|
||||||
_fields_ = [
|
_fields_ = [
|
||||||
('Internal', ULONG_PTR),
|
('Internal', ULONG_PTR),
|
||||||
|
@ -115,6 +118,7 @@ if os.name == 'nt':
|
||||||
]
|
]
|
||||||
_anonymous_ = ['_offset_union']
|
_anonymous_ = ['_offset_union']
|
||||||
|
|
||||||
|
|
||||||
LPOVERLAPPED = POINTER(OVERLAPPED)
|
LPOVERLAPPED = POINTER(OVERLAPPED)
|
||||||
LockFileEx = windll.kernel32.LockFileEx
|
LockFileEx = windll.kernel32.LockFileEx
|
||||||
LockFileEx.restype = BOOL
|
LockFileEx.restype = BOOL
|
||||||
|
@ -148,6 +152,7 @@ if os.name == 'nt':
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
import fcntl
|
import fcntl
|
||||||
|
|
||||||
LOCK_SH = fcntl.LOCK_SH
|
LOCK_SH = fcntl.LOCK_SH
|
||||||
LOCK_NB = fcntl.LOCK_NB
|
LOCK_NB = fcntl.LOCK_NB
|
||||||
LOCK_EX = fcntl.LOCK_EX
|
LOCK_EX = fcntl.LOCK_EX
|
||||||
|
@ -155,6 +160,7 @@ else:
|
||||||
except (ImportError, AttributeError):
|
except (ImportError, AttributeError):
|
||||||
LOCK_EX = LOCK_SH = LOCK_NB = 0
|
LOCK_EX = LOCK_SH = LOCK_NB = 0
|
||||||
|
|
||||||
|
|
||||||
def flock(f, flags):
|
def flock(f, flags):
|
||||||
return flags == LOCK_UN
|
return flags == LOCK_UN
|
||||||
else:
|
else:
|
||||||
|
@ -454,10 +460,13 @@ class BarTenderPrint:
|
||||||
self.bt_format.PrintOut(False, False)
|
self.bt_format.PrintOut(False, False)
|
||||||
|
|
||||||
def generate_preview(self):
|
def generate_preview(self):
|
||||||
path = os.path.abspath(os.path.join(tempfile.gettempdir(), '%s%s.png' % ('preview_', int(round(time.time() * 1000)))))
|
path = os.path.abspath(
|
||||||
|
os.path.join(tempfile.gettempdir(), '%s%s.png' % ('preview_', int(round(time.time() * 1000)))))
|
||||||
if (self.bt_format is not None) == 1:
|
if (self.bt_format is not None) == 1:
|
||||||
self.logger.i('%s%s' % ('Generate preview to ', path))
|
self.logger.i('%s%s' % ('Generate preview to ', path))
|
||||||
self.bt_format.ExportToFile(path, 'PNG', BarTender.BtColors.btColors24Bit, BarTender.BtResolution.btResolutionPrinter, BarTender.BtSaveOptions.btDoNotSaveChanges)
|
self.bt_format.ExportToFile(path, 'PNG', BarTender.BtColors.btColors24Bit,
|
||||||
|
BarTender.BtResolution.btResolutionPrinter,
|
||||||
|
BarTender.BtSaveOptions.btDoNotSaveChanges)
|
||||||
return path
|
return path
|
||||||
|
|
||||||
def quit(self):
|
def quit(self):
|
||||||
|
@ -518,7 +527,8 @@ class CustomPushButton(QPushButton):
|
||||||
class CustomLabel(QLabel):
|
class CustomLabel(QLabel):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
self.setStyleSheet('font-size: 12px; font-family: \'Microsoft YaHei\'; color: #0C0C0C; border: 1px solid #0C0C0C;')
|
self.setStyleSheet(
|
||||||
|
'font-size: 12px; font-family: \'Microsoft YaHei\'; color: #0C0C0C; border: 1px solid #0C0C0C;')
|
||||||
|
|
||||||
|
|
||||||
class CustomComboBox(QComboBox):
|
class CustomComboBox(QComboBox):
|
||||||
|
@ -549,12 +559,17 @@ class MainWindow(QMainWindow):
|
||||||
def __init__(self, logger: Logger):
|
def __init__(self, logger: Logger):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.app_name = '标签打印'
|
self.app_name = '标签打印'
|
||||||
self.app_version = ('1.0.3', '20240810', 'zhaoyafan', 'zhaoyafan@foxmail.com', 'https://www.fanscloud.net/')
|
self.app_version = ('1.0.4', '20241019', 'zhaoyafan', 'zhaoyafan@foxmail.com', 'https://www.fanscloud.net/')
|
||||||
self.logger = logger
|
self.logger = logger
|
||||||
self.setting = Setting(os.path.abspath(os.path.join(tempfile.gettempdir(), '%s.config' % self.md5(__file__)[:16])), {})
|
self.toast = ToastNotification()
|
||||||
|
self.setting = Setting(
|
||||||
|
os.path.abspath(os.path.join(tempfile.gettempdir(), '%s.config' % self.md5(__file__)[:16])), {})
|
||||||
self.bt = BarTenderPrint(logger=self.logger)
|
self.bt = BarTenderPrint(logger=self.logger)
|
||||||
self.sv = ScanVerify(logger=self.logger, rule_file=os.path.abspath(os.path.join(os.path.dirname(__file__), 'rules.json')))
|
self.sv = ScanVerify(logger=self.logger,
|
||||||
self.ditto = Ditto(db_file=os.path.abspath(os.path.join(tempfile.gettempdir(), '%s.db' % self.md5(__file__)[:16])), class_name='LabelPrint', limit_time=7776000, limit_rows=100000)
|
rule_file=os.path.abspath(os.path.join(os.path.dirname(__file__), 'rules.json')))
|
||||||
|
self.ditto = Ditto(
|
||||||
|
db_file=os.path.abspath(os.path.join(tempfile.gettempdir(), '%s.db' % self.md5(__file__)[:16])),
|
||||||
|
class_name='LabelPrint', limit_time=7776000, limit_rows=100000)
|
||||||
self.last_opened_template = ['', '']
|
self.last_opened_template = ['', '']
|
||||||
self.input_convert_letter = 0
|
self.input_convert_letter = 0
|
||||||
self.input_scan_prohibited_enter = 0
|
self.input_scan_prohibited_enter = 0
|
||||||
|
@ -666,7 +681,8 @@ class MainWindow(QMainWindow):
|
||||||
r_layout_2.addWidget(self.chkDET)
|
r_layout_2.addWidget(self.chkDET)
|
||||||
# Scan
|
# Scan
|
||||||
self.edtSCN = CustomLineEdit('')
|
self.edtSCN = CustomLineEdit('')
|
||||||
self.edtSCN.setStyleSheet('QLineEdit {font-size: 28px; font-family: \'Microsoft YaHei\'; color: #000000; background-color: #FFFFCC;}')
|
self.edtSCN.setStyleSheet(
|
||||||
|
'QLineEdit {font-size: 28px; font-family: \'Microsoft YaHei\'; color: #000000; background-color: #FFFFCC;}')
|
||||||
self.edtSCN.setFixedSize(455, 45)
|
self.edtSCN.setFixedSize(455, 45)
|
||||||
r_layout_3.addWidget(self.edtSCN)
|
r_layout_3.addWidget(self.edtSCN)
|
||||||
# Print button
|
# Print button
|
||||||
|
@ -683,7 +699,8 @@ class MainWindow(QMainWindow):
|
||||||
self.setFixedSize(self.minimumSizeHint())
|
self.setFixedSize(self.minimumSizeHint())
|
||||||
screen_rect = QApplication.desktop().availableGeometry()
|
screen_rect = QApplication.desktop().availableGeometry()
|
||||||
window_rect = self.geometry()
|
window_rect = self.geometry()
|
||||||
self.move(int((screen_rect.width() - window_rect.width()) * 0.5), int((screen_rect.height() - window_rect.height()) * 0.5))
|
self.move(int((screen_rect.width() - window_rect.width()) * 0.5),
|
||||||
|
int((screen_rect.height() - window_rect.height()) * 0.5))
|
||||||
self.edtSCN.setFocus()
|
self.edtSCN.setFocus()
|
||||||
self.show()
|
self.show()
|
||||||
self.load_setting()
|
self.load_setting()
|
||||||
|
@ -696,7 +713,8 @@ class MainWindow(QMainWindow):
|
||||||
# load blockRepeat
|
# load blockRepeat
|
||||||
self.blockRepeatAction.setChecked(bool(self.setting['blockRepeat']))
|
self.blockRepeatAction.setChecked(bool(self.setting['blockRepeat']))
|
||||||
# load printer
|
# load printer
|
||||||
self.slcSPT.setCurrentIndex(next((index for index, item in enumerate(self.bt.printer_list) if item == self.setting['printer']), 0))
|
self.slcSPT.setCurrentIndex(
|
||||||
|
next((index for index, item in enumerate(self.bt.printer_list) if item == self.setting['printer']), 0))
|
||||||
# load checker
|
# load checker
|
||||||
self.slcSVR.setCurrentIndex(self.setting['checker'] or 0)
|
self.slcSVR.setCurrentIndex(self.setting['checker'] or 0)
|
||||||
# load printCopies
|
# load printCopies
|
||||||
|
@ -714,7 +732,7 @@ class MainWindow(QMainWindow):
|
||||||
def clearRecordActionFunction(self):
|
def clearRecordActionFunction(self):
|
||||||
count = self.ditto.clear()
|
count = self.ditto.clear()
|
||||||
if (count > 0) == 1:
|
if (count > 0) == 1:
|
||||||
QMessageBox.information(self, '提示', '打印记录已经清空:%s' % (count,))
|
self.toast.show_toast('已成功清空%s条打印记录' % (count,))
|
||||||
|
|
||||||
def designStateActionFunction(self, checked):
|
def designStateActionFunction(self, checked):
|
||||||
if (not self.bt.bt_app) == 1:
|
if (not self.bt.bt_app) == 1:
|
||||||
|
@ -745,7 +763,8 @@ class MainWindow(QMainWindow):
|
||||||
def aboutWindowActionFunction(self):
|
def aboutWindowActionFunction(self):
|
||||||
_c = self.app_version
|
_c = self.app_version
|
||||||
if (not _c) == 0:
|
if (not _c) == 0:
|
||||||
QMessageBox.information(self, '关于', "" 'version: %s, build: %s, author: %s, email: %s, site: %s' % (_c[0], _c[1], _c[2], _c[3], '<a href=\'%s\'>%s</a>' % (_c[4], _c[4])))
|
QMessageBox.information(self, '关于', "" 'version: %s, build: %s, author: %s, email: %s, site: %s' % (
|
||||||
|
_c[0], _c[1], _c[2], _c[3], '<a href=\'%s\'>%s</a>' % (_c[4], _c[4])))
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def md5(input_data):
|
def md5(input_data):
|
||||||
|
@ -792,7 +811,8 @@ class MainWindow(QMainWindow):
|
||||||
def set_preview(self, preview_image: str):
|
def set_preview(self, preview_image: str):
|
||||||
if (preview_image and os.path.exists(preview_image)) == 1:
|
if (preview_image and os.path.exists(preview_image)) == 1:
|
||||||
pixmap = QPixmap(preview_image)
|
pixmap = QPixmap(preview_image)
|
||||||
pixmap = pixmap.scaled(self.labPRV.size(), aspectRatioMode=Qt.KeepAspectRatio, transformMode=Qt.SmoothTransformation)
|
pixmap = pixmap.scaled(self.labPRV.size(), aspectRatioMode=Qt.KeepAspectRatio,
|
||||||
|
transformMode=Qt.SmoothTransformation)
|
||||||
self.labPRV.setPixmap(pixmap)
|
self.labPRV.setPixmap(pixmap)
|
||||||
if (tempfile.gettempdir() in preview_image) == 1:
|
if (tempfile.gettempdir() in preview_image) == 1:
|
||||||
rm(preview_image)
|
rm(preview_image)
|
||||||
|
@ -809,6 +829,7 @@ class MainWindow(QMainWindow):
|
||||||
self.set_preview(self.bt.generate_preview())
|
self.set_preview(self.bt.generate_preview())
|
||||||
self.last_opened_template[0] = file
|
self.last_opened_template[0] = file
|
||||||
self.last_opened_template[1] = self.md5(open(file, 'rb'))
|
self.last_opened_template[1] = self.md5(open(file, 'rb'))
|
||||||
|
self.toast.show_toast('模板加载成功')
|
||||||
except pywintypes.com_error as e:
|
except pywintypes.com_error as e:
|
||||||
t = str(e.args[1])
|
t = str(e.args[1])
|
||||||
m = str(e.args[2][2] if isinstance(e.args[2], tuple) else e.args[2])
|
m = str(e.args[2][2] if isinstance(e.args[2], tuple) else e.args[2])
|
||||||
|
@ -822,7 +843,8 @@ class MainWindow(QMainWindow):
|
||||||
QMessageBox.critical(self, '错误', '%s' % e)
|
QMessageBox.critical(self, '错误', '%s' % e)
|
||||||
|
|
||||||
def on_open_template_file(self):
|
def on_open_template_file(self):
|
||||||
filename, _ = QFileDialog.getOpenFileName(self, '打开文件', os.path.dirname(self.last_opened_template[0]), 'BarTender 文档 (*.btw)')
|
filename, _ = QFileDialog.getOpenFileName(self, '打开文件', os.path.dirname(self.last_opened_template[0]),
|
||||||
|
'BarTender 文档 (*.btw)')
|
||||||
if (filename and os.path.exists(filename)) == 1:
|
if (filename and os.path.exists(filename)) == 1:
|
||||||
self.load_template(filename)
|
self.load_template(filename)
|
||||||
self.setting['template'] = filename
|
self.setting['template'] = filename
|
||||||
|
@ -833,7 +855,7 @@ class MainWindow(QMainWindow):
|
||||||
self.bt.start_printing_template()
|
self.bt.start_printing_template()
|
||||||
self.set_preview(self.bt.generate_preview())
|
self.set_preview(self.bt.generate_preview())
|
||||||
return None
|
return None
|
||||||
QMessageBox.critical(self, '错误', '请先加载模板文件')
|
self.toast.show_toast('请先加载模板文件')
|
||||||
except pywintypes.com_error as e:
|
except pywintypes.com_error as e:
|
||||||
t = str(e.args[1])
|
t = str(e.args[1])
|
||||||
m = str(e.args[2][2] if isinstance(e.args[2], tuple) else e.args[2])
|
m = str(e.args[2][2] if isinstance(e.args[2], tuple) else e.args[2])
|
||||||
|
@ -903,14 +925,18 @@ class MainWindow(QMainWindow):
|
||||||
def on_convert_letter_changed(self, checked):
|
def on_convert_letter_changed(self, checked):
|
||||||
if (checked == 2) == 1:
|
if (checked == 2) == 1:
|
||||||
self.input_convert_letter = 1
|
self.input_convert_letter = 1
|
||||||
|
self.toast.show_toast('强制大写开启')
|
||||||
else:
|
else:
|
||||||
self.input_convert_letter = 0
|
self.input_convert_letter = 0
|
||||||
|
self.toast.show_toast('强制大写关闭')
|
||||||
|
|
||||||
def on_prohibit_enter_changed(self, checked):
|
def on_prohibit_enter_changed(self, checked):
|
||||||
if (checked == 2) == 1:
|
if (checked == 2) == 1:
|
||||||
self.input_scan_prohibited_enter = 1
|
self.input_scan_prohibited_enter = 1
|
||||||
|
self.toast.show_toast('禁用回车开启')
|
||||||
else:
|
else:
|
||||||
self.input_scan_prohibited_enter = 0
|
self.input_scan_prohibited_enter = 0
|
||||||
|
self.toast.show_toast('禁用回车关闭')
|
||||||
|
|
||||||
def on_print_scan_enter(self):
|
def on_print_scan_enter(self):
|
||||||
self.input_scan_prohibited_enter or self.on_start_printing()
|
self.input_scan_prohibited_enter or self.on_start_printing()
|
||||||
|
@ -923,13 +949,15 @@ class MainWindow(QMainWindow):
|
||||||
text = edit.text().strip()
|
text = edit.text().strip()
|
||||||
edit.setText(text)
|
edit.setText(text)
|
||||||
if (self.bt.bt_format is None) == 1:
|
if (self.bt.bt_format is None) == 1:
|
||||||
|
self.toast.show_toast('未加载模板文件')
|
||||||
edit.selectAll()
|
edit.selectAll()
|
||||||
return None
|
return None
|
||||||
if (text == '') == 1:
|
if (text == '') == 1:
|
||||||
|
self.toast.show_toast('输入的内容为空')
|
||||||
edit.selectAll()
|
edit.selectAll()
|
||||||
return None
|
return None
|
||||||
if (not self.sv.verify(text)) == 1:
|
if (not self.sv.verify(text)) == 1:
|
||||||
QMessageBox.critical(self, '错误', '打印的内容不符合验证规则:\n\n%s' % (text,))
|
self.toast.show_toast('输入的内容不符合验证规则')
|
||||||
edit.selectAll()
|
edit.selectAll()
|
||||||
return None
|
return None
|
||||||
if (not self.ditto.addit(text) and self.setting['blockRepeat']) == 1:
|
if (not self.ditto.addit(text) and self.setting['blockRepeat']) == 1:
|
||||||
|
@ -953,10 +981,52 @@ class MainWindow(QMainWindow):
|
||||||
QMessageBox.critical(self, '错误', '%s' % e)
|
QMessageBox.critical(self, '错误', '%s' % e)
|
||||||
|
|
||||||
|
|
||||||
|
class ToastNotification(QDialog):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.WindowType.Tool)
|
||||||
|
layout = QVBoxLayout()
|
||||||
|
layout.setContentsMargins(5, 705, 5, 5)
|
||||||
|
|
||||||
|
self.label = QLabel("")
|
||||||
|
self.label.setStyleSheet("font-family: 'Microsoft YaHei'; font-size: 24px; color: #ffffff;")
|
||||||
|
layout.addWidget(self.label)
|
||||||
|
self.setLayout(layout)
|
||||||
|
self.setAttribute(Qt.WA_TranslucentBackground)
|
||||||
|
self.setStyleSheet("background-color: rgba(65, 65, 65, 180); border-radius: 5px; padding: 10px 16px 10px 16px")
|
||||||
|
|
||||||
|
self.adjustSize()
|
||||||
|
|
||||||
|
self.timer = QTimer(self)
|
||||||
|
self.timer.setInterval(2000)
|
||||||
|
self.timer.timeout.connect(self.close)
|
||||||
|
|
||||||
|
self.fade_animation = QPropertyAnimation(self, b"windowOpacity")
|
||||||
|
self.fade_animation.setDuration(500)
|
||||||
|
|
||||||
|
def show_toast(self, message):
|
||||||
|
self.close()
|
||||||
|
self.label.setText(message)
|
||||||
|
self.timer.isActive() and self.timer.stop()
|
||||||
|
self.timer.start()
|
||||||
|
self.adjustSize()
|
||||||
|
self.fade_animation.setStartValue(0.0)
|
||||||
|
self.fade_animation.setEndValue(1.0)
|
||||||
|
self.show()
|
||||||
|
self.fade_animation.start()
|
||||||
|
|
||||||
|
def closeEvent(self, event):
|
||||||
|
if self.timer.isActive():
|
||||||
|
self.timer.stop()
|
||||||
|
super().closeEvent(event)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
if (os.path.basename(__file__).lower().endswith('.int')) == 1:
|
if (os.path.basename(__file__).lower().endswith('.int')) == 1:
|
||||||
QCoreApplication.addLibraryPath(os.path.abspath(os.path.join(os.path.dirname(__file__), 'site-packages/PyQt5/Qt5/plugins')))
|
QCoreApplication.addLibraryPath(
|
||||||
f_lock = open(file=os.path.abspath(os.path.join(tempfile.gettempdir(), '%s.lock' % hashlib.md5(bytes(__file__, encoding='utf-8')).hexdigest()[:16])), mode='w', encoding='utf-8')
|
os.path.abspath(os.path.join(os.path.dirname(__file__), 'site-packages/PyQt5/Qt5/plugins')))
|
||||||
|
f_lock = open(file=os.path.abspath(os.path.join(tempfile.gettempdir(), '%s.lock' % hashlib.md5(
|
||||||
|
bytes(__file__, encoding='utf-8')).hexdigest()[:16])), mode='w', encoding='utf-8')
|
||||||
if (not flock(f_lock, LOCK_EX | LOCK_NB)) == 1:
|
if (not flock(f_lock, LOCK_EX | LOCK_NB)) == 1:
|
||||||
app = QApplication(sys.argv)
|
app = QApplication(sys.argv)
|
||||||
msg = QMessageBox()
|
msg = QMessageBox()
|
||||||
|
|
96
rules.json
96
rules.json
|
@ -66,5 +66,101 @@
|
||||||
[
|
[
|
||||||
"24位长度",
|
"24位长度",
|
||||||
"^.{24}$"
|
"^.{24}$"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"25位长度",
|
||||||
|
"^.{25}$"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"26位长度",
|
||||||
|
"^.{26}$"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"27位长度",
|
||||||
|
"^.{27}$"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"28位长度",
|
||||||
|
"^.{28}$"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"29位长度",
|
||||||
|
"^.{29}$"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"30位长度",
|
||||||
|
"^.{30}$"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"31位长度",
|
||||||
|
"^.{31}$"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"32位长度",
|
||||||
|
"^.{32}$"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"33位长度",
|
||||||
|
"^.{33}$"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"34位长度",
|
||||||
|
"^.{34}$"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"35位长度",
|
||||||
|
"^.{35}$"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"36位长度",
|
||||||
|
"^.{36}$"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"37位长度",
|
||||||
|
"^.{37}$"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"38位长度",
|
||||||
|
"^.{38}$"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"39位长度",
|
||||||
|
"^.{39}$"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"40位长度",
|
||||||
|
"^.{40}$"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"41位长度",
|
||||||
|
"^.{41}$"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"42位长度",
|
||||||
|
"^.{42}$"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"43位长度",
|
||||||
|
"^.{43}$"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"44位长度",
|
||||||
|
"^.{44}$"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"45位长度",
|
||||||
|
"^.{45}$"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"46位长度",
|
||||||
|
"^.{46}$"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"47位长度",
|
||||||
|
"^.{47}$"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"48位长度",
|
||||||
|
"^.{48}$"
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
Loading…
Reference in New Issue