提交
This commit is contained in:
1
backend/.gitignore
vendored
1
backend/.gitignore
vendored
@@ -93,7 +93,6 @@ ENV/
|
||||
*.pyc
|
||||
conf/*
|
||||
!conf/env.example.py
|
||||
db.sqlite3
|
||||
media/
|
||||
__pypackages__/
|
||||
package-lock.json
|
||||
|
||||
@@ -28,7 +28,7 @@ from conf.env import *
|
||||
# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/
|
||||
|
||||
# SECURITY WARNING: keep the secret key used in production secret!
|
||||
SECRET_KEY = "django-insecure--z8%exyzt7e_%i@1+#1mm=%lb5=^fx_57=1@a+_y7bg5-w%)sm"
|
||||
SECRET_KEY = "django-insecure--z8%exyz2sae4e_%i@1+#1mm=%lb5=^fx_57=1@a+_y7bg5-w%)sm"
|
||||
# 初始化plugins插件路径到环境变量中
|
||||
PLUGINS_PATH = os.path.join(BASE_DIR, "plugins")
|
||||
sys.path.insert(0, os.path.join(PLUGINS_PATH))
|
||||
@@ -408,7 +408,8 @@ SHARED_APPS = []
|
||||
# ********** 一键导入插件配置开始 **********
|
||||
# 例如:
|
||||
# from dvadmin_upgrade_center.settings import * # 升级中心
|
||||
from dvadmin3_celery.settings import * # celery 异步任务
|
||||
from code_info.settings import * # celery 异步任务
|
||||
# from dvadmin3_celery.settings import * # celery 异步任务
|
||||
# from dvadmin_third.settings import * # 第三方用户管理
|
||||
# from dvadmin_ak_sk.settings import * # 秘钥管理管理
|
||||
# from dvadmin_tenants.settings import * # 租户管理
|
||||
@@ -416,3 +417,22 @@ from dvadmin3_celery.settings import * # celery 异步任务
|
||||
#from dvadmin_uniapp.settings import *
|
||||
# ...
|
||||
# ********** 一键导入插件配置结束 **********
|
||||
|
||||
|
||||
if locals().get('ENVIRONMENT') != 'local':
|
||||
# 1. 定义统一的迁移文件存放目录(例如:`./all_migrations/`)
|
||||
BASE_MIGRATIONS_DIR = "all_migrations"
|
||||
# 2. 自动生成 MIGRATION_MODULES
|
||||
# 2. 定义需要排除的 App(如 Django 内置 App 或第三方 App)
|
||||
EXCLUDED_APPS = ('django','admin','auth.','contenttypes.','sessions.','psqlextra','rest_framework','drf_yasg',)
|
||||
MIGRATION_MODULES = {}
|
||||
for app in INSTALLED_APPS:
|
||||
if app.startswith(EXCLUDED_APPS):
|
||||
continue
|
||||
# 判断是否存在目录,并在目录下创建一个__init__.py 文件
|
||||
app_migrations_dir = os.path.join(BASE_DIR, BASE_MIGRATIONS_DIR, app.split('.')[-1], 'migrations')
|
||||
if not os.path.exists(app_migrations_dir):
|
||||
os.makedirs(os.path.join(app_migrations_dir))
|
||||
open(os.path.join(BASE_DIR, BASE_MIGRATIONS_DIR, app.split('.')[-1],'migrations', '__init__.py'), 'w').close()
|
||||
MIGRATION_MODULES.update(
|
||||
{app.split('.')[-1]: f"{BASE_MIGRATIONS_DIR}.{app.split('.')[-1]}.migrations"})
|
||||
@@ -1,6 +1,6 @@
|
||||
[
|
||||
{
|
||||
"name": "DVAdmin团队",
|
||||
"name": "总部",
|
||||
"key": "dvadmin",
|
||||
"sort": 1,
|
||||
"owner": "",
|
||||
@@ -11,7 +11,7 @@
|
||||
"children": [
|
||||
{
|
||||
"name": "运营部",
|
||||
"key": "",
|
||||
"key": "zongbu",
|
||||
"sort": 2,
|
||||
"owner": "",
|
||||
"phone": "",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -97,7 +97,7 @@
|
||||
"parent": 1,
|
||||
"title": "网站标题",
|
||||
"key": "site_title",
|
||||
"value": "Dvadmin",
|
||||
"value": "协众防重码",
|
||||
"sort": 1,
|
||||
"status": true,
|
||||
"data_options": null,
|
||||
@@ -111,7 +111,7 @@
|
||||
"parent": 1,
|
||||
"title": "网站名称",
|
||||
"key": "site_name",
|
||||
"value": "企业级后台管理系统",
|
||||
"value": "协众防重码系统",
|
||||
"sort": 1,
|
||||
"status": true,
|
||||
"data_options": null,
|
||||
@@ -158,7 +158,7 @@
|
||||
"parent": 1,
|
||||
"title": "版权信息",
|
||||
"key": "copyright",
|
||||
"value": "2021-2024 django-vue-admin.com 版权所有",
|
||||
"value": "2021-2025 协众防重码系统 版权所有",
|
||||
"sort": 4,
|
||||
"status": true,
|
||||
"data_options": null,
|
||||
@@ -177,7 +177,7 @@
|
||||
"parent": 1,
|
||||
"title": "备案信息",
|
||||
"key": "keep_record",
|
||||
"value": "晋ICP备18005113号-3",
|
||||
"value": "",
|
||||
"sort": 5,
|
||||
"status": true,
|
||||
"data_options": null,
|
||||
@@ -196,7 +196,7 @@
|
||||
"parent": 1,
|
||||
"title": "帮助链接",
|
||||
"key": "help_url",
|
||||
"value": "https://django-vue-admin.com",
|
||||
"value": "#",
|
||||
"sort": 6,
|
||||
"status": true,
|
||||
"data_options": null,
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
"last_name": "",
|
||||
"is_staff": true,
|
||||
"is_active": true,
|
||||
"password": "pbkdf2_sha256$260000$g17x5wlSiW1FZAh1Eudchw$ZeSAqj3Xak0io8v/pmPW0BX9EX5R2zFXDwbbD68oBFk=",
|
||||
"description": "A01",
|
||||
"password": "pbkdf2_sha256$600000$ITjuHRKiVCgPpiuCYxAaEp$aA9LDAfujtdMJRstK9YcBPz9a9MkfFG5Tsq1NviWxy0=",
|
||||
"last_login": null,
|
||||
"is_superuser": true
|
||||
},
|
||||
@@ -34,7 +35,8 @@
|
||||
"last_name": "",
|
||||
"is_staff": true,
|
||||
"is_active": true,
|
||||
"password": "pbkdf2_sha256$260000$g17x5wlSiW1FZAh1Eudchw$ZeSAqj3Xak0io8v/pmPW0BX9EX5R2zFXDwbbD68oBFk=",
|
||||
"description": "A02",
|
||||
"password": "pbkdf2_sha256$600000$ITjuHRKiVCgPpiuCYxAaEp$aA9LDAfujtdMJRstK9YcBPz9a9MkfFG5Tsq1NviWxy0=",
|
||||
"last_login": null,
|
||||
"is_superuser": false
|
||||
},
|
||||
@@ -49,11 +51,12 @@
|
||||
"role": [],
|
||||
"role_key": ["public"],
|
||||
"dept_key": "technology",
|
||||
"description": "A03",
|
||||
"first_name": "",
|
||||
"last_name": "",
|
||||
"is_staff": true,
|
||||
"is_active": true,
|
||||
"password": "pbkdf2_sha256$260000$g17x5wlSiW1FZAh1Eudchw$ZeSAqj3Xak0io8v/pmPW0BX9EX5R2zFXDwbbD68oBFk=",
|
||||
"password": "pbkdf2_sha256$600000$ITjuHRKiVCgPpiuCYxAaEp$aA9LDAfujtdMJRstK9YcBPz9a9MkfFG5Tsq1NviWxy0=",
|
||||
"last_login": null,
|
||||
"is_superuser": false
|
||||
}
|
||||
|
||||
0
backend/plugins/code_info/__init__.py
Normal file
0
backend/plugins/code_info/__init__.py
Normal file
3
backend/plugins/code_info/admin.py
Normal file
3
backend/plugins/code_info/admin.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
||||
6
backend/plugins/code_info/apps.py
Normal file
6
backend/plugins/code_info/apps.py
Normal file
@@ -0,0 +1,6 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class CodeInfoConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'plugins.code_info'
|
||||
0
backend/plugins/code_info/fixtures/__init__.py
Normal file
0
backend/plugins/code_info/fixtures/__init__.py
Normal file
1
backend/plugins/code_info/fixtures/init_dictionary.json
Normal file
1
backend/plugins/code_info/fixtures/init_dictionary.json
Normal file
@@ -0,0 +1 @@
|
||||
[]
|
||||
49
backend/plugins/code_info/fixtures/init_menu.json
Normal file
49
backend/plugins/code_info/fixtures/init_menu.json
Normal file
@@ -0,0 +1,49 @@
|
||||
[ {
|
||||
"name": "扫码信息",
|
||||
"icon": "ele-Bell",
|
||||
"sort": 8,
|
||||
"is_link": false,
|
||||
"is_catalog": true,
|
||||
"web_path": "/releaseInfo",
|
||||
"component": "",
|
||||
"component_name": "",
|
||||
"status": true,
|
||||
"cache": true,
|
||||
"visible": true,
|
||||
"parent": null,
|
||||
"children": [
|
||||
{
|
||||
"name": "扫码数据",
|
||||
"icon": "ele-Bell",
|
||||
"sort": 1,
|
||||
"is_link": false,
|
||||
"is_catalog": false,
|
||||
"web_path": "/scanData",
|
||||
"component": "plugins/scanInfo/src/scanData/index",
|
||||
"component_name": "scanData",
|
||||
"status": true,
|
||||
"cache": false,
|
||||
"visible": true,
|
||||
"children": [],
|
||||
"menu_button": [],
|
||||
"menu_field": []
|
||||
},{
|
||||
"name": "异常扫码记录",
|
||||
"icon": "ele-Bell",
|
||||
"sort": 2,
|
||||
"is_link": false,
|
||||
"is_catalog": false,
|
||||
"web_path": "/scanRecord",
|
||||
"component": "plugins/scanInfo/src/scanRecord/index",
|
||||
"component_name": "scanRecord",
|
||||
"status": true,
|
||||
"cache": false,
|
||||
"visible": true,
|
||||
"children": [],
|
||||
"menu_button": [],
|
||||
"menu_field": []
|
||||
}
|
||||
],
|
||||
"menu_button": [],
|
||||
"menu_field": []
|
||||
}]
|
||||
33
backend/plugins/code_info/fixtures/initialize.py
Normal file
33
backend/plugins/code_info/fixtures/initialize.py
Normal file
@@ -0,0 +1,33 @@
|
||||
# 初始化
|
||||
import os
|
||||
|
||||
import django
|
||||
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "application.settings")
|
||||
django.setup()
|
||||
|
||||
from dvadmin.system.fixtures.initSerializer import MenuInitSerializer, SystemConfigInitSerializer, \
|
||||
DictionaryInitSerializer
|
||||
|
||||
from dvadmin.utils.core_initialize import CoreInitialize
|
||||
|
||||
|
||||
class Initialize(CoreInitialize):
|
||||
|
||||
def init_menu(self):
|
||||
"""
|
||||
初始化菜单信息
|
||||
"""
|
||||
self.init_base(MenuInitSerializer, unique_fields=['name', 'web_path', 'component', 'component_name'])
|
||||
def init_dictionary(self):
|
||||
"""
|
||||
初始化字典表
|
||||
"""
|
||||
self.init_base(DictionaryInitSerializer, unique_fields=['value', 'parent', ])
|
||||
|
||||
def run(self):
|
||||
self.init_menu()
|
||||
self.init_dictionary()
|
||||
print(22)
|
||||
if __name__ == '__main__':
|
||||
Initialize(app='release_info').run()
|
||||
0
backend/plugins/code_info/migrations/__init__.py
Normal file
0
backend/plugins/code_info/migrations/__init__.py
Normal file
29
backend/plugins/code_info/models.py
Normal file
29
backend/plugins/code_info/models.py
Normal file
@@ -0,0 +1,29 @@
|
||||
from django.db import models
|
||||
|
||||
from django.db import models
|
||||
from dvadmin.utils.models import CoreModel
|
||||
|
||||
table_prefix = "release_info_"
|
||||
|
||||
|
||||
class ScanData(CoreModel):
|
||||
# 产品件号、供应商代码、生产批次、产品序列码、版本号、扫码时间、班次和人员信息
|
||||
code = models.CharField(null=True, blank=True, max_length=255, verbose_name='扫码值', help_text='扫码值')
|
||||
product_code = models.CharField(null=True, blank=True, max_length=255, verbose_name='产品件号', help_text='产品件号')
|
||||
supplier_code = models.CharField(null=True, blank=True, max_length=255, verbose_name='供应商代码', help_text='供应商代码')
|
||||
production_batch = models.CharField(null=True, blank=True, max_length=255, verbose_name='生产批次', help_text='生产批次')
|
||||
product_serial_number = models.CharField(null=True, blank=True, max_length=255, verbose_name='产品序列码', help_text='产品序列码')
|
||||
version_number = models.CharField(null=True, blank=True, max_length=255, verbose_name='版本号', help_text='版本号')
|
||||
shift = models.CharField(null=True, blank=True, max_length=255, verbose_name='班次', help_text='班次')
|
||||
STATUS_EMU = (
|
||||
(0, "重复扫码"),
|
||||
(1, "正常"),
|
||||
(2, "未识别码"),
|
||||
)
|
||||
status = models.IntegerField(default=1, choices=STATUS_EMU, verbose_name='状态', help_text='状态')
|
||||
|
||||
class Meta:
|
||||
db_table = table_prefix + "scan_data"
|
||||
verbose_name = "扫码数据"
|
||||
verbose_name_plural = verbose_name
|
||||
ordering = ('-create_datetime',)
|
||||
22
backend/plugins/code_info/settings.py
Normal file
22
backend/plugins/code_info/settings.py
Normal file
@@ -0,0 +1,22 @@
|
||||
from application import settings
|
||||
|
||||
# ================================================= #
|
||||
# ***************** 插件配置区开始 *******************
|
||||
# ================================================= #
|
||||
# 路由配置
|
||||
plugins_url_patterns = [
|
||||
{"re_path": r'api/code_info/', "include": "code_info.urls"},
|
||||
]
|
||||
# app 配置
|
||||
apps = ['code_info']
|
||||
# 租户模式中,public模式共享app配置
|
||||
tenant_shared_apps = ['code_info']
|
||||
# ================================================= #
|
||||
# ******************* 插件配置区结束 *****************
|
||||
# ================================================= #
|
||||
|
||||
# ********** 赋值到 settings 中 **********
|
||||
settings.INSTALLED_APPS += [app for app in apps if app not in settings.INSTALLED_APPS]
|
||||
settings.TENANT_SHARED_APPS += tenant_shared_apps
|
||||
# ********** 注册路由 **********
|
||||
settings.PLUGINS_URL_PATTERNS += plugins_url_patterns
|
||||
15
backend/plugins/code_info/urls.py
Normal file
15
backend/plugins/code_info/urls.py
Normal file
@@ -0,0 +1,15 @@
|
||||
from django.urls import path
|
||||
from rest_framework import routers
|
||||
|
||||
from plugins.code_info.views.scan_data import ScanDataViewSet
|
||||
from plugins.code_info.views.scan_record import ScanRecordViewSet
|
||||
|
||||
route_url = routers.SimpleRouter()
|
||||
|
||||
route_url.register(r'scan_data', ScanDataViewSet,basename='scan_data')
|
||||
route_url.register(r'scan_record', ScanRecordViewSet)
|
||||
|
||||
urlpatterns = [
|
||||
|
||||
]
|
||||
urlpatterns += route_url.urls
|
||||
0
backend/plugins/code_info/views/__init__.py
Normal file
0
backend/plugins/code_info/views/__init__.py
Normal file
67
backend/plugins/code_info/views/scan_data.py
Normal file
67
backend/plugins/code_info/views/scan_data.py
Normal file
@@ -0,0 +1,67 @@
|
||||
from dvadmin.utils.field_permission import FieldPermissionMixin
|
||||
from dvadmin.utils.serializers import CustomModelSerializer
|
||||
from dvadmin.utils.validator import CustomValidationError
|
||||
from dvadmin.utils.viewset import CustomModelViewSet
|
||||
from plugins.code_info.models import ScanData
|
||||
|
||||
|
||||
class ScanDataSerializer(CustomModelSerializer):
|
||||
"""
|
||||
扫码数据-序列化器
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
model = ScanData
|
||||
fields = "__all__"
|
||||
read_only_fields = ["id"]
|
||||
|
||||
class CreateScanDataSerializer(CustomModelSerializer):
|
||||
"""
|
||||
扫码数据-序列化器
|
||||
"""
|
||||
|
||||
def create(self, validated_data):
|
||||
code = validated_data.get("code")
|
||||
print(code)
|
||||
code_list = code.split("/")
|
||||
if len(code_list) == 5:
|
||||
validated_data["product_code"] = code_list[0]
|
||||
validated_data["supplier_code"] = code_list[1]
|
||||
validated_data["production_batch"] = code_list[2]
|
||||
validated_data["product_serial_number"] = code_list[3]
|
||||
validated_data["version_number"] = code_list[4]
|
||||
validated_data["shift"] = self.request.user.description
|
||||
instance = super().create(validated_data)
|
||||
# 1.格式错误
|
||||
if len(code_list) != 5:
|
||||
instance.status = 2
|
||||
instance.save()
|
||||
raise CustomValidationError("数据格式错误")
|
||||
# 2.查询数据是否已存在数据库
|
||||
print("ScanData.objects.filter(code=code, status=1)",ScanData.objects.filter(code=code, status=1))
|
||||
if ScanData.objects.filter(code=code, status=1).exclude(id=instance.id).exists():
|
||||
instance.status = 0
|
||||
instance.save()
|
||||
raise CustomValidationError("重复扫码")
|
||||
return instance
|
||||
|
||||
|
||||
class Meta:
|
||||
model = ScanData
|
||||
fields = "__all__"
|
||||
read_only_fields = ["id"]
|
||||
|
||||
|
||||
class ScanDataViewSet(CustomModelViewSet, FieldPermissionMixin):
|
||||
"""
|
||||
扫码数据接口
|
||||
list:查询
|
||||
create:新增
|
||||
update:修改
|
||||
retrieve:单例
|
||||
destroy:删除
|
||||
"""
|
||||
queryset = ScanData.objects.filter(status=1)
|
||||
serializer_class = ScanDataSerializer
|
||||
create_serializer_class = CreateScanDataSerializer
|
||||
extra_filter_class = []
|
||||
29
backend/plugins/code_info/views/scan_record.py
Normal file
29
backend/plugins/code_info/views/scan_record.py
Normal file
@@ -0,0 +1,29 @@
|
||||
from dvadmin.utils.field_permission import FieldPermissionMixin
|
||||
from dvadmin.utils.serializers import CustomModelSerializer
|
||||
from dvadmin.utils.viewset import CustomModelViewSet
|
||||
from plugins.code_info.models import ScanData
|
||||
|
||||
|
||||
class ScanRecordSerializer(CustomModelSerializer):
|
||||
"""
|
||||
扫码数据-序列化器
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
model = ScanData
|
||||
fields = "__all__"
|
||||
read_only_fields = ["id"]
|
||||
|
||||
|
||||
class ScanRecordViewSet(CustomModelViewSet, FieldPermissionMixin):
|
||||
"""
|
||||
异常扫码数据记录接口
|
||||
list:查询
|
||||
create:新增
|
||||
update:修改
|
||||
retrieve:单例
|
||||
destroy:删除
|
||||
"""
|
||||
queryset = ScanData.objects.exclude(status=1)
|
||||
serializer_class = ScanRecordSerializer
|
||||
extra_filter_class = []
|
||||
@@ -8,8 +8,7 @@ django-restql==0.15.4
|
||||
django-simple-captcha==0.6.0
|
||||
django-timezone-field==7.0
|
||||
djangorestframework_simplejwt==5.4.0
|
||||
drf-yasg==1.21.7
|
||||
mysqlclient==2.2.0
|
||||
drf-yasg==1.21.10
|
||||
pypinyin==0.51.0
|
||||
ua-parser==0.18.0
|
||||
pyparsing==3.1.2
|
||||
|
||||
168
web/README.en.md
168
web/README.en.md
@@ -1,168 +0,0 @@
|
||||
# Django-Vue3-Admin
|
||||
|
||||
[](https://gitee.com/huge-dream/django-vue3-admin/blob/master/LICENSE) [](https://python.org/) [](https://docs.djangoproject.com/zh-hans/3.2/) [](https://nodejs.org/zh-cn/) [](https://gitee.com/huge-dream/django-vue3-admin)
|
||||
|
||||
[preview](https://demo.dvadmin.com) | [Official website document](https://www.django-vue-admin.com) | [qq group](https://qm.qq.com/cgi-bin/qm/qr?k=fOdnHhC8DJlRHGYSnyhoB8P5rgogA6Vs&jump_from=webapi) | [community](https://bbs.django-vue-admin.com) | [plugins market](https://bbs.django-vue-admin.com/plugMarket.html) | [Github](https://github.com/liqianglog/django-vue-admin)
|
||||
|
||||
💡 **「About」**
|
||||
|
||||
We are a group of young people who love Code. In this hot era, we hope to calm down and bring some of our colors and colors through code.
|
||||
|
||||
Because of love, so embrace the future
|
||||
|
||||
## framework introduction
|
||||
|
||||
💡 [django-vue3-admin](https://gitee.com/huge-dream/django-vue3-admin.git) Is a set of all open source rapid development platform, no reservation for individuals and enterprises free use.
|
||||
|
||||
* 🧑🤝🧑Front-end adoption Vue3+TS+pinia+fastcrud。
|
||||
* 👭The backend uses the Python language Django framework as well as the powerful[Django REST Framework](https://pypi.org/project/djangorestframework)。
|
||||
* 👫Permission authentication use[Django REST Framework SimpleJWT](https://pypi.org/project/djangorestframework-simplejwt),Supports the multi-terminal authentication system.
|
||||
* 👬Support loading dynamic permission menu, multi - way easy permission control.
|
||||
* 💏 Special thanks: [vue-next-admin](https://lyt-top.gitee.io/vue-next-admin-doc-preview/).
|
||||
* 💡 💏 Special thanks:[jetbrains](https://www.jetbrains.com/) To provide a free IntelliJ IDEA license for this open source project.
|
||||
|
||||
## Online experience
|
||||
|
||||
👩👧👦👩👧👦 demo address:[https://demo.dvadmin.com](https://demo.dvadmin.com)
|
||||
|
||||
* demo account:superadmin
|
||||
|
||||
* demo password:admin123456
|
||||
|
||||
👩👦👦docs:[https://django-vue-admin.com](https://django-vue-admin.com)
|
||||
|
||||
## communication
|
||||
|
||||
* Communication community:[click here](https://bbs.django-vue-admin.com)👩👦👦
|
||||
|
||||
* plugins market:[click here](https://bbs.django-vue-admin.com/plugMarket.html)👩👦👦
|
||||
|
||||
## source code url:
|
||||
|
||||
gitee(Main push):[https://gitee.com/huge-dream/django-vue3-admin](https://gitee.com/huge-dream/django-vue3-admin)👩👦👦
|
||||
|
||||
github:no data
|
||||
|
||||
## core function
|
||||
|
||||
1. 👨⚕️ Menu management: Configure the system menu, operation permissions, button permissions, back-end interface permissions, etc.
|
||||
2. 🧑⚕️ Department management: Configure the system organization (company, department, role).
|
||||
3. 👩⚕️ Role management: role menu permission allocation, data permission allocation, set roles according to the department for data range permission division.
|
||||
4. 🧑🎓 Rights Specifies the rights of the authorization role.
|
||||
5. 👨🎓 User management: The user is the system operator, this function mainly completes the system user configuration.
|
||||
6. 👬 Interface whitelist: specifies the interface that does not need permission verification.
|
||||
7. 🧑🔧 Dictionary management: Maintenance of some fixed data frequently used in the system.
|
||||
8. 🧑🔧 Regional management: to manage provinces, cities, counties and regions.
|
||||
9. 📁 Attachment management: Unified management of all files and pictures on the platform.
|
||||
10. 🗓 ️operation logs: log and query the system normal operation; Log and query system exception information.
|
||||
11.🔌 [plugins market] (<https://bbs.django-vue-admin.com/plugMarket.html>) : based on the Django framework - Vue - Admin application and plug-in development.
|
||||
|
||||
## plugins market 🔌
|
||||
|
||||
* Celery Asynchronous task:[dvadmin-celery](https://gitee.com/huge-dream/dvadmin-celery)
|
||||
* Upgrade center backend:[dvadmin-upgrade-center](https://gitee.com/huge-dream/dvadmin-upgrade-center)
|
||||
* Upgrade center front:[dvadmin-upgrade-center-web](https://gitee.com/huge-dream/dvadmin-upgrade-center-web)
|
||||
|
||||
## before start project you need:
|
||||
|
||||
~~~
|
||||
Python >= 3.8.0
|
||||
nodejs >= 14.0
|
||||
Mysql >= 5.7.0 (Optional. The default database is sqlite3. 8.0 is recommended)
|
||||
Redis(Optional, the latest edition)
|
||||
~~~
|
||||
|
||||
## frontend♝
|
||||
|
||||
```bash
|
||||
# clone code
|
||||
git clone https://gitee.com/huge-dream/django-vue3-admin.git
|
||||
|
||||
# enter code dir
|
||||
cd web
|
||||
|
||||
# install dependence
|
||||
npm install --registry=https://registry.npm.taobao.org
|
||||
|
||||
# Start service
|
||||
npm run dev
|
||||
# Visit http://localhost:8080 in your browser
|
||||
# Parameters such as boot port can be configured in the #.env.development file
|
||||
# Build the production environment
|
||||
# npm run build
|
||||
```
|
||||
|
||||
## backend💈
|
||||
|
||||
~~~bash
|
||||
1. enter code dir cd backend
|
||||
2. copy ./conf/env.example.py to ./conf dir,rename as env.py
|
||||
3. in env.py configure database information
|
||||
mysql database recommended version: 8.0
|
||||
mysql database character set: utf8mb4
|
||||
4. install pip dependence
|
||||
pip3 install -r requirements.txt
|
||||
5. Execute the migration command:
|
||||
python3 manage.py makemigrations
|
||||
python3 manage.py migrate
|
||||
6. Initialization data
|
||||
python3 manage.py init
|
||||
7. Initialize provincial, municipal and county data:
|
||||
python3 manage.py init_area
|
||||
8. start backend
|
||||
python3 manage.py runserver 0.0.0.0:8000
|
||||
or daphne :
|
||||
daphne -b 0.0.0.0 -p 8000 application.asgi:application
|
||||
~~~
|
||||
|
||||
### visit backend swagger
|
||||
|
||||
* visit url:[http://localhost:8080](http://localhost:8080) (The default address is this one. If you want to change it, follow the configuration file)
|
||||
* account:`superadmin` password:`admin123456`
|
||||
|
||||
### docker-compose
|
||||
|
||||
~~~shell
|
||||
docker-compose up -d
|
||||
# Initialize backend data (first execution only)
|
||||
docker exec -ti dvadmin-django bash
|
||||
python manage.py makemigrations
|
||||
python manage.py migrate
|
||||
python manage.py init_area
|
||||
python manage.py init
|
||||
exit
|
||||
|
||||
frontend url:http://127.0.0.1:8080
|
||||
backend url:http://127.0.0.1:8080/api
|
||||
# Change 127.0.0.1 to your own public ip address on the server
|
||||
account:`superadmin` password:`admin123456`
|
||||
|
||||
# docker-compose stop
|
||||
docker-compose down
|
||||
# docker-compose restart
|
||||
docker-compose restart
|
||||
# docker-compose on start build
|
||||
docker-compose up -d --build
|
||||
~~~
|
||||
|
||||
## Demo screenshot✅
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
212
web/README.md
212
web/README.md
@@ -1,212 +0,0 @@
|
||||
# Django-Vue3-Admin
|
||||
|
||||
[](https://gitee.com/liqianglog/django-vue-admin/blob/master/LICENSE) [](https://python.org/) [](https://docs.djangoproject.com/zh-hans/3.2/) [](https://nodejs.org/zh-cn/) [](https://gitee.com/liqianglog/django-vue-admin)
|
||||
|
||||
[预 览](https://demo.dvadmin.com) | [官网文档](https://www.django-vue-admin.com) | [群聊](https://qm.qq.com/cgi-bin/qm/qr?k=fOdnHhC8DJlRHGYSnyhoB8P5rgogA6Vs&jump_from=webapi) | [社区](https://bbs.django-vue-admin.com) | [插件市场](https://bbs.django-vue-admin.com/plugMarket.html) | [Github](https://github.com/liqianglog/django-vue-admin)
|
||||
|
||||
|
||||
|
||||
💡 **「关于」**
|
||||
|
||||
我们是一群热爱代码的青年,在这个炙热的时代下,我们希望静下心来通过Code带来一点我们的色彩和颜色。
|
||||
|
||||
因为热爱,所以拥抱未来!
|
||||
|
||||
|
||||
## 平台简介
|
||||
|
||||
💡 [django-vue3-admin](https://gitee.com/huge-dream/django-vue3-admin.git) 是一套全部开源的快速开发平台,毫无保留给个人及企业免费使用。
|
||||
django-vue3-admin 基于 vue3 + CompositionAPI + typescript + vite + element plus, 是一款全栈,快速,开源的后台管理系统!
|
||||
|
||||
|
||||
|
||||
|
||||
* 🧑🤝🧑前端采用 Vue3+TS+pinia+fastcrud(感谢[vue-next-admin](https://lyt-top.gitee.io/vue-next-admin-doc-preview/))
|
||||
* 👭后端采用 Python 语言 Django 框架以及强大的 [Django REST Framework](https://pypi.org/project/djangorestframework)。
|
||||
* 👫权限认证使用[Django REST Framework SimpleJWT](https://pypi.org/project/djangorestframework-simplejwt),支持多终端认证系统。
|
||||
* 👬支持加载动态权限菜单,多方式轻松权限控制。
|
||||
* 💏特别鸣谢:[vue-next-admin](https://lyt-top.gitee.io/vue-next-admin-doc-preview/)。
|
||||
* 💡 特别感谢[jetbrains](https://www.jetbrains.com/) 为本开源项目提供免费的 IntelliJ IDEA 授权。
|
||||
|
||||
#### 🏭 环境支持
|
||||
|
||||
| Edge | Firefox | Chrome | Safari |
|
||||
| --------- | ------------ | ----------- | ----------- |
|
||||
| Edge ≥ 79 | Firefox ≥ 78 | Chrome ≥ 64 | Safari ≥ 12 |
|
||||
|
||||
> 由于 Vue3 不再支持 IE11,故而 ElementPlus 也不支持 IE11 及之前版本。
|
||||
|
||||
|
||||
|
||||
## 在线体验
|
||||
|
||||
👩👧👦演示地址:[https://demo.dvadmin.com](https://demo.dvadmin.com)
|
||||
|
||||
- 账号:superadmin
|
||||
|
||||
- 密码:admin123456
|
||||
|
||||
👩👦👦文档地址:[coding](https://dvadmin-private.coding.net/share/km/cec69f3d-30fe-47d5-bd97-e9e851f0b776/K-2)
|
||||
|
||||
|
||||
## 给框架点赞
|
||||
<img src='https://django-vue-admin.com/alipay.jpg' width='200'>
|
||||
<img src='https://django-vue-admin.com/wechat.jpg' width='200'>
|
||||
|
||||
|
||||
## 交流
|
||||
|
||||
- 交流社区:[戳我](https://bbs.django-vue-admin.com)👩👦👦
|
||||
|
||||
- 插件市场:[戳我](https://bbs.django-vue-admin.com/plugMarket.html)👩👦👦
|
||||
|
||||
- django-vue-admin交流01群(已满):812482043 [点击链接加入群聊](https://qm.qq.com/cgi-bin/qm/qr?k=aJVwjDvH-Es4MPJQuoO32N0SucK22TE5&jump_from=webapi)
|
||||
- django-vue-admin交流02群(已满):687252418 [点击链接加入群聊](https://qm.qq.com/cgi-bin/qm/qr?k=4jJN4IjWGfxJ8YJXbb_gTsuWjR34WLdc&jump_from=webapi)
|
||||
- django-vue-admin交流03群:442108213 [点击链接加入群聊](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=wsm5oSz3K8dElBYUDtLTcQSEPhINFkl8&authKey=M6sbER0z59ZakgBr5erFeZyFZU15CI52bErNZa%2FxSvvGIuVAbY0N5866v89hm%2FK4&noverify=0&group_code=442108213)
|
||||
|
||||
- 二维码
|
||||
|
||||
<img src='https://images.gitee.com/uploads/images/2022/0530/233203_5fb11883_5074988.jpeg' width='200'>
|
||||
|
||||
## 源码地址
|
||||
|
||||
gitee地址(主推):[https://gitee.com/huge-dream/django-vue3-admin](https://gitee.com/huge-dream/django-vue3-admin)👩👦👦
|
||||
|
||||
github地址:暂无
|
||||
|
||||
|
||||
## 内置功能
|
||||
|
||||
1. 👨⚕️菜单管理:配置系统菜单,操作权限,按钮权限标识、后端接口权限等。
|
||||
2. 🧑⚕️部门管理:配置系统组织机构(公司、部门、角色)。
|
||||
3. 👩⚕️角色管理:角色菜单权限分配、数据权限分配、设置角色按部门进行数据范围权限划分。
|
||||
4. 🧑🎓按钮权限权限:授权角色的按钮权限和接口权限,可做到每一个接口都能授权数据范围。
|
||||
5. 🧑🎓字段权限权限:授权页面的字段显示权限。
|
||||
5. 👨🎓用户管理:用户是系统操作者,该功能主要完成系统用户配置。
|
||||
6. 👬接口白名单:配置不需要进行权限校验的接口。
|
||||
7. 🧑🔧字典管理:对系统中经常使用的一些较为固定的数据进行维护。
|
||||
8. 🧑🔧地区管理:对省市县区域进行管理。
|
||||
9. 📁附件管理:对平台上所有文件、图片等进行统一管理。
|
||||
10. 🗓️操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询。
|
||||
11. 🔌[插件市场 ](https://bbs.django-vue-admin.com/plugMarket.html):基于Django-Vue-Admin框架开发的应用和插件。
|
||||
|
||||
## 插件市场 🔌
|
||||
|
||||
- Celery异步任务:[dvadmin-celery](https://gitee.com/huge-dream/dvadmin-celery)
|
||||
- 升级中心后端:[dvadmin-upgrade-center](https://gitee.com/huge-dream/dvadmin-upgrade-center)
|
||||
- 升级中心前端:[dvadmin-upgrade-center-web](https://gitee.com/huge-dream/dvadmin-upgrade-center-web)
|
||||
|
||||
## 准备工作
|
||||
~~~
|
||||
Python >= 3.8.0 (推荐3.8+版本)
|
||||
nodejs >= 14.0 (推荐最新)
|
||||
Mysql >= 5.7.0 (可选,默认数据库sqlite3,推荐8.0版本)
|
||||
Redis(可选,最新版)
|
||||
~~~
|
||||
|
||||
## 前端♝
|
||||
|
||||
```bash
|
||||
# 克隆项目
|
||||
git clone https://gitee.com/huge-dream/django-vue3-admin.git
|
||||
|
||||
# 进入项目目录
|
||||
cd web
|
||||
|
||||
# 安装依赖
|
||||
npm install --registry=https://registry.npm.taobao.org
|
||||
|
||||
# 启动服务
|
||||
npm run dev
|
||||
# 浏览器访问 http://localhost:8080
|
||||
# .env.development 文件中可配置启动端口等参数
|
||||
# 构建生产环境
|
||||
# npm run build
|
||||
```
|
||||
|
||||
|
||||
|
||||
## 后端💈
|
||||
|
||||
~~~bash
|
||||
1. 进入项目目录 cd backend
|
||||
2. 在项目根目录中,复制 ./conf/env.example.py 文件为一份新的到 ./conf 文件夹下,并重命名为 env.py
|
||||
3. 在 env.py 中配置数据库信息
|
||||
mysql数据库版本建议:8.0
|
||||
mysql数据库字符集:utf8mb4
|
||||
4. 安装依赖环境
|
||||
pip3 install -r requirements.txt
|
||||
5. 执行迁移命令:
|
||||
python3 manage.py makemigrations
|
||||
python3 manage.py migrate
|
||||
6. 初始化数据
|
||||
python3 manage.py init
|
||||
7. 初始化省市县数据:
|
||||
python3 manage.py init_area
|
||||
8. 启动项目
|
||||
python3 manage.py runserver 0.0.0.0:8000
|
||||
或使用 daphne :
|
||||
daphne -b 0.0.0.0 -p 8000 application.asgi:application
|
||||
~~~
|
||||
|
||||
### 访问项目
|
||||
|
||||
- 访问地址:[http://localhost:8080](http://localhost:8080) (默认为此地址,如有修改请按照配置文件)
|
||||
- 账号:`superadmin` 密码:`admin123456`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### docker-compose 运行
|
||||
|
||||
~~~shell
|
||||
# 先安装docker-compose (自行百度安装),执行此命令等待安装,如有使用celery插件请打开docker-compose.yml中celery 部分注释
|
||||
docker-compose up -d
|
||||
# 初始化后端数据(第一次执行即可)
|
||||
docker exec -ti dvadmin-django bash
|
||||
python manage.py makemigrations
|
||||
python manage.py migrate
|
||||
python manage.py init_area
|
||||
python manage.py init
|
||||
exit
|
||||
|
||||
前端地址:http://127.0.0.1:8080
|
||||
后端地址:http://127.0.0.1:8080/api
|
||||
# 在服务器上请把127.0.0.1 换成自己公网ip
|
||||
账号:superadmin 密码:admin123456
|
||||
|
||||
# docker-compose 停止
|
||||
docker-compose down
|
||||
# docker-compose 重启
|
||||
docker-compose restart
|
||||
# docker-compose 启动时重新进行 build
|
||||
docker-compose up -d --build
|
||||
~~~
|
||||
|
||||
|
||||
|
||||
## 演示图✅
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
<LockScreen v-if="themeConfig.isLockScreen" />
|
||||
<Setings ref="setingsRef" v-show="themeConfig.lockScreenTime > 1" />
|
||||
<CloseFull v-if="!themeConfig.isLockScreen" />
|
||||
<Scanned ref="scannedRef" ></Scanned>
|
||||
<!-- <Upgrade v-if="getVersion" />-->
|
||||
</el-config-provider>
|
||||
</template>
|
||||
@@ -20,17 +21,22 @@ import other from '/@/utils/other';
|
||||
import { Local, Session } from '/@/utils/storage';
|
||||
import mittBus from '/@/utils/mitt';
|
||||
import setIntroduction from '/@/utils/setIconfont';
|
||||
import Scan from './scan';
|
||||
const scan = new Scan(200); // 200是扫码枪有效输入间隔毫秒
|
||||
let removeScanListener: () => void;
|
||||
|
||||
|
||||
// 引入组件
|
||||
const LockScreen = defineAsyncComponent(() => import('/@/layout/lockScreen/index.vue'));
|
||||
const Setings = defineAsyncComponent(() => import('/@/layout/navBars/breadcrumb/setings.vue'));
|
||||
const CloseFull = defineAsyncComponent(() => import('/@/layout/navBars/breadcrumb/closeFull.vue'));
|
||||
const Upgrade = defineAsyncComponent(() => import('/@/layout/upgrade/index.vue'));
|
||||
const Scanned = defineAsyncComponent(() => import('/@/layout/Scanned/index.vue'));
|
||||
import { ElMessageBox, ElNotification, NotificationHandle } from 'element-plus';
|
||||
import { useCore } from '/@/utils/cores';
|
||||
// 定义变量内容
|
||||
const { messages, locale } = useI18n();
|
||||
const setingsRef = ref();
|
||||
const scannedRef = ref();
|
||||
const route = useRoute();
|
||||
const stores = useTagsViewRoutes();
|
||||
const storesThemeConfig = useThemeConfig();
|
||||
@@ -61,8 +67,21 @@ onBeforeMount(() => {
|
||||
// 设置批量第三方 js
|
||||
setIntroduction.jsCdn();
|
||||
});
|
||||
// 扫码后的 处理
|
||||
const handleScan = (code: string) => {
|
||||
console.log('Scanned code:', code);
|
||||
scannedRef.value.isShow = true;
|
||||
scannedRef.value.scanCode = code;
|
||||
scannedRef.value.postData();
|
||||
// 处理扫描后的逻辑
|
||||
};
|
||||
|
||||
// 页面加载时
|
||||
onMounted(() => {
|
||||
// 开始监听扫码枪扫码并设置回调
|
||||
removeScanListener = scan.onScan(handleScan);
|
||||
scan.start();
|
||||
|
||||
nextTick(() => {
|
||||
// 监听布局配'置弹窗点击打开
|
||||
mittBus.on('openSetingsDrawer', () => {
|
||||
@@ -89,7 +108,13 @@ onMounted(() => {
|
||||
});
|
||||
// 页面销毁时,关闭监听布局配置/i18n监听
|
||||
onUnmounted(() => {
|
||||
// 结束监听
|
||||
scan.stop();
|
||||
// 移除全局事件监听器
|
||||
if (removeScanListener) removeScanListener();
|
||||
|
||||
mittBus.off('openSetingsDrawer', () => {});
|
||||
mittBus.off('scanDataDoRefresh', () => {});
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
12
web/src/layout/Scanned/api.ts
Normal file
12
web/src/layout/Scanned/api.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { request } from '/@/utils/service';
|
||||
import { UserPageQuery, AddReq, DelReq, EditReq, InfoReq } from '@fast-crud/fast-crud';
|
||||
|
||||
export const apiPrefix = '/api/code_info/scan_data/';
|
||||
|
||||
export function AddObj(obj: AddReq) {
|
||||
return request({
|
||||
url: apiPrefix,
|
||||
method: 'post',
|
||||
data: obj,
|
||||
});
|
||||
}
|
||||
87
web/src/layout/Scanned/index.vue
Normal file
87
web/src/layout/Scanned/index.vue
Normal file
@@ -0,0 +1,87 @@
|
||||
<template>
|
||||
<div class="upgrade-dialog">
|
||||
<el-dialog
|
||||
v-model="isShow"
|
||||
width="500px"
|
||||
destroy-on-close
|
||||
:show-close="true"
|
||||
:close-on-click-modal="false"
|
||||
:close-on-press-escape="false"
|
||||
>
|
||||
<div style="text-align: center">
|
||||
<div v-if="status===0">
|
||||
<el-icon size="100" color="rgb(177, 179, 184)"><Loading /></el-icon>
|
||||
<div style="font-size: 18px">识别中请稍等</div>
|
||||
</div>
|
||||
<div v-if="status===1">
|
||||
<el-icon size="100" color="#57B046"><CircleCheckFilled /></el-icon>
|
||||
<div style="font-size: 18px">扫码成功</div>
|
||||
</div>
|
||||
<div v-if="status===2">
|
||||
<el-icon size="100" color="#F56C6C"><CircleCloseFilled /></el-icon>
|
||||
<div style="font-size: 18px">条码重复</div>
|
||||
</div>
|
||||
<div v-if="status===3">
|
||||
<el-icon size="100" color="#F56C6C"><WarningFilled /></el-icon>
|
||||
<div style="font-size: 18px">条码错误</div>
|
||||
</div>
|
||||
<div style="font-size: 16px;color: #979b9c">{{scanCode}}</div>
|
||||
<div style="width: 100%;margin-top: 50px;">
|
||||
<el-button type="primary" style="width: 300px;" size="large" @click="onclick" v-if="time !== -1">{{time}}秒后自动关闭</el-button>
|
||||
<el-button type="primary" style="width: 300px;" size="large" @click="onclick" v-else>关闭</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="layoutUpgrade">
|
||||
import {reactive, computed, onMounted, ref} from 'vue';
|
||||
import * as api from './api';
|
||||
import mittBus from "/@/utils/mitt";
|
||||
const isShow = ref(false);
|
||||
const scanCode = ref('');
|
||||
const status = ref(0);
|
||||
const time = ref(-1)
|
||||
const timer = ref()
|
||||
|
||||
const postData = () => {
|
||||
api.AddObj({
|
||||
code: scanCode.value,
|
||||
}).then(() => {
|
||||
time.value = 5;
|
||||
status.value = 1;
|
||||
timer.value = setInterval(() => {
|
||||
if (time.value <= 0){
|
||||
onclick()
|
||||
clearTimeout(timer.value)
|
||||
time.value = 5
|
||||
} else {
|
||||
time.value -= 1
|
||||
}
|
||||
}, 1000)
|
||||
}).catch((err: any) => {
|
||||
status.value = err?.msg === '重复扫码' ? 2 : 3
|
||||
time.value = -1
|
||||
})
|
||||
}
|
||||
const onclick = () => {
|
||||
isShow.value = false;
|
||||
mittBus.emit('scanDataDoRefresh', () => {});
|
||||
}
|
||||
// 页面加载时
|
||||
onMounted(() => {
|
||||
|
||||
});
|
||||
// 暴露变量
|
||||
defineExpose({
|
||||
isShow,
|
||||
onclick,
|
||||
scanCode,
|
||||
postData
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
</style>
|
||||
@@ -4,7 +4,7 @@
|
||||
<el-scrollbar ref="layoutMainScrollbarRef" class="layout-main-scroll layout-backtop-header-fixed"
|
||||
wrap-class="layout-main-scroll" view-class="layout-main-scroll">
|
||||
<LayoutParentView />
|
||||
<LayoutFooter v-if="isFooter" />
|
||||
<!-- <LayoutFooter v-if="isFooter" />-->
|
||||
</el-scrollbar>
|
||||
<el-backtop :target="setBacktopClass" />
|
||||
</el-main>
|
||||
@@ -20,7 +20,7 @@ import { NextLoading } from '/@/utils/loading';
|
||||
|
||||
// 引入组件
|
||||
const LayoutParentView = defineAsyncComponent(() => import('/@/layout/routerView/parent.vue'));
|
||||
const LayoutFooter = defineAsyncComponent(() => import('/@/layout/footer/index.vue'));
|
||||
// const LayoutFooter = defineAsyncComponent(() => import('/@/layout/footer/index.vue'));
|
||||
|
||||
// 定义变量内容
|
||||
const layoutMainScrollbarRef = ref();
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
<template>
|
||||
<div class="layout-footer pb5 pt2">
|
||||
<div class="layout-footer-warp">
|
||||
<div>❤️ Powered by Django-Vue3-Admin Copyright © DVAdmin团队 ❤️</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -11,14 +8,4 @@
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.layout-footer {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
&-warp {
|
||||
margin: auto;
|
||||
color: var(--el-text-color-secondary);
|
||||
text-align: center;
|
||||
animation: error-num 0.3s ease;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
84
web/src/scan.ts
Normal file
84
web/src/scan.ts
Normal file
@@ -0,0 +1,84 @@
|
||||
// scan.ts
|
||||
export default class Scan {
|
||||
private barCode: string = '';
|
||||
private lastTime: number = 0;
|
||||
private timeout: number;
|
||||
private timer: NodeJS.Timeout | null = null;
|
||||
private eventHandler: (e: KeyboardEvent) => void;
|
||||
|
||||
constructor(timeout = 100) {
|
||||
this.timeout = timeout;
|
||||
this.eventHandler = this.eventListenerScanCode.bind(this);
|
||||
}
|
||||
|
||||
private eventListenerScanCode(e: KeyboardEvent): void {
|
||||
const currCode = e.keyCode || e.which || e.charCode;
|
||||
const currTime = new Date().getTime();
|
||||
|
||||
if (this.lastTime > 0) {
|
||||
if (currTime - this.lastTime <= this.timeout) {
|
||||
this.barCode += String.fromCharCode(currCode!);
|
||||
} else {
|
||||
this.clearBarCode();
|
||||
}
|
||||
} else {
|
||||
this.barCode = String.fromCharCode(currCode!);
|
||||
}
|
||||
|
||||
// console.log(currTime, "监听到的值:", this.barCode);
|
||||
this.lastTime = currTime;
|
||||
|
||||
if (currCode === 13) { // Enter键
|
||||
if (this.barCode) {
|
||||
const code = this.barCode.substring(0, this.barCode.length - 1).trim(); // 去除末尾的Enter键
|
||||
if (code) {
|
||||
this.emitScan(code);
|
||||
}
|
||||
}
|
||||
this.clearBarCode();
|
||||
}
|
||||
|
||||
if (this.timer) {
|
||||
clearTimeout(this.timer);
|
||||
}
|
||||
this.timer = setTimeout(() => {
|
||||
if (this.lastTime) {
|
||||
this.clearBarCode();
|
||||
console.log("执行清空");
|
||||
}
|
||||
clearTimeout(this.timer);
|
||||
}, this.timeout);
|
||||
}
|
||||
|
||||
private clearBarCode(): void {
|
||||
this.barCode = '';
|
||||
this.lastTime = 0;
|
||||
if (this.timer) {
|
||||
clearTimeout(this.timer);
|
||||
this.timer = null;
|
||||
}
|
||||
}
|
||||
|
||||
public start(): void {
|
||||
window.addEventListener("keypress", this.eventHandler);
|
||||
}
|
||||
|
||||
public stop(): void {
|
||||
window.removeEventListener("keypress", this.eventHandler);
|
||||
this.clearBarCode();
|
||||
}
|
||||
|
||||
private emitScan(code: string): void {
|
||||
this.onScanCallbacks.forEach(callback => callback(code));
|
||||
}
|
||||
|
||||
private onScanCallbacks: ((code: string) => void)[] = [];
|
||||
|
||||
public onScan(callback: (code: string) => void): () => void {
|
||||
this.onScanCallbacks.push(callback);
|
||||
console.log(9090)
|
||||
return () => {
|
||||
this.onScanCallbacks = this.onScanCallbacks.filter(cb => cb !== callback);
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -11,140 +11,51 @@ import { defineStore } from 'pinia';
|
||||
export const useThemeConfig = defineStore('themeConfig', {
|
||||
state: (): ThemeConfigState => ({
|
||||
themeConfig: {
|
||||
// 是否开启布局配置抽屉
|
||||
isDrawer: false,
|
||||
|
||||
/**
|
||||
* 全局主题
|
||||
*/
|
||||
// 默认 primary 主题颜色
|
||||
primary: '#409eff',
|
||||
// 是否开启深色模式
|
||||
isIsDark: false,
|
||||
|
||||
/**
|
||||
* 顶栏设置
|
||||
*/
|
||||
// 默认顶栏导航背景颜色
|
||||
topBar: '#ffffff',
|
||||
// 默认顶栏导航字体颜色
|
||||
topBar: '#edf1ff',
|
||||
topBarColor: '#606266',
|
||||
// 是否开启顶栏背景颜色渐变
|
||||
isTopBarColorGradual: false,
|
||||
|
||||
/**
|
||||
* 菜单设置
|
||||
*/
|
||||
// 默认菜单导航背景颜色
|
||||
menuBar: '#334054',
|
||||
// 默认菜单导航字体颜色
|
||||
menuBarColor: '#eaeaea',
|
||||
// 默认菜单高亮背景色
|
||||
menuBarActiveColor: 'rgba(0, 0, 0, 0.2)',
|
||||
// 是否开启菜单背景颜色渐变
|
||||
menuBar: '#edf1ff',
|
||||
menuBarColor: '#000000',
|
||||
menuBarActiveColor: 'rgb(237, 241, 255)',
|
||||
isMenuBarColorGradual: false,
|
||||
|
||||
/**
|
||||
* 分栏设置
|
||||
*/
|
||||
// 默认分栏菜单背景颜色
|
||||
columnsMenuBar: '#334054',
|
||||
// 默认分栏菜单字体颜色
|
||||
columnsMenuBarColor: '#e6e6e6',
|
||||
// 是否开启分栏菜单背景颜色渐变
|
||||
isColumnsMenuBarColorGradual: false,
|
||||
// 是否开启分栏菜单鼠标悬停预加载(预览菜单)
|
||||
isColumnsMenuHoverPreload: false,
|
||||
|
||||
/**
|
||||
* 界面设置
|
||||
*/
|
||||
// 是否开启菜单水平折叠效果
|
||||
isCollapse: false,
|
||||
// 是否开启菜单手风琴效果
|
||||
isUniqueOpened: true,
|
||||
// 是否开启固定 Header
|
||||
isFixedHeader: false,
|
||||
// 初始化变量,用于更新菜单 el-scrollbar 的高度,请勿删除
|
||||
isFixedHeader: true,
|
||||
isFixedHeaderChange: false,
|
||||
// 是否开启经典布局分割菜单(仅经典布局生效)
|
||||
isClassicSplitMenu: false,
|
||||
// 是否开启自动锁屏
|
||||
isLockScreen: false,
|
||||
// 开启自动锁屏倒计时(s/秒)
|
||||
lockScreenTime: 30,
|
||||
|
||||
/**
|
||||
* 界面显示
|
||||
*/
|
||||
// 是否开启侧边栏 Logo
|
||||
isShowLogo: true,
|
||||
// 初始化变量,用于 el-scrollbar 的高度更新,请勿删除
|
||||
isShowLogoChange: false,
|
||||
// 是否开启 Breadcrumb,强制经典、横向布局不显示
|
||||
isBreadcrumb: true,
|
||||
// 是否开启 Tagsview
|
||||
isBreadcrumb: false,
|
||||
isTagsview: true,
|
||||
// 是否开启 Breadcrumb 图标
|
||||
isBreadcrumbIcon: true,
|
||||
// 是否开启 Tagsview 图标
|
||||
isTagsviewIcon: true,
|
||||
// 是否开启 TagsView 缓存
|
||||
isCacheTagsView: true,
|
||||
// 是否开启 TagsView 拖拽
|
||||
isSortableTagsView: true,
|
||||
// 是否开启 TagsView 共用
|
||||
isShareTagsView: false,
|
||||
// 是否开启 Footer 底部版权信息
|
||||
isFooter: true,
|
||||
// 是否开启灰色模式
|
||||
isGrayscale: false,
|
||||
// 是否开启色弱模式
|
||||
isInvert: false,
|
||||
// 是否开启水印
|
||||
isWartermark: false,
|
||||
// 水印文案
|
||||
wartermarkText: '',
|
||||
|
||||
/**
|
||||
* 其它设置
|
||||
*/
|
||||
// Tagsview 风格:可选值"<tags-style-one|tags-style-four|tags-style-five>",默认 tags-style-five
|
||||
// 定义的值与 `/src/layout/navBars/tagsView/tagsView.vue` 中的 class 同名
|
||||
tagsStyle: 'tags-style-five',
|
||||
// 主页面切换动画:可选值"<slide-right|slide-left|opacitys>",默认 slide-right
|
||||
animation: 'slide-right',
|
||||
// 分栏高亮风格:可选值"<columns-round|columns-card>",默认 columns-round
|
||||
columnsAsideStyle: 'columns-round',
|
||||
// 分栏布局风格:可选值"<columns-horizontal|columns-vertical>",默认 columns-horizontal
|
||||
columnsAsideLayout: 'columns-vertical',
|
||||
|
||||
/**
|
||||
* 布局切换
|
||||
* 注意:为了演示,切换布局时,颜色会被还原成默认,代码位置:/@/layout/navBars/breadcrumb/setings.vue
|
||||
* 中的 `initSetLayoutChange(设置布局切换,重置主题样式)` 方法
|
||||
*/
|
||||
// 布局切换:可选值"<defaults|classic|transverse|columns>",默认 defaults
|
||||
layout: 'defaults',
|
||||
|
||||
/**
|
||||
* 后端控制路由
|
||||
*/
|
||||
// 是否开启后端控制路由
|
||||
layout: 'classic',
|
||||
isRequestRoutes: true,
|
||||
|
||||
/**
|
||||
* 全局网站标题 / 副标题
|
||||
*/
|
||||
// 网站主标题(菜单导航、浏览器当前网页标题)
|
||||
globalTitle: 'DVAdmin',
|
||||
// 网站副标题(登录页顶部文字)
|
||||
globalViceTitle: 'DVAdmin',
|
||||
// 网站副标题(登录页顶部文字)
|
||||
globalViceTitleMsg: '企业级快速开发平台',
|
||||
// 默认初始语言,可选值"<zh-cn|en|zh-tw>",默认 zh-cn
|
||||
globalTitle: '协众防重码',
|
||||
globalViceTitle: '协众防重码',
|
||||
globalViceTitleMsg: '',
|
||||
globalI18n: 'zh-cn',
|
||||
// 默认全局组件大小,可选值"<large|'default'|small>",默认 'large'
|
||||
globalComponentSize: 'default',
|
||||
},
|
||||
}),
|
||||
|
||||
1
web/src/types/mitt.d.ts
vendored
1
web/src/types/mitt.d.ts
vendored
@@ -14,6 +14,7 @@
|
||||
*/
|
||||
declare type MittType<T = any> = {
|
||||
openSetingsDrawer?: string;
|
||||
scanDataDoRefresh?: string;
|
||||
restoreDefault?: string;
|
||||
setSendColumnsChildren: T;
|
||||
setSendClassicChildren: T;
|
||||
|
||||
@@ -94,28 +94,6 @@ export const commonCrudConfig = (options: CrudOptions = {}) => {
|
||||
helper: '默认不填则为当前创建用户的部门ID',
|
||||
},
|
||||
},
|
||||
description: {
|
||||
title: '备注',
|
||||
search: {
|
||||
show: merged.description.search,
|
||||
},
|
||||
type: 'textarea',
|
||||
column: {
|
||||
width: merged.description.width,
|
||||
show: merged.description.table,
|
||||
},
|
||||
form: {
|
||||
show: merged.description.form,
|
||||
component: {
|
||||
placeholder: '请输入内容',
|
||||
showWordLimit: true,
|
||||
maxlength: '200',
|
||||
},
|
||||
},
|
||||
viewForm: {
|
||||
show: true,
|
||||
},
|
||||
},
|
||||
|
||||
modifier_name: {
|
||||
title: '修改人',
|
||||
|
||||
0
web/src/views/plugins/scanInfo/index.ts
Normal file
0
web/src/views/plugins/scanInfo/index.ts
Normal file
41
web/src/views/plugins/scanInfo/src/scanData/api.ts
Normal file
41
web/src/views/plugins/scanInfo/src/scanData/api.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import { request } from '/@/utils/service';
|
||||
import { UserPageQuery, AddReq, DelReq, EditReq, InfoReq } from '@fast-crud/fast-crud';
|
||||
|
||||
export const apiPrefix = '/api/code_info/scan_data/';
|
||||
export function GetList(query: UserPageQuery) {
|
||||
return request({
|
||||
url: apiPrefix,
|
||||
method: 'get',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
export function GetObj(id: InfoReq) {
|
||||
return request({
|
||||
url: apiPrefix + id,
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
|
||||
export function AddObj(obj: AddReq) {
|
||||
return request({
|
||||
url: apiPrefix,
|
||||
method: 'post',
|
||||
data: obj,
|
||||
});
|
||||
}
|
||||
|
||||
export function UpdateObj(obj: EditReq) {
|
||||
return request({
|
||||
url: apiPrefix + obj.id + '/',
|
||||
method: 'put',
|
||||
data: obj,
|
||||
});
|
||||
}
|
||||
|
||||
export function DelObj(id: DelReq) {
|
||||
return request({
|
||||
url: apiPrefix + id + '/',
|
||||
method: 'delete',
|
||||
data: { id },
|
||||
});
|
||||
}
|
||||
195
web/src/views/plugins/scanInfo/src/scanData/crud.tsx
Normal file
195
web/src/views/plugins/scanInfo/src/scanData/crud.tsx
Normal file
@@ -0,0 +1,195 @@
|
||||
import * as api from './api';
|
||||
import { UserPageQuery, AddReq, DelReq, EditReq, CreateCrudOptionsProps, CreateCrudOptionsRet, dict } from '@fast-crud/fast-crud';
|
||||
import {commonCrudConfig} from "/@/utils/commonCrud";
|
||||
|
||||
export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
||||
const pageRequest = async (query: UserPageQuery) => {
|
||||
return await api.GetList(query);
|
||||
};
|
||||
const editRequest = async ({ form, row }: EditReq) => {
|
||||
form.id = row.id;
|
||||
return await api.UpdateObj(form);
|
||||
};
|
||||
const delRequest = async ({ row }: DelReq) => {
|
||||
return await api.DelObj(row.id);
|
||||
};
|
||||
const addRequest = async ({ form }: AddReq) => {
|
||||
return await api.AddObj(form);
|
||||
};
|
||||
return {
|
||||
crudOptions: {
|
||||
request: {
|
||||
pageRequest,
|
||||
addRequest,
|
||||
editRequest,
|
||||
delRequest,
|
||||
},
|
||||
actionbar: {
|
||||
buttons: {
|
||||
add: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
rowHandle: {
|
||||
fixed:'right',
|
||||
width: 100,
|
||||
buttons: {
|
||||
view: {
|
||||
type: 'text',
|
||||
},
|
||||
edit: {
|
||||
show: false,
|
||||
},
|
||||
remove: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
columns: {
|
||||
_index: {
|
||||
title: '序号',
|
||||
form: { show: false },
|
||||
column: {
|
||||
//type: 'index',
|
||||
align: 'center',
|
||||
width: '70px',
|
||||
columnSetDisabled: true, //禁止在列设置中选择
|
||||
formatter: (context) => {
|
||||
//计算序号,你可以自定义计算规则,此处为翻页累加
|
||||
let index = context.index ?? 1;
|
||||
let pagination = crudExpose!.crudBinding.value.pagination;
|
||||
return ((pagination!.currentPage ?? 1) - 1) * pagination!.pageSize + index + 1;
|
||||
},
|
||||
},
|
||||
},
|
||||
search: {
|
||||
title: '关键词',
|
||||
column: {
|
||||
show: false,
|
||||
},
|
||||
search: {
|
||||
show: true,
|
||||
component: {
|
||||
props: {
|
||||
clearable: true,
|
||||
},
|
||||
placeholder: '请输入关键词',
|
||||
},
|
||||
},
|
||||
form: {
|
||||
show: false,
|
||||
component: {
|
||||
props: {
|
||||
clearable: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
product_code: {
|
||||
title: '产品件号',
|
||||
search: {
|
||||
show: true,
|
||||
},
|
||||
type: 'input',
|
||||
column:{
|
||||
minWidth: 120,
|
||||
},
|
||||
form: {
|
||||
disabled: true,
|
||||
component: {
|
||||
placeholder: '请输入产品件号',
|
||||
},
|
||||
},
|
||||
},
|
||||
supplier_code: {
|
||||
title: '供应商代码',
|
||||
search: {
|
||||
show: true,
|
||||
},
|
||||
type: 'input',
|
||||
column:{
|
||||
minWidth: 120,
|
||||
},
|
||||
form: {
|
||||
disabled: true,
|
||||
component: {
|
||||
placeholder: '请输入供应商代码',
|
||||
},
|
||||
},
|
||||
},
|
||||
production_batch: {
|
||||
title: '生产批次',
|
||||
search: {
|
||||
show: true,
|
||||
},
|
||||
type: 'input',
|
||||
column:{
|
||||
minWidth: 120,
|
||||
},
|
||||
form: {
|
||||
disabled: true,
|
||||
component: {
|
||||
placeholder: '请输入生产批次',
|
||||
},
|
||||
},
|
||||
},
|
||||
product_serial_number: {
|
||||
title: '产品序列码',
|
||||
search: {
|
||||
show: true,
|
||||
},
|
||||
type: 'input',
|
||||
column:{
|
||||
minWidth: 120,
|
||||
},
|
||||
form: {
|
||||
disabled: true,
|
||||
component: {
|
||||
placeholder: '请输入产品序列码',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
version_number: {
|
||||
title: '版本号',
|
||||
search: {
|
||||
show: true,
|
||||
},
|
||||
disabled: true,
|
||||
type: 'input',
|
||||
column:{
|
||||
minWidth: 120,
|
||||
},
|
||||
form: {
|
||||
component: {
|
||||
placeholder: '请输入版本号',
|
||||
},
|
||||
},
|
||||
},
|
||||
shift: {
|
||||
title: '班次',
|
||||
type: 'input',
|
||||
column:{
|
||||
minWidth: 90,
|
||||
},
|
||||
search: {
|
||||
show: true,
|
||||
},
|
||||
form: {
|
||||
disabled: true,
|
||||
component: {
|
||||
placeholder: '请输入班次',
|
||||
},
|
||||
},
|
||||
component: { props: { color: 'auto' } }, // 自动染色
|
||||
},
|
||||
...commonCrudConfig({
|
||||
create_datetime: { form: false, table: true, search: false, width: 160 },
|
||||
update_datetime: { form: false, table: true, search: false, width: 160 },
|
||||
creator_name: { form: false, table: true, search: false, width: 100 },
|
||||
})
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
30
web/src/views/plugins/scanInfo/src/scanData/index.vue
Normal file
30
web/src/views/plugins/scanInfo/src/scanData/index.vue
Normal file
@@ -0,0 +1,30 @@
|
||||
<template>
|
||||
<fs-page>
|
||||
<fs-crud ref="crudRef" v-bind="crudBinding"> </fs-crud>
|
||||
</fs-page>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup name="scanData">
|
||||
import { onMounted,onUnmounted } from 'vue';
|
||||
import { useFs } from '@fast-crud/fast-crud';
|
||||
import { createCrudOptions } from './crud';
|
||||
import mittBus from "/@/utils/mitt";
|
||||
import { handleColumnPermission } from '/@/utils/columnPermission';
|
||||
|
||||
const { crudBinding, crudRef, crudExpose, crudOptions, resetCrudOptions } = useFs({ createCrudOptions });
|
||||
|
||||
// 页面打开后获取列表数据
|
||||
onMounted(async () => {
|
||||
// 刷新
|
||||
mittBus.on('scanDataDoRefresh', () => {
|
||||
crudExpose.doRefresh();
|
||||
});
|
||||
crudExpose.doRefresh();
|
||||
});
|
||||
|
||||
// 页面销毁时,关闭监听布局配置/i18n监听
|
||||
onUnmounted(() => {
|
||||
mittBus.off('scanDataDoRefresh', () => {});
|
||||
});
|
||||
|
||||
</script>
|
||||
41
web/src/views/plugins/scanInfo/src/scanRecord/api.ts
Normal file
41
web/src/views/plugins/scanInfo/src/scanRecord/api.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import { request } from '/@/utils/service';
|
||||
import { UserPageQuery, AddReq, DelReq, EditReq, InfoReq } from '@fast-crud/fast-crud';
|
||||
|
||||
export const apiPrefix = '/api/code_info/scan_record/';
|
||||
export function GetList(query: UserPageQuery) {
|
||||
return request({
|
||||
url: apiPrefix,
|
||||
method: 'get',
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
export function GetObj(id: InfoReq) {
|
||||
return request({
|
||||
url: apiPrefix + id,
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
|
||||
export function AddObj(obj: AddReq) {
|
||||
return request({
|
||||
url: apiPrefix,
|
||||
method: 'post',
|
||||
data: obj,
|
||||
});
|
||||
}
|
||||
|
||||
export function UpdateObj(obj: EditReq) {
|
||||
return request({
|
||||
url: apiPrefix + obj.id + '/',
|
||||
method: 'put',
|
||||
data: obj,
|
||||
});
|
||||
}
|
||||
|
||||
export function DelObj(id: DelReq) {
|
||||
return request({
|
||||
url: apiPrefix + id + '/',
|
||||
method: 'delete',
|
||||
data: { id },
|
||||
});
|
||||
}
|
||||
229
web/src/views/plugins/scanInfo/src/scanRecord/crud.tsx
Normal file
229
web/src/views/plugins/scanInfo/src/scanRecord/crud.tsx
Normal file
@@ -0,0 +1,229 @@
|
||||
import * as api from './api';
|
||||
import { UserPageQuery, AddReq, DelReq, EditReq, CreateCrudOptionsProps, CreateCrudOptionsRet, dict } from '@fast-crud/fast-crud';
|
||||
import {commonCrudConfig} from "/@/utils/commonCrud";
|
||||
import {dictionary} from "/@/utils/dictionary";
|
||||
|
||||
export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
||||
const pageRequest = async (query: UserPageQuery) => {
|
||||
return await api.GetList(query);
|
||||
};
|
||||
const editRequest = async ({ form, row }: EditReq) => {
|
||||
form.id = row.id;
|
||||
return await api.UpdateObj(form);
|
||||
};
|
||||
const delRequest = async ({ row }: DelReq) => {
|
||||
return await api.DelObj(row.id);
|
||||
};
|
||||
const addRequest = async ({ form }: AddReq) => {
|
||||
return await api.AddObj(form);
|
||||
};
|
||||
return {
|
||||
crudOptions: {
|
||||
request: {
|
||||
pageRequest,
|
||||
addRequest,
|
||||
editRequest,
|
||||
delRequest,
|
||||
},
|
||||
actionbar: {
|
||||
buttons: {
|
||||
add: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
rowHandle: {
|
||||
fixed:'right',
|
||||
width: 100,
|
||||
buttons: {
|
||||
view: {
|
||||
type: 'text',
|
||||
},
|
||||
edit: {
|
||||
show: false,
|
||||
},
|
||||
remove: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
columns: {
|
||||
_index: {
|
||||
title: '序号',
|
||||
form: { show: false },
|
||||
column: {
|
||||
//type: 'index',
|
||||
align: 'center',
|
||||
width: '70px',
|
||||
columnSetDisabled: true, //禁止在列设置中选择
|
||||
formatter: (context) => {
|
||||
//计算序号,你可以自定义计算规则,此处为翻页累加
|
||||
let index = context.index ?? 1;
|
||||
let pagination = crudExpose!.crudBinding.value.pagination;
|
||||
return ((pagination!.currentPage ?? 1) - 1) * pagination!.pageSize + index + 1;
|
||||
},
|
||||
},
|
||||
},
|
||||
search: {
|
||||
title: '关键词',
|
||||
column: {
|
||||
show: false,
|
||||
},
|
||||
search: {
|
||||
show: true,
|
||||
component: {
|
||||
props: {
|
||||
clearable: true,
|
||||
},
|
||||
placeholder: '请输入关键词',
|
||||
},
|
||||
},
|
||||
form: {
|
||||
show: false,
|
||||
component: {
|
||||
props: {
|
||||
clearable: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
code: {
|
||||
title: '扫码数据',
|
||||
search: {
|
||||
show: true,
|
||||
},
|
||||
type: 'input',
|
||||
column:{
|
||||
width: 200,
|
||||
},
|
||||
form: {
|
||||
disabled: true,
|
||||
component: {
|
||||
placeholder: '请输入产品件号',
|
||||
},
|
||||
},
|
||||
},
|
||||
product_code: {
|
||||
title: '产品件号',
|
||||
search: {
|
||||
show: true,
|
||||
},
|
||||
type: 'input',
|
||||
column:{
|
||||
minWidth: 120,
|
||||
},
|
||||
form: {
|
||||
disabled: true,
|
||||
component: {
|
||||
placeholder: '请输入产品件号',
|
||||
},
|
||||
},
|
||||
},
|
||||
supplier_code: {
|
||||
title: '供应商代码',
|
||||
search: {
|
||||
show: true,
|
||||
},
|
||||
type: 'input',
|
||||
column:{
|
||||
minWidth: 120,
|
||||
},
|
||||
form: {
|
||||
disabled: true,
|
||||
component: {
|
||||
placeholder: '请输入供应商代码',
|
||||
},
|
||||
},
|
||||
},
|
||||
production_batch: {
|
||||
title: '生产批次',
|
||||
search: {
|
||||
show: true,
|
||||
},
|
||||
type: 'input',
|
||||
column:{
|
||||
minWidth: 120,
|
||||
},
|
||||
form: {
|
||||
disabled: true,
|
||||
component: {
|
||||
placeholder: '请输入生产批次',
|
||||
},
|
||||
},
|
||||
},
|
||||
product_serial_number: {
|
||||
title: '产品序列码',
|
||||
search: {
|
||||
show: true,
|
||||
},
|
||||
type: 'input',
|
||||
column:{
|
||||
minWidth: 120,
|
||||
},
|
||||
form: {
|
||||
disabled: true,
|
||||
component: {
|
||||
placeholder: '请输入产品序列码',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
version_number: {
|
||||
title: '版本号',
|
||||
search: {
|
||||
show: true,
|
||||
},
|
||||
disabled: true,
|
||||
type: 'input',
|
||||
column:{
|
||||
minWidth: 120,
|
||||
},
|
||||
form: {
|
||||
component: {
|
||||
placeholder: '请输入版本号',
|
||||
},
|
||||
},
|
||||
},
|
||||
shift: {
|
||||
title: '班次',
|
||||
type: 'input',
|
||||
column:{
|
||||
minWidth: 90,
|
||||
},
|
||||
search: {
|
||||
show: true,
|
||||
},
|
||||
form: {
|
||||
disabled: true,
|
||||
component: {
|
||||
placeholder: '请输入班次',
|
||||
},
|
||||
},
|
||||
component: { props: { color: 'auto' } }, // 自动染色
|
||||
},
|
||||
status: {
|
||||
title: '状态',
|
||||
type: 'dict-select',
|
||||
dict: dict({
|
||||
data: [
|
||||
{ label: '重复扫码', value: 0 },
|
||||
{ label: '正常', value: 1 },
|
||||
{ label: '未识别码', value: 2 },
|
||||
]
|
||||
}),
|
||||
column: {
|
||||
width: 120
|
||||
},
|
||||
search: {
|
||||
show: true
|
||||
}
|
||||
},
|
||||
...commonCrudConfig({
|
||||
create_datetime: { form: false, table: true, search: false, width: 160 },
|
||||
update_datetime: { form: false, table: true, search: false, width: 160 },
|
||||
creator_name: { form: false, table: true, search: false, width: 100 },
|
||||
})
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
20
web/src/views/plugins/scanInfo/src/scanRecord/index.vue
Normal file
20
web/src/views/plugins/scanInfo/src/scanRecord/index.vue
Normal file
@@ -0,0 +1,20 @@
|
||||
<template>
|
||||
<fs-page>
|
||||
<fs-crud ref="crudRef" v-bind="crudBinding"> </fs-crud>
|
||||
</fs-page>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup name="scanRecord">
|
||||
import { onMounted } from 'vue';
|
||||
import { useFs } from '@fast-crud/fast-crud';
|
||||
import { createCrudOptions } from './crud';
|
||||
import { handleColumnPermission } from '/@/utils/columnPermission';
|
||||
|
||||
const { crudBinding, crudRef, crudExpose, crudOptions, resetCrudOptions } = useFs({ createCrudOptions });
|
||||
|
||||
// 页面打开后获取列表数据
|
||||
onMounted(async () => {
|
||||
// 刷新
|
||||
crudExpose.doRefresh();
|
||||
});
|
||||
</script>
|
||||
BIN
web/src/views/system/home/home.png
Normal file
BIN
web/src/views/system/home/home.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 182 KiB |
File diff suppressed because one or more lines are too long
@@ -204,6 +204,29 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
|
||||
},
|
||||
},
|
||||
},
|
||||
description: {
|
||||
title: '班次',
|
||||
search: {
|
||||
show: true,
|
||||
},
|
||||
type: 'input',
|
||||
column: {
|
||||
minWidth: 100, //最小列宽
|
||||
},
|
||||
form: {
|
||||
rules: [
|
||||
// 表单校验规则
|
||||
{
|
||||
required: true,
|
||||
message: '班次必填项',
|
||||
},
|
||||
],
|
||||
component: {
|
||||
span: 12,
|
||||
placeholder: '请输入班次',
|
||||
}
|
||||
},
|
||||
},
|
||||
dept: {
|
||||
title: '部门',
|
||||
search: {
|
||||
|
||||
Reference in New Issue
Block a user