Commit 016f1194 authored by wanli's avatar wanli

update

parent 06038fd0
No preview for this file type
......@@ -17,12 +17,12 @@ config = dict(
BACKUP_DIR=conf.get('application', 'backup_dir'),
NETDISC=conf.get('uploads', 'netdisc'),
DATABASE=conf.get('database', 'filename'),
DATABASE_FILE=conf.get('scheduler', 'db'),
PONY={
'provider': conf.get('database', 'provider'),
'filename': "../{}".format(conf.get('database', 'filename')),
'create_db': True,
},
DATABASE_FILE=conf.get('scheduler', 'db'),
TABLE_PREFIX='evm_store_',
MD5_SALT="EhuqUkwV",
UPLOAD_SERVER="{}://{}:{}/".format(conf.get('uploads', 'protocol'), conf.get('uploads', 'host'), conf.get('uploads', 'port')),
......
......@@ -53,6 +53,20 @@ class SignalManager(object):
actionGetAnnexList = PySignal()
actionUpdateAnnex = PySignal()
# 系统框架模块
actionAddFramework = PySignal()
actionDeleteFramework = PySignal()
actionGetFramework = PySignal()
actionGetFrameworkList = PySignal()
actionUpdateFramework = PySignal()
# 应用下载统计模块
actionAddDownload = PySignal()
actionDeleteDownload = PySignal()
actionGetDownload = PySignal()
actionGetDownloadList = PySignal()
actionUpdateDownload = PySignal()
def __init__(self):
super(SignalManager, self).__init__()
......
......@@ -17,4 +17,6 @@ db = scheduler.db
name = evm_store
nginx = NginxService
backup_dir = backup
evueapps_dir = evueapps
\ No newline at end of file
evueapps_dir = evueapps
launcher_dir = launcher
framework = framework
\ No newline at end of file
......@@ -9,6 +9,8 @@ from .login_manager import loginManager
from .annex_manager import annexManager
from .upload_manager import uploadManager
from .apps_manager import appsManager
from .download_manager import downloadManager
from .framework_manager import frameworkManager
from .build_logs_manager import buildLogsManager
logger = logging.getLogger("controller")
......@@ -50,4 +52,18 @@ def initConnect():
signalManager.actionGetAnnexList.connect(annexManager.getList)
signalManager.actionUpdateAnnex.connect(annexManager.update)
# 系统框架模块
signalManager.actionAddFramework.connect(frameworkManager.add)
signalManager.actionDeleteFramework.connect(frameworkManager.delete)
signalManager.actionGetFramework.connect(frameworkManager.get)
signalManager.actionGetFrameworkList.connect(frameworkManager.getList)
signalManager.actionUpdateFramework.connect(frameworkManager.update)
# 应用下载统计模块
signalManager.actionAddDownload.connect(downloadManager.add)
signalManager.actionDeleteDownload.connect(downloadManager.delete)
signalManager.actionGetDownload.connect(downloadManager.get)
signalManager.actionGetDownloadList.connect(downloadManager.getList)
signalManager.actionUpdateDownload.connect(downloadManager.update)
initConnect()
\ No newline at end of file
......@@ -39,18 +39,23 @@ class AppsManager(object):
'update_at': datetime.now(),
})
icon = Annex(title=data.get("app_icon").get("filename"), path=data.get("app_icon").get("filepath"), size=data.get("app_icon").get("filesize"), create_by=editor, create_at=datetime.now(), update_by=editor, update_at=datetime.now())
commit()
app_files = []
if data.get("app_files"):
app_files = data.get("app_files")
data.pop("app_files")
data.update({ "app_icon": icon })
result = Apps(**data)
commit()
for a in app_files:
Annex(app_id=result, title=a.get("filename"), path=a.get("filepath"), size=a.get("filesize"), create_by=editor, create_at=datetime.now(), update_by=editor, update_at=datetime.now())
flush()
commit()
if result:
for a in app_files:
Annex(app=result, title=a.get("filename"), path=a.get("filepath"), size=a.get("filesize"), create_by=editor, create_at=datetime.now(), update_by=editor, update_at=datetime.now())
flush()
commit()
return result, "add app {}.".format("success" if result else "fail")
......@@ -89,15 +94,15 @@ class AppsManager(object):
temp.append(item.to_dict(only=["uuid", "app_name"]))
return temp, len(temp), "get app {}.".format("success" if temp else "fail")
result = Apps.select().where(**temp).order_by(desc(Apps.create_at)).page(data.get("pagenum", 1), pagesize=data.get("pagesize", 10))
count = Apps.select().where(**temp).count()
if result and len(result):
temp = []
for item in result:
t = item.to_dict(with_collections=True, related_objects=True, exclude=["app_annex", "app_build_log", "is_delete", "delete_by", "delete_at"])
t = item.to_dict(with_collections=True, related_objects=True, exclude=["app_annex", "app_build_log", "app_download", "is_delete", "delete_by", "delete_at"])
t.update({
"app_icon": item.app_icon.to_dict(only=["path"]),
"create_by": item.create_by.to_dict(only=["uuid", "username"]),
"update_by": item.update_by.to_dict(only=["uuid", "username"]),
"create_at": item.create_at.strftime("%Y-%m-%d %H:%M:%S") if item.create_at else None,
......@@ -113,12 +118,42 @@ class AppsManager(object):
if len(data) <= 0 or (len(data.keys()) == 1 and "id" in data):
return False, "app can not be null."
# 查询请求者是否存在
editor = User.get(id=request.current_user.get("id"))
if not editor:
return False, "current user is not exists"
with db_session:
editor = User.get(id=request.current_user.get("id"))
if not editor:
return False, "current user is not exists"
result = Apps.get(uuid=uuid)
if not result:
return False, "app not found"
if data.get("app_files"):
app_files = data.get("app_files")
for a in app_files:
Annex(app=result, title=a.get("filename"), path=a.get("filepath"), size=a.get("filesize"), create_by=editor, create_at=datetime.now(), update_by=editor, update_at=datetime.now())
flush()
commit()
data.pop("app_files")
if data.get("app_icon"):
condition = {
'update_by': editor,
'update_at': datetime.now()
}
if data.get("app_icon").get("filename"):
condition.update({"title": data.get("app_icon").get("filename")})
if data.get("app_icon").get("filepath"):
condition.update({"path": data.get("app_icon").get("filepath")})
if data.get("app_icon").get("filesize"):
condition.update({"size": data.get("app_icon").get("filesize")})
result.app_icon.set(**condition)
commit()
data.pop("app_icon")
result.set(update_at=datetime.now(), update_by=editor, **data)
commit()
result = fullStackDB.update(Apps, { 'uuid': uuid }, update_at=datetime.now(), update_by=editor, **data)
return result, "update app {}.".format("success" if result else "fail")
return result, "update app {}.".format("success" if result else "fail")
appsManager = AppsManager()
......@@ -28,32 +28,32 @@ class BuildLogsManager(object):
def __init__(self):
super(BuildLogsManager, self).__init__()
def add(self, app_id):
def add(self, app):
with db_session:
editor = User.get(id=request.current_user.get("id"))
if not editor:
return False, "current user is not exists"
# 根据app_id查询应用,获取应用有哪些文件
# 根据app查询应用,获取应用有哪些文件
# 按格式创建文件夹,将这些文件移动到这个文件夹
# 将这些零散文件进行打包
# 更新数据库对应文件的路径
app = Apps.get(uuid=app_id)
app = Apps.get(uuid=app)
if not app:
return None, "app not found"
source_files = Annex.select().filter(app_id=app)
source_files = Annex.select().filter(app=app)
if not source_files:
return None, "apps file not found"
dir_format = "{}-{}-{}".format(app.app_name, app.app_version, int(time.time()))
dir_format = "{}-{}-{}".format(app.app_name, app.app_version, datetime.now().strftime("%Y%m%d%H%M%S"))
upload_dir = os.sep.join([config.get("UPLOAD_PATH"), config.get("UPLOAD_DIR"), "evueapps"])
target_dir = os.sep.join([upload_dir, editor.account, dir_format])
dest_dir = os.sep.join([target_dir, "src"])
if not os.path.exists(dest_dir):
os.makedirs(dest_dir)
app_files = []
for sf in source_files:
parsed_result = urlparse(sf.path)
......@@ -84,7 +84,7 @@ class BuildLogsManager(object):
epk_path = urljoin(config.get("UPLOAD_SERVER"), epk_path.replace('\\', '/'))
app_info['md5'] = str(app_info['md5'])
result = BuildLogs(app_id=app, app_path=epk_path, app_info=app_info, create_by=editor, create_at=datetime.now(), update_by=editor, update_at=datetime.now())
result = BuildLogs(app=app, app_path=epk_path, app_info=app_info, create_by=editor, create_at=datetime.now(), update_by=editor, update_at=datetime.now())
commit()
return epk_path, "add build_logs {}.".format("success" if result else "fail")
......@@ -131,7 +131,7 @@ class BuildLogsManager(object):
for item in result:
t = item.to_dict(with_collections=True, related_objects=True, exclude=["is_delete", "delete_by", "delete_at"])
t.update({
"app_id": item.app_id.to_dict(exclude=["is_delete", "delete_by", "delete_at"]),
"app": item.app.to_dict(exclude=["is_delete", "delete_by", "delete_at"]),
"create_by": item.create_by.to_dict(only=["uuid", "username"]),
"update_by": item.update_by.to_dict(only=["uuid", "username"]),
"create_at": item.create_at.strftime("%Y-%m-%d %H:%M:%S") if item.create_at else None,
......
#!/usr/bin/env python
# -*- coding: utf_8 -*-
import os
import copy
import time
import types
import json
import logging
import traceback
import shutil
from collections import OrderedDict
from urllib.parse import urlparse, urljoin
from datetime import datetime
from pony.orm import *
from flask import request
from app.setting import config, conf
from model import fullStackDB
from model.download import AppDownload
from model.framework import Framework
from model.apps import Apps
from model.user import User
from utils import sql_filter
from utils.tools_epk import EpkApp
logger = logging.getLogger("DownloadManager")
def convert_url_to_local_path(url):
parsed_result = urlparse(url)
target_file = os.sep.join([config.get("UPLOAD_PATH").replace('\\', '/'), parsed_result.path])
target_file = os.path.normpath(target_file)
return target_file
class DownloadManager(object):
def __init__(self):
super(DownloadManager, self).__init__()
def add(self, data):
with db_session:
app = Apps.get(id=data.get("app"))
if not app:
return False, "app does not found"
editor = User.get(id=request.current_user.get("id"))
if not editor:
return False, "current user is not exists"
data.update({
'create_by': editor,
'create_at': datetime.now(),
'update_by': editor,
'update_at': datetime.now(),
})
result = AppDownload(app=app, imei=data.get("imei"), **data)
commit()
return result, "add dictionary {}.".format("success" if result else "fail")
def delete(self, uuid):
with db_session:
editor = User.get(id=request.current_user.get("id"))
if not editor:
return False, "current user is not exists"
result = AppDownload.get(uuid=uuid)
if not result:
return False, "dict does not exists"
result.set(is_delete=True, delete_at=datetime.now(), delete_by=editor)
commit()
return result, "delete dictionary {}.".format("success" if result else "fail")
def get(self, data):
# 流程如下:
# 获取前端传来的应用UUID和IMEI
# 根据应用UUID查找应用信息,找不到返回失败信息
# 如果应用ID是evue_launcher,则进行如下处理
# 遍历系统所有应用,将相关应用根据4个一组拼接到一个数组里面去
# 最后将这些信息导出为一个JSON文件
# 将evue_launcher.evue和evue_dock.evue以及相关资源文件进行打包
# 以上文件全部是复制处理,最后根据格式生成文件夹,将epk文件写入到这里
# 读取这个epk文件,以encoding='utf8'格式返回字节流
# 否则就是普通应用
# 查找出这个应用路径以及依赖文件
# 将这些文件进行打包
# 读取这个epk文件,以encoding='utf8'格式返回字节流
# 此次下载将生成一次下载记录
# 当前还没有校验前端传来的IMEI是否是合法的
epk_path = None
with db_session:
# 判断应用UUID是否等于evue_launcher
if data.get("id") == "evue_launcher":
# 读取evue_launcher.evue和evue_dock.evue以及相关资源文件
launcher_file = Framework.get(name="evue_launcher")
if not launcher_file:
return False, "evue_launcher not found"
dock_file = Framework.get(name="evue_dock")
if not dock_file:
return False, "evue_launcher not found"
# 按照格式创建文件夹
dir_format = datetime.now().strftime("%Y%m%d%H%M%S")
build_path = os.sep.join([os.getcwd(), config.get("UPLOAD_DIR"), conf.get('application', 'launcher_dir'), data.get("imei"), dir_format])
if not os.path.exists(build_path):
os.makedirs(build_path)
build_source_path = os.sep.join([build_path, "src"])
if not os.path.exists(build_source_path):
os.mkdir(build_source_path)
target_path = launcher_file.assets.get("files", []) + dock_file.assets.get("files", [])
# 将取evue_launcher.evue和evue_dock.evue以及相关资源文件复制到这个目录下
for f in target_path:
tf = convert_url_to_local_path(f)
if not os.path.exists(tf):
return False, "{} not found".format(tf)
shutil.copy(tf, build_source_path)
temp = []
# 读取当前系统所有应用及其资源文件
apps = Apps.select().where(is_delete=False).order_by(Apps.create_at)
result_json = []
for val in apps:
tmp = val.to_dict(with_collections=True, related_objects=True)
if val.app_build_log:
temp.append({
'icon': val.app_icon.title,
'name': val.app_name,
'url': val.app_url,
'version': val.app_version,
'epk': tmp.get("app_build_log")[0].app_path,
'category': val.category,
'id': str(val.uuid),
})
if val.app_annex:
# 需要将每个应用的文件拷贝到目标文件夹中
for f in val.app_annex:
tf = convert_url_to_local_path(f.path)
if not os.path.exists(tf):
return False, "{} not found".format(tf)
shutil.copy(tf, build_source_path)
if len(temp) % 4 == 0 and temp:
result_json.append(copy.deepcopy(temp))
temp = []
if temp:
result_json.append(copy.deepcopy(temp))
json_str = json.dumps(result_json, sort_keys=False, ensure_ascii=False)
with open(os.sep.join([build_source_path, 'evue_dock_apps.json']), 'w') as json_file:
json_file.write(json_str)
# 打包成EPK文件
epk = EpkApp(appName="evue_launcher", appDir=build_source_path, appVersion="1.0", output=build_path)
epk.pack()
epk_path = os.sep.join([build_path, 'evue_launcher.epk'])
else:
# 根据应用UUID查找相关应用
app = Apps.get(uuid=data.get("id"), is_delete=False)
if not app:
return False, "app not found"
if not app.app_build_log:
return False, "app build file not found"
tmp = app.to_dict(with_collections=True, related_objects=True)
epk_path = convert_url_to_local_path(tmp.get("app_build_log")[0].app_path)
if not os.path.exists(epk_path):
return False, "epk file not found"
# 创建一条下载记录
if app:
AppDownload(app=app, imei=data.get("imei"))
commit()
# 读取epk文件,按照格式返回相应结构体数据
result = None
with open(epk_path, "rb") as f:
result = f.read()
return str(result), "get dictionary {}.".format("success" if result else "no data")
def getList(self, data):
if not data or len(data) <= 0:
return False, 0, "parameters can not be null."
temp = copy.deepcopy(data)
if 'pagenum' in temp:
temp.pop('pagenum')
if 'pagesize' in temp:
temp.pop('pagesize')
if 'scope_type' in temp:
temp.pop('scope_type')
temp.setdefault("is_delete", False)
with db_session:
if "scope_type" in data and data.get("scope_type") == "list":
result = AppDownload.select().where(**temp).order_by(AppDownload.sort)
temp = []
for item in result:
temp.append(item.to_dict(only=["uuid"]))
return temp, len(temp), "get dictionary list {}.".format("success" if temp else "no data")
result = AppDownload.select().where(**temp).order_by(desc(AppDownload.download_at)).page(data.get("pagenum", 1), data.get("pagesize", 10))
count = AppDownload.select().where(**temp).count()
if result:
temp = []
for item in result:
t = item.to_dict(with_collections=True, related_objects=True)
t.update({
"app": item.app.to_dict(exclude=["create_by", "update_by", "delete_by", "is_delete"]),
"download_at": item.download_at.strftime("%Y-%m-%d %H:%M:%S")
})
temp.append(t)
result = temp
return result, count, "get dictionary {}.".format("success" if result else "fail")
def update(self, uuid, data):
# 当参数为空时,直接返回错误
if len(data) <= 0 or (len(data.keys()) == 1 and "id" in data):
return False, "parameters can not be null."
with db_session:
# 查询请求者是否存在
editor = User.get(id=request.current_user.get("id"))
if not editor:
return False, "current user is not exists"
result = AppDownload.get(uuid=uuid)
if not result:
return False, "app does not found"
result.set(update_at=datetime.now(), update_by=editor, **data)
commit()
return result, "update dictionary {}.".format("success" if result else "fail")
downloadManager = DownloadManager()
#!/usr/bin/env python
# -*- coding: utf_8 -*-
import copy
import time
import types
import json
import logging
import traceback
from datetime import datetime
from pony.orm import *
from flask import request
from model import fullStackDB
from model.framework import Framework
from model.user import User
from utils import sql_filter
logger = logging.getLogger("FrameworkManager")
class FrameworkManager(object):
def __init__(self):
super(FrameworkManager, self).__init__()
def add(self, data):
editor = User.get(id=request.current_user.get("id"))
if not editor:
return False, "current user is not exists"
data.update({
'create_by': editor,
'create_at': datetime.now(),
'update_by': editor,
'update_at': datetime.now(),
})
result = fullStackDB.add(Framework, **data)
return result, "add framework {}.".format("success" if result else "fail")
def delete(self, uuid):
editor = User.get(id=request.current_user.get("id"))
if not editor:
return False, "current user is not exists"
result = fullStackDB.update(Framework, { 'uuid': uuid }, is_delete=True, delete_at=datetime.now(), delete_by=editor)
return result, "delete framework {}.".format("success" if result else "fail")
def get(self, data):
result = Framework.get(**data)
if result:
result = result.to_dict(with_collections=True, related_objects=True, only=["uuid", "create_at", "update_at", "delete_at"])
return result, "get framework {}.".format("success" if result else "fail")
def getList(self, data):
if not data or len(data) <= 0:
return False, 0, "parameters can not be null."
temp = copy.deepcopy(data)
if 'pagenum' in temp:
temp.pop('pagenum')
if 'pagesize' in temp:
temp.pop('pagesize')
if 'scope_type' in temp:
temp.pop('scope_type')
temp.setdefault("is_delete", False)
if "scope_type" in data and data.get("scope_type") == "list":
result = Framework.select().where(**temp).order_by(desc(Framework.create_at))
temp = []
for item in result:
temp.append(item.to_dict(only=["uuid", "name"]))
return temp, len(temp), "get select {}.".format("success" if temp else "no data")
result = fullStackDB.pagination(Framework, Framework.create_at, pagenum=data.get("pagenum", 1), pagesize=data.get("pagesize", 10), **temp)
count = fullStackDB.count(Framework, **temp)
if result and len(result):
temp = []
for item in result:
t = item.to_dict(with_collections=True, related_objects=True, exclude=["is_delete", "delete_at", "delete_by"])
t.update({
"create_at": item.create_at.strftime("%Y-%m-%d %H:%M:%S"),
"update_at": item.update_at.strftime("%Y-%m-%d %H:%M:%S"),
"create_by": item.create_by.to_dict(only=["uuid", "username"]),
"update_by": item.update_by.to_dict(only=["uuid", "username"])
})
temp.append(t)
result = temp
return result, count, "get framework {}.".format("success" if result else "no data")
def update(self, uuid, data):
# 当参数为空时,直接返回错误
if len(data) <= 0 or (len(data.keys()) == 1 and "id" in data):
return False, "parameters can not be null."
# 查询请求者是否存在
editor = User.get(id=request.current_user.get("id"))
if not editor:
return False, "current user is not exists"
result = None
with db_session:
result = Framework.get(uuid=uuid)
if result:
result.set(update_at=datetime.now(), update_by=editor, **data)
commit()
# result = fullStackDB.update(Role, { 'uuid': uuid }, update_at=datetime.now(), update_by=editor, **data)
return result, "update role {}.".format("success" if result else "fail")
frameworkManager = FrameworkManager()
......@@ -118,7 +118,7 @@ class UserManager(object):
user = User.get(uuid=uuid)
if user:
user.set(update_at=datetime.now(), update_by=editor.id, **data)
result = user.to_dict(only=["account", "gender", "birthday", "hometown", "contact", "email",])
result = user.to_dict(only=["account", "gender", "birthday", "hometown", "phone", "email",])
if result.get("birthday"):
result.update({ "birthday": result.get("birthday").strftime("%Y-%m-%d") })
return result, "update user success"
......@@ -131,7 +131,7 @@ class UserManager(object):
'''
result = User.get(id=request.current_user.get("id"), is_delete=False)
if result:
temp = result.to_dict(with_collections=True, related_objects=True, only=["uuid", "username", "account", "contact", "email", "hometown", "gender", "birthday", "entry_time", "expire_date", "create_at", "update_at"])
temp = result.to_dict(with_collections=True, related_objects=True, only=["uuid", "username", "account", "phone", "email", "hometown", "gender", "birthday", "entry_time", "expire_date", "create_at", "update_at"])
temp.update({
"birthday": result.birthday.strftime("%Y-%m-%d") if result.birthday else None,
"create_at": result.create_at.strftime("%Y-%m-%d %H:%M:%S") if result.create_at else None,
......@@ -218,7 +218,7 @@ class UserManager(object):
if result and len(result):
temp = []
for item in result:
t = item.to_dict(with_collections=True, related_objects=True, only=["uuid", "username", "account", "contact", "email", "hometown", "gender", "birthday", "entry_time", "expire_date", "create_at", "update_at", "remarks"])
t = item.to_dict(with_collections=True, related_objects=True, only=["uuid", "username", "account", "phone", "email", "hometown", "gender", "birthday", "entry_time", "expire_date", "create_at", "update_at", "remarks"])
t.update({
"email": "" if item.email == "user@example.com" else item.email,
"birthday": item.birthday.strftime("%Y-%m-%d") if item.birthday else None,
......
......@@ -9,7 +9,7 @@ from apscheduler.executors.pool import ThreadPoolExecutor, ProcessPoolExecutor
jobstores = {
# 'mongo': MongoDBJobStore(),
'default': SQLAlchemyJobStore(url='sqlite:///{}'.format(config.get("DATABASE_FILE")), engine_options={ 'connect_args': { 'timeout': 15 } })
'default': SQLAlchemyJobStore(url='sqlite:///{}'.format("scheduler.db", engine_options={ 'connect_args': { 'timeout': 15 } })
}
executors = {
'default': ThreadPoolExecutor(20),
......
......@@ -13,7 +13,8 @@ class Annex(db.Entity):
_table_ = "{}".format(config['TABLE_PREFIX']) + "annex"
id = PrimaryKey(int, auto=True)
uuid = Required(uuid.UUID, unique=True, default=uuid.uuid1, index=True)
app_id = Optional("Apps", reverse="app_annex")
app = Optional("Apps", reverse="app_annex")
app_icon = Optional("Apps", reverse="app_icon")
title = Required(str, max_len=200) # 文件名
path = Required(LongStr) # 文件路径
type = Required(int, default=0) # 文件类型 PNG/JPG/GIF/MP3/MP4/DOCX/XLSX/PPT/PDF...
......
#!/usr/bin/env python
# -*- coding: utf_8 -*-
import uuid
from datetime import datetime
from pony.orm import PrimaryKey, Required, Optional, Set
from app import config
from . import fullStackDB
db = fullStackDB.db
# 当前用户拥有哪些APP
class AppUser(db.Entity):
_table_ = "{}".format(config['TABLE_PREFIX']) + "app_user"
id = PrimaryKey(int, auto=True)
uuid = Required(uuid.UUID, unique=True, default=uuid.uuid1, index=True)
app = Required("Apps", reverse="app_user")
imei = Optional(str)
create_at = Required(datetime, default=datetime.now)
create_by = Required("User", reverse='app_users_creator')
update_at = Required(datetime, default=datetime.now)
update_by = Required("User", reverse='app_users_updater')
delete_at = Optional(datetime)
delete_by = Optional("User", reverse='app_users_deleter')
is_delete = Required(bool, default=False)
sort = Optional(int, size=32, default=0)
remarks = Optional(str, max_len=255, default="", nullable=True)
\ No newline at end of file
......@@ -7,6 +7,10 @@ from pony.orm import PrimaryKey, Required, Optional, Set, LongStr, Json
from app import config
from . import fullStackDB
# ********************************
from .app_users import AppUser
# ********************************
db = fullStackDB.db
class Apps(db.Entity):
......@@ -15,10 +19,14 @@ class Apps(db.Entity):
uuid = Required(uuid.UUID, unique=True, default=uuid.uuid1, index=True)
app_name = Required(str, max_len=200)
app_version = Optional(str, default="")
app_logo = Optional(str, default="")
app_url = Optional(str, default="")
category = Optional(str, default="")
app_icon = Required("Annex", reverse="app_icon")
app_desc = Optional(str, default="")
app_annex = Set("Annex", reverse="app_id")
app_build_log = Set("BuildLogs", reverse="app_id")
app_annex = Set("Annex", reverse="app")
app_user = Optional("AppUser", reverse="app")
app_build_log = Set("BuildLogs", reverse="app")
app_download = Set("AppDownload", reverse="app")
create_at = Required(datetime, default=datetime.now)
create_by = Required("User", reverse='apps_creator') # BuildLogs与User一对一关系
update_at = Required(datetime, default=datetime.now)
......
......@@ -13,7 +13,7 @@ class BuildLogs(db.Entity):
_table_ = "{}".format(config['TABLE_PREFIX']) + "build_logs"
id = PrimaryKey(int, auto=True)
uuid = Required(uuid.UUID, unique=True, default=uuid.uuid1, index=True)
app_id = Optional("Apps", reverse="app_build_log")
app = Optional("Apps", reverse="app_build_log")
app_path = Optional(str, default="")
app_info = Optional(Json, default={})
create_at = Required(datetime, default=datetime.now)
......
#!/usr/bin/env python
# -*- coding: utf_8 -*-
import uuid
from datetime import datetime
from pony.orm import PrimaryKey, Required, Optional, Set
from app import config
from . import fullStackDB
db = fullStackDB.db
class AppDownload(db.Entity):
_table_ = "{}".format(config['TABLE_PREFIX']) + "download"
id = PrimaryKey(int, auto=True)
uuid = Required(uuid.UUID, unique=True, default=uuid.uuid1, index=True)
app = Optional("Apps", reverse="app_download")
imei = Required(str)
download_at = Required(datetime, default=datetime.now)
is_delete = Required(bool, default=False)
sort = Optional(int, size=32, default=0)
remarks = Optional(str, max_len=255, default="", nullable=True)
#!/usr/bin/env python
# -*- coding: utf_8 -*-
import uuid
from datetime import datetime
from pony.orm import PrimaryKey, Required, Optional, Set, LongStr, Json
from app import config
from . import fullStackDB
db = fullStackDB.db
class Framework(db.Entity):
_table_ = "{}".format(config['TABLE_PREFIX']) + "framework"
id = PrimaryKey(int, auto=True)
uuid = Required(uuid.UUID, unique=True, default=uuid.uuid1, index=True)
name = Required(str) # 名称
url = Required(str) # 路径
desc = Required(str) # 描述信息
type = Required(str) # 模板类型
assets = Optional(Json, default={}) # 静态资源文件
create_at = Required(datetime, default=datetime.now)
create_by = Required("User", reverse='framework_creator')
update_at = Required(datetime, default=datetime.now)
update_by = Required("User", reverse='framework_updater')
delete_at = Optional(datetime)
delete_by = Optional("User", reverse='framework_deleter')
is_delete = Required(bool, default=False)
sort = Optional(int, size=32, default=0)
remarks = Optional(str, max_len=255, default="", nullable=True)
\ No newline at end of file
......@@ -18,7 +18,7 @@ class User(db.Entity):
password = Required(str, max_len=64)
gender = Required(int, size=8) # 性别,未知0 男1 女2
birthday = Optional(date, default=date.today()) # 使用age会带来age无法随时间变化问题
contact = Required(str, max_len=11) # 联系方式
phone = Required(str, max_len=11) # 联系方式
email = Optional(str, max_len=100) # 邮箱
hometown = Optional(str, max_len=50) # 籍贯
entry_time = Required(datetime, default=datetime.now) # 入职时间
......@@ -38,6 +38,12 @@ class User(db.Entity):
apps_creator = Set('Apps', reverse='create_by')
apps_updater = Set('Apps', reverse='update_by')
apps_deleter = Set('Apps', reverse='delete_by')
app_users_creator = Set('AppUser', reverse='create_by')
app_users_updater = Set('AppUser', reverse='update_by')
app_users_deleter = Set('AppUser', reverse='delete_by')
build_logs_creator = Set('BuildLogs', reverse='create_by')
build_logs_updater = Set('BuildLogs', reverse='update_by')
build_logs_deleter = Set('BuildLogs', reverse='delete_by')
\ No newline at end of file
build_logs_deleter = Set('BuildLogs', reverse='delete_by')
framework_creator = Set('Framework', reverse='create_by')
framework_updater = Set('Framework', reverse='update_by')
framework_deleter = Set('Framework', reverse='delete_by')
\ No newline at end of file
......@@ -3,8 +3,6 @@ from . import BaseSchema
from marshmallow import fields, validate, RAISE, INCLUDE, EXCLUDE
class AddSchema(BaseSchema):
flow = fields.UUID(required=False)
project = fields.UUID(required=False)
title = fields.String(required=True)
path = fields.String(required=True)
size = fields.Float(required=True)
......@@ -14,8 +12,6 @@ class AddSchema(BaseSchema):
unknown = EXCLUDE
class UpdateSchema(BaseSchema):
flow = fields.UUID(required=False)
title = fields.String(required=False)
path = fields.String(required=False)
type = fields.Int(required=False)
size = fields.Float(required=False)
......@@ -31,8 +27,6 @@ class DeleteSchema(BaseSchema):
class QuerySchema(BaseSchema):
uuid = fields.UUID(required=False)
title = fields.String(required=False)
project = fields.Int(required=False)
flow = fields.Int(required=False)
class Meta:
unknown = EXCLUDE
......
......@@ -5,7 +5,9 @@ from marshmallow import fields, validate, RAISE, INCLUDE, EXCLUDE
class AddSchema(BaseSchema):
app_name = fields.String(required=True)
app_version = fields.String(required=False)
app_logo = fields.String(required=False)
app_icon = fields.Dict(required=True)
app_url = fields.String(required=False)
category = fields.String(required=False)
app_desc = fields.String(required=False)
app_files = fields.List(fields.Dict, required=False)
......@@ -15,7 +17,9 @@ class AddSchema(BaseSchema):
class UpdateSchema(BaseSchema):
app_name = fields.String(required=False)
app_version = fields.String(required=False)
app_logo = fields.String(required=False)
app_icon = fields.Dict(required=True)
app_url = fields.String(required=False)
category = fields.String(required=False)
app_desc = fields.String(required=False)
app_files = fields.List(fields.Dict, required=False)
......
from datetime import datetime
from . import BaseSchema
from marshmallow import fields, validate, RAISE, INCLUDE, EXCLUDE
class AddSchema(BaseSchema):
app = fields.String(required=True)
imei = fields.String(required=True)
class Meta:
unknown = EXCLUDE
class UpdateSchema(BaseSchema):
app = fields.String(required=False)
imei = fields.String(required=False)
class Meta:
unknown = EXCLUDE
class DeleteSchema(BaseSchema):
class Meta:
unknown = EXCLUDE
class DownloadSchema(BaseSchema):
id = fields.String(required=True)
imei = fields.String(required=True)
class Meta:
unknown = EXCLUDE
class QuerySchema(BaseSchema):
uuid = fields.UUID(required=False)
scope_type = fields.String(required=False)
pagenum = fields.Int(required=False)
pagesize = fields.Int(required=False, max=50) # 防止用户传特别大的数,导致数据库查询阻塞
class Meta:
unknown = EXCLUDE
class ResponseSchema(BaseSchema):
uuid = fields.UUID(required=False)
create_at = fields.DateTime(required=False, default=datetime.now)
update_at = fields.DateTime(required=False, default=datetime.now)
class Meta:
unknown = INCLUDE
from datetime import datetime
from . import BaseSchema
from marshmallow import fields, validate, RAISE, INCLUDE, EXCLUDE
class AddSchema(BaseSchema):
name = fields.String(required=True)
url = fields.String(required=True)
desc = fields.String(required=True)
type = fields.String(required=True)
assets = fields.Dict(required=False)
sort = fields.Integer(required=False, default=0, allow_none=True)
remarks = fields.String(required=False, default=" ", allow_none=True)
is_system = fields.Boolean(required=False, default=False, allow_none=True)
class Meta:
unknown = EXCLUDE
class UpdateSchema(BaseSchema):
name = fields.String(required=False)
url = fields.String(required=False)
desc = fields.String(required=False)
type = fields.String(required=False)
assets = fields.Dict(required=False)
sort = fields.Integer(required=False)
remarks = fields.String(required=False)
class Meta:
unknown = EXCLUDE
class DeleteSchema(BaseSchema):
class Meta:
unknown = EXCLUDE
class QuerySchema(BaseSchema):
uuid = fields.UUID(required=False)
scope_type = fields.String(required=False)
type = fields.Integer(required=False)
pagenum = fields.Int(required=False)
pagesize = fields.Int(required=False, max=50) # 防止用户传特别大的数,导致数据库查询阻塞
class Meta:
unknown = EXCLUDE
class ResponseSchema(BaseSchema):
uuid = fields.UUID(required=False)
create_at = fields.DateTime(required=False, default=datetime.now)
update_at = fields.DateTime(required=False, default=datetime.now)
class Meta:
unknown = INCLUDE
......@@ -12,7 +12,7 @@ class RegisterSchema(BaseSchema):
username = fields.String(required=True, validate=validate.Length(min=3, max=20))
password = fields.String(required=True, validate=validate.Length(min=3, max=18))
email = fields.Email(required=False, missing="user@example.com")
contact = fields.String(required=True, validate=validate.Length(min=11, max=11))
phone = fields.String(required=True, validate=validate.Length(min=11, max=11))
gender = fields.Int(required=True,)
birthday = fields.DateTime(missing=None)
hometown = fields.String(missing="")
......
......@@ -17,7 +17,7 @@ class AddSchema(BaseSchema):
username = fields.String(required=False, validate=validate.Length(min=2, max=20))
password = fields.String(required=True, validate=validate.Length(min=6, max=18))
email = fields.Email(required=False)
contact = fields.String(required=True, validate=validate.Length(min=11, max=11))
phone = fields.String(required=True, validate=validate.Length(min=11, max=11))
gender = fields.Int(required=True)
birthday = fields.Date(missing=None)
hometown = fields.String(missing="")
......@@ -39,7 +39,7 @@ class UpdateSchema(BaseSchema):
account = fields.String(required=False, validate=validate.Length(min=2, max=20))
username = fields.String(required=False, validate=validate.Length(min=2, max=20))
email = fields.Email(required=False)
contact = fields.String(required=False, validate=validate.Length(min=11, max=11))
phone = fields.String(required=False, validate=validate.Length(min=11, max=11))
gender = fields.Int(required=False)
birthday = fields.Date(required=False)
hometown = fields.String(required=False)
......@@ -69,7 +69,7 @@ class ResponseSchema(BaseSchema):
username = fields.String(required=True, validate=validate.Length(min=2, max=20))
password = fields.String(required=True, validate=validate.Length(min=6, max=18))
email = fields.Email(required=False)
contact = fields.String(required=True, validate=validate.Length(min=11, max=11))
phone = fields.String(required=True, validate=validate.Length(min=11, max=11))
gender = fields.Int(required=True)
birthday = fields.Date(required=False)
hometown = fields.String(required=False)
......
......@@ -12,6 +12,8 @@ from .login import login_api
from .user import user_api
from .annex import annex_api
from .apps import apps_api
from .framework import framework_api
from .download import download_api
from .ws import NotifyHandler, ThreadNotifyHandler
from model import fullStackDB
from fullstack.response import ResponseCode, response_result
......@@ -42,6 +44,8 @@ def create_app():
app.register_blueprint(user_api)
app.register_blueprint(annex_api)
app.register_blueprint(apps_api)
app.register_blueprint(framework_api)
app.register_blueprint(download_api)
@app.errorhandler(InternalServerError)
def handle_500(e):
......
......@@ -58,4 +58,8 @@ def upload_file():
@api.route("/system/updateDatabase", methods=['GET'])
def update_db():
result = []
for index in range(16):
print(index)
result.append(str(uuid.uuid1()))
return response_result(ResponseCode.OK, data=result)
......@@ -11,7 +11,7 @@ from fullstack.login import Auth
from fullstack.validation import validate_schema
from fullstack.response import ResponseCode, response_result
from schema.apps import AddSchema, DeleteSchema, QuerySchema, UpdateSchema
from schema.build_logs import AddSchema, QuerySchema
from schema.build_logs import AddSchema as LogAddScheme, QuerySchema as LogQuerySchema
logger = logging.getLogger("appsApi")
......@@ -64,27 +64,6 @@ def get():
logger.error(str(e))
return response_result(ResponseCode.SERVER_ERROR, msg=str(e))
@apps_api.route("/build/<uuid:id>", methods=['POST'])
@validate_schema(AddSchema)
@Auth.auth_required
def build_app(id):
result, message = signalManager.actionAddBuildLog.emit(id)
if result:
return response_result(ResponseCode.OK, data=result, msg=message)
else:
return response_result(ResponseCode.NOTHING_CHANGE, msg=message)
@apps_api.route("/buildLogs", methods=['POST'])
@validate_schema(QuerySchema)
@Auth.auth_required
def get_build_logs():
result, count, message = signalManager.actionGetBuildLogList.emit(request.schema_data)
if result:
return response_result(ResponseCode.OK, data=result, msg=message, count=count)
else:
return response_result(ResponseCode.NOTHING_CHANGE, msg=message)
@apps_api.route("/list", methods=['POST'])
@validate_schema(QuerySchema)
@Auth.auth_required
......@@ -115,3 +94,23 @@ def update(id):
traceback.print_exc()
logger.error(str(e))
return response_result(ResponseCode.SERVER_ERROR)
@apps_api.route("/build/<uuid:id>", methods=['POST'])
@validate_schema(LogAddScheme)
@Auth.auth_required
def build_app(id):
result, message = signalManager.actionAddBuildLog.emit(id)
if result:
return response_result(ResponseCode.OK, data=result, msg=message)
else:
return response_result(ResponseCode.NOTHING_CHANGE, msg=message)
@apps_api.route("/buildLogs", methods=['POST'])
@validate_schema(LogQuerySchema)
@Auth.auth_required
def get_build_logs():
result, count, message = signalManager.actionGetBuildLogList.emit(request.schema_data)
if result:
return response_result(ResponseCode.OK, data=result, msg=message, count=count)
else:
return response_result(ResponseCode.NOTHING_CHANGE, msg=message)
\ No newline at end of file
#!/usr/bin/env python
# -*- coding: utf_8 -*-
import os
import json
import datetime
import logging
import traceback
from flask import Blueprint, request
from app import config, signalManager
from fullstack.login import Auth
from fullstack.validation import validate_schema
from fullstack.response import ResponseCode, response_result
from schema.download import AddSchema, DeleteSchema, QuerySchema, UpdateSchema, DownloadSchema
logger = logging.getLogger("DownloadApi")
download_api = Blueprint("download_api", __name__, url_prefix="/api/v1/%s/download" % config['NAME'])
@download_api.route("/add", methods=['POST'])
@validate_schema(AddSchema)
@Auth.auth_required
def add():
try:
isSuccess, message = signalManager.actionAddDownload.emit(request.schema_data)
if isSuccess:
return response_result(ResponseCode.OK, msg=message)
else:
return response_result(ResponseCode.REQUEST_ERROR, msg=message)
except Exception as e:
traceback.print_exc()
logger.error(str(e))
return response_result(ResponseCode.SERVER_ERROR, msg=str(e))
@download_api.route("/delete/<uuid:id>", methods=['POST'])
@validate_schema(DeleteSchema)
@Auth.auth_required
def delete(id):
try:
isSuccess, message = signalManager.actionDeleteDownload.emit(id)
if isSuccess:
return response_result(ResponseCode.OK, msg=message)
else:
return response_result(ResponseCode.REQUEST_ERROR, msg=message)
except Exception as e:
traceback.print_exc()
logger.error(str(e))
return response_result(ResponseCode.SERVER_ERROR)
@download_api.route("/apps", methods=["POST"])
@validate_schema(DownloadSchema)
@Auth.auth_required
def get():
try:
result, message = signalManager.actionGetDownload.emit(request.schema_data)
if result:
return response_result(ResponseCode.OK, data=result, msg=message)
else:
return response_result(ResponseCode.REQUEST_ERROR, msg=message)
except Exception as e:
traceback.print_exc()
logger.error(str(e))
return response_result(ResponseCode.SERVER_ERROR, msg=str(e))
@download_api.route("/list", methods=['POST'])
@validate_schema(QuerySchema)
@Auth.auth_required
def get_list():
try:
result, count, message = signalManager.actionGetDownloadList.emit(request.schema_data)
if result:
return response_result(ResponseCode.OK, data=result, msg=message, count=count)
else:
return response_result(ResponseCode.REQUEST_ERROR, msg=message)
except Exception as e:
traceback.print_exc()
logger.error(str(e))
return response_result(ResponseCode.SERVER_ERROR)
@download_api.route("/update/<uuid:id>", methods=['POST'])
@validate_schema(UpdateSchema)
@Auth.auth_required
def update(id):
try:
isSuccess, message = signalManager.actionUpdateDownload.emit(id, request.schema_data)
if isSuccess:
return response_result(ResponseCode.OK, msg=message)
else:
return response_result(ResponseCode.REQUEST_ERROR, msg=message)
except Exception as e:
traceback.print_exc()
logger.error(str(e))
return response_result(ResponseCode.SERVER_ERROR)
......@@ -10,18 +10,18 @@ from app import config, signalManager
from fullstack.login import Auth
from fullstack.validation import validate_schema
from fullstack.response import ResponseCode, response_result
from schema.summary import AddSchema, DeleteSchema, QuerySchema, UpdateSchema
from schema.framework import AddSchema, DeleteSchema, QuerySchema, UpdateSchema
logger = logging.getLogger("summaryApi")
logger = logging.getLogger("frameworkApi")
summary_api = Blueprint("summary_api", __name__, url_prefix="/api/v1/%s/summary" % config['NAME'])
framework_api = Blueprint("framework_api", __name__, url_prefix="/api/v1/%s/framework" % config['NAME'])
@summary_api.route("/add", methods=['POST'])
@framework_api.route("/add", methods=['POST'])
@validate_schema(AddSchema)
@Auth.auth_required
def add():
try:
isSuccess, message = signalManager.actionAddSummary.emit(request.schema_data)
isSuccess, message = signalManager.actionAddFramework.emit(request.schema_data)
if isSuccess:
return response_result(ResponseCode.OK, msg=message)
else:
......@@ -32,12 +32,12 @@ def add():
return response_result(ResponseCode.SERVER_ERROR, msg=str(e))
@summary_api.route("/delete/<uuid:id>", methods=['POST'])
@framework_api.route("/delete/<uuid:id>", methods=['POST'])
@validate_schema(DeleteSchema)
@Auth.auth_required
def delete(id):
try:
isSuccess, message = signalManager.actionDeleteSummary.emit(id)
isSuccess, message = signalManager.actionDeleteFramework.emit(id)
if isSuccess:
return response_result(ResponseCode.OK, msg=message)
else:
......@@ -48,12 +48,12 @@ def delete(id):
return response_result(ResponseCode.SERVER_ERROR)
@summary_api.route("/get", methods=["POST"])
@framework_api.route("/get", methods=["POST"])
@validate_schema(QuerySchema)
@Auth.auth_required
def get():
try:
result, message = signalManager.actionGetSummary.emit(request.schema_data)
result, message = signalManager.actionGetFramework.emit(request.schema_data)
if result:
return response_result(ResponseCode.OK, data=result, msg=message)
else:
......@@ -64,12 +64,12 @@ def get():
return response_result(ResponseCode.SERVER_ERROR, msg=str(e))
@summary_api.route("/list", methods=['POST'])
@framework_api.route("/list", methods=['POST'])
@validate_schema(QuerySchema)
@Auth.auth_required
def get_list():
try:
result, count, message = signalManager.actionGetSummaryList.emit(request.schema_data)
result, count, message = signalManager.actionGetFrameworkList.emit(request.schema_data)
if result:
return response_result(ResponseCode.OK, data=result, msg=message, count=count)
else:
......@@ -80,12 +80,12 @@ def get_list():
return response_result(ResponseCode.SERVER_ERROR)
@summary_api.route("/update/<uuid:id>", methods=['POST'])
@framework_api.route("/update/<uuid:id>", methods=['POST'])
@validate_schema(UpdateSchema)
@Auth.auth_required
def update(id):
try:
isSuccess, message = signalManager.actionUpdateSummary.emit(id, request.schema_data)
isSuccess, message = signalManager.actionUpdateFramework.emit(id, request.schema_data)
if isSuccess:
return response_result(ResponseCode.OK, msg=message)
else:
......
......@@ -45,3 +45,67 @@ export function getBuildLogsList(params) {
data: params,
});
}
export function getFrameworkList(params) {
return request({
url: "/api/v1/evm_store/framework/list",
method: "post",
data: params,
});
}
export function addFramework(params) {
return request({
url: "/api/v1/evm_store/framework/add",
method: "post",
data: params,
});
}
export function updateFramework(id, params) {
return request({
url: `/api/v1/evm_store/framework/update/${id}`,
method: "post",
data: params,
});
}
export function deleteFramework(params) {
return request({
url: "/api/v1/evm_store/framework/delete",
method: "post",
data: params,
});
}
export function getDownloadList(params) {
return request({
url: "/api/v1/evm_store/download/list",
method: "post",
data: params,
});
}
export function addDownload(params) {
return request({
url: "/api/v1/evm_store/download/add",
method: "post",
data: params,
});
}
export function updateDownload(id, params) {
return request({
url: `/api/v1/evm_store/download/update/${id}`,
method: "post",
data: params,
});
}
export function deleteDownload(params) {
return request({
url: "/api/v1/evm_store/framework/delete",
method: "post",
data: params,
});
}
......@@ -42,6 +42,20 @@ export default {
icon: "gongzuotai",
path: "build",
},
{
vue: "app-store/download.vue",
title: "下载记录",
name: "AppDownload",
icon: "gongzuotai",
path: "download",
},
{
vue: "app-store/framework.vue",
title: "系统页面",
name: "Framework",
icon: "gongzuotai",
path: "framework",
},
{
vue: "profile/index.vue",
title: "个人中心",
......
<template>
<div class="app-container">
<el-form :inline="true" ref="form" :model="form" size="mini">
<el-form-item label="预警级别" prop="type">
<el-select v-model="form.type" filterable placeholder="请选择预警级别">
<el-option
v-for="(item, index) in ruleTypeList"
:key="index"
:label="item.name"
:value="item.id"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="起止时间" prop="start">
<el-date-picker
v-model="datetime"
type="datetimerange"
:picker-options="pickerOptions"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
format="yyyy-MM-dd HH:mm:ss"
value-format="yyyy-MM-dd HH:mm:ss"
align="right"
>
</el-date-picker>
</el-form-item>
<el-form-item prop="end">
<el-button type="primary" @click="onSubmit">查询</el-button>
</el-form-item>
<el-form-item>
<el-button @click="onReset('form')">重置</el-button>
</el-form-item>
</el-form>
<el-table
v-loading="isLoading"
element-loading-text="Loading"
:data="list"
size="mini"
border
stripe
fit
highlight-current-row
>
<el-table-column
prop="title"
label="预警事件"
align="center"
width="300"
:show-overflow-tooltip="true"
></el-table-column>
<el-table-column prop="type" label="预警级别" align="center" width="80">
<template slot-scope="scope">
{{ scope.row.type | getLevelDays }}
</template>
</el-table-column>
<el-table-column
prop="color"
label="预警颜色"
align="center"
width="80"
></el-table-column>
<el-table-column
prop="user.username"
label="消息接收者"
align="center"
width="120"
:show-overflow-tooltip="true"
></el-table-column>
<el-table-column prop="ignore" label="是否查看" align="center" width="80">
<template slot-scope="scope">
<el-tag v-if="scope.row.ignore" size="small" type="success"
>已查看</el-tag
>
<el-tag v-else size="small" type="warning">未查看</el-tag>
</template>
</el-table-column>
<el-table-column
prop="create_at"
label="预警时间"
align="center"
width="150"
></el-table-column>
<el-table-column
prop="content"
label="预警内容"
align="left"
min-width="150"
:show-overflow-tooltip="true"
></el-table-column>
</el-table>
<div class="page-wrapper">
<el-pagination
@current-change="handleCurrentChange"
:current-page.sync="form.pagenum"
background
small
:page-size="form.pagesize"
:pager-count="5"
layout="pager, prev, next, total"
:total="total"
></el-pagination>
</div>
</div>
</template>
<script>
import { getWarningLogList } from "@/api/warning";
import { mapTrim } from "@/utils/index";
import { formatUTCDateTime } from "@/utils/utils";
const today = new Date();
const yestoday = new Date();
yestoday.setDate(today.getDate() - 1); // 昨天
export default {
name: "WarningLog",
data() {
return {
total: 0,
list: [],
isLoading: false,
datetime: [yestoday, today],
form: {
uuid: null,
type: null,
start: null,
end: null,
user: null,
pagesize: 15,
pagenum: 1,
},
dialogVisible: false,
currentValue: null,
currentIndex: null,
post: {
title: null,
type: 1,
color: "yellow",
time: null,
content: null,
},
rules: {
name: [
{
type: "string",
required: true,
message: "用户名不能为空",
trigger: "blur",
},
{
min: 1,
max: 20,
message: "字符串长度在 1 到 20 之间",
trigger: "blur",
},
],
},
ruleTypeList: [
{ id: 0, name: "一般" },
{ id: 1, name: "重要" },
{ id: 2, name: "紧急" },
],
pickerOptions: {
shortcuts: [
{
text: "最近一周",
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
picker.$emit("pick", [start, end]);
},
},
{
text: "最近一个月",
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
picker.$emit("pick", [start, end]);
},
},
{
text: "最近三个月",
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
picker.$emit("pick", [start, end]);
},
},
],
},
};
},
filters: {
getLevelDays(type) {
if (type == 0) return "一般";
else if (type == 1) return "重要";
else return "紧急";
},
},
methods: {
fetchData(params) {
this.isLoading = true;
getWarningLogList(params)
.then((res) => {
this.total = res.count;
this.list = res.data;
})
.catch((err) => {
this.$message.warning(err.message)
})
.finally(() => {
this.isLoading = false;
});
},
handleSizeChange(e) {
this.form.pagesize = e;
this.fetchData(mapTrim(this.form));
},
handleCurrentChange(e) {
this.form.pagenum = e;
this.fetchData(mapTrim(this.form));
},
onSubmit() {
this.form.pagenum = 1;
this.form.pagesize = 15;
if (this.form.start !== formatUTCDateTime(this.datetime[0]))
this.form.start = formatUTCDateTime(this.datetime[0])
else this.form.start = null
if (this.form.end !== formatUTCDateTime(this.datetime[1]))
this.form.end = formatUTCDateTime(this.datetime[1])
else this.form.end = null
this.fetchData(mapTrim(this.form));
},
onReset(formName) {
this.form.start = null
this.form.end = null
this.$refs[formName].resetFields()
this.form.pagenum = 1
this.form.pagesize = 15
this.fetchData(mapTrim(this.form))
},
},
mounted() {},
created() {
if (this.$route.params.uuid) {
this.form.uuid = this.$route.params.uuid
}
this.fetchData(mapTrim(this.form))
},
};
</script>
<style lang="less" scoped>
.app-container {
& > div.page-wrapper {
margin: 10px 0px;
}
}
</style>
<template>
<div class="app-container">
<el-form :inline="true" ref="form" :model="form" size="mini">
<el-form-item label="预警级别" prop="type">
<el-select v-model="form.type" filterable placeholder="请选择预警类型">
<el-option
v-for="(item, index) in ruleTypeList"
:key="index"
:label="item.name"
:value="item.id"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="起止时间" prop="start">
<el-date-picker
v-model="datetime"
type="datetimerange"
:picker-options="pickerOptions"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
format="yyyy-MM-dd HH:mm:ss"
value-format="yyyy-MM-dd HH:mm:ss"
align="right"
>
</el-date-picker>
</el-form-item>
<el-form-item prop="end">
<el-button type="primary" @click="onSubmit">查询</el-button>
</el-form-item>
<el-form-item>
<el-button @click="onReset('form')">重置</el-button>
</el-form-item>
<el-form-item>
<el-button type="warning" @click="onAdd">添加</el-button>
</el-form-item>
</el-form>
<el-table
v-loading="isLoading"
element-loading-text="Loading"
:data="list"
size="mini"
border
stripe
fit
highlight-current-row
>
<el-table-column
prop="title"
label="预警事件"
align="center"
width="300"
:show-overflow-tooltip="true"
></el-table-column>
<el-table-column prop="type" label="预警级别" align="center" width="100">
<template slot-scope="scope">
{{ scope.row.type | getLevelDays }}
</template>
</el-table-column>
<el-table-column
prop="color"
label="预警颜色"
align="center"
width="80"
></el-table-column>
<el-table-column
prop="remarks"
label="预警状态"
align="center"
width="80"
></el-table-column>
<el-table-column
prop="create_at"
label="预警时间"
align="center"
width="150"
></el-table-column>
<el-table-column label="附件" align="center" width="90">
<template slot-scope="scope">
<el-popover placement="right" width="400" trigger="click">
<p
style="margin: 5px 0px; display: block"
v-for="(p, i) in scope.row.user"
:key="i"
>
{{ p.username }}
</p>
<el-button size="mini" type="text" slot="reference"
>查看成员</el-button
>
</el-popover>
</template>
</el-table-column>
<el-table-column
prop="content"
label="预警内容"
align="left"
:show-overflow-tooltip="true"
min-width="150"
></el-table-column>
</el-table>
<div class="page-wrapper">
<el-pagination
@current-change="handleCurrentChange"
:current-page.sync="form.pagenum"
background
small
:page-size="form.pagesize"
:pager-count="5"
layout="pager, prev, next, total"
:total="total"
@change="onDateTimeChange"
></el-pagination>
</div>
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="45%">
<el-form
:model="post"
status-icon
:rules="rules"
:inline="true"
ref="post"
size="mini"
label-width="120px"
>
<el-form-item label="预警事件" prop="title">
<el-input
type="text"
v-model="post.title"
autocomplete="off"
></el-input>
</el-form-item>
<el-form-item label="预警级别" prop="type">
<el-select
v-model="post.type"
@change="onLevelChange"
placeholder="请选择预警级别"
>
<el-option
v-for="item in ruleTypeList"
:key="item.id"
:label="item.name"
:value="item.id"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item label="预警时间" prop="time">
<el-date-picker
v-model="post.time"
type="datetime"
placeholder="选择日期"
>
</el-date-picker>
</el-form-item>
<el-form-item label="预警成员" prop="users">
<el-select
v-model="post.users"
multiple
filterable
placeholder="请选择预警成员"
>
<el-option
v-for="(item, index) in users"
:key="index"
:label="item.username"
:value="item.uuid"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="预警消息" prop="content">
<el-input
type="textarea"
v-model="post.content"
autocomplete="off"
></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" size="mini" plain @click="submitForm('post')"
>提交</el-button
>
<el-button type="success" size="mini" plain @click="onReset('post')"
>重置</el-button
>
<el-button size="mini" @click="dialogVisible = false">关闭</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { getUserList } from "@/api/index";
import { addWarningRule, getWarningRuleList } from "@/api/warning";
import { mapTrim } from "@/utils/index";
import { formatUTCDateTime } from "@/utils/utils";
const today = new Date();
const yestoday = new Date();
yestoday.setDate(today.getDate() - 1); // 昨天
export default {
name: "WarningRule",
data() {
return {
total: 0,
list: [],
isLoading: false,
ruleTypeList: [
{ id: 0, name: "一般" },
{ id: 1, name: "重要" },
{ id: 2, name: "紧急" },
],
form: {
uuid: null,
start: null,
end: null,
type: null,
pagesize: 15,
pagenum: 1,
},
users: [],
datetime: [yestoday, today],
dialogTitle: "",
dialogVisible: false,
currentValue: null,
currentIndex: null,
post: {
title: null,
type: 0,
color: "yellow",
time: null,
users: null,
content: "",
},
rules: {
name: [
{
type: "string",
required: true,
message: "用户名不能为空",
trigger: "blur",
},
{
min: 1,
max: 20,
message: "字符串长度在 1 到 20 之间",
trigger: "blur",
},
],
},
pickerOptions: {
shortcuts: [
{
text: "最近一周",
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
picker.$emit("pick", [start, end]);
},
},
{
text: "最近一个月",
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
picker.$emit("pick", [start, end]);
},
},
{
text: "最近三个月",
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
picker.$emit("pick", [start, end]);
},
},
],
},
};
},
filters: {
getLevelDays(type) {
if (type == 0) return "一般";
else if (type == 1) return "重要";
else return "紧急";
},
},
methods: {
fetchData(params) {
this.isLoading = true;
getWarningRuleList(params)
.then((res) => {
this.total = res.count
this.list = res.data
})
.catch((err) => {
this.$message.warning(err.message)
})
.finally(() => {
this.isLoading = false;
});
},
getUserList() {
getUserList({ scope_type: "list" })
.then((res) => {
this.users = res.data;
})
.catch((err) => {
console.log(err);
});
},
onLevelChange(e) {
if (e == 0) this.form.color = "yellow";
else if (e == 1) this.form.color = "orange";
else this.form.color = "red";
},
handleSizeChange(e) {
this.form.pagesize = e
this.fetchData(mapTrim(this.form))
},
handleCurrentChange(e) {
this.form.pagenum = e
this.fetchData(mapTrim(this.form))
},
handleEdit(index, row) {
this.post.title = row.title;
this.post.type = row.type;
this.post.color = row.color;
this.post.time = row.time;
this.post.users = row.users;
this.post.content = row.content;
this.currentValue = row;
this.currentIndex = row;
this.dialogTitle = "编辑";
this.dialogVisible = true;
},
submitForm(formName) {
this.$refs[formName].validate((valid) => {
let result = true;
if (valid) {
addWarningRule(this.post)
.then((res) => {
console.log(res);
this.$message({ type: "success", message: "添加成功" });
this.fetchData(mapTrim(this.form))
})
.catch((err) => {
this.$message.error(err.message);
});
} else {
result = false;
}
this.dialogVisible = false;
return result;
});
},
onAdd() {
this.dialogTitle = "添加";
this.post.time = new Date();
this.dialogVisible = true;
},
onDateTimeChange (e) {
console.log(e)
},
onSubmit() {
this.form.pagenum = 1;
this.form.pagesize = 15;
if (this.form.start !== formatUTCDateTime(this.datetime[0]))
this.form.start = formatUTCDateTime(this.datetime[0])
else this.form.start = null
if (this.form.end !== formatUTCDateTime(this.datetime[1]))
this.form.end = formatUTCDateTime(this.datetime[1])
else this.form.end = null
this.fetchData(mapTrim(this.form))
},
onReset(formName) {
this.form.start = null
this.form.end = null
this.$refs[formName].resetFields()
this.form.pagesize = 15
this.form.pagenum = 1
this.fetchData(mapTrim(this.form))
},
},
mounted() {},
created() {
this.fetchData(mapTrim(this.form))
this.getUserList()
},
};
</script>
<style lang="less" scoped>
.app-container {
& > div.page-wrapper {
margin: 10px 0px;
}
}
</style>
......@@ -17,9 +17,6 @@
></el-form-item
>
<el-form-item><el-button @click="onReset">重置</el-button></el-form-item>
<el-form-item
><el-button type="warning" @click="onAdd">添加</el-button></el-form-item
>
</el-form>
<el-table
v-loading="isLoading"
......@@ -32,7 +29,7 @@
highlight-current-row
>
<el-table-column
prop="app_id.app_name"
prop="app.app_name"
label="应用名称"
width="180"
></el-table-column>
......@@ -87,56 +84,6 @@
:total="total"
></el-pagination>
</div>
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="50%">
<el-form
:model="post"
status-icon
:rules="rules"
:inline="true"
ref="post"
size="mini"
label-width="200px"
>
<el-form-item label="标题" prop="name">
<el-input
type="text"
v-model="post.name"
autocomplete="off"
></el-input>
</el-form-item>
<el-form-item label="年度调派现场总天数" prop="year_dispatch_site_days">
<el-input
type="number"
v-model.number="post.year_dispatch_site_days"
autocomplete="off"
></el-input>
</el-form-item>
<el-form-item label="应用文件" prop="app_files">
<el-upload
drag
action="https://jsonplaceholder.typicode.com/posts/"
multiple
>
<i class="el-icon-upload"></i>
<div class="el-upload__text">
将文件拖到此处,或<em>点击上传</em>
</div>
<div class="el-upload__tip" slot="tip">
只能上传jpg/png文件,且不超过500kb
</div>
</el-upload>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" size="mini" plain @click="submitForm('post')"
>提交</el-button
>
<el-button type="success" size="mini" plain @click="onReset('form')"
>重置</el-button
>
<el-button size="mini" @click="dialogVisible = false">关闭</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
......@@ -148,7 +95,6 @@ export default {
data() {
return {
dialogImageUrl: "",
dialogVisible: false,
disabled: false,
total: 0,
list: [],
......@@ -162,20 +108,10 @@ export default {
},
currentIndex: 0,
currentValue: null,
dialogTitle: "",
post: {
name: null,
year_dispatch_site_days: null,
},
rules: {
year_dispatch_site_days: [
{
type: "number",
required: true,
message: "字段不能为空",
trigger: "blur",
},
],
name: [
{
type: "string",
......@@ -227,7 +163,6 @@ export default {
},
handlePictureCardPreview(file) {
this.dialogImageUrl = file.url;
this.dialogVisible = true;
},
handleDownload(index, row) {
console.log(index);
......@@ -250,8 +185,6 @@ export default {
this.post = Object.assign(row);
this.currentIndex = index;
this.currentValue = row;
this.dialogTitle = "编辑";
this.dialogVisible = true;
},
handleDelete(index, row) {
this.$alert(
......@@ -265,22 +198,6 @@ export default {
}
);
},
submitForm(formName) {
this.$refs[formName].validate((valid) => {
let result = true;
if (valid) {
console.log(valid);
} else {
result = false;
}
this.dialogVisible = false;
return result;
});
},
onAdd() {
this.dialogTitle = "添加";
this.dialogVisible = true;
},
onSubmit() {
this.form.pagenum = 1;
this.form.pagesize = 15;
......
<template>
<div class="app-container">
<el-form :inline="true" :model="form" size="mini">
<el-form-item><el-button type="primary" @click="onSubmit">查询</el-button></el-form-item>
<el-form-item><el-button @click="onReset">重置</el-button></el-form-item>
</el-form>
<el-table v-loading="isLoading" element-loading-text="Loading" :data="list" size="mini" border stripe fit highlight-current-row>
<el-table-column prop="app.app_name" label="应用" align="center" min-width="150"></el-table-column>
<el-table-column prop="imei" label="IMEI" align="center" min-width="150"></el-table-column>
<el-table-column prop="download_at" label="下载时间" min-width="150"></el-table-column>
</el-table>
<div class="page-wrapper">
<el-pagination @current-change="handleCurrentChange" :current-page.sync="form.pagenum" background small :page-size="form.pagesize" :pager-count="5" layout="pager, prev, next, total" :total="total"></el-pagination>
</div>
</div>
</template>
<script>
import checkPermission from '@/utils/permission'
import { getDownloadList, deleteDownload } from '@/api/app-store'
import { mapTrim } from '@/utils/index'
import { formatUTCDateTime } from '@/utils/utils'
export default {
name: "AppDownload",
data() {
return {
total: 0,
list: [],
isLoading: false,
form: {
uuid: null,
imei: null,
pagesize: 15,
pagenum: 1
},
}
},
methods: {
checkPermission,
fetchData(params) {
this.isLoading = true
getDownloadList(params).then(res => {
if (res.code == 200) {
this.total = res.count
this.list = res.data.map(item => {
item.create_at = formatUTCDateTime(item.create_at)
item.update_at = formatUTCDateTime(item.update_at)
return item
})
}
}).catch(err => {
// this.$message.error(err.message)
console.log(err.message)
}).finally(() => {
this.isLoading = false
})
},
handleSizeChange(e) {
this.form.pagesize = e
this.fetchData(mapTrim(this.form))
},
handleCurrentChange(e) {
this.form.pagenum = e
this.fetchData(mapTrim(this.form))
},
handleDelete(index, row) {
this.$alert('您确定要删除么?删除操作将不可恢复。如需取消操作,请点击右上角关闭按钮。', '删除提醒', {
confirmButtonText: '确定',
callback: action => {
if (action == 'confirm') deleteDownload(row.id).then(res => {
console.log(res)
this.total -= 1
this.$delete(this.list, index)
this.$message({ type: 'success', message: `成功删除第${ index }行` })
}).catch(err => {
this.$message.error(err.message)
})
}
})
},
onSubmit() {
this.form.pagenum = 1
this.form.pagesize = 15
this.fetchData(mapTrim(this.form))
},
onReset(formName) {
this.form = {
account: null,
username: null,
pagesize: 15,
pagenum: 1
}
this.$refs[formName].resetFields()
this.fetchData(mapTrim(this.form))
}
},
mounted() {},
created() {
this.fetchData(mapTrim(this.form))
}
}
</script>
<style lang="less" scoped>
.app-container {
& > div.page-wrapper {
margin: 10px 0px;
}
}
</style>
<template>
<div class="app-container">
<el-form :inline="true" :model="form" size="mini">
<el-form-item><el-button type="primary" @click="onSubmit">查询</el-button></el-form-item>
<el-form-item><el-button @click="onReset">重置</el-button></el-form-item>
<el-form-item><el-button type="warning" @click="onAdd">添加</el-button></el-form-item>
</el-form>
<el-table v-loading="isLoading" element-loading-text="Loading" :data="list" size="mini" border stripe fit highlight-current-row>
<el-table-column prop="name" label="页面名称" align="center" width="150"></el-table-column>
<el-table-column prop="url" label="页面路径" align="center" width="150"></el-table-column>
<el-table-column prop="type" label="页面类型" align="center" width="150"></el-table-column>
<el-table-column prop="desc" label="页面描述" align="center" width="200"></el-table-column>
<el-table-column prop="create_at" label="创建时间" width="150"></el-table-column>
<el-table-column prop="create_by.username" label="创建者" width="150"></el-table-column>
<el-table-column prop="update_at" label="更新时间" width="150" :show-overflow-tooltip="true"></el-table-column>
<el-table-column prop="update_by.username" label="更新者" width="150"></el-table-column>
<el-table-column label="操作" align="center" min-width="180" fixed="right">
<template slot-scope="scope">
<el-button size="mini" type="success" @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
<el-button size="mini" type="danger" @click="handleDelete(scope.$index, scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<div class="page-wrapper">
<el-pagination @current-change="handleCurrentChange" :current-page.sync="form.pagenum" background small :page-size="form.pagesize" :pager-count="5" layout="pager, prev, next, total" :total="total"></el-pagination>
</div>
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="45%">
<el-form :model="form" ref="post" :rules="rules" label-width="100px">
<el-form-item label="页面名称">
<el-input v-model="post.name" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="页面路径">
<el-input v-model="post.url" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="活动描述">
<el-input v-model="post.desc" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="活动类型">
<el-input v-model="post.type" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="资源文件" prop="app_icon">
<el-upload
drag
multiple
name="binfile"
:action="`${window.location.protocol}//${window.location.host}/api/v1/evm_store/upload`"
:on-remove="handleRemove"
:on-success="handleSuccess"
:file-list="fileList"
>
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
<div class="el-upload__tip" slot="tip">只能上传jpg/png文件,且不超过500kb</div>
</el-upload>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" size="mini" plain @click="submitForm('post')">提交</el-button>
<el-button type="success" size="mini" plain @click="onReset('post')">重置</el-button>
<el-button size="mini" @click="dialogVisible = false">关闭</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { getFrameworkList, deleteFramework, addFramework, updateFramework } from '@/api/app-store'
import { mapTrim, compareObjectDiff } from '@/utils/index'
import { formatUTCDateTime } from '@/utils/utils'
export default {
name: "Framework",
data() {
return {
total: 0,
list: [],
form: {
uuid: null,
name: null,
pagesize: 15,
pagenum: 1
},
isLoading: false,
dialogTitle: "",
dialogVisible: false,
currentValue: null,
currentIndex: null,
fileList: [],
post: {
name: null,
url: null,
desc: null,
type: null,
assets: {
files: []
}
},
rules: {
permission: [{ type: 'string', required: true, message: '权限名称不能为空', trigger: 'blur' }],
name: [
{ type: 'string', required: true, message: '用户名不能为空', trigger: 'blur' },
{ min: 1, max: 20, message: '字符串长度在 1 到 20 之间', trigger: 'blur' }
]
}
}
},
computed: {
window: () => window
},
methods: {
fetchData(params) {
this.isLoading = true
getFrameworkList(Object.assign({
pagenum: this.form.pagenum,
pagesize: this.form.pagesize,
}, params)).then(res => {
if (res.code == 200) {
this.total = res.count
this.list = res.data.map(item => {
item.create_at = formatUTCDateTime(item.create_at)
item.update_at = formatUTCDateTime(item.update_at)
return item
})
}
}).catch(err => {
// this.$message.error(err.message)
console.log(err.message)
}).finally(() => {
this.isLoading = false
})
},
fetchSelectData() {
getFrameworkList({ "scope_type": "list" }).then(res => {
if (res.code == 200) this.roles = res.data
}).catch(err => {
// this.$message.error(err.message)
console.log(err.message)
})
},
handleSizeChange(e) {
this.form.pagesize = e
this.fetchData(mapTrim(this.form))
},
handleCurrentChange(e) {
this.form.pagenum = e
this.fetchData(mapTrim(this.form))
},
handleEdit(index, row) {
this.post.name = row.name
this.post.url = row.url
this.post.desc = row.desc
this.post.type = row.type
this.currentValue = row
this.currentIndex = index
this.dialogTitle = "编辑"
this.dialogVisible = true
},
handleDelete(index, row) {
this.$alert('您确定要删除么?删除操作将不可恢复。如需取消操作,请点击右上角关闭按钮。', '删除提醒', {
confirmButtonText: '确定',
callback: action => {
if (action == 'confirm') deleteFramework(row.uuid).then(res => {
console.log(res)
// this.total -= 1
// this.$delete(this.list, index)
this.fetchData(mapTrim(this.form))
this.$message({ type: 'success', message: `成功删除第${ index }行` })
}).catch(err => {
this.$message.error(err.message)
})
}
})
},
handleRemove() {
},
handleSuccess(res) {
this.post.assets.files.push(res.data.filepath)
},
submitForm(formName) {
this.$refs[formName].validate((valid) => {
let result = true
if (valid) {
if (this.dialogTitle === '添加') addFramework(this.post).then(res => {
this.$message({ type: 'success', message: res.message })
this.fetchData(mapTrim(this.form))
}).catch(err => {
this.$message.error(err.message)
})
else if (this.dialogTitle === '编辑') updateFramework(this.currentValue.uuid, compareObjectDiff(this.post, this.currentValue)).then(res => {
// this.$set(this.list, this.currentIndex, Object.assign(this.currentValue, tmp))
this.$message({ type: 'success', message: res.message })
this.fetchData(mapTrim(this.form))
}).catch(err => {
this.$message.error(err.message)
})
} else {
result = false
}
this.dialogVisible = false
return result
})
},
onAdd() {
this.dialogTitle = "添加"
this.dialogVisible = true
},
onSubmit() {
this.form.pagenum = 1
this.form.pagesize = 15
this.fetchData(mapTrim(this.form))
},
onReset(formName) {
this.form.name = null
this.form.pagesize = 15,
this.form.pagenum = 1
this.$refs[formName].resetFields()
this.fetchData()
}
},
mounted() {},
created() {
this.fetchData()
this.fetchSelectData()
}
}
</script>
<style lang="less" scoped>
.app-container {
& > div.page-wrapper {
margin: 10px 0px;
}
}
</style>
<template>
<div class="app-container">
<el-form :inline="true" ref="form" :model="form" size="mini">
<el-form-item
><el-button type="warning" @click="onAdd">添加</el-button></el-form-item
>
<el-form-item><el-button type="warning" @click="onAdd">添加应用</el-button></el-form-item>
<el-form-item><el-button type="success" @click="onAddFramework">添加系统页面</el-button></el-form-item>
</el-form>
<el-table
v-loading="isLoading"
......@@ -25,6 +24,16 @@
label="应用版本号"
width="150"
></el-table-column>
<el-table-column
prop="category"
label="应用类别"
width="120"
></el-table-column>
<el-table-column
prop="app_url"
label="应用路径"
width="120"
></el-table-column>
<el-table-column
prop="app_desc"
label="应用描述"
......@@ -86,37 +95,24 @@
:total="total"
></el-pagination>
</div>
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="50%">
<el-form
:model="post"
status-icon
:inline="true"
ref="post"
size="mini"
label-width="200px"
>
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="45%">
<el-form :model="post" status-icon ref="post" size="medium" label-width="100px">
<el-form-item label="应用名称" prop="app_name">
<el-input
type="text"
v-model="post.app_name"
autocomplete="off"
></el-input>
<el-input type="text" v-model="post.app_name" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="应用版本号" prop="app_version">
<el-input
type="text"
v-model="post.app_version"
autocomplete="off"
></el-input>
<el-input type="text" v-model="post.app_version" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="应用路径" prop="app_url">
<el-input type="text" v-model="post.app_url" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="应用类别" prop="category">
<el-input type="text" v-model="post.category" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="应用描述" prop="app_desc">
<el-input
type="text"
v-model="post.app_desc"
autocomplete="off"
></el-input>
<el-input type="text" v-model="post.app_desc" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="应用Logo" prop="app_logo">
<el-form-item label="应用Logo" prop="app_icon">
<el-upload
class="avatar-uploader"
:action="`${window.location.protocol}//${window.location.host}/api/v1/evm_store/upload`"
......@@ -149,19 +145,50 @@
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" size="mini" plain @click="submitForm('post')"
>提交</el-button
>
<el-button type="success" size="mini" plain @click="onReset('form')"
>重置</el-button
>
<el-button size="mini" @click="dialogVisible = false">关闭</el-button>
<el-button type="primary" size="medium" plain @click="submitForm('post')">提交</el-button>
<el-button type="success" size="medium" plain @click="onReset('form')">重置</el-button>
<el-button size="medium" @click="dialogVisible = false">关闭</el-button>
</div>
</el-dialog>
<el-dialog title="添加系统页面" :visible.sync="frameworkDialog">
<el-form :model="form" label-width="100px">
<el-form-item label="页面名称">
<el-input v-model="framework.name" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="页面路径">
<el-input v-model="framework.url" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="活动描述">
<el-input v-model="framework.desc" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="活动类型">
<el-input v-model="framework.type" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="资源文件" prop="app_icon">
<el-upload
drag
multiple
name="binfile"
:action="`${window.location.protocol}//${window.location.host}/api/v1/evm_store/upload`"
:on-remove="handleFrameworkRemove"
:on-success="handleFrameworkSuccess"
:file-list="fileList"
>
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
<div class="el-upload__tip" slot="tip">只能上传jpg/png文件,且不超过500kb</div>
</el-upload>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="frameworkDialog = false">取 消</el-button>
<el-button type="primary" @click="addFramework">确 定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { getAppsList, deleteApp, addApp, updateApp, buildApp } from "@/api/app-store";
import { getAppsList, deleteApp, addApp, updateApp, buildApp, addFramework } from "@/api/app-store";
import { mapTrim } from "@/utils/index";
export default {
......@@ -171,6 +198,7 @@ export default {
imageUrl: "",
total: 0,
list: [],
fileList: [],
isLoading: false,
form: {
uuid: null,
......@@ -178,14 +206,26 @@ export default {
pagesize: 15,
pagenum: 1,
},
framework: {
name: null,
url: null,
desc: null,
type: null,
assets: {
files: []
}
},
currentIndex: 0,
currentValue: null,
frameworkDialog: false,
dialogTitle: "",
dialogVisible: false,
post: {
app_name: null,
app_version: null,
app_logo: null,
app_icon: null,
app_url: null,
category: null,
app_desc: null,
app_files: [],
},
......@@ -260,13 +300,11 @@ export default {
);
},
handleAppFilesUploadSuccess(res) {
console.log(res)
this.post.app_files.push(res.data)
},
handleAvatarSuccess(res, file) {
console.log(res)
if (res.code == 200)
this.post.app_logo = res.data.filepath
this.post.app_icon = res.data
this.imageUrl = URL.createObjectURL(file.raw);
},
beforeAvatarUpload() {
......@@ -295,6 +333,12 @@ export default {
}
console.log(file);
},
handleFrameworkRemove() {
},
handleFrameworkSuccess(res) {
this.framework.assets.files.push(res.data)
},
submitForm(formName) {
this.$refs[formName].validate((valid) => {
let result = true;
......@@ -327,6 +371,20 @@ export default {
return result;
});
},
submitFramework() {
},
addFramework() {
addFramework(this.framework).then(res => {
this.$message.success(res.message)
this.frameworkDialog = false
}).catch(err => {
this.$message.error(err.message)
})
},
onAddFramework() {
this.frameworkDialog = true;
},
onAdd() {
this.dialogTitle = "添加";
this.dialogVisible = true;
......
<template>
<div class="block">
<el-tabs v-model="activeName">
<el-tab-pane label="流程管理" name="first">
<el-row :gutter="20">
<el-col :span="8">
<h3>项目状态</h3>
<el-timeline style="margin: 15px">
<el-timeline-item
v-for="(activity, index) in activities"
:key="index"
:icon="activity.icon"
:type="activity.type"
:color="activity.color"
:size="activity.size"
:timestamp="activity.timestamp"
>
{{ activity.content }}
</el-timeline-item>
</el-timeline>
<div>
<el-button
type="primary"
style="width: 100%; margin-top: 15px"
:disabled="isEnable(1)"
@click="reviewProject"
>审核项目</el-button
>
<el-button
type="success"
style="width: 100%; margin-top: 15px; margin-left: 0px"
:disabled="isEnable(2)"
@click="startProject"
>启动项目</el-button
>
<el-button
type="danger"
style="width: 100%; margin-top: 15px; margin-left: 0px"
:disabled="isEnable(3)"
@click="finishProject"
>结束项目</el-button
>
<el-button
type="warning"
style="width: 100%; margin-top: 15px; margin-left: 0px"
:disabled="isEnable(4)"
@click="archiveProject"
>归档项目</el-button
>
</div>
</el-col>
<el-col :span="16">
<h3>流程状态</h3>
<el-table :data="tableData" size="mini">
<el-table-column type="expand">
<template slot-scope="props" size="mini">
<p v-for="(item, index) in props.row.annex" :key="index">
<a
target="_blank"
:href="item.path"
style="color: blue; text-decoration: underline"
>{{ item.title }}</a
>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<el-popconfirm v-show="currentFlowStatus == 4 && item.creater == user.uuid" title="确定删除附件吗?" @confirm="deleteAnnex(item)">
<span slot="reference" style="color: grey;cursor: pointer;">删除</span>
</el-popconfirm>
</p>
<p v-if="!props.row.annex" style="color: grey">没有附件</p>
</template>
</el-table-column>
<el-table-column prop="status_text" label="审批状态" width="80">
<template slot-scope="scope">
<el-tag
size="mini"
:type="scope.row.status | getStatusColor"
>{{ scope.row.status_text }}</el-tag
>
</template>
</el-table-column>
<el-table-column
prop="title"
label="节点标题"
width="120"
:show-overflow-tooltip="true"
></el-table-column>
<el-table-column
prop="remarks"
label="备注"
width="180"
:show-overflow-tooltip="true"
></el-table-column>
<el-table-column
prop="submitter.username"
label="提交者"
width="120"
:show-overflow-tooltip="true"
></el-table-column>
<el-table-column
prop="submit_at"
label="提交时间"
width="150"
></el-table-column>
<el-table-column
prop="reviewer.username"
label="审批者"
width="120"
:show-overflow-tooltip="true"
></el-table-column>
<el-table-column
prop="review_at"
label="审批时间"
width="150"
></el-table-column>
<el-table-column
fixed="right"
align="center"
label="操作"
width="100"
>
<template slot-scope="scope">
<el-button
:disabled="hasPermission(scope.$index, scope.row)"
@click="handleClick(scope.row)"
type="text"
size="small"
>{{ role.name !== '技术负责人' ? "更新" : "审核" }}</el-button
>
<el-button
v-show="role.name !== '技术负责人'"
:disabled="hasPermission(scope.$index, scope.row)"
@click="handleFlowSubmit(scope.row)"
type="text"
size="small"
>提交</el-button
>
</template>
</el-table-column>
</el-table>
<el-col :span="12">
<h3>整体验收表</h3>
<el-upload
:action="`${window.location.protocol}//${window.location.host}/api/v1/evm_store/upload`"
:on-preview="handlePreview"
:on-remove="handleRemove"
:on-success="handleUploadSuccess"
:before-remove="beforeRemove"
:disabled="project.status >= 5"
:on-exceed="handleExceed"
:file-list="acceptanceList"
name="binfile"
:data="{ annex_type: 'project', note: 'acceptance', file_dir: project.title }"
multiple
>
<el-button size="small" :disabled="project.status >= 5" type="primary">点击上传</el-button>
<div slot="tip" class="el-upload__tip">文件大小不超过10MB</div>
</el-upload>
<a style="display: block;text-decoration: underline;color: blue;" target="_blank" :href="item.url" v-for="(item, index) in acceptanceList" :key="index">{{ item.name }}</a>
</el-col>
<el-col :span="12">
<h3>评价表</h3>
<el-upload
:action="`${window.location.protocol}//${window.location.host}/api/v1/evm_store/upload`"
:on-preview="handlePreview"
:on-remove="handleRemove"
:on-success="handleUploadSuccess"
:before-remove="beforeRemove"
:disabled="project.status >= 5"
:on-exceed="handleExceed"
:file-list="evaluationList"
name="binfile"
:data="{ annex_type: 'project', note: 'evaluation', file_dir: project.title }"
multiple
>
<el-button size="small" :disabled="project.status >= 5" type="primary">点击上传</el-button>
<div slot="tip" class="el-upload__tip">文件大小不超过10MB</div>
</el-upload>
<a style="display: block;text-decoration: underline;color: blue;" target="_blank" :href="item.url" v-for="(item, index) in evaluationList" :key="index">{{ item.name }}</a>
</el-col>
<el-col :span="12">
<h3>诊断报告</h3>
<el-upload
:action="`${window.location.protocol}//${window.location.host}/api/v1/evm_store/upload`"
:on-preview="handlePreview"
:on-remove="handleRemove"
:before-remove="beforeRemove"
:on-success="handleUploadSuccess"
:data="{ annex_type: 'project', note: 'diagnose', file_dir: project.title }"
:disabled="project.status >= 5"
name="binfile"
multiple
:on-exceed="handleExceed"
:file-list="diagnoseList">
<el-button size="small" type="primary" :disabled="project.status >= 5">点击上传</el-button>
<div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>
</el-upload>
<a style="display: block;text-decoration: underline;color: blue;" target="_blank" :href="item.url" v-for="(item, index) in diagnoseList" :key="index">{{ item.name }}</a>
</el-col>
<el-col :span="12">
<h3>总结报告</h3>
<el-upload
:action="`${window.location.protocol}//${window.location.host}/api/v1/evm_store/upload`"
:on-preview="handlePreview"
:on-remove="handleRemove"
:before-remove="beforeRemove"
:on-success="handleUploadSuccess"
:data="{ annex_type: 'project', note: 'summary', file_dir: project.title }"
:disabled="project.status >= 5"
name="binfile"
multiple
:on-exceed="handleExceed"
:file-list="summaryList">
<el-button size="small" type="primary" :disabled="project.status >= 5">点击上传</el-button>
<div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>
</el-upload>
<a style="display: block;text-decoration: underline;color: blue;" target="_blank" :href="item.url" v-for="(item, index) in summaryList" :key="index">{{ item.name }}</a>
</el-col>
</el-col>
</el-row>
</el-tab-pane>
<el-tab-pane label="回款管理" name="second">
<el-row :gutter="20">
<el-col :span="12">
<el-form
label-position="right"
label-width="80px"
:model="payback"
size="mini"
ref="invoice"
:rules="paybackRules"
>
<el-form-item label="发票标题" prop="title">
<el-input v-model="payback.title"></el-input>
</el-form-item>
<el-form-item label="发票金额" prop="funds">
<el-input v-model.number="payback.funds"></el-input>
</el-form-item>
<el-form-item label="开票时间" prop="real_time">
<el-date-picker
v-model="payback.real_time"
type="datetime"
format="yyyy-MM-dd HH:mm:ss"
value-format="yyyy-MM-dd HH:mm:ss"
placeholder="请选择日期时间"
></el-date-picker>
</el-form-item>
</el-form>
<div class="form-footer">
<el-button
type="primary"
size="mini"
plain
@click="submitPaybackForm('invoice')"
:disabled="role.permission.paybackProgress !== '可读写'"
>提交</el-button
>
<el-button size="mini" @click="onReset('invoice')"
>重置表单</el-button
>
</div>
</el-col>
<el-col :span="12">
<el-form
label-position="right"
label-width="80px"
:model="payback"
size="mini"
ref="payback"
:rules="paybackRules"
>
<el-form-item label="收款标题" prop="title">
<el-input v-model="payback.title"></el-input>
</el-form-item>
<el-form-item label="到账金额" prop="funds">
<el-input v-model.number="payback.funds"></el-input>
</el-form-item>
<el-form-item label="到账时间" prop="real_time">
<el-date-picker
v-model="payback.real_time"
type="datetime"
format="yyyy-MM-dd HH:mm:ss"
value-format="yyyy-MM-dd HH:mm:ss"
placeholder="请选择日期时间"
></el-date-picker>
</el-form-item>
</el-form>
<div class="form-footer">
<el-button
type="primary"
size="mini"
plain
@click="submitPaybackForm('payback')"
:disabled="role.permission.paybackProgress !== '可读写'"
>提交</el-button
>
<el-button size="mini" @click="onReset('payback')"
>重置表单</el-button
>
</div>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<h3>计划回款</h3>
<el-timeline>
<el-timeline-item v-for="(item, index) in planList" :key="index" :timestamp="item.plan_time" placement="top">
<div class="pay-div">
<h4>【{{ item.title }}】 &nbsp;&nbsp;回款金额&nbsp;&nbsp;<label style="color: red">{{ item.funds }}</label></h4>
<p>{{ item.create_by.username }} 提交于 {{ item.create_at }}</p>
</div>
</el-timeline-item>
</el-timeline>
</el-col>
<el-col :span="8">
<h3>发票列表</h3>
<el-timeline>
<el-timeline-item
v-for="(item, index) in invoiceList" :key="index" :timestamp="item.real_time" placement="top" >
<div class="pay-div">
<h4>【{{ item.title }}】 &nbsp;&nbsp;发票金额&nbsp;&nbsp;<label style="color: red">{{ item.funds }}</label>
&nbsp;&nbsp;<span style="color: blue;cursor: pointer;" @click="deletePayback(item)" :disabled="role.permission.paybackProgress !== '可读写'">删除</span>
</h4>
<p>{{ item.create_by.username }} 提交于 {{ item.create_at }}</p>
</div>
</el-timeline-item>
</el-timeline>
</el-col>
<el-col :span="8">
<h3>实际回款</h3>
<el-timeline>
<el-timeline-item
v-for="(item, index) in realList" :key="index" :timestamp="item.real_time" placement="top" >
<div class="pay-div">
<h4>【{{ item.title }}】 &nbsp;&nbsp;回款金额&nbsp;&nbsp;<label style="color: red">{{ item.funds }}</label>
&nbsp;&nbsp;<span style="color: blue;cursor: pointer;" @click="deletePayback(item)" :disabled="role.permission.paybackProgress !== '可读写'">删除</span>
</h4>
<p>{{ item.create_by.username }} 提交于 {{ item.create_at }}</p>
</div>
</el-timeline-item>
</el-timeline>
</el-col>
</el-row>
</el-tab-pane>
</el-tabs>
<el-dialog
title="编辑节点"
:visible.sync="editDialogVisible"
:modal="false"
width="30%"
>
<el-form
label-position="right"
label-width="80px"
:model="flow"
size="mini"
ref="flow"
:rules="flowRules"
>
<el-form-item label="备注" props="remarks">
<el-input
v-model="flow.remarks"
placeholder="请输入备注信息"
></el-input>
</el-form-item>
<el-form-item label="附件">
<el-upload
:action="`${window.location.protocol}//${window.location.host}/api/v1/evm_store/upload`"
:on-preview="handlePreview"
:on-remove="handleRemove"
:on-success="handleUploadSuccess"
:before-remove="beforeRemove"
:on-exceed="handleExceed"
:file-list="fileList"
:data="{ annex_type: 'project', file_dir: project.title }"
name="binfile"
multiple
>
<el-button size="small" type="primary">点击上传</el-button>
<div slot="tip" class="el-upload__tip">文件大小不超过10MB</div>
</el-upload>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button
type="primary"
size="mini"
plain
@click="submitFlowForm('flow')"
>提交</el-button
>
<el-button size="mini" @click="editDialogVisible = false"
>关闭</el-button
>
</div>
</el-dialog>
</div>
</template>
<script>
import {
addFlow,
getFlowList,
addPayback,
updateFlow,
getAnnexList,
getPaybackList,
updateProject,
deletePayback,
addAnnex,
deleteAnnex,
} from "@/api/index";
const statusList = [
{ id: 1, name: "未交付" },
{ id: 2, name: "已交付" },
{ id: 3, name: "已审核" },
];
function getStatusText(status) {
let result = "";
for (let i = 0; i < statusList.length; i++) {
if (statusList[i].id === status) {
result = statusList[i].name;
break;
}
}
return result;
}
// 新增节点和更新节点时,对于附件的上传都是通过附件接口完成
export default {
props: {
project: {
type: Object,
},
},
data() {
return {
window: window,
editDialogVisible: false,
direction: "rtl",
statusList: [
{ id: 2, name: "已交付" },
{ id: 3, name: "已审核" },
],
activeName: "first",
fileList: [],
summaryList: [],
acceptanceList: [],
evaluationList: [],
diagnoseList: [],
activities: [
{
id: 1,
content: "未审核",
size: "large",
type: "info",
icon: "el-icon-error",
},
{
id: 2,
content: "已审核",
size: "large",
type: "info",
icon: "el-icon-success",
},
{
id: 3,
content: "启动中",
size: "large",
type: "info",
icon: "el-icon-s-opportunity",
},
{
id: 4,
content: "结束",
size: "large",
type: "info",
icon: "el-icon-s-flag",
},
{
id: 5,
content: "归档",
size: "large",
type: "info",
icon: "el-icon-s-check",
},
],
tableData: [],
planList: [],
realList: [],
invoiceList: [],
options: [
{ value: 1, label: "未收款" },
{ value: 2, label: "收款中" },
{ value: 3, label: "收款结束" },
],
payback: {
project: null,
title: "",
funds: 0,
status: 1,
type: null,
real_time: null,
},
paybackRules: {
datetime: [
{
type: "string",
required: true,
message: "请选择日期",
trigger: "change",
},
],
funds: [
{
type: "number",
required: true,
message: "请输入金额",
trigger: "change",
},
],
title: [
{
type: "string",
required: true,
message: "请填写标题",
trigger: "blur",
},
],
},
flow: {
uuid: null,
project: null,
status: -1,
remarks: "",
},
flowRules: {
remarks: [
{
type: "string",
required: true,
message: "请填写节点标题",
trigger: "blur",
},
],
status: [
{
type: "number",
required: false,
message: "请选择节点状态",
trigger: "change",
},
],
},
};
},
watch: {
project(n) {
this.fetchFlowData({ project: n.uuid });
this.fetchPaybackData({ project: n.uuid });
this.initProject(n);
if (n.id) this.getAnnexList({ project: n.id });
},
},
computed: {
user() {
return JSON.parse(sessionStorage.getItem("user")) || { uuid: "" };
},
role() {
const user = JSON.parse(sessionStorage.getItem("user"));
if (user) return user.role;
else return "";
},
currentFlowStatus() {
return this.project.extend1.currentFlow.status
},
hasPermission() {
return (index, row) => {
if (
row.status === 1 &&
row.extend1.currentEdit[row.status].length === 0
)
return false;
if (!row.extend1.currentEdit[row.status].includes(this.role.uuid))
return true;
return !row.can_edit;
};
},
isEnable() {
return function (status) {
if (this.project.status === 5) return true;
if (
this.project.status === status &&
this.project.extend1.currentProjectEdit[this.project.status]
.length === 0
)
return false;
if (
this.project.extend1.currentProjectEdit[this.project.status].includes(
this.role.uuid
) === false
)
return true;
return this.project.status !== status;
};
},
},
filters: {
getStatusColor(status) {
if (status === 1) return "danger";
else if (status === 2) return "warning";
else if (status === 3) return "success";
else if (status === 4) return "info";
else if (status === 5) return "info";
},
getPaybackStatus(status) {
if (status === 3) return "收款结束";
else if (status === 2) return "收款中";
else return "未收款";
},
getPaybackColor(status) {
if (status === 3) return "success";
else if (status === 2) return "warning";
else return "danger";
},
getAnnexURL(path) {
return path.replace("localhost", window.location.hostname);
},
},
methods: {
isEnableUpdateFlow(row) {
if (
row.extend1.currentEdit[row.status - 1].includes(this.role.uuid) ===
false
)
true;
return !row.can_edit;
},
getAnnexList(params) {
getAnnexList(params).then(res => {
const f = [], g = [], h = [], i = [];
res.data.forEach(item => {
item.url = item.url.replace(/localhost/i, window.location.hostname);
switch(item.type) {
case 'summary': f.push(item); break;
case 'acceptance': g.push(item); break;
case 'evaluation': h.push(item); break;
case 'diagnose': i.push(item); break;
}
})
if (this.role.name !== '项目负责人' && this.role.name !== '项目成员') {
this.summaryList = f
this.diagnoseList = i
}
this.acceptanceList = g
this.evaluationList = h
}).catch(err => {
console.log(err.message)
this.$message.warning(err.message)
})
},
deleteAnnex(row) {
deleteAnnex(row.uuid).then(res => {
this.$message.success(res.message)
this.fetchFlowData({ project: this.project.uuid })
}).catch(err => {
this.$message.warning(err.message)
})
},
initProject(project) {
this.getProjectStatus(project.status);
this.payback.project = project.uuid;
this.project.extend1.list.forEach((item) => {
this.activities[item.index - 1].timestamp = item.update_at;
this.activities[item.index - 1].type = "success";
});
},
handleAddFlow() {
addFlow()
.then((res) => {
console.log(res);
})
.catch((err) => {
this.$message.warning(err.message);
});
},
fetchFlowData(params) {
getFlowList(params)
.then((res) => {
this.tableData = res.data.map((item) => {
if (item.annex)
item.annex = item.annex.map((a) => {
a.path = a.path.replace("localhost", window.location.hostname);
return a;
});
item.status_text = getStatusText(item.status);
return item;
});
})
.catch((err) => {
if (err.code === 204) this.tableData = [];
this.$message.warning(err.message);
});
},
fetchPaybackData(params) {
getPaybackList(params)
.then((res) => {
const a = [],
b = [], c = [];
res.data.forEach((item) => {
if (item.type === 1) a.push(item);
else if (item.type === 2) b.push(item);
else if (item.type === 3) c.push(item);
});
this.planList = a;
this.realList = b;
this.invoiceList = c;
})
.catch((err) => {
console.log(err.message)
// this.$message.warning(err.message);
});
},
updateProject(params) {
updateProject(this.project.uuid, params)
.then((res) => {
this.$message({
type: "success",
message: res.code === 200 ? "状态更新成功" : res.message,
});
this.$emit("submit");
})
.catch((err) => {
console.log(err.message)
// this.$message.warning(err.message);
});
},
deletePayback(row) {
deletePayback(row.uuid).then(res => {
this.fetchPaybackData({ project: this.project.uuid })
this.$message.success(res.message)
}).catch(err => {
this.$message.error(err.message)
})
},
getProjectStatus(status) {
for (let i = 0; i < this.activities.length; i++) {
let tmp = this.activities[i];
if (i < status) tmp.type = "success";
else tmp.type = "info";
this.$set(this.activities, i, Object.assign(tmp));
}
},
handleUploadSuccess(response) {
if (response.data.note) addAnnex({
project: this.project.uuid,
size: response.data.filesize,
title: response.data.filename,
path: response.data.filepath,
remarks: response.data.note
})
.then((res) => {
this.$message.success(res.message);
this.updateProject({ uploads: response.data.note })
})
.catch((err) => {
this.$message.warning(err.message);
});
else addAnnex({
flow: this.flow.uuid,
size: response.data.filesize,
title: response.data.filename,
path: response.data.filepath,
})
.then((res) => {
this.$message.success(res.message)
})
.catch((err) => {
this.$message.warning(err.message)
});
},
reviewProject() {
// 审核项目
this.updateProject({ status: 2 })
},
startProject() {
// 开始项目
this.updateProject({ status: 3 })
},
finishProject() {
// 结束项目
this.updateProject({ status: 4 })
},
archiveProject() {
// 归档项目
if (!this.project.extend1.uploads) return this.$message.warning("项目资料未上传,请点击项目【编辑】按钮上传相关资料")
if (!this.project.extend1.uploads.diagnose) return this.$message.warning("您还没上传诊断报告,上传后方可提交")
if (!this.project.extend1.uploads.summary) return this.$message.warning("您还没上传诊断报告,上传后方可提交")
if (!this.project.extend1.uploads.acceptance) return this.$message.warning("项目验收表未上传")
if (!this.project.extend1.uploads.bidding) return this.$message.warning("项目招标书未上传")
if (!this.project.extend1.uploads.contract) return this.$message.warning("项目合同书未上传")
if (!this.project.extend1.uploads.evaluation) return this.$message.warning("项目评价表未上传")
this.updateProject({ status: 5 })
},
handleRemove(file) {
if (file.uuid) deleteAnnex(file.uuid).then(res => {
this.$message.success(res.message)
}).catch(err => {
console.log(err.message)
// this.$message.warning(err.message)
})
},
handlePreview(file) {
console.log(file);
},
handleExceed(files, fileList) {
this.$message.warning(
`当前限制选择 3 个文件,本次选择了 ${files.length} 个文件,共选择了 ${
files.length + fileList.length
} 个文件`
);
},
beforeRemove(file) {
return this.$confirm(`确定移除 ${file.name}?`);
},
submitPaybackForm(formName) {
this.$refs[formName].validate((valid) => {
let result = true;
if (valid) {
this.payback.type = formName === 'payback' ? 2 : 3
addPayback(this.payback)
.then((res) => {
this.$message({
type: "success",
message: res.code === 200 ? "更新成功" : res.message,
});
this.fetchPaybackData({ project: this.project.uuid });
})
.catch((err) => {
console.log(err.message)
// this.$message.error(err.message);
});
} else {
result = false;
}
this.dialogVisible = false;
return result;
});
},
submitFlowForm(formName) {
this.$refs[formName].validate((valid) => {
let result = true;
if (valid) {
if (this.role.name === '技术负责人') this.flow.auto = "yes"
this.updateFlow(this.flow.uuid, this.flow)
} else {
result = false;
}
this.dialogVisible = false;
return result;
});
},
onReset(formName) {
this.$refs[formName].resetFields();
},
handleClick(row) {
this.flow.uuid = row.uuid;
this.flow.project = this.project.uuid;
this.editDialogVisible = true;
},
handleFlowSubmit(row) {
this.updateFlow(row.uuid, { auto: "yes", project: this.project.uuid })
},
updateFlow(uuid, params) {
updateFlow(uuid, params)
.then((res) => {
this.$message({
type: "success",
message: res.code === 200 ? "更新成功" : res.message,
});
this.$emit("submit");
})
.catch((err) => {
console.log(err.message)
// this.$message.error(err.message);
});
},
handleClose(done) {
this.$confirm("确认关闭?")
.then((res) => {
done();
console.log(res);
})
.catch((err) => {
console.log(err);
});
},
},
mounted() {
if (this.project) {
this.fetchFlowData({ project: this.project.uuid });
this.fetchPaybackData({ project: this.project.uuid });
this.initProject(this.project);
}
},
created() {},
};
</script>
<style lang="less" scoped>
.block {
& > div.radio {
margin: 20px 0px;
}
div.flow-form {
margin: 25px 0px;
& > div.form-footer {
display: block;
}
}
div.timeline-wrapper {
margin: 0px 10px;
h4 {
label {
color: red;
}
}
}
div.pay-div {
padding: 15px;
border-radius: 20px;
border: 1px solid grey;
}
}
</style>
\ No newline at end of file
<template>
<div class="app-container">
<el-form :inline="true" ref="form" :model="form" size="mini">
<el-form-item label="项目名称" prop="uuid">
<el-select v-model="form.uuid" clearable filterable placeholder="请输入项目名称">
<el-option v-for="(item, index) in projects" :key="index" :label="item.title" :value="item.uuid"></el-option>
</el-select>
</el-form-item>
<el-form-item label="项目类别" prop="type">
<el-select v-model="form.type" clearable filterable placeholder="请选择项目类别">
<el-option v-for="(item, index) in projectType" :key="index" :label="item.name" :value="item.value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="项目状态" prop="status">
<el-select v-model="form.status" clearable filterable placeholder="请选择项目状态">
<el-option v-for="(item, index) in projectStatus" :key="index" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item label="项目乙方" prop="party_b">
<el-select v-model="form.party_b" clearable filterable placeholder="请选择项目乙方">
<el-option v-for="(item, index) in partyBList" :key="index" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="起止时间">
<el-date-picker v-model="datetime" clearable unlink-panels type="datetimerange" start-placeholder="开始日期" end-placeholder="结束日期"></el-date-picker>
</el-form-item>
<el-form-item label="项目负责人" prop="type">
<el-select v-model="form.charge_person" clearable filterable placeholder="请选择项目负责人">
<el-option v-for="(item, index) in projectLeader" :key="index" :label="item.username" :value="item.uuid"></el-option>
</el-select>
</el-form-item>
<el-form-item label="项目成员" prop="member">
<el-select v-model="form.member" clearable filterable placeholder="请选择项目成员">
<el-option v-for="(item, index) in members" :key="index" :label="item.username" :value="item.uuid"></el-option>
</el-select>
</el-form-item>
<el-form-item label="项目开发人" prop="leader">
<el-input v-model="form.leader" clearable placeholder="请输入项目开发人"></el-input>
</el-form-item>
<el-form-item label="项目甲方" prop="party_a">
<el-input v-model="form.party_a" clearable placeholder="请选择项目甲方"></el-input>
</el-form-item>
<el-form-item label="项目金额">
<el-col :span="11">
<el-input type="number" clearable placeholder="请输入最小金额" v-model.number="form.min_amount"></el-input>
</el-col>
<el-col style="text-align: center;" :span="2">-</el-col>
<el-col :span="11">
<el-input type="number" clearable placeholder="请输入最大金额" v-model.number="form.max_amount"></el-input>
</el-col>
</el-form-item>
<el-form-item label="同业引进人" prop="introducer">
<el-input v-model="form.introducer" clearable placeholder="请输入同业引进人"></el-input>
</el-form-item>
<el-form-item label="中标通知书" prop="is_bidding">
<el-select v-model="form.is_bidding" clearable filterable placeholder="请选择是否有中标通知书">
<el-option v-for="(item, index) in haveOption" :key="index" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="验收表" prop="is_acceptance">
<el-select v-model="form.is_acceptance" clearable filterable placeholder="请选择是否有验收表">
<el-option v-for="(item, index) in haveOption" :key="index" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="评价表" prop="is_evaluation">
<el-select v-model="form.is_evaluation" clearable filterable placeholder="请选择是否有评价表">
<el-option v-for="(item, index) in haveOption" :key="index" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="合同书" prop="is_contract">
<el-select v-model="form.is_contract" clearable filterable placeholder="请选择是否有合同书">
<el-option v-for="(item, index) in haveOption" :key="index" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="有无坏账" prop="is_bad_debts">
<el-select v-model="form.is_bad_debts" clearable filterable placeholder="请选择有无坏账">
<el-option v-for="(item, index) in haveOption" :key="index" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="开发级别" prop="level">
<el-input v-model="form.level" clearable placeholder="请输入开发级别"></el-input>
</el-form-item>
<el-form-item label="是否终止" prop="is_stop">
<el-select v-model="form.is_stop" clearable filterable placeholder="请选择是否终止">
<el-option v-for="(item, index) in isOption" :key="index" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="是否满意" prop="is_satisfied">
<el-select v-model="form.is_satisfied" clearable filterable placeholder="请选择是否满意">
<el-option v-for="(item, index) in isOption" :key="index" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
<el-form-item><el-button type="primary" plain @click="onSubmit">查询</el-button></el-form-item>
<el-form-item><el-button @click="onReset('form')">重置</el-button></el-form-item>
<el-form-item><el-button type="warning" plain @click="onAdd">添加</el-button></el-form-item>
<el-form-item>
<el-popover placement="top-start" width="250" trigger="click">
<el-checkbox-group :min="1" v-model="checkList" @change="onCheckboxChange">
<el-checkbox :label="item" v-for="(item, index) in headerList" :key="index"></el-checkbox>
</el-checkbox-group>
<el-button type="success" slot="reference">项目表头设置</el-button>
</el-popover>
</el-form-item>
<el-form-item>
<el-popover placement="top-start" width="250" trigger="click">
<el-checkbox-group v-model="planCheckList">
<el-checkbox :label="item" v-for="(item, index) in planHeaderList" :key="index"></el-checkbox>
</el-checkbox-group>
<el-button type="success" slot="reference">生产计划表头设置</el-button>
</el-popover>
</el-form-item>
<el-form-item>
<el-button type="info" plain @click="handleDownload">导出当前数据</el-button>
</el-form-item>
</el-form>
<el-table v-loading="isLoading" element-loading-text="Loading" :data="list" size="mini" border stripe fit highlight-current-row>
<el-table-column v-for="(item, index) in tableHeader" :key="index" :prop="item.prop" :label="item.label" :align="item.align" :width="item.width" :show-overflow-tooltip="true"></el-table-column>
<el-table-column prop="status_text" label="项目状态" align="center" width="100">
<template slot-scope="scope">
<el-tag size="mini" :type="scope.row.status | getStatusColor">{{ scope.row.status | getStatusText }}</el-tag>
</template>
</el-table-column>
<el-table-column prop="extend1.currentFlow.status" label="当前流程状态" align="center" width="100">
<template slot-scope="scope">
<el-tag size="mini" :type="scope.row.extend1.currentFlow.status | getFlowStatusColor">{{ scope.row.extend1.currentFlow.status | getFlowStatusText }}</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" align="center" min-width="240" fixed="right">
<template slot-scope="scope">
<el-button size="mini" type="primary" :disabled="permission.flow === '无权限'" @click="handleApprove(scope.$index, scope.row)">审批</el-button>
<el-button size="mini" type="success" :disabled="permission.basic === '无权限'" @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
<el-button size="mini" type="danger" :disabled="permission.basic !== '可读写'" @click="handleDelete(scope.$index, scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<div class="page-wrapper">
<el-pagination @current-change="handleCurrentChange" :current-page.sync="form.pagenum" background small :page-size="form.pagesize" :pager-count="5" layout="pager, prev, next, total" :total="total"></el-pagination>
</div>
<el-dialog
:title="dialogTitle"
:visible.sync="dialogVisible"
width="60%"
:close-on-click-modal="false"
>
<el-steps :active="showIndex" simple>
<el-step title="①基本信息" icon="el-icon-edit"></el-step>
<el-step title="②生产计划" icon="el-icon-s-management"></el-step>
<el-step title="③里程碑管理" icon="el-icon-upload"></el-step>
<el-step title="④回款计划" icon="el-icon-picture"></el-step>
<!-- <el-step title="⑤权限设置" icon="el-icon-s-operation"></el-step> -->
</el-steps>
<el-form v-show="showIndex == 0" :model="post" status-icon :rules="rules" :inline="true" ref="post" size="mini" label-width="120px">
<el-divider content-position="left">基本信息</el-divider>
<el-form-item label="项目名称" prop="title">
<el-input type="text" v-model="post.title" autocomplete="off" placeholder="请输入项目名称"></el-input>
</el-form-item>
<el-form-item label="合同编号" prop="code">
<el-input type="text" v-model="post.code" autocomplete="off" placeholder="请输入合同编号"></el-input>
</el-form-item>
<el-form-item label="项目类别" prop="type">
<el-select v-model="post.type" filterable placeholder="请选择项目类别">
<el-option v-for="(item, index) in projectType" :key="index" :label="item.name" :value="item.value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="咨询类别" prop="consult_type">
<el-select v-model="post.consult_type" filterable placeholder="请选择项目类别">
<el-option v-for="(item, index) in consultType" :key="index" :label="item.name" :value="item.value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="项目金额" prop="amount">
<el-input type="number" v-model.number="post.amount" autocomplete="off" placeholder="请输入项目金额"></el-input>
</el-form-item>
<el-form-item label="项目甲方" prop="party_a">
<el-input type="text" v-model="post.party_a" autocomplete="off" placeholder="请输入项目甲方"></el-input>
</el-form-item>
<el-form-item label="项目乙方" prop="party_b">
<el-select v-model="post.party_b" filterable placeholder="请选择项目乙方">
<el-option v-for="(item, index) in partyBList" :key="index" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="项目开发人" prop="leader">
<el-input type="text" v-model="post.leader" autocomplete="off" placeholder="请输入项目开发人"></el-input>
</el-form-item>
<el-form-item label="开发级别" prop="level">
<el-input type="text" v-model="post.level" autocomplete="off" placeholder="请输入开发级别"></el-input>
</el-form-item>
<el-form-item label="同业引进人" prop="introducer">
<el-input type="text" v-model="post.introducer" autocomplete="off" placeholder="请输入同业引进人"></el-input>
</el-form-item>
<el-form-item label="项目来源" prop="source">
<el-select v-model="post.source" filterable placeholder="请选择项目来源">
<el-option v-for="(item, index) in sourceList" :key="index" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="体系类型" prop="standard_type">
<el-select v-model="post.standard_type" filterable placeholder="请选择体系类型">
<el-option v-for="(item, index) in standardList" :key="index" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="审核类型" prop="review_type">
<el-select v-model="post.review_type" filterable placeholder="请选择审核类型">
<el-option v-for="(item, index) in reviewList" :key="index" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="客户地址" prop="customer_addr">
<el-input type="text" v-model="post.customer_addr" autocomplete="off" placeholder="请输入客户地址"></el-input>
</el-form-item>
<el-form-item label="客户联系人" prop="customer_contact">
<el-input type="text" v-model="post.customer_contact" autocomplete="off" placeholder="请输入客户联系人"></el-input>
</el-form-item>
<el-form-item label="客户联系电话" prop="customer_phone">
<el-input type="text" v-model="post.customer_phone" autocomplete="off" placeholder="请输入客户联系电话"></el-input>
</el-form-item>
<el-form-item label="项目归属" prop="ascription">
<el-input type="text" v-model="post.ascription" autocomplete="off" placeholder="请输入项目归属"></el-input>
</el-form-item>
<el-form-item label="风险级别" prop="risk">
<el-select v-model="post.risk" filterable placeholder="请选择风险级别">
<el-option v-for="(item, index) in projectRisk" :key="index" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="客户雇员规模" prop="people_nums">
<el-input type="number" v-model="post.people_nums" autocomplete="off" placeholder="请输入客户雇员规模"></el-input>
</el-form-item>
<el-form-item label="签订日期" prop="contract_sign_at">
<el-date-picker v-model="post.contract_sign_at" type="datetime" format="yyyy-MM-dd HH:mm:ss" value-format="yyyy-MM-dd HH:mm:ss" placeholder="请选择合同签订日期"></el-date-picker>
</el-form-item>
<el-form-item label="启动时间" prop="start_time">
<el-date-picker v-model="post.start_time" type="datetime" format="yyyy-MM-dd HH:mm:ss" value-format="yyyy-MM-dd HH:mm:ss" placeholder="启动时间"></el-date-picker>
</el-form-item>
<el-form-item label="结案时间" prop="end_time">
<el-date-picker v-model="post.end_time" type="datetime" format="yyyy-MM-dd HH:mm:ss" value-format="yyyy-MM-dd HH:mm:ss" placeholder="结案时间"></el-date-picker>
</el-form-item>
<el-form-item label="技术负责人" prop="technicalManagerSelected">
<el-select v-model="post.technicalManagerSelected" @change="onSelectChange" :multiple-limit="1" multiple placeholder="请选择">
<el-option v-for="item in technicalManager" :key="item.uuid" :label="item.username" :value="item.uuid"></el-option>
</el-select>
</el-form-item>
<el-form-item label="项目总控人" prop="projectMasterSelected">
<el-select v-model="post.projectMasterSelected" @change="onSelectChange" :multiple-limit="1" multiple placeholder="请选择">
<el-option v-for="item in projectMaster" :key="item.uuid" :label="item.username" :value="item.uuid"></el-option>
</el-select>
</el-form-item>
<el-form-item label="项目负责人" prop="projectSupervisorSelected">
<el-select v-model="post.projectSupervisorSelected" @change="onSelectChange" :multiple-limit="1" multiple placeholder="请选择">
<el-option v-for="item in projectSupervisor" :key="item.uuid" :label="item.username" :value="item.uuid"></el-option>
</el-select>
</el-form-item>
<el-form-item label="项目管理员" prop="projectManagerSelected">
<el-select v-model="post.projectManagerSelected" @change="onSelectChange" multiple placeholder="请选择">
<el-option v-for="item in projectManager" :key="item.uuid" :label="item.username" :value="item.uuid"></el-option>
</el-select>
</el-form-item>
<el-form-item label="项目成员" prop="projectMemeberSelected">
<el-select v-model="post.projectMemeberSelected" @change="onSelectChange" multiple placeholder="请选择">
<el-option v-for="item in projectMemeber" :key="item.uuid" :label="item.username" :value="item.uuid"></el-option>
</el-select>
</el-form-item>
<el-form-item label="有无坏账" prop="is_bad_debts">
<el-radio-group v-model="post.is_bad_debts">
<el-radio :label="true"></el-radio>
<el-radio :label="false"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="是否终止" prop="is_stop">
<el-radio-group v-model="post.is_stop">
<el-radio :label="true"></el-radio>
<el-radio :label="false"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="是否满意" prop="is_satisfied">
<el-radio-group v-model="post.is_satisfied">
<el-radio :label="true"></el-radio>
<el-radio :label="false"></el-radio>
</el-radio-group>
</el-form-item>
<!-- <el-form-item label="项目备注" prop="remakrs">
<el-input type="textarea" v-model="post.remarks" @change="$forceUpdate()" :autosize="{ minRows: 4, maxRows: 8 }" placeholder="请输入备注信息"></el-input>
</el-form-item> -->
<el-divider content-position="left">中标通知书</el-divider>
<el-form-item label="中标通知书" prop="bidding">
<el-upload
:action="`${window.location.protocol}//${window.location.host}/api/v1/evm_store/upload`"
:on-preview="handlePreview"
:on-remove="handleRemove"
:on-success="handleUploadSuccess"
:before-remove="beforeRemove"
:on-exceed="handleExceed"
:file-list="biddingList"
name="binfile"
:data="{ annex_type: 'project', note: 'bidding', file_dir: project.title }"
multiple
>
<el-button size="small" type="primary">点击上传</el-button>
<div slot="tip" class="el-upload__tip">文件大小不超过10MB</div>
</el-upload>
</el-form-item>
<el-form-item label="中标通知书附件">
<a style="display: block;text-decoration: underline;color: blue;" target="_blank" :href="item.url" v-for="(item, index) in biddingList" :key="index">{{ item.name }}</a>
</el-form-item>
<el-divider content-position="left">合同</el-divider>
<el-form-item label="合同" prop="contract">
<el-upload
:action="`${window.location.protocol}//${window.location.host}/api/v1/evm_store/upload`"
:on-preview="handlePreview"
:on-remove="handleRemove"
:on-success="handleUploadSuccess"
:before-remove="beforeRemove"
:on-exceed="handleExceed"
:file-list="contractList"
name="binfile"
:data="{ annex_type: 'project', note: 'contract', file_dir: project.title }"
multiple
>
<el-button size="small" type="primary">点击上传</el-button>
<div slot="tip" class="el-upload__tip">文件大小不超过10MB</div>
</el-upload>
</el-form-item>
<el-form-item label="合同附件">
<a style="display: block;text-decoration: underline;color: blue;" target="_blank" :href="item.url" v-for="(item, index) in contractList" :key="index">{{ item.name }}</a>
</el-form-item>
</el-form>
<el-form :model="post" v-show="showIndex == 1" :inline="true" ref="production" size="mini" status-icon label-width="120px">
<el-divider content-position="left">费用汇总</el-divider>
<el-form-item label="项目毛利润">
<el-input type="number" :disabled="true" size="mini" v-model="post.production.gross_profit"></el-input>
</el-form-item>
<el-form-item label="项目毛利润率">
<el-input type="number" :disabled="true" size="mini" v-model="post.production.gross_profit_rate"></el-input>
</el-form-item>
<el-form-item label="毛利润目标">
<el-input type="number" :disabled="true" size="mini" v-model="post.production.gross_profit_rate_goal"></el-input>
</el-form-item>
<el-form-item label="成本合计">
<el-input type="number" :disabled="true" size="mini" v-model="post.production.cost"></el-input>
</el-form-item>
<el-form-item label="项目盈余">
<el-input type="number" :disabled="true" size="mini" v-model="post.production.profit"></el-input>
</el-form-item>
<el-divider content-position="left">相关费用</el-divider>
<el-form-item label="人员计划费用">
<el-input type="number" size="mini" v-model.number="post.production.staff_plan_fee"></el-input>
</el-form-item>
<el-form-item label="人员实际费用">
<el-input type="number" size="mini" v-model.number="post.production.staff_real_fee"></el-input>
</el-form-item>
<el-form-item label="计划人天">
<el-input type="number" size="mini" v-model.number="post.production.plan_man_day_fee"></el-input>
</el-form-item>
<el-form-item label="实际人天">
<el-input type="number" size="mini" v-model.number="post.production.real_man_day_fee"></el-input>
</el-form-item>
<el-form-item label="合同金额">
<el-input type="number" size="mini" @change="onAmountChange" v-model.number="post.production.contract_amount"></el-input>
</el-form-item>
<el-form-item label="认可合同金额">
<el-input type="number" size="mini" v-model.number="post.production.agree_cont_amount"></el-input>
</el-form-item>
<el-form-item label="市场费用">
<el-input type="number" size="mini" @change="onAmountChange" v-model.number="post.production.market_cost"></el-input>
</el-form-item>
<el-form-item label="相关人员返款">
<el-input type="number" size="mini" v-model.number="post.production.related_rebate"></el-input>
</el-form-item>
<el-form-item label="营业税">
<el-input type="number" size="mini" v-model.number="post.production.business_tax"></el-input>
</el-form-item>
<el-form-item label="返款税金">
<el-input type="number" size="mini" v-model.number="post.production.tax_rebate"></el-input>
</el-form-item>
<el-form-item label="销售佣金">
<el-input type="number" size="mini" v-model.number="post.production.sales_commission"></el-input>
</el-form-item>
<el-form-item label="管理费用">
<el-input type="number" size="mini" v-model.number="post.production.management_fee"></el-input>
</el-form-item>
<el-form-item label="审核费用">
<el-input type="number" size="mini" v-model.number="post.production.audit_fee"></el-input>
</el-form-item>
<el-form-item label="认证费用">
<el-input type="number" size="mini" @change="onAmountChange" v-model.number="post.production.certification_fee"></el-input>
</el-form-item>
<el-form-item label="外包技术费用">
<el-input type="number" size="mini" @change="onAmountChange" v-model.number="post.production.technology_fee"></el-input>
</el-form-item>
<el-form-item label="差旅费用">
<el-input type="number" size="mini" v-model.number="post.production.travel_fee"></el-input>
</el-form-item>
<el-form-item label="投标费用">
<el-input type="number" size="mini" v-model.number="post.production.bidding_fee"></el-input>
</el-form-item>
<el-form-item label="资料打印费">
<el-input type="number" size="mini" v-model.number="post.production.doc_print_fee"></el-input>
</el-form-item>
<el-form-item label="专家评审费">
<el-input type="number" size="mini" v-model.number="post.production.expert_review_fee"></el-input>
</el-form-item>
<el-form-item label="招待费用">
<el-input type="number" size="mini" v-model.number="post.production.hosting_fee"></el-input>
</el-form-item>
<el-form-item label="其他费用">
<el-input type="number" size="mini" v-model.number="post.production.other_fee"></el-input>
</el-form-item>
</el-form>
<el-form :model="post" v-show="showIndex == 2" ref="flow" size="mini" status-icon label-width="80px">
<el-divider content-position="left">节点信息</el-divider>
<el-form-item v-for="(node, index) in post.flow" :label="'节点' + (index + 1)" :key="index" :prop="'flow.' + index + '.title'" :rules="{ required: true, message: '流程节点名称不能为空', trigger: 'blur' }">
<el-col :span="11">
<el-input size="mini" v-model="node.title"></el-input>
</el-col>
<el-col :span="6" :offset="1">
<el-date-picker v-model="node.deadline" type="datetime" format="yyyy-MM-dd HH:mm:ss" value-format="yyyy-MM-dd HH:mm:ss" placeholder="选择节点截止时间"></el-date-picker>
</el-col>
<el-col :span="4" :offset="2">
<el-button size="mini" @click.prevent="removeFlowNode(node)" :disabled="permission.flow !== '可读写'">删除</el-button>
</el-col>
</el-form-item>
<el-form-item>
<el-button type="button" @click="addFlowNode" :disabled="permission.flow !== '可读写'">添加新项</el-button>
</el-form-item>
</el-form>
<el-form :model="post" v-show="showIndex == 3" ref="payback" size="mini" status-icon label-width="80px">
<el-divider content-position="left">节点信息</el-divider>
<el-form-item v-for="(node, index) in post.payback" :label="'回款' + (index + 1)" :key="index" :prop="'payback.' + index + '.title'" :rules="{ required: true, message: '回款计划名称不能为空', trigger: 'blur' }">
<el-col :span="6">
<el-input size="mini" v-model="node.title" placeholder="回款计划"></el-input>
</el-col>
<el-col :span="4" :offset="1">
<el-input size="mini" v-model.number="node.funds" placeholder="回款金额"></el-input>
</el-col>
<el-col :span="6" :offset="1">
<el-date-picker v-model="node.plan_time" type="datetime" format="yyyy-MM-dd HH:mm:ss" value-format="yyyy-MM-dd HH:mm:ss" placeholder="回款时间"></el-date-picker>
</el-col>
<el-col :span="4" :offset="2">
<el-button size="mini" @click.prevent="removePaybackNode(node)" :disabled="permission.paybackPlan !== '可读写'">删除</el-button>
</el-col>
</el-form-item>
<el-form-item>
<el-button type="button" @click="addPaybackNode" :disabled="permission.paybackPlan !== '可读写'">添加新项</el-button>
</el-form-item>
</el-form>
<el-table :data="tableData" v-show="showIndex == 4">
<el-table-column prop="name" label="姓名" width="100"></el-table-column>
<el-table-column prop="role" label="角色" width="120"></el-table-column>
<el-table-column label="基础信息权限" align="center" min-width="220">
<template slot-scope="scope">
<el-radio-group v-model="scope.row.radioActive1" size="mini">
<el-radio-button label="可读"></el-radio-button>
<el-radio-button label="可读写"></el-radio-button>
<el-radio-button label="无权限"></el-radio-button>
</el-radio-group>
</template>
</el-table-column>
<el-table-column label="流程管理权限" align="center" width="220">
<template slot-scope="scope">
<el-radio-group v-model="scope.row.radioActive2" size="mini">
<el-radio-button label="可读"></el-radio-button>
<el-radio-button label="可读写"></el-radio-button>
<el-radio-button label="无权限"></el-radio-button>
</el-radio-group>
</template>
</el-table-column>
<el-table-column label="回款计划权限" align="center" width="220">
<template slot-scope="scope">
<el-radio-group v-model="scope.row.radioActive3" size="mini">
<el-radio-button label="可读"></el-radio-button>
<el-radio-button label="可读写"></el-radio-button>
<el-radio-button label="无权限"></el-radio-button>
</el-radio-group>
</template>
</el-table-column>
<el-table-column label="回款进度权限" align="center" width="220">
<template slot-scope="scope">
<el-radio-group v-model="scope.row.radioActive4" size="mini">
<el-radio-button label="可读"></el-radio-button>
<el-radio-button label="可读写"></el-radio-button>
<el-radio-button label="无权限"></el-radio-button>
</el-radio-group>
</template>
</el-table-column>
</el-table>
<div slot="footer" class="dialog-footer">
<el-button type="primary" size="mini" plain @click="submitForm('post')" :disabled="permission.flow !== '可读写'">提交</el-button>
<el-button type="success" size="mini" plain v-show="showIndex > 0" @click="onPreviousStep">上一步</el-button>
<el-button type="success" size="mini" plain v-show="showIndex < 3" @click="onNextStep">下一步</el-button>
<el-button type="danger" size="mini" plain @click="onReset('post')">重置</el-button>
<el-button size="mini" @click="dialogVisible = false">关闭</el-button>
</div>
</el-dialog>
<el-dialog title="流程" :visible.sync="flowVisible" :close-on-click-modal="false" width="60%">
<flow :project="project" @submit="onFlowSubmit"></flow>
</el-dialog>
</div>
</template>
<script>
import { mapState } from "vuex"
import {
getDictsList,
getProjectList,
deleteProject,
addNewProject,
addAnnex,
deleteAnnex,
getProject,
updateProject,
getUserList,
deleteProjectUser,
modifyProjectUser,
deleteFlow,
deletePayback,
updateFlowList,
updatePaybackList,
getRoleUser,
exportProject,
updateProduction,
} from '@/api/index'
import { mapTrim, compareObjectDiff } from '@/utils/index'
import { formatUTCDateTime } from "@/utils/utils"
import { exportJsonToExcel } from "@/utils/excel"
import flow from "./flow"
// const today = new Date();
// const yestoday = new Date();
// yestoday.setDate(today.getDate() - 1); // 昨天
const projectStatus = [{ id: 1, name: '未审核' }, { id: 2, name: '已审核' }, { id: 3, name: '启动中' }, { id: 4, name: '结束' }, { id: 5, name: '归档' }]
const fieldList = [
{ label: "项目名称", prop: "title", isShow: true, align: "center", width: "200" },
{ label: "项目类型", prop: "type", isShow: true, align: "center", width: "150" },
{ label: "咨询类型", prop: "consult_type", isShow: true, align: "center", width: "150" },
{ label: "项目金额", prop: "amount", isShow: true, align: "left", width: "150" },
{ label: "项目甲方", prop: "party_a", isShow: true, align: "center", width: "180" },
{ label: "项目乙方", prop: "party_b", isShow: true, align: "center", width: "180" },
{ label: "项目开发人", prop: "leader", isShow: true, align: "center", width: "150" },
{ label: "开发级别", prop: "level", isShow: false, align: "center", width: "150" },
{ label: "签订日期", prop: "contract_sign_at", isShow: false, align: "center", width: "150" },
{ label: "项目来源", prop: "source", isShow: false, align: "center", width: "150" },
{ label: "同业引进人", prop: "introducer", isShow: false, align: "center", width: "150" },
{ label: "体系类型", prop: "standard_type", isShow: false, align: "center", width: "150" },
{ label: "审核类型", prop: "review_type", isShow: false, align: "center", width: "150" },
{ label: "客户地址", prop: "customer_addr", isShow: false, align: "center", width: "150" },
{ label: "联系人", prop: "customer_contact", isShow: false, align: "center", width: "150" },
{ label: "联系方式", prop: "customer_phone", isShow: false, align: "center", width: "150" },
{ label: "项目归属", prop: "ascription", isShow: false, align: "center", width: "150" },
{ label: "风险级别", prop: "risk", isShow: false, align: "center", width: "150" },
{ label: "参与人数", prop: "people_nums", isShow: false, align: "center", width: "120" },
{ label: "招标通知书", prop: "is_bidding", isShow: false, align: "center", width: "100" },
{ label: "有无验收表", prop: "is_acceptance", isShow: false, align: "center", width: "100" },
{ label: "有无评价表", prop: "is_evaluation", isShow: false, align: "center", width: "100" },
{ label: "有无合同", prop: "is_contract", isShow: false, align: "center", width: "100" },
{ label: "有无坏账", prop: "is_bad_debts", isShow: false, align: "center", width: "100" },
{ label: "是否停止", prop: "is_stop", isShow: false, align: "center", width: "100" },
{ label: "是否满意", prop: "is_satisfied", isShow: false, align: "center", width: "100" },
{ label: "开始时间", prop: "start_time", isShow: false, align: "center", width: "150" },
{ label: "结束时间", prop: "end_time", isShow: false, align: "center", width: "150" },
]
const tableHeader = fieldList.filter(item => {
if (item.isShow) return item
})
const planHeaderList = [
{ label: "人员计划开支", prop: "staff_plan_fee" },
{ label: "人员实际开支", prop: "staff_real_fee" },
{ label: "计划人天", prop: "plan_man_day_fee" },
{ label: "实际人天", prop: "real_man_day_fee" },
{ label: "项目毛利润", prop: "gross_profit" },
{ label: "项目毛利润率", prop: "gross_profit_rate" },
{ label: "项目毛利润目标", prop: "gross_profit_rate_goal" },
{ label: "项目成本", prop: "cost" },
{ label: "项目盈利", prop: "profit" },
{ label: "合同金额", prop: "contract_amount" },
{ label: "认可合金额", prop: "agree_cont_amount" },
{ label: "市场费用", prop: "market_cost" },
{ label: "相关方返款", prop: "related_rebate" },
{ label: "营业税", prop: "business_tax" },
{ label: "返款税金", prop: "tax_rebate" },
{ label: "销售佣金", prop: "sales_commission" },
{ label: "管理费", prop: "management_fee" },
{ label: "审核费", prop: "audit_fee" },
{ label: "认证费", prop: "certification_fee" },
{ label: "外包技术费", prop: "technology_fee" },
{ label: "差旅费", prop: "travel_fee" },
{ label: "投标费", prop: "bidding_fee" },
{ label: "资料打印费", prop: "doc_print_fee" },
{ label: "专家评审费", prop: "expert_review_fee" },
{ label: "招待费", prop: "hosting_fee" },
{ label: "其他费用", prop: "other_fee" },
]
export default {
data() {
return {
window,
checkList: tableHeader.map(item => item.label),
headerList: fieldList.map(item => item.label),
planCheckList: [],
planHeaderList: planHeaderList.map(item => item.label),
tableHeader,
projectStatus,
total: 0,
list: [],
projects: [],
fileList: [],
biddingList: [],
contractList: [],
evaluationList: [],
acceptanceList: [],
currentIndex: null,
currentValue: null,
isLoading: false,
flowVisible: false,
datetime: null,
projectType: [],
consultType: [],
projectRisk: [],
reviewList: [],
standardList: [],
sourceList: [],
partyBList: [],
form: {
uuid: null,
type: null,
party_a: null,
party_b: null,
status: null,
start_time: null,
end_time: null,
min_amount: null,
max_amount: null,
member: null,
charge_person: null,
leader: null,
level: null,
introducer: null,
is_bidding: null,
is_acceptance: null,
is_evaluation: null,
is_contract: null,
is_bad_debts: null,
is_stop: null,
is_satisfied: null,
pagesize: 15,
pagenum: 1
},
dialogTitle: "",
dialogVisible: false,
post: {
type: null,
code: "",
title: null,
amount: 0,
consult_type: "",
contract_sign_at: null,
party_a: "",
party_b: "",
leader: "",
level: "",
introducer: "",
source: "",
standard_type: "",
review_type: "",
customer_addr: "",
customer_contact: "",
customer_phone: "",
ascription: "",
risk: "",
people_nums: 0,
is_bad_debts: 0,
is_stop: 0,
is_satisfied: 1,
start_time: null,
end_time: null,
remakrs: null,
flow: [],
payback: [],
production: {
gross_profit: null,
gross_profit_rate: null,
gross_profit_rate_goal: null,
cost: null,
profit: null,
staff_plan_fee: 0,
staff_real_fee: 0,
plan_man_day_fee: 0,
real_man_day_fee: 0,
contract_amount: 0,
agree_cont_amount: 0,
market_cost: 0,
related_rebate: 0,
business_tax: 0,
tax_rebate: 0,
sales_commission: 0,
management_fee: 0,
audit_fee: 0,
certification_fee: 0,
technology_fee: 0,
travel_fee: 0,
bidding_fee: 0,
doc_print_fee: 0,
expert_review_fee: 0,
hosting_fee: 0,
other_fee: 0
},
technicalManagerSelected: [],
projectManagerSelected: [],
projectSupervisorSelected: [],
projectMemeberSelected: [],
projectMasterSelected: []
},
rules: {
type: [{ type: 'string', required: false, message: '类型不能为空', trigger: 'blur' }],
title: [{ type: 'string', required: true, message: '项目名不能为空', trigger: 'blur' }],
code: [{ type: 'string', required: false, message: '项目编号不能为空', trigger: 'blur' }],
amount: [{ type: 'number', required: false, message: '项目金额不能为空', trigger: 'blur' }],
consult_type: [{ type: 'string', required: false, message: '项目备注不能为空', trigger: 'blur' }],
start_time: [{ type: 'string', required: true, message: '项目开始不能为空', trigger: 'blur' }],
end_time: [{ type: 'string', required: true, message: '项目结束不能为空', trigger: 'blur' }],
contract_sign_at: [{ type: 'string', required: false, message: '项目签订时间不能为空', trigger: 'blur' }],
technicalManagerSelected: [{ type: 'array', required: true, message: '技术负责人不能为空', trigger: 'blur' }],
projectMasterSelected: [{ type: 'array', required: true, message: '项目总控人不能为空', trigger: 'blur' }],
projectManagerSelected: [{ type: 'array', required: true, message: '项目管理员不能为空', trigger: 'blur' }],
projectSupervisorSelected: [{ type: 'array', required: true, message: '项目负责人不能为空', trigger: 'blur' }],
projectMemeberSelected: [{ type: 'array', required: false, message: '项目成员不能为空', trigger: 'blur' }],
party_a: [{ type: 'string', required: false, message: '项目甲方不能为空', trigger: 'blur' }],
party_b: [{ type: 'string', required: false, message: '项目乙方不能为空', trigger: 'blur' }],
},
showIndex: 0,
technicalManager: [],
projectMaster: [],
projectManager: [],
projectSupervisor: [],
projectMemeber: [],
project: { title: "" },
members: [], // 项目成员
projectLeader: [], // 项目负责人
haveOption: [
{ label: "", value: 1 },
{ label: "", value: 0 }
],
isOption: [
{ label: "", value: 1 },
{ label: "", value: 0 }
],
tableData: [{
name: '王小虎',
role: '普通用户',
radioActive1: '无权限',
radioActive2: '无权限',
radioActive3: '无权限',
radioActive4: '无权限',
}, {
name: '李小虎',
role: '普通用户',
radioActive1: '无权限',
radioActive2: '无权限',
radioActive3: '无权限',
radioActive4: '无权限',
}, {
name: '张小虎',
role: '普通用户',
radioActive1: '无权限',
radioActive2: '无权限',
radioActive3: '无权限',
radioActive4: '无权限',
}, {
name: '刘小虎',
role: '普通用户',
radioActive1: '无权限',
radioActive2: '无权限',
radioActive3: '无权限',
radioActive4: '无权限',
}],
}
},
computed: {
...mapState("user", [ "role", ]),
permission: () => {
const user = JSON.parse(sessionStorage.getItem("user"))
if (user) return user.role.permission
else return {
basic: "",
flow: "",
paybackPlan: "",
paybackProgress: "",
}
},
},
components: { flow },
filters: {
getStatusColor(status) {
if (status === 0) return "info"
else if (status === 1) return "danger"
else if (status === 2) return "warning"
else if (status === 3) return "success"
else if (status === 4) return "info"
else if (status === 5) return ""
},
getStatusText(status) {
if (status === 0) return "未启动"
else if (status === 1) return "未审核"
else if (status === 2) return "已审核"
else if (status === 3) return "启动中"
else if (status === 4) return "结束"
else if (status === 5) return "归档"
},
getFlowStatusColor(status) {
if (status === 0) return "danger"
else if (status === 1) return "danger"
else if (status === 2) return "warning"
else if (status === 3) return "success"
else if (status === 4) return ""
else if (status === 5) return "info"
},
getFlowStatusText(status) {
if (status === 0) return "未启动"
else if (status === 1) return "未交付"
else if (status === 2) return "已交付"
else if (status === 3) return "已审核"
else if (status === 4) return "运行中"
else if (status === 5) return "已结束"
},
},
methods: {
onAmountChange() {
this.post.production.business_tax = 0.08 * this.post.production.contract_amount
this.post.production.market_cost = 0.1 * this.post.production.contract_amount
this.post.production.agree_cont_amount = this.post.production.contract_amount - this.post.production.certification_fee - this.post.production.market_cost - this.post.production.technology_fee
console.log(this.post.production.agree_cont_amount)
},
onCheckboxChange(evt) {
let header = []
evt.forEach(f => {
for(let i = 0 ; i < fieldList.length; i++) {
if (fieldList[i].label === f) {
header.push(fieldList[i])
break
}
}
})
this.tableHeader = header
},
handleDownload() {
const loading = this.$loading({
lock: true,
text: 'Loading',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
})
let header = []
this.planCheckList.forEach(f => {
for(let i = 0 ; i < planHeaderList.length; i++) {
if (planHeaderList[i].label === f) {
header.push(planHeaderList[i])
break
}
}
})
exportProject({ "condition": mapTrim(this.form), "project": this.tableHeader.map(item => item.prop), "production": header.map(item => item.prop) })
.then((res) => {
exportJsonToExcel({
header: this.tableHeader.concat(header),
headerLabel: "label",
headerProp: "prop",
jsonData: res.data,
filename: Date.now()
})
})
.catch((err) => {
this.$message.warning(err.message)
}).finally(() => {
loading.close()
})
},
fetchUserList() {
getUserList({ "scope_type": "list" }).then(res => {
const a = [], b = [], c = [], d = [], e = [];
res.data.forEach(item => {
switch(item.role.name) {
case "技术负责人": a.push(item); break;
case "项目管理员": b.push(item); break;
case "项目负责人": c.push(item); break;
case "项目成员": d.push(item); break;
case "项目总控人": e.push(item); break;
}
})
this.technicalManager = a
this.projectManager = b
this.projectSupervisor = c
this.projectMemeber = d
this.projectMaster = e
}).catch(err => {
// this.$message.error(err.message)
console.log(err.message)
})
},
fetchData(params) {
this.isLoading = true
getProjectList(Object.assign({
pagenum: this.form.pagenum,
pagesize: this.form.pagesize,
}, params)).then(res => {
if (res.code == 200) {
this.total = res.count
this.list = res.data.map(item => {
for(let i = 0; i < this.projectStatus.length; i++) {
if (this.projectStatus[i].id === item.status) {
item.status_text = this.projectStatus[i].name
}
}
return item
})
}
}).catch(err => {
// this.$message.error(err.message)
console.log(err.message)
}).finally(() => {
this.isLoading = false
})
},
fetchRoleUser() {
getRoleUser({ "roles": ["项目成员", "项目负责人"] }).then(res => {
const a = [], b = []
res.data.forEach(item => {
if (item.role === "项目成员") a.push(item)
else if (item.role === "项目负责人") b.push(item)
})
this.members = a
this.projectLeader = b
}).catch(err => {
console.log(err.message)
})
},
fetchSelectData() {
getProjectList({ "scope_type": "list" }).then(res => {
if (res.code == 200) this.projects = res.data
}).catch(err => {
// this.$message.error(err.message)
console.log(err.message)
})
},
fetchDictList() {
let a = [], b = [], c = [], d = [], e = [], f = [], g = [];
getDictsList({ "scope_type": "list", "category": ["party-b", "project-type", "consult-type", "project-risk", "review-type", "standard-type", "project-source"] }).then(res => {
for (let item of res.data) {
switch (item.category) {
case "party-b": a.push(item); break;
case "project-type": b.push(item); break;
case "consult-type": c.push(item); break;
case "project-risk": d.push(item); break;
case "review-type": e.push(item); break;
case "standard-type": f.push(item); break;
case "project-source": g.push(item); break;
}
}
this.partyBList = a
this.projectType = b
this.consultType = c
this.projectRisk = d
this.reviewList = e
this.standardList = f
this.sourceList = g
}).catch(err => {
console.log(err.message)
})
},
fetchProjectData(params) {
getProject(params).then(res => {
// 按照不同角色,对项目参与者进行划分
const a = [], b = [], c = [], d = [], e = [];
res.data.users.forEach(item => {
switch(item.user.role.name) {
case "技术负责人": a.push(item.user_uuid); break;
case "项目管理员": b.push(item.user_uuid); break;
case "项目负责人": c.push(item.user_uuid); break;
case "项目成员": d.push(item.user_uuid); break;
case "项目总控人": e.push(item.user_uuid); break;
}
})
this.post.technicalManagerSelected = a
this.post.projectManagerSelected = b
this.post.projectSupervisorSelected = c
this.post.projectMemeberSelected = d
this.post.projectMasterSelected = e
this.post.users = res.data.users
// 项目上传的附件
const f = [], g = [], h = [], i = [];
res.data.annex.forEach(item => {
item.url = item.url.replace(/localhost/i, window.location.hostname);
switch(item.type) {
case 'bidding': f.push(item); break;
case 'acceptance': g.push(item); break;
case 'evaluation': h.push(item); break;
case 'contract': i.push(item); break;
}
})
if (this.role.name !== '项目负责人' && this.role.name !== '项目成员') {
this.biddingList = f
this.contractList = i
}
this.acceptanceList = g
this.evaluationList = h
// 处理项目节点
this.post.flow = res.data.flow
// 处理项目回款计划
this.post.payback = res.data.payback
// 生产计划
if (res.data.production) {
let production = res.data.production
if (production.gross_profit) production.gross_profit = production.gross_profit.toFixed(2)
if (production.gross_profit_rate) production.gross_profit_rate = production.gross_profit_rate.toFixed(2)
if (production.gross_profit_rate_goal) production.gross_profit_rate_goal = production.gross_profit_rate_goal.toFixed(2)
if (production.cost) production.cost = production.cost.toFixed(2)
if (production.profit) production.profit = production.profit.toFixed(2)
this.post.production = production
}
}).catch(err => {
this.$message.error(err.message)
})
},
handleSizeChange(e) {
this.form.pagesize = e
this.fetchData(mapTrim(this.form))
},
handleCurrentChange(e) {
this.form.pagenum = e
this.fetchData(mapTrim(this.form))
},
handleEdit(index, row) {
this.project = Object.assign({}, row)
this.post.type = row.type
this.post.code = row.code
this.post.title = row.title
this.post.amount = row.amount
this.post.consult_type = row.consult_type
this.post.contract_sign_at = row.contract_sign_at
this.post.party_a = row.party_a
this.post.party_b = row.party_b
this.post.leader = row.leader
this.post.level = row.level
this.post.source = row.source
this.post.introducer = row.introducer
this.post.standard_type = row.standard_type
this.post.review_type = row.review_type
this.post.customer_addr = row.customer_addr
this.post.customer_contact = row.customer_contact
this.post.customer_phone = row.customer_phone
this.post.ascription = row.ascription
this.post.risk = row.risk
this.post.people_nums = row.people_nums
this.post.is_bad_debts = row.is_bad_debts
this.post.is_stop = row.is_stop
this.post.is_satisfied = row.is_satisfied
this.post.start_time = row.start_time
this.post.end_time = row.end_time
this.post.remarks = row.remarks
this.dialogTitle = "编辑"
this.dialogVisible = true
this.currentIndex = index
this.currentValue = row
this.fetchProjectData({ uuid: row.uuid })
},
handleDelete(index, row) {
this.$alert('您确定要删除么?删除操作将不可恢复。如需取消操作,请点击右上角关闭按钮。', '删除提醒', {
confirmButtonText: '确定',
callback: action => {
if (action == 'confirm') deleteProject(row.uuid).then(res => {
console.log(res)
this.total -= 1
this.$delete(this.list, index)
this.$message({ type: 'success', message: `成功删除第${ index }行` })
}).catch(err => {
this.$message.error(err.message)
})
}
})
},
handleApprove(index, row) {
this.project = row
this.flowVisible = true
this.currentIndex = index
this.currentValue = row
},
exportProject() {
exportProject().then(res => {
console.log(res)
}).catch(err => {
console.log(err)
})
},
onFlowSubmit() {
getProject({ uuid: this.currentValue.uuid }).then(res => {
this.project = res.data
}).catch(err => {
this.$message.error(err.message)
}).finally(() => {
this.fetchData()
})
},
onSelectChange() {
if (this.dialogTitle == "添加") return
let t = [];
t = t.concat(this.post.projectSupervisorSelected)
t = t.concat(this.post.technicalManagerSelected)
t = t.concat(this.post.projectManagerSelected)
t = t.concat(this.post.projectMemeberSelected)
t = t.concat(this.post.projectMasterSelected)
modifyProjectUser({
"project": this.currentValue.uuid,
"users": t
}).then(res => {
this.post.users.push({})
this.$message.success(res.message)
}).catch(err => {
this.$message.error(err.message)
})
},
onRemoveUser(e) {
deleteProjectUser({
"project": this.currentValue.uuid,
"uuid": e
}).then(res => {
this.$message.success(res.message)
}).catch(err => {
this.$message.error(err.message)
})
},
submitForm(formName) {
if (this.dialogTitle === "添加") {
let t = [];
t = t.concat(this.post.projectSupervisorSelected)
t = t.concat(this.post.technicalManagerSelected)
t = t.concat(this.post.projectManagerSelected)
t = t.concat(this.post.projectMemeberSelected)
t = t.concat(this.post.projectMasterSelected)
this.post.users = t
}
this.$refs[formName].validate((valid) => {
let result = true
if (valid) {
if (this.dialogTitle === '添加') {
addNewProject(this.post).then(res => {
console.log(res)
this.$message({ type: 'success', message: '添加成功' })
this.fetchData()
}).catch(err => {
if (typeof err.message === 'object') this.$message.error("参数错误")
else this.$message.error(err.message)
})
}
else if (this.dialogTitle === '编辑') {
// 如果是在编辑状态下点击的提交按钮,则需要将此操作产生的数据变更同步到数据库
updateProject(this.currentValue.uuid, compareObjectDiff(this.post, this.currentValue)).then(res => {
console.log(res)
this.fetchData()
// this.$set(this.list, this.currentIndex, Object.assign(this.currentValue, tmp))
this.$message({ type: 'success', message: '更新成功' })
}).catch(err => {
this.$message.warning(err.message)
})
updateFlowList({
"uuid": this.currentValue.uuid,
"flow": this.post.flow
}).then(res => {
this.$message.success(res.message)
}).catch(err => {
this.$message.error(err.message)
})
updatePaybackList({
"uuid": this.currentValue.uuid,
"payback": this.post.payback
}).then(res => {
this.$message.success(res.message)
}).catch(err => {
this.$message.error(err.message)
})
updateProduction({
"uuid": this.currentValue.uuid,
"production": this.post.production
}).then(res => {
this.post.production = Object.assign(this.post.production, res.data)
this.$message.success(res.message)
}).catch(err => {
this.$message.error(err.message)
})
}
} else {
result = false
this.$message.warning("输入框参数校验未通过")
}
this.dialogVisible = false
return result
})
},
onAdd() {
this.dialogTitle = "添加"
this.dialogVisible = true
},
onSubmit() {
this.form.pagenum = 1
this.form.pagesize = 15
if (this.datetime && this.datetime.length == 2) {
this.form.start_time = formatUTCDateTime(this.datetime[0])
this.form.end_time = formatUTCDateTime(this.datetime[1])
}
this.fetchData(mapTrim(this.form))
},
onReset(formName) {
if (formName === 'form') {
this.form.pagesize = 15
this.form.pagenum = 1
this.form.start_time = null
this.form.end_time = null
this.form.min_amount = null
this.form.max_amount = null
this.form.member = null
this.form.charge_person = null
}
this.$refs[formName].resetFields()
this.fetchData()
},
addFlowNode() {
this.post.flow.push({ title: '', key: Date.now(), deadline: null, sort: this.post.flow.length + 1 })
},
handleUploadSuccess(response) {
addAnnex({
project: this.project.uuid,
size: response.data.filesize,
title: response.data.filename,
path: response.data.filepath,
remarks: response.data.note
})
.then((res) => {
this.$message.success(res.message)
// 上传成功后,根据类型更新该项目对应字段
return updateProject(this.project.uuid, { uploads: response.data.note })
})
.then(res => {
console.log(res)
})
.catch((err) => {
this.$message.warning(err.message)
})
},
handleRemove(file) {
if (file.uuid) deleteAnnex(file.uuid).then(res => {
this.$message.success(res.message)
}).catch(err => {
this.$message.warning(err.message)
})
},
handlePreview(file) {
console.log(file)
},
handleExceed(files, fileList) {
this.$message.warning(
`当前限制选择 3 个文件,本次选择了 ${files.length} 个文件,共选择了 ${
files.length + fileList.length
} 个文件`
)
},
beforeRemove(file) {
return this.$confirm(`确定移除 ${file.name}?`)
},
removeFlowNode(item) {
const index = this.post.flow.indexOf(item)
if (index !== -1) this.post.flow.splice(index, 1)
// 如果是在编辑状态下,则需要将删除的数据同步到数据库
if (this.dialogTitle == "编辑" && !item.key) deleteFlow(item.uuid).then(res => {
this.$message.success(res.message)
}).catch(err => {
this.$message.error(err.message)
})
},
addPaybackNode() {
this.post.payback.push({ title: '', key: Date.now(), funds: 0, plan_time: null, sort: this.post.payback.length + 1 })
},
removePaybackNode(item) {
const index = this.post.payback.indexOf(item)
if (index !== -1) this.post.payback.splice(index, 1)
// 如果是在编辑状态下,则需要将删除的数据同步到数据库
if (this.dialogTitle == "编辑" && !item.key) deletePayback(item.uuid).then(res => {
this.$message.success(res.message)
}).catch(err => {
this.$message.error(err.message)
})
},
onPreviousStep() {
this.showIndex--
},
onNextStep() {
this.showIndex++
}
},
mounted() {},
created() {
if (!sessionStorage.getItem("user")) {
this.$store.dispatch("user/removeToken", {
success() {
this.$router.push("/403")
}
})
}
this.fetchData()
this.fetchSelectData()
this.fetchUserList()
this.fetchRoleUser()
this.fetchDictList()
}
}
</script>
<style lang="less" scoped>
.app-container {
& > div.page-wrapper {
margin: 10px 0px;
}
}
</style>
<template>
<div class="app-container">
<el-form :inline="true" ref="query" :model="query" size="mini">
<el-form-item :label="queryTitle" prop="uuid">
<el-select v-model="query.uuid" filterable :placeholder="queryPlaceHolder">
<el-option v-for="(item, index) in queryList" :key="index" :label="item.name" :value="item.uuid"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onQuery">查询</el-button>
</el-form-item>
<el-form-item>
<el-button @click="onReset('query')">重置</el-button>
</el-form-item>
<el-form-item>
<el-button type="warning" @click="onAdd">添加</el-button>
</el-form-item>
</el-form>
<el-table v-loading="isLoading" element-loading-text="Loading" :data="tableData" size="mini" border stripe fit highlight-current-row>
<el-table-column v-for="(item, index) in tableHeader" :key="index" :prop="item.prop" :label="item.label" :align="item.align" :min-width="item.width" :show-overflow-tooltip="item.overflow"></el-table-column>
<el-table-column label="操作" align="center" width="180" fixed="right">
<template slot-scope="scope">
<el-button size="mini" type="success" @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
<el-button size="mini" type="danger" @click="handleDelete(scope.$index, scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<div class="page-wrapper">
<el-pagination @current-change="handleCurrentChange" :current-page.sync="query.pagenum" background small :page-size="query.pagesize" :pager-count="5" layout="pager, prev, next, total" :total="total"></el-pagination>
</div>
<formdialog ref="formdialog" :title="dialogTitle" :visible="dialogVisible" @close="dialogVisible=false" @confirm="submitForm"></formdialog>
</div>
</template>
<script>
import request from "@/utils/request";
import {
mapTrim
} from '@/utils/index'
import formdialog from './components/companyDialog'
export default {
name: "CompanyQualification",
components: {
formdialog,
},
data() {
return {
queryTitle: "查询条件",
queryPlaceHolder: "输入查询字段",
total: 0,
tableData: [],
isLoading: false,
queryList: [],
query: {
uuid: null,
pagesize: 15,
pagenum: 1
},
dialogTitle: "",
dialogVisible: false,
urlPrefix: "/api/v1/evm_store/qualification/company",
tableHeader: [
{
label: "公司名称" ,
prop: "name",
align: "center",
width: "150"
},
{
label: "资质名称" ,
prop: "qual_name",
align: "center",
width: "150"
},
{
label: "资质等级" ,
prop: "qual_level",
align: "center",
width: "120"
},
{
label: "有效期" ,
prop: "qual_validity",
align: "center",
width: "150"
},
{
label: "资质范围" ,
prop: "qual_scope",
align: "center",
width: "150",
overflow: true
},
],
}
},
methods: {
addItem(params) {
return request({
url: this.urlPrefix + `/add`,
method: "post",
data: params,
});
},
getItemList(params) {
return request({
url: this.urlPrefix + `/list`,
method: "post",
data: params,
});
},
updateItem(id, params) {
return request({
url: `${this.urlPrefix}/update/${id}`,
method: "post",
data: params,
});
},
deleteItem(id) {
return request({
url: `${this.urlPrefix}/delete/${id}`,
method: "post",
});
},
fetchQueryList() {
this.getItemList({ "scope_type": "list" }).then(res => {
this.queryList = res.data
}).catch(err => {
console.log(err.message)
})
},
fetchData(params) {
this.isLoading = true
this.getItemList(params).then(res => {
this.total = res.count
this.tableData = res.data
}).catch(err => {
console.log(err.message)
}).finally(() => {
this.isLoading = false
})
},
handleSizeChange(e) {
this.query.pagesize = e
this.fetchData(mapTrim(this.query))
},
handleCurrentChange(e) {
this.query.pagenum = e
this.fetchData(mapTrim(this.query))
},
handleEdit(index, row) {
this.dialogTitle = "编辑"
this.dialogVisible = true
this.$refs["formdialog"].update(row);
},
handleDelete(index, row) {
this.$alert('您确定要删除么?删除操作将不可恢复。如需取消操作,请点击右上角关闭按钮。', '删除提醒', {
confirmButtonText: '确定',
callback: action => {
if (action == 'confirm') this.deleteItem(row.uuid).then(res => {
console.log(res)
this.total -= 1
this.$delete(this.tableData, index)
this.$message({ type: 'success', message: `成功删除第${ index + 1 }行` })
}).catch(err => {
this.$message.error(err.message)
})
}
})
},
submitForm(formdata) {
if (this.dialogTitle === "添加") {
this.addItem(formdata).then(res => {
console.log(res)
this.$message({ type: 'success', message: '添加成功' })
this.fetchData(mapTrim(this.query))
}).catch(err => {
this.$message.error(err.message)
})
} else if (this.dialogTitle === "编辑") {
this.updateItem(formdata.uuid, formdata).then(res => {
console.log(res)
this.$message({ type: 'success', message: '更新成功' })
this.fetchData(mapTrim(this.query))
}).catch(err => {
this.$message.error(err.message)
})
}
},
onAdd() {
this.dialogTitle = "添加"
this.dialogVisible = true
},
onQuery() {
this.query.pagenum = 1
this.query.pagesize = 15
this.fetchData(mapTrim(this.query))
},
onReset(formName) {
this.query.pagenum = 1
this.query.pagesize = 15
this.$refs[formName].resetFields()
this.fetchData(mapTrim(this.query))
}
},
mounted() {},
created() {
this.fetchData(mapTrim(this.query))
this.fetchQueryList()
}
}
</script>
<style lang="less" scoped>
.app-container {
& > div.page-wrapper {
margin: 10px 0px;
}
}
</style>
{
"fields": [{
"__config__": {
"label": "公司名称",
"labelWidth": null,
"showLabel": true,
"changeTag": true,
"tag": "el-input",
"tagIcon": "input",
"required": true,
"layout": "colFormItem",
"span": 24,
"document": "https://element.eleme.cn/#/zh-CN/component/input",
"regList": [],
"formId": 101,
"renderKey": 1609589864146
},
"__slot__": {
"prepend": "",
"append": ""
},
"placeholder": "请输入公司名称",
"style": {
"width": "100%"
},
"clearable": true,
"prefix-icon": "",
"suffix-icon": "",
"maxlength": null,
"show-word-limit": false,
"readonly": false,
"disabled": false,
"__vModel__": "name"
}, {
"__config__": {
"label": "资质名称",
"labelWidth": null,
"showLabel": true,
"changeTag": true,
"tag": "el-input",
"tagIcon": "input",
"required": true,
"layout": "colFormItem",
"span": 24,
"document": "https://element.eleme.cn/#/zh-CN/component/input",
"regList": [],
"formId": 102,
"renderKey": 1609589903373
},
"__slot__": {
"prepend": "",
"append": ""
},
"placeholder": "请输入资质名称",
"style": {
"width": "100%"
},
"clearable": true,
"prefix-icon": "",
"suffix-icon": "",
"maxlength": null,
"show-word-limit": false,
"readonly": false,
"disabled": false,
"__vModel__": "qual_name"
}, {
"__config__": {
"label": "资质等级",
"labelWidth": null,
"showLabel": true,
"changeTag": true,
"tag": "el-input",
"tagIcon": "input",
"required": true,
"layout": "colFormItem",
"span": 24,
"document": "https://element.eleme.cn/#/zh-CN/component/input",
"regList": [],
"formId": 103,
"renderKey": 1609589932990
},
"__slot__": {
"prepend": "",
"append": ""
},
"placeholder": "请输入资质等级",
"style": {
"width": "100%"
},
"clearable": true,
"prefix-icon": "",
"suffix-icon": "",
"maxlength": null,
"show-word-limit": false,
"readonly": false,
"disabled": false,
"__vModel__": "qual_level"
}, {
"__config__": {
"label": "有效期",
"tag": "el-date-picker",
"tagIcon": "date",
"defaultValue": null,
"showLabel": true,
"labelWidth": null,
"span": 24,
"layout": "colFormItem",
"required": true,
"regList": [],
"changeTag": true,
"document": "https://element.eleme.cn/#/zh-CN/component/date-picker",
"formId": 107,
"renderKey": 1609591081474
},
"placeholder": "请选择有效期",
"type": "datetime",
"style": {
"width": "100%"
},
"disabled": false,
"clearable": true,
"format": "yyyy-MM-dd HH:mm:ss",
"value-format": "yyyy-MM-dd HH:mm:ss",
"readonly": false,
"__vModel__": "qual_validity"
}, {
"__config__": {
"label": "资质范围",
"labelWidth": null,
"showLabel": true,
"changeTag": true,
"tag": "el-input",
"tagIcon": "input",
"required": true,
"layout": "colFormItem",
"span": 24,
"document": "https://element.eleme.cn/#/zh-CN/component/input",
"regList": [],
"formId": 105,
"renderKey": 1609589971050
},
"__slot__": {
"prepend": "",
"append": ""
},
"placeholder": "请输入资质范围",
"style": {
"width": "100%"
},
"clearable": true,
"prefix-icon": "",
"suffix-icon": "",
"maxlength": null,
"show-word-limit": false,
"readonly": false,
"disabled": false,
"__vModel__": "qual_scope"
}],
"formRef": "elForm",
"formModel": "formData",
"size": "medium",
"labelPosition": "right",
"labelWidth": 100,
"formRules": "rules",
"gutter": 15,
"disabled": false,
"span": 24,
"formBtns": true
}
<template>
<div>
<el-dialog :visible.sync="isVisible" v-bind="$attrs" v-on="$listeners" @open="onOpen" @close="onClose" :title="title" :width="width">
<formpage ref="formpage"></formpage>
<div slot="footer">
<el-button size="medium" @click="close">取消</el-button>
<el-button size="medium" type="primary" @click="handelConfirm">确定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import formpage from './companyForm'
export default {
inheritAttrs: false,
components: {formpage},
props: {
visible: {
type: Boolean,
default() {
return false
}
},
title: {
type: String,
default () {
return "dialog"
}
},
width: {
type: String,
required: false,
default() {
return "30%"
}
}
},
data() {
return {}
},
computed: {
isVisible: {
get: function () {
return this.visible;
},
set: function (newValue) {
return newValue;
}
}
},
watch: {},
created() {},
mounted() {},
methods: {
update(data) {
this.$nextTick(() => {
this.$refs['formpage'].formData = data;
})
},
onOpen() {},
onClose() {
this.close()
},
close() {
this.$emit('close', this.formData)
},
handelConfirm() {
const elform = this.$refs['formpage'].$refs['elForm']
elform.validate(valid => {
if (!valid) return
this.$emit('confirm', elform.model)
this.close()
})
},
}
}
</script>
<style>
</style>
<template>
<el-form ref="elForm" :model="formData" :rules="rules" size="medium" label-width="100px">
<el-form-item label="公司名称" prop="name">
<el-input v-model="formData.name" placeholder="请输入公司名称" :readonly="isReadOnly" clearable :style="{width: '100%'}"></el-input>
</el-form-item>
<el-form-item label="资质名称" prop="qual_name">
<el-input v-model="formData.qual_name" placeholder="请输入资质名称" :readonly="isReadOnly" clearable :style="{width: '100%'}"></el-input>
</el-form-item>
<el-form-item label="资质等级" prop="qual_level">
<el-input v-model="formData.qual_level" placeholder="请输入资质等级" :readonly="isReadOnly" clearable :style="{width: '100%'}"></el-input>
</el-form-item>
<el-form-item label="有效期" prop="qual_validity">
<el-date-picker type="datetime" v-model="formData.qual_validity" format="yyyy-MM-dd HH:mm:ss"
value-format="yyyy-MM-dd HH:mm:ss" :style="{width: '100%'}" placeholder="请选择有效期" clearable>
</el-date-picker>
</el-form-item>
<el-form-item label="资质范围" prop="qual_scope">
<el-input v-model="formData.qual_scope" placeholder="请输入资质范围" :readonly="isReadOnly" clearable :style="{width: '100%'}">
</el-input>
</el-form-item>
</el-form>
</template>
<script>
export default {
inheritAttrs: false,
components: {},
props: {
data: {
type: Object
},
isReadOnly: {
type: Boolean,
default: false
}
},
data() {
return {
formData: {
name: undefined,
qual_name: undefined,
qual_level: undefined,
qual_validity: null,
qual_scope: undefined,
},
rules: {
name: [{
required: true,
message: '请输入公司名称',
trigger: 'blur'
}],
qual_name: [{
required: true,
message: '请输入资质名称',
trigger: 'blur'
}],
qual_level: [{
required: true,
message: '请输入资质等级',
trigger: 'blur'
}],
qual_validity: [{
required: true,
message: '请选择有效期',
trigger: 'change'
}],
qual_scope: [{
required: true,
message: '请输入资质范围',
trigger: 'blur'
}],
},
}
},
computed: {},
watch: {},
created() {},
mounted() {
if (this.data) this.formData = this.data;
},
methods: {}
}
</script>
<style>
</style>
{
"fields": [{
"__config__": {
"label": "设备名称",
"labelWidth": null,
"showLabel": true,
"changeTag": true,
"tag": "el-input",
"tagIcon": "input",
"required": true,
"layout": "colFormItem",
"span": 24,
"document": "https://element.eleme.cn/#/zh-CN/component/input",
"regList": [],
"formId": 101,
"renderKey": 1609589864146
},
"__slot__": {
"prepend": "",
"append": ""
},
"placeholder": "请输入设备名称",
"style": {
"width": "100%"
},
"clearable": true,
"prefix-icon": "",
"suffix-icon": "",
"maxlength": null,
"show-word-limit": false,
"readonly": false,
"disabled": false,
"__vModel__": "name"
}, {
"__config__": {
"label": "检测日期",
"tag": "el-date-picker",
"tagIcon": "date",
"defaultValue": null,
"showLabel": true,
"labelWidth": null,
"span": 24,
"layout": "colFormItem",
"required": true,
"regList": [],
"changeTag": true,
"document": "https://element.eleme.cn/#/zh-CN/component/date-picker",
"formId": 108,
"renderKey": 1609595122327
},
"placeholder": "请选择检测日期",
"type": "datetime",
"style": {
"width": "100%"
},
"disabled": false,
"clearable": true,
"format": "yyyy-MM-dd HH:mm:ss",
"value-format": "yyyy-MM-dd HH:mm:ss",
"readonly": false,
"__vModel__": "test_date"
}, {
"__config__": {
"label": "有效期",
"tag": "el-date-picker",
"tagIcon": "date",
"defaultValue": null,
"showLabel": true,
"labelWidth": null,
"span": 24,
"layout": "colFormItem",
"required": true,
"regList": [],
"changeTag": true,
"document": "https://element.eleme.cn/#/zh-CN/component/date-picker",
"formId": 107,
"renderKey": 1609591081474
},
"placeholder": "请选择有效期",
"type": "datetime",
"style": {
"width": "100%"
},
"disabled": false,
"clearable": true,
"format": "yyyy-MM-dd HH:mm:ss",
"value-format": "yyyy-MM-dd HH:mm:ss",
"readonly": false,
"__vModel__": "validity"
}],
"formRef": "elForm",
"formModel": "formData",
"size": "medium",
"labelPosition": "right",
"labelWidth": 100,
"formRules": "rules",
"gutter": 15,
"disabled": false,
"span": 24,
"formBtns": true
}
<template>
<div>
<el-dialog :visible.sync="isVisible" v-bind="$attrs" v-on="$listeners" @open="onOpen" @close="onClose" :title="title" :width="width">
<formpage ref="formpage"></formpage>
<div slot="footer">
<el-button size="medium" @click="close">取消</el-button>
<el-button size="medium" type="primary" @click="handelConfirm">确定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import formpage from './equipmentForm'
export default {
inheritAttrs: false,
components: {formpage},
props: {
visible: {
type: Boolean,
default() {
return false
}
},
title: {
type: String,
default () {
return "dialog"
}
},
width: {
type: String,
required: false,
default() {
return "50%"
}
}
},
data() {
return {}
},
computed: {
isVisible: {
get: function () {
return this.visible;
},
set: function (newValue) {
return newValue;
}
}
},
watch: {},
created() {},
mounted() {},
methods: {
update(data) {
this.$nextTick(() => {
this.$refs['formpage'].formData = data;
})
},
onOpen() {},
onClose() {
this.close()
},
close() {
this.$emit('close', this.formData)
},
handelConfirm() {
const elform = this.$refs['formpage'].$refs['elForm']
elform.validate(valid => {
if (!valid) return
this.$emit('confirm', elform.model)
this.close()
})
},
}
}
</script>
<style>
</style>
<template>
<el-form ref="elForm" :model="formData" :rules="rules" size="medium" label-width="100px">
<el-form-item label="设备名称" prop="name">
<el-input v-model="formData.name" placeholder="请输入设备名称" :readonly="isReadOnly" clearable :style="{width: '100%'}"></el-input>
</el-form-item>
<el-form-item label="检测日期" prop="test_date">
<el-date-picker type="datetime" v-model="formData.test_date" format="yyyy-MM-dd HH:mm:ss"
value-format="yyyy-MM-dd HH:mm:ss" :style="{width: '100%'}" placeholder="请选择检测日期" :readonly="isReadOnly" clearable>
</el-date-picker>
</el-form-item>
<el-form-item label="有效期" prop="validity">
<el-date-picker type="datetime" v-model="formData.validity" format="yyyy-MM-dd HH:mm:ss"
value-format="yyyy-MM-dd HH:mm:ss" :style="{width: '100%'}" placeholder="请选择有效期" clearable>
</el-date-picker>
</el-form-item>
</el-form>
</template>
<script>
export default {
inheritAttrs: false,
components: {},
props: {
data: {
type: Object
},
isReadOnly: {
type: Boolean,
default: false
}
},
data() {
return {
formData: {
name: undefined,
test_date: null,
validity: null,
},
rules: {
name: [{
required: true,
message: '请输入设备名称',
trigger: 'blur'
}],
test_date: [{
required: true,
message: '请选择检测日期',
trigger: 'change'
}],
validity: [{
required: true,
message: '请选择有效期',
trigger: 'change'
}],
},
}
},
computed: {},
watch: {},
created() {},
mounted() {
if (this.data) this.formData = this.data;
},
methods: {}
}
</script>
<style>
</style>
{
"fields": [{
"__config__": {
"label": "姓名",
"labelWidth": null,
"showLabel": true,
"changeTag": true,
"tag": "el-input",
"tagIcon": "input",
"required": true,
"layout": "colFormItem",
"span": 24,
"document": "https://element.eleme.cn/#/zh-CN/component/input",
"regList": [],
"formId": 101,
"renderKey": 1609589864146
},
"__slot__": {
"prepend": "",
"append": ""
},
"placeholder": "请输入姓名",
"style": {
"width": "100%"
},
"clearable": true,
"prefix-icon": "",
"suffix-icon": "",
"maxlength": null,
"show-word-limit": false,
"readonly": false,
"disabled": false,
"__vModel__": "name"
}, {
"__config__": {
"label": "出生日期",
"tag": "el-date-picker",
"tagIcon": "date",
"defaultValue": null,
"showLabel": true,
"labelWidth": null,
"span": 24,
"layout": "colFormItem",
"required": true,
"regList": [],
"changeTag": true,
"document": "https://element.eleme.cn/#/zh-CN/component/date-picker",
"formId": 108,
"renderKey": 1609595122327
},
"placeholder": "请选择出生日期",
"type": "datetime",
"style": {
"width": "100%"
},
"disabled": false,
"clearable": true,
"format": "yyyy-MM-dd HH:mm:ss",
"value-format": "yyyy-MM-dd HH:mm:ss",
"readonly": false,
"__vModel__": "birthday"
}, {
"__config__": {
"label": "性别",
"showLabel": true,
"labelWidth": null,
"tag": "el-select",
"tagIcon": "select",
"layout": "colFormItem",
"span": 24,
"required": true,
"regList": [],
"changeTag": true,
"document": "https://element.eleme.cn/#/zh-CN/component/select",
"formId": 101,
"renderKey": 1609815136865
},
"__slot__": {
"options": [{
"label": "男",
"value": true
}, {
"label": "女",
"value": false
}]
},
"placeholder": "请选择性别",
"style": {
"width": "100%"
},
"clearable": true,
"disabled": false,
"filterable": false,
"multiple": false,
"__vModel__": "gender"
}, {
"__config__": {
"label": "身份证有效期",
"tag": "el-date-picker",
"tagIcon": "date",
"defaultValue": null,
"showLabel": true,
"labelWidth": null,
"span": 24,
"layout": "colFormItem",
"required": true,
"regList": [],
"changeTag": true,
"document": "https://element.eleme.cn/#/zh-CN/component/date-picker",
"formId": 107,
"renderKey": 1609591081474
},
"placeholder": "请选择身份证身份证有效期",
"type": "datetime",
"style": {
"width": "100%"
},
"disabled": false,
"clearable": true,
"format": "yyyy-MM-dd HH:mm:ss",
"value-format": "yyyy-MM-dd HH:mm:ss",
"readonly": false,
"__vModel__": "id_validity"
}, {
"__config__": {
"label": "身份证照片",
"tag": "el-upload",
"tagIcon": "upload",
"layout": "colFormItem",
"defaultValue": null,
"showLabel": true,
"labelWidth": null,
"required": true,
"span": 24,
"showTip": false,
"buttonText": "点击上传",
"regList": [],
"changeTag": true,
"fileSize": 50,
"sizeUnit": "MB",
"document": "https://element.eleme.cn/#/zh-CN/component/upload",
"formId": 110,
"renderKey": 1609598368303
},
"__slot__": {
"list-type": true
},
"action": "https://jsonplaceholder.typicode.com/posts/",
"disabled": false,
"accept": "image/*",
"name": "binfile",
"auto-upload": true,
"list-type": "text",
"multiple": false,
"__vModel__": ""
}, {
"__config__": {
"label": "电话",
"labelWidth": null,
"showLabel": true,
"changeTag": true,
"tag": "el-input",
"tagIcon": "input",
"required": true,
"layout": "colFormItem",
"span": 24,
"document": "https://element.eleme.cn/#/zh-CN/component/input",
"regList": [],
"formId": 111,
"renderKey": 1609598474973
},
"__slot__": {
"prepend": "",
"append": ""
},
"placeholder": "请输入电话",
"style": {
"width": "100%"
},
"clearable": true,
"prefix-icon": "",
"suffix-icon": "",
"maxlength": null,
"show-word-limit": false,
"readonly": false,
"disabled": false,
"__vModel__": "phone"
}, {
"__config__": {
"label": "地址",
"labelWidth": null,
"showLabel": true,
"changeTag": true,
"tag": "el-input",
"tagIcon": "input",
"required": true,
"layout": "colFormItem",
"span": 24,
"document": "https://element.eleme.cn/#/zh-CN/component/input",
"regList": [],
"formId": 112,
"renderKey": 1609598488402
},
"__slot__": {
"prepend": "",
"append": ""
},
"placeholder": "请输入地址",
"style": {
"width": "100%"
},
"clearable": true,
"prefix-icon": "",
"suffix-icon": "",
"maxlength": null,
"show-word-limit": false,
"readonly": false,
"disabled": false,
"__vModel__": "address"
}, {
"__config__": {
"label": "合同有效期",
"tag": "el-date-picker",
"tagIcon": "date",
"defaultValue": null,
"showLabel": true,
"labelWidth": null,
"span": 24,
"layout": "colFormItem",
"required": true,
"regList": [],
"changeTag": true,
"document": "https://element.eleme.cn/#/zh-CN/component/date-picker",
"formId": 118,
"renderKey": 1609598697543
},
"placeholder": "请选择合同有效期",
"type": "datetime",
"style": {
"width": "100%"
},
"disabled": false,
"clearable": true,
"format": "yyyy-MM-dd HH:mm:ss",
"value-format": "yyyy-MM-dd HH:mm:ss",
"readonly": false,
"__vModel__": "contract_validity"
}, {
"__config__": {
"label": "学历照片",
"tag": "el-upload",
"tagIcon": "upload",
"layout": "colFormItem",
"defaultValue": null,
"showLabel": true,
"labelWidth": null,
"required": true,
"span": 24,
"showTip": false,
"buttonText": "点击上传",
"regList": [],
"changeTag": true,
"fileSize": 2,
"sizeUnit": "MB",
"document": "https://element.eleme.cn/#/zh-CN/component/upload",
"formId": 113,
"renderKey": 1609598512820
},
"__slot__": {
"list-type": true
},
"action": "https://jsonplaceholder.typicode.com/posts/",
"disabled": false,
"accept": "",
"name": "binfile",
"auto-upload": true,
"list-type": "text",
"multiple": false,
"__vModel__": ""
}, {
"__config__": {
"label": "职称有效期",
"tag": "el-date-picker",
"tagIcon": "date",
"defaultValue": null,
"showLabel": true,
"labelWidth": null,
"span": 24,
"layout": "colFormItem",
"required": true,
"regList": [],
"changeTag": true,
"document": "https://element.eleme.cn/#/zh-CN/component/date-picker",
"formId": 115,
"renderKey": 1609598558355
},
"placeholder": "请选择职称有效期",
"type": "datetime",
"style": {
"width": "100%"
},
"disabled": false,
"clearable": true,
"format": "yyyy-MM-dd HH:mm:ss",
"value-format": "yyyy-MM-dd HH:mm:ss",
"readonly": false,
"__vModel__": "job_title_validity"
}, {
"__config__": {
"label": "职称照片",
"tag": "el-upload",
"tagIcon": "upload",
"layout": "colFormItem",
"defaultValue": null,
"showLabel": true,
"labelWidth": null,
"required": true,
"span": 24,
"showTip": false,
"buttonText": "点击上传",
"regList": [],
"changeTag": true,
"fileSize": 2,
"sizeUnit": "MB",
"document": "https://element.eleme.cn/#/zh-CN/component/upload",
"formId": 116,
"renderKey": 1609598573599
},
"__slot__": {
"list-type": true
},
"action": "https://jsonplaceholder.typicode.com/posts/",
"disabled": false,
"accept": "",
"name": "binfile",
"auto-upload": true,
"list-type": "text",
"multiple": false,
"__vModel__": ""
}, {
"__config__": {
"label": "执业证书有效期",
"tag": "el-date-picker",
"tagIcon": "date",
"defaultValue": null,
"showLabel": true,
"labelWidth": null,
"span": 24,
"layout": "colFormItem",
"required": true,
"regList": [],
"changeTag": true,
"document": "https://element.eleme.cn/#/zh-CN/component/date-picker",
"formId": 117,
"renderKey": 1609598641014
},
"placeholder": "请选择执业证书有效期",
"type": "datetime",
"style": {
"width": "100%"
},
"disabled": false,
"clearable": true,
"format": "yyyy-MM-dd HH:mm:ss",
"value-format": "yyyy-MM-dd HH:mm:ss",
"readonly": false,
"__vModel__": "pract_cert_validity"
}, {
"__config__": {
"label": "执业证书照片",
"tag": "el-upload",
"tagIcon": "upload",
"layout": "colFormItem",
"defaultValue": null,
"showLabel": true,
"labelWidth": null,
"required": true,
"span": 24,
"showTip": false,
"buttonText": "点击上传",
"regList": [],
"changeTag": true,
"fileSize": 2,
"sizeUnit": "MB",
"document": "https://element.eleme.cn/#/zh-CN/component/upload",
"formId": 119,
"renderKey": 1609598717475
},
"__slot__": {
"list-type": true
},
"action": "https://jsonplaceholder.typicode.com/posts/",
"disabled": false,
"accept": "",
"name": "binfile",
"auto-upload": true,
"list-type": "text",
"multiple": false,
"__vModel__": ""
}],
"formRef": "elForm",
"formModel": "formData",
"size": "medium",
"labelPosition": "right",
"labelWidth": 120,
"formRules": "rules",
"gutter": 15,
"disabled": false,
"span": 24,
"formBtns": true
}
<template>
<div>
<el-dialog :visible.sync="isVisible" v-bind="$attrs" v-on="$listeners" @open="onOpen" @close="onClose" :title="title" :width="width">
<formpage ref="formpage"></formpage>
<div slot="footer">
<el-button size="medium" @click="close">取消</el-button>
<el-button size="medium" type="primary" @click="handelConfirm">确定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import formpage from './personForm'
export default {
inheritAttrs: false,
components: {formpage},
props: {
visible: {
type: Boolean,
default() {
return false
}
},
title: {
type: String,
default () {
return "dialog"
}
},
width: {
type: String,
required: false,
default() {
return "50%"
}
}
},
data() {
return {}
},
computed: {
isVisible: {
get: function () {
return this.visible;
},
set: function (newValue) {
return newValue;
}
}
},
watch: {},
created() {},
mounted() {},
methods: {
update(data) {
this.$nextTick(() => {
this.$refs['formpage'].formData = data
})
},
onOpen() {},
onClose() {
this.close()
},
close() {
this.$emit('close', this.formData)
},
handelConfirm() {
const elform = this.$refs['formpage'].$refs['elForm']
elform.validate(valid => {
if (!valid) return
this.$emit('confirm', elform.model)
this.close()
})
},
}
}
</script>
<style>
</style>
<template>
<el-form
ref="elForm"
:model="formData"
:rules="rules"
size="medium"
label-width="140px"
>
<el-form-item label="姓名" prop="name">
<el-input
v-model="formData.name"
placeholder="请输入姓名"
clearable
:style="{ width: '100%' }"
></el-input>
</el-form-item>
<el-form-item label="出生日期" prop="birthday">
<el-date-picker
type="date"
v-model="formData.birthday"
format="yyyy-MM-dd"
value-format="yyyy-MM-dd"
:style="{ width: '100%' }"
placeholder="请选择出生日期"
clearable
>
</el-date-picker>
</el-form-item>
<el-form-item label="性别" prop="gender">
<el-select
v-model="formData.gender"
placeholder="请选择性别"
clearable
:style="{ width: '100%' }"
>
<el-option
v-for="(item, index) in genderOptions"
:key="index"
:label="item.label"
:value="item.value"
:disabled="item.disabled"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="身份证号" prop="id_number">
<el-input
v-model="formData.id_number"
placeholder="请输入身份证号码"
clearable
:style="{ width: '100%' }"
></el-input>
</el-form-item>
<el-form-item label="身份证有效期" prop="id_validity">
<el-date-picker
type="date"
v-model="formData.id_validity"
format="yyyy-MM-dd"
value-format="yyyy-MM-dd"
:style="{ width: '100%' }"
placeholder="请选择身份证身份证有效期"
clearable
>
</el-date-picker>
</el-form-item>
<!-- <el-form-item label="身份证照片">
<el-upload
:file-list="idCardFileList"
:on-success="onUploadSuccess"
:before-remove="onBeforeRemove"
:action="action"
:data="{ annex_type: 'qual_person', note: 'idcard' }"
:before-upload="beforeUpload"
name="binfile"
>
<el-button size="small" type="primary" icon="el-icon-upload"
>点击上传</el-button
>
</el-upload>
</el-form-item> -->
<el-form-item label="电话" prop="phone">
<el-input
v-model="formData.phone"
placeholder="请输入电话"
clearable
:style="{ width: '100%' }"
></el-input>
</el-form-item>
<el-form-item label="地址" prop="address">
<el-input
v-model="formData.address"
placeholder="请输入地址"
clearable
:style="{ width: '100%' }"
>
</el-input>
</el-form-item>
<el-form-item label="合同有效期" prop="contract_validity">
<el-date-picker
type="date"
v-model="formData.contract_validity"
format="yyyy-MM-dd"
value-format="yyyy-MM-dd"
:style="{ width: '100%' }"
placeholder="请选择合同有效期"
clearable
>
</el-date-picker>
</el-form-item>
<!-- <el-form-item label="学历照片">
<el-upload
:file-list="educationFileList"
:on-success="onUploadSuccess"
:before-remove="onBeforeRemove"
:action="action"
:data="{ annex_type: 'qual_person', note: 'education' }"
:before-upload="beforeUpload"
name="binfile"
>
<el-button size="small" type="primary" icon="el-icon-upload"
>点击上传</el-button
>
</el-upload>
</el-form-item> -->
<el-form-item label="职称有效期" prop="job_title_validity">
<el-date-picker
type="date"
v-model="formData.job_title_validity"
format="yyyy-MM-dd"
value-format="yyyy-MM-dd"
:style="{ width: '100%' }"
placeholder="请选择职称有效期"
clearable
>
</el-date-picker>
</el-form-item>
<!-- <el-form-item label="职称照片">
<el-upload
:file-list="jobTitleFileList"
:on-success="onUploadSuccess"
:before-remove="onBeforeRemove"
:action="action"
:data="{ annex_type: 'qual_person', note: 'jobtitle' }"
:before-upload="beforeUpload"
name="binfile"
>
<el-button size="small" type="primary" icon="el-icon-upload"
>点击上传</el-button
>
</el-upload>
</el-form-item> -->
<el-form-item label="执业证书有效期" prop="pract_cert_validity">
<el-date-picker
type="date"
v-model="formData.pract_cert_validity"
format="yyyy-MM-dd"
value-format="yyyy-MM-dd"
:style="{ width: '100%' }"
placeholder="请选择执业证书有效期"
clearable
>
</el-date-picker>
</el-form-item>
<!-- <el-form-item label="执业证书照片">
<el-upload
:file-list="certFileList"
:on-success="onUploadSuccess"
:before-remove="onBeforeRemove"
:action="action"
:data="{ annex_type: 'qual_person', note: 'certificate' }"
:before-upload="beforeUpload"
name="binfile"
>
<el-button size="small" type="primary" icon="el-icon-upload"
>点击上传</el-button
>
</el-upload>
</el-form-item> -->
</el-form>
</template>
<script>
export default {
inheritAttrs: false,
components: {},
props: {
data: {
type: Object,
},
isReadOnly: {
type: Boolean,
default: false,
},
},
data() {
return {
currentValue: null,
formData: {
name: null,
birthday: null,
gender: null,
id_number: null,
id_validity: null,
phone: null,
address: null,
contract_validity: null,
job_title_validity: null,
pract_cert_validity: null,
annex: [],
},
rules: {
name: [
{
required: true,
message: "请输入姓名",
trigger: "blur",
},
],
birthday: [
{
required: false,
message: "请选择出生日期",
trigger: "change",
},
],
gender: [
{
required: false,
message: "性别不能为空",
trigger: "change",
},
],
id_validity: [
{
required: false,
message: "请选择身份证有效期",
trigger: "change",
},
],
phone: [
{
required: false,
message: "请输入电话",
trigger: "blur",
},
],
address: [
{
required: false,
message: "请输入地址",
trigger: "blur",
},
],
contract_validity: [
{
required: false,
message: "请选择合同有效期",
trigger: "change",
},
],
job_title_validity: [
{
required: false,
message: "请选择职称有效期",
trigger: "change",
},
],
pract_cert_validity: [
{
required: false,
message: "请选择执业证书有效期",
trigger: "change",
},
],
annex: [
{
required: false,
type: "array",
min: 1,
},
],
},
idCardFileList: [],
educationFileList: [],
jobTitleFileList: [],
certFileList: [],
action: `${window.location.protocol}//${window.location.host}/api/v1/evm_store/upload`,
genderOptions: [
{
label: "",
value: true,
},
{
label: "",
value: false,
},
],
};
},
computed: {},
watch: {},
created() {},
mounted() {
if (this.data) this.formData = this.data;
},
methods: {
onUploadSuccess(response) {
if (!this.formData.annex) this.formData.annex = []
this.formData.annex.push({
path: response.data.filepath,
remarks: response.data.note,
size: response.data.filesize,
title: response.data.filename,
uuid: response.data.uuid,
});
},
onBeforeRemove(file) {
const index = this.formData.annex.findIndex((item) => {
return item.uuid === file.response.data.uuid;
});
if (index >= 0) this.formData.annex.splice(index, 1);
},
beforeUpload(file) {
let isRightSize = file.size / 1024 / 1024 < 50;
if (!isRightSize) {
this.$message.error("文件大小超过 50MB");
}
return isRightSize;
// let isAccept = new RegExp("image/*").test(file.type);
// if (!isAccept) {
// this.$message.error("应该选择image/*类型的文件");
// }
// return isRightSize && isAccept;
},
},
};
</script>
<style>
</style>
<template>
<div class="app-container">
<el-form :inline="true" ref="query" :model="query" size="mini">
<el-form-item :label="queryTitle" prop="uuid">
<el-select v-model="query.uuid" filterable :placeholder="queryPlaceHolder">
<el-option v-for="(item, index) in queryList" :key="index" :label="item.name" :value="item.uuid"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onQuery">查询</el-button>
</el-form-item>
<el-form-item>
<el-button @click="onReset('query')">重置</el-button>
</el-form-item>
<el-form-item>
<el-button type="warning" @click="onAdd">添加</el-button>
</el-form-item>
</el-form>
<el-table v-loading="isLoading" element-loading-text="Loading" :data="tableData" size="mini" border stripe fit highlight-current-row>
<el-table-column v-for="(item, index) in tableHeader" :key="index" :prop="item.prop" :label="item.label" :align="item.align" :min-width="item.width" :show-overflow-tooltip="item.overflow"></el-table-column>
<el-table-column label="操作" align="center" width="180" fixed="right">
<template slot-scope="scope">
<el-button size="mini" type="success" @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
<el-button size="mini" type="danger" @click="handleDelete(scope.$index, scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<div class="page-wrapper">
<el-pagination @current-change="handleCurrentChange" :current-page.sync="query.pagenum" background small :page-size="query.pagesize" :pager-count="5" layout="pager, prev, next, total" :total="total"></el-pagination>
</div>
<formdialog ref="formdialog" :title="dialogTitle" :visible="dialogVisible" @close="dialogVisible=false" @confirm="submitForm"></formdialog>
</div>
</template>
<script>
import request from "@/utils/request";
import {
mapTrim
} from '@/utils/index'
import formdialog from './components/equipmentDialog'
export default {
name: "EquipmentQualification",
components: {
formdialog,
},
data() {
return {
queryTitle: "查询条件",
queryPlaceHolder: "输入查询字段",
total: 0,
tableData: [],
isLoading: false,
queryList: [],
query: {
uuid: null,
pagesize: 15,
pagenum: 1
},
dialogTitle: "",
dialogVisible: false,
urlPrefix: "/api/v1/evm_store/qualification/equipment",
tableHeader: [
{
label: "设备名称" ,
prop: "name",
align: "center",
width: "150"
},
{
label: "检测日期" ,
prop: "test_date",
align: "center",
width: "150"
},
{
label: "有效期" ,
prop: "validity",
align: "center",
width: "120"
},
],
}
},
methods: {
addItem(params) {
return request({
url: this.urlPrefix + `/add`,
method: "post",
data: params,
});
},
getItemList(params) {
return request({
url: this.urlPrefix + `/list`,
method: "post",
data: params,
});
},
updateItem(id, params) {
return request({
url: `${this.urlPrefix}/update/${id}`,
method: "post",
data: params,
});
},
deleteItem(id) {
return request({
url: `${this.urlPrefix}/delete/${id}`,
method: "post",
});
},
fetchQueryList() {
this.getItemList({ "scope_type": "list" }).then(res => {
this.queryList = res.data
}).catch(err => {
console.log(err.message)
})
},
fetchData(params) {
this.isLoading = true
this.getItemList(params).then(res => {
this.total = res.count
this.tableData = res.data
}).catch(err => {
// this.$message.error(err.message)
console.log(err.message)
}).finally(() => {
this.isLoading = false
})
},
handleSizeChange(e) {
this.query.pagesize = e
this.fetchData(mapTrim(this.query))
},
handleCurrentChange(e) {
this.query.pagenum = e
this.fetchData(mapTrim(this.query))
},
handleEdit(index, row) {
this.dialogTitle = "编辑"
this.dialogVisible = true
this.$refs["formdialog"].update(row);
},
handleDelete(index, row) {
this.$alert('您确定要删除么?删除操作将不可恢复。如需取消操作,请点击右上角关闭按钮。', '删除提醒', {
confirmButtonText: '确定',
callback: action => {
if (action == 'confirm') this.deleteItem(row.uuid).then(res => {
console.log(res)
this.total -= 1
this.$delete(this.tableData, index)
this.$message({ type: 'success', message: `成功删除第${ index + 1 }行` })
}).catch(err => {
this.$message.error(err.message)
})
}
})
},
submitForm(formdata) {
if (this.dialogTitle === "添加") {
this.addItem(formdata).then(res => {
console.log(res)
this.$message({ type: 'success', message: '添加成功' })
this.fetchData(mapTrim(this.query))
}).catch(err => {
this.$message.error(err.message)
})
} else if (this.dialogTitle === "编辑") {
this.updateItem(formdata.uuid, formdata).then(res => {
console.log(res)
this.$message({ type: 'success', message: '更新成功' })
this.fetchData(mapTrim(this.query))
}).catch(err => {
this.$message.error(err.message)
})
}
},
onAdd() {
this.dialogTitle = "添加"
this.dialogVisible = true
},
onQuery() {
this.query.pagenum = 1
this.query.pagesize = 15
this.fetchData(mapTrim(this.query))
},
onReset(formName) {
this.query.pagenum = 1
this.query.pagesize = 15
this.$refs[formName].resetFields()
this.fetchData(mapTrim(this.query))
}
},
mounted() {},
created() {
this.fetchData(mapTrim(this.query))
this.fetchQueryList()
}
}
</script>
<style lang="less" scoped>
.app-container {
& > div.page-wrapper {
margin: 10px 0px;
}
}
</style>
<template>
<div class="app-container">
<el-form :inline="true" ref="query" :model="query" size="mini">
<el-form-item :label="queryTitle" prop="uuid">
<el-select v-model="query.uuid" filterable :placeholder="queryPlaceHolder">
<el-option v-for="(item, index) in queryList" :key="index" :label="item.name" :value="item.uuid"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onQuery">查询</el-button>
</el-form-item>
<el-form-item>
<el-button @click="onReset('query')">重置</el-button>
</el-form-item>
<el-form-item>
<el-button type="warning" @click="onAdd">添加</el-button>
</el-form-item>
</el-form>
<el-table v-loading="isLoading" element-loading-text="Loading" :data="tableData" size="mini" border stripe fit highlight-current-row>
<el-table-column prop="name" label="姓名" align="center" min-width="120" :show-overflow-tooltip="false"></el-table-column>
<el-table-column prop="gender_text" label="性别" align="center" width="80" :show-overflow-tooltip="false"></el-table-column>
<el-table-column prop="birthday" label="出生日期" align="center" width="100" :show-overflow-tooltip="false"></el-table-column>
<el-table-column prop="phone" label="电话" align="center" min-width="100" :show-overflow-tooltip="false"></el-table-column>
<el-table-column prop="address" label="地址" align="center" min-width="150" :show-overflow-tooltip="true"></el-table-column>
<el-table-column prop="id_validity" label="身份证有效期" align="center" width="100" :show-overflow-tooltip="false"></el-table-column>
<el-table-column prop="contract_validity" label="合同有效期" align="center" width="100" :show-overflow-tooltip="false"></el-table-column>
<el-table-column prop="job_title_validity" label="职称有效期" align="center" width="100" :show-overflow-tooltip="false"></el-table-column>
<el-table-column prop="pract_cert_validity" label="证书有效期" align="center" width="100" :show-overflow-tooltip="false"></el-table-column>
<el-table-column label="操作" align="center" width="160" fixed="right">
<template slot-scope="scope">
<el-button size="mini" type="success" @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
<el-button size="mini" type="danger" @click="handleDelete(scope.$index, scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<div class="page-wrapper">
<el-pagination @current-change="handleCurrentChange" :current-page.sync="query.pagenum" background small :page-size="query.pagesize" :pager-count="5" layout="pager, prev, next, total" :total="total"></el-pagination>
</div>
<formdialog ref="formdialog" :title="dialogTitle" :visible="dialogVisible" @close="dialogVisible=false" @confirm="submitForm"></formdialog>
</div>
</template>
<script>
import request from "@/utils/request"
import { mapTrim } from '@/utils/index'
import { deleteAnnex } from '@/api/index'
import formdialog from './components/personDialog'
export default {
name: "InnerPersonQualification",
components: {
formdialog,
},
data() {
return {
queryTitle: "查询条件",
queryPlaceHolder: "输入查询字段",
total: 0,
tableData: [],
isLoading: false,
queryList: [],
query: {
uuid: null,
pagesize: 15,
pagenum: 1
},
dialogTitle: "",
dialogVisible: false,
urlPrefix: "/api/v1/evm_store/qualification/person",
}
},
filters: {
getAnnexType(annex) {
if (annex === 'idcard') return '[身份证]'
else if (annex === 'education') return '[学历]'
else if (annex === 'jobtitle') return '[职称]'
else if (annex === 'certificate') return '[证书]'
else return ''
},
getAnnexURL(path) {
return path.replace("localhost", window.location.hostname)
}
},
methods: {
addItem(params) {
return request({
url: this.urlPrefix + `/add`,
method: "post",
data: params,
});
},
fetchQueryList() {
this.getItemList({ "scope_type": "list", "type": 2 }).then(res => {
this.queryList = res.data
}).catch(err => {
console.log(err.message)
})
},
getItemList(params) {
return request({
url: this.urlPrefix + `/list`,
method: "post",
data: params,
});
},
updateItem(id, params) {
return request({
url: `${this.urlPrefix}/update/${id}`,
method: "post",
data: params,
});
},
deleteItem(id) {
return request({
url: `${this.urlPrefix}/delete/${id}`,
method: "post",
});
},
fetchData(params) {
this.isLoading = true
this.getItemList(Object.assign(params, { "type": 2 })).then(res => {
if (res.code == 200) {
this.total = res.count
this.tableData = res.data.map(item => {
item.gender_text = item.gender ? "" : ""
return item
})
}
}).catch(err => {
// this.$message.error(err.message)
console.log(err.message)
}).finally(() => {
this.isLoading = false
})
},
handleSizeChange(e) {
this.query.pagesize = e
this.fetchData(mapTrim(this.query))
},
handleCurrentChange(e) {
this.query.pagenum = e
this.fetchData(mapTrim(this.query))
},
handleEdit(index, row) {
this.dialogTitle = "编辑"
this.dialogVisible = true
this.$refs["formdialog"].update(row)
},
handleDelete(index, row) {
this.$alert('您确定要删除么?删除操作将不可恢复。如需取消操作,请点击右上角关闭按钮。', '删除提醒', {
confirmButtonText: '确定',
callback: action => {
if (action == 'confirm') this.deleteItem(row.uuid).then(res => {
console.log(res)
this.total -= 1
this.$delete(this.tableData, index)
this.$message({ type: 'success', message: `成功删除第${ index + 1 }行` })
}).catch(err => {
this.$message.error(err.message)
})
}
})
},
submitForm(formdata) {
if (this.dialogTitle === "添加") {
this.addItem(Object.assign(mapTrim(formdata), { "type": 2 })).then(res => {
console.log(res)
this.$message({ type: 'success', message: '添加成功' })
this.fetchData(mapTrim(this.query))
}).catch(err => {
this.$message.error(err.message)
})
} else if (this.dialogTitle === "编辑") {
this.updateItem(formdata.uuid, mapTrim(formdata)).then(res => {
console.log(res)
this.$message({ type: 'success', message: '更新成功' })
this.fetchData(mapTrim(this.query))
}).catch(err => {
this.$message.error(err.message)
})
}
},
onTagClose(index, row) { // 删除附件
this.$alert('您确定要删除么?删除操作将不可恢复。如需取消操作,请点击右上角关闭按钮。', '删除提醒', {
confirmButtonText: '确定',
callback: action => {
if (action == 'confirm') deleteAnnex(row.annex[index].uuid).then(res => {
console.log(res)
this.$delete(row.annex, index)
this.$message({ type: 'success', message: `成功删除第${ index }行` })
}).catch(err => {
this.$message.error(err.message)
})
}
})
},
onAdd() {
this.dialogTitle = "添加"
this.dialogVisible = true
},
onQuery() {
this.query.pagenum = 1
this.query.pagesize = 15
this.fetchData(mapTrim(this.query))
},
onReset(formName) {
this.query.pagenum = 1
this.query.pagesize = 15
this.$refs[formName].resetFields()
this.fetchData(mapTrim(this.query))
}
},
mounted() {},
created() {
this.fetchData(mapTrim(this.query))
this.fetchQueryList()
}
}
</script>
<style lang="less" scoped>
.app-container {
& > div.page-wrapper {
margin: 10px 0px;
}
}
</style>
<template>
<div class="app-container">
<el-form :inline="true" ref="query" :model="query" size="mini">
<el-form-item :label="queryTitle" prop="uuid">
<el-select v-model="query.uuid" filterable :placeholder="queryPlaceHolder">
<el-option v-for="(item, index) in queryList" :key="index" :label="item.name" :value="item.uuid"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onQuery">查询</el-button>
</el-form-item>
<el-form-item>
<el-button @click="onReset('query')">重置</el-button>
</el-form-item>
<el-form-item>
<el-button type="warning" @click="onAdd">添加</el-button>
</el-form-item>
</el-form>
<el-table v-loading="isLoading" element-loading-text="Loading" :data="tableData" size="mini" border stripe fit highlight-current-row>
<el-table-column prop="name" label="姓名" align="center" min-width="120" :show-overflow-tooltip="false"></el-table-column>
<el-table-column prop="gender_text" label="性别" align="center" width="80" :show-overflow-tooltip="false"></el-table-column>
<el-table-column prop="birthday" label="出生日期" align="center" width="100" :show-overflow-tooltip="false"></el-table-column>
<el-table-column prop="phone" label="电话" align="center" min-width="100" :show-overflow-tooltip="false"></el-table-column>
<el-table-column prop="address" label="地址" align="center" min-width="150" :show-overflow-tooltip="true"></el-table-column>
<el-table-column prop="id_validity" label="身份证有效期" align="center" width="100" :show-overflow-tooltip="false"></el-table-column>
<el-table-column prop="contract_validity" label="合同有效期" align="center" width="100" :show-overflow-tooltip="false"></el-table-column>
<el-table-column prop="job_title_validity" label="职称有效期" align="center" width="100" :show-overflow-tooltip="false"></el-table-column>
<el-table-column prop="pract_cert_validity" label="证书有效期" align="center" width="100" :show-overflow-tooltip="false"></el-table-column>
<el-table-column label="操作" align="center" width="160" fixed="right">
<template slot-scope="scope">
<el-button size="mini" type="success" @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
<el-button size="mini" type="danger" @click="handleDelete(scope.$index, scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<div class="page-wrapper">
<el-pagination @current-change="handleCurrentChange" :current-page.sync="query.pagenum" background small :page-size="query.pagesize" :pager-count="5" layout="pager, prev, next, total" :total="total"></el-pagination>
</div>
<formdialog ref="formdialog" :title="dialogTitle" :visible="dialogVisible" @close="dialogVisible=false" @confirm="submitForm"></formdialog>
</div>
</template>
<script>
import request from "@/utils/request"
import { mapTrim } from '@/utils/index'
import { deleteAnnex } from '@/api/index'
import formdialog from './components/personDialog'
export default {
name: "OuterPersonQualification",
components: {
formdialog,
},
data() {
return {
queryTitle: "查询条件",
queryPlaceHolder: "输入查询字段",
total: 0,
tableData: [],
isLoading: false,
queryList: [],
query: {
uuid: null,
pagesize: 15,
pagenum: 1
},
dialogTitle: "",
dialogVisible: false,
urlPrefix: "/api/v1/evm_store/qualification/person",
}
},
filters: {
getAnnexType(annex) {
if (annex === 'idcard') return '[身份证]'
else if (annex === 'education') return '[学历]'
else if (annex === 'jobtitle') return '[职称]'
else if (annex === 'certificate') return '[证书]'
else return ''
},
getAnnexURL(path) {
return path.replace("localhost", window.location.hostname)
}
},
methods: {
addItem(params) {
return request({
url: this.urlPrefix + `/add`,
method: "post",
data: params,
});
},
fetchQueryList() {
this.getItemList({ "scope_type": "list", "type": 1 }).then(res => {
this.queryList = res.data
}).catch(err => {
console.log(err.message)
})
},
getItemList(params) {
return request({
url: this.urlPrefix + `/list`,
method: "post",
data: params,
});
},
updateItem(id, params) {
return request({
url: `${this.urlPrefix}/update/${id}`,
method: "post",
data: params,
});
},
deleteItem(id) {
return request({
url: `${this.urlPrefix}/delete/${id}`,
method: "post",
});
},
fetchData(params) {
this.isLoading = true
this.getItemList(Object.assign(params, { "type": 1 })).then(res => {
if (res.code == 200) {
this.total = res.count
this.tableData = res.data.map(item => {
item.gender_text = item.gender ? "" : ""
return item
})
}
}).catch(err => {
// this.$message.error(err.message)
console.log(err.message)
}).finally(() => {
this.isLoading = false
})
},
handleSizeChange(e) {
this.query.pagesize = e
this.fetchData(mapTrim(this.query))
},
handleCurrentChange(e) {
this.query.pagenum = e
this.fetchData(mapTrim(this.query))
},
handleEdit(index, row) {
this.dialogTitle = "编辑"
this.dialogVisible = true
this.$refs["formdialog"].update(row)
},
handleDelete(index, row) {
this.$alert('您确定要删除么?删除操作将不可恢复。如需取消操作,请点击右上角关闭按钮。', '删除提醒', {
confirmButtonText: '确定',
callback: action => {
if (action == 'confirm') this.deleteItem(row.uuid).then(res => {
console.log(res)
this.total -= 1
this.$delete(this.tableData, index)
this.$message({ type: 'success', message: `成功删除第${ index + 1 }行` })
}).catch(err => {
this.$message.error(err.message)
})
}
})
},
submitForm(formdata) {
if (this.dialogTitle === "添加") {
this.addItem(Object.assign(mapTrim(formdata), { "type": 1 })).then(res => {
console.log(res)
this.$message({ type: 'success', message: '添加成功' })
this.fetchData(mapTrim(this.query))
}).catch(err => {
this.$message.error(err.message)
})
} else if (this.dialogTitle === "编辑") {
this.updateItem(formdata.uuid, mapTrim(formdata)).then(res => {
console.log(res)
this.$message({ type: 'success', message: '更新成功' })
this.fetchData(mapTrim(this.query))
}).catch(err => {
this.$message.error(err.message)
})
}
},
onTagClose(index, row) { // 删除附件
this.$alert('您确定要删除么?删除操作将不可恢复。如需取消操作,请点击右上角关闭按钮。', '删除提醒', {
confirmButtonText: '确定',
callback: action => {
if (action == 'confirm') deleteAnnex(row.annex[index].uuid).then(res => {
console.log(res)
this.$delete(row.annex, index)
this.$message({ type: 'success', message: `成功删除第${ index }行` })
}).catch(err => {
this.$message.error(err.message)
})
}
})
},
onAdd() {
this.dialogTitle = "添加"
this.dialogVisible = true
},
onQuery() {
this.query.pagenum = 1
this.query.pagesize = 15
this.fetchData(mapTrim(this.query))
},
onReset(formName) {
this.query.pagenum = 1
this.query.pagesize = 15
this.$refs[formName].resetFields()
this.fetchData(mapTrim(this.query))
}
},
mounted() {},
created() {
this.fetchData(mapTrim(this.query))
this.fetchQueryList()
}
}
</script>
<style lang="less" scoped>
.app-container {
& > div.page-wrapper {
margin: 10px 0px;
}
}
</style>
<template>
<div class="app-container">
<el-form :inline="true" ref="query" :model="query" size="mini">
<el-form-item :label="queryTitle" prop="uuid">
<el-select v-model="query.uuid" filterable :placeholder="queryPlaceHolder">
<el-option v-for="(item, index) in queryList" :key="index" :label="item.name" :value="item.uuid"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onQuery">查询</el-button>
</el-form-item>
<el-form-item>
<el-button @click="onReset('query')">重置</el-button>
</el-form-item>
<el-form-item>
<el-button type="warning" @click="onAdd">添加</el-button>
</el-form-item>
</el-form>
<el-table v-loading="isLoading" element-loading-text="Loading" :data="tableData" size="mini" border stripe fit highlight-current-row>
<el-table-column prop="name" label="姓名" align="center" min-width="120" :show-overflow-tooltip="false"></el-table-column>
<el-table-column prop="gender_text" label="性别" align="center" width="80" :show-overflow-tooltip="false"></el-table-column>
<el-table-column prop="birthday" label="出生日期" align="center" width="100" :show-overflow-tooltip="false"></el-table-column>
<el-table-column prop="phone" label="电话" align="center" min-width="100" :show-overflow-tooltip="false"></el-table-column>
<el-table-column prop="address" label="地址" align="center" min-width="150" :show-overflow-tooltip="true"></el-table-column>
<el-table-column prop="id_validity" label="身份证有效期" align="center" width="100" :show-overflow-tooltip="false"></el-table-column>
<el-table-column prop="contract_validity" label="合同有效期" align="center" width="100" :show-overflow-tooltip="false"></el-table-column>
<el-table-column prop="job_title_validity" label="职称有效期" align="center" width="100" :show-overflow-tooltip="false"></el-table-column>
<el-table-column prop="pract_cert_validity" label="证书有效期" align="center" width="100" :show-overflow-tooltip="false"></el-table-column>
<el-table-column label="操作" align="center" width="160" fixed="right">
<template slot-scope="scope">
<el-button size="mini" type="success" @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
<el-button size="mini" type="danger" @click="handleDelete(scope.$index, scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<div class="page-wrapper">
<el-pagination @current-change="handleCurrentChange" :current-page.sync="query.pagenum" background small :page-size="query.pagesize" :pager-count="5" layout="pager, prev, next, total" :total="total"></el-pagination>
</div>
<formdialog ref="formdialog" :title="dialogTitle" :visible="dialogVisible" @close="dialogVisible=false" @confirm="submitForm"></formdialog>
</div>
</template>
<script>
import request from "@/utils/request";
import {
mapTrim
} from '@/utils/index'
import { deleteAnnex } from '@/api/index'
import formdialog from './components/personDialog'
export default {
name: "PersonQualification",
components: {
formdialog,
},
data() {
return {
queryTitle: "查询条件",
queryPlaceHolder: "输入查询字段",
total: 0,
tableData: [],
isLoading: false,
queryList: [],
query: {
uuid: null,
pagesize: 15,
pagenum: 1
},
dialogTitle: "",
dialogVisible: false,
urlPrefix: "/api/v1/evm_store/qualification/person",
}
},
filters: {
getAnnexType(annex) {
if (annex === 'idcard') return '[身份证]'
else if (annex === 'education') return '[学历]'
else if (annex === 'jobtitle') return '[职称]'
else if (annex === 'certificate') return '[证书]'
else return ''
},
getAnnexURL(path) {
return path.replace("localhost", window.location.hostname)
}
},
methods: {
addItem(params) {
return request({
url: this.urlPrefix + `/add`,
method: "post",
data: params,
});
},
fetchQueryList() {
this.getItemList({ "scope_type": "list" }).then(res => {
this.queryList = res.data
}).catch(err => {
console.log(err.message)
})
},
getItemList(params) {
return request({
url: this.urlPrefix + `/list`,
method: "post",
data: params,
});
},
updateItem(id, params) {
return request({
url: `${this.urlPrefix}/update/${id}`,
method: "post",
data: params,
});
},
deleteItem(id) {
return request({
url: `${this.urlPrefix}/delete/${id}`,
method: "post",
});
},
fetchData(params) {
this.isLoading = true
this.getItemList(params).then(res => {
if (res.code == 200) {
this.total = res.count
this.tableData = res.data.map(item => {
item.gender_text = item.gender ? "" : ""
return item
})
}
}).catch(err => {
// this.$message.error(err.message)
console.log(err.message)
}).finally(() => {
this.isLoading = false
})
},
handleSizeChange(e) {
this.query.pagesize = e
this.fetchData(mapTrim(this.query))
},
handleCurrentChange(e) {
this.query.pagenum = e
this.fetchData(mapTrim(this.query))
},
handleEdit(index, row) {
this.dialogTitle = "编辑"
this.dialogVisible = true
this.$refs["formdialog"].update(row)
},
handleDelete(index, row) {
this.$alert('您确定要删除么?删除操作将不可恢复。如需取消操作,请点击右上角关闭按钮。', '删除提醒', {
confirmButtonText: '确定',
callback: action => {
if (action == 'confirm') this.deleteItem(row.uuid).then(res => {
console.log(res)
this.total -= 1
this.$delete(this.tableData, index)
this.$message({ type: 'success', message: `成功删除第${ index + 1 }行` })
}).catch(err => {
this.$message.error(err.message)
})
}
})
},
submitForm(formdata) {
formdata = Object.assign({}, formdata)
const fields = ['birthday', 'id_validity', 'contract_validity', 'job_title_validity', 'pract_cert_validity']
fields.forEach(prop => {
if (Object.prototype.hasOwnProperty.call(formdata, prop))
formdata[prop] = formdata[prop] + " 00:00:00"
})
if (this.dialogTitle === "添加") {
this.addItem(formdata).then(res => {
console.log(res)
this.$message({ type: 'success', message: '添加成功' })
this.fetchData(mapTrim(this.query))
}).catch(err => {
this.$message.error(err.message)
})
} else if (this.dialogTitle === "编辑") {
this.updateItem(formdata.uuid, formdata).then(res => {
console.log(res)
this.$message({ type: 'success', message: '更新成功' })
this.fetchData(mapTrim(this.query))
}).catch(err => {
this.$message.error(err.message)
})
}
},
onTagClose(index, row) { // 删除附件
this.$alert('您确定要删除么?删除操作将不可恢复。如需取消操作,请点击右上角关闭按钮。', '删除提醒', {
confirmButtonText: '确定',
callback: action => {
if (action == 'confirm') deleteAnnex(row.annex[index].uuid).then(res => {
console.log(res)
this.$delete(row.annex, index)
this.$message({ type: 'success', message: `成功删除第${ index }行` })
}).catch(err => {
this.$message.error(err.message)
})
}
})
},
onAdd() {
this.dialogTitle = "添加"
this.dialogVisible = true
},
onQuery() {
this.query.pagenum = 1
this.query.pagesize = 15
this.fetchData(mapTrim(this.query))
},
onReset(formName) {
this.query.pagenum = 1
this.query.pagesize = 15
this.$refs[formName].resetFields()
this.fetchData(mapTrim(this.query))
}
},
mounted() {},
created() {
this.fetchData(mapTrim(this.query))
this.fetchQueryList()
}
}
</script>
<style lang="less" scoped>
.app-container {
& > div.page-wrapper {
margin: 10px 0px;
}
}
</style>
{
"fields": [
{
"__config__": {
"label": "姓名",
"labelWidth": null,
"showLabel": true,
"changeTag": true,
"tag": "el-input",
"tagIcon": "input",
"required": true,
"layout": "colFormItem",
"span": 8,
"document": "https://element.eleme.cn/#/zh-CN/component/input",
"regList": [],
"formId": 101,
"renderKey": 1608904146575
},
"__slot__": {
"prepend": "",
"append": ""
},
"placeholder": "请输入姓名",
"style": {
"width": "100%"
},
"clearable": true,
"prefix-icon": "",
"suffix-icon": "",
"maxlength": null,
"show-word-limit": false,
"readonly": false,
"disabled": false,
"__vModel__": "username"
},
{
"__config__": {
"label": "性别",
"labelWidth": null,
"showLabel": true,
"changeTag": true,
"tag": "el-input",
"tagIcon": "input",
"required": true,
"layout": "colFormItem",
"span": 8,
"document": "https://element.eleme.cn/#/zh-CN/component/input",
"regList": [],
"formId": 102,
"renderKey": 1608904178596
},
"__slot__": {
"prepend": "",
"append": ""
},
"placeholder": "请输入性别",
"style": {
"width": "100%"
},
"clearable": true,
"prefix-icon": "",
"suffix-icon": "",
"maxlength": null,
"show-word-limit": false,
"readonly": false,
"disabled": false,
"__vModel__": "gender"
},
{
"__config__": {
"label": "身份证号",
"labelWidth": null,
"showLabel": true,
"changeTag": true,
"tag": "el-input",
"tagIcon": "input",
"required": true,
"layout": "colFormItem",
"span": 8,
"document": "https://element.eleme.cn/#/zh-CN/component/input",
"regList": [],
"formId": 103,
"renderKey": 1608904179827
},
"__slot__": {
"prepend": "",
"append": ""
},
"placeholder": "请输入身份证号",
"style": {
"width": "100%"
},
"clearable": true,
"prefix-icon": "",
"suffix-icon": "",
"maxlength": null,
"show-word-limit": false,
"readonly": false,
"disabled": false,
"__vModel__": "identity_number"
},
{
"__config__": {
"label": "联系方式",
"labelWidth": null,
"showLabel": true,
"changeTag": true,
"tag": "el-input",
"tagIcon": "input",
"required": true,
"layout": "colFormItem",
"span": 8,
"document": "https://element.eleme.cn/#/zh-CN/component/input",
"regList": [],
"formId": 104,
"renderKey": 1608904180659
},
"__slot__": {
"prepend": "",
"append": ""
},
"placeholder": "请输入联系方式",
"style": {
"width": "100%"
},
"clearable": true,
"prefix-icon": "",
"suffix-icon": "",
"maxlength": null,
"show-word-limit": false,
"readonly": false,
"disabled": false,
"__vModel__": "contact"
},
{
"__config__": {
"label": "邮箱",
"labelWidth": null,
"showLabel": true,
"changeTag": true,
"tag": "el-input",
"tagIcon": "input",
"required": true,
"layout": "colFormItem",
"span": 8,
"document": "https://element.eleme.cn/#/zh-CN/component/input",
"regList": [],
"formId": 105,
"renderKey": 1608904181106
},
"__slot__": {
"prepend": "",
"append": ""
},
"placeholder": "请输入邮箱",
"style": {
"width": "100%"
},
"clearable": true,
"prefix-icon": "",
"suffix-icon": "",
"maxlength": null,
"show-word-limit": false,
"readonly": false,
"disabled": false,
"__vModel__": "email"
},
{
"__config__": {
"label": "目前住址",
"labelWidth": null,
"showLabel": true,
"changeTag": true,
"tag": "el-input",
"tagIcon": "input",
"required": true,
"layout": "colFormItem",
"span": 8,
"document": "https://element.eleme.cn/#/zh-CN/component/input",
"regList": [],
"formId": 106,
"renderKey": 1608904181299
},
"__slot__": {
"prepend": "",
"append": ""
},
"placeholder": "请输入目前住址",
"style": {
"width": "100%"
},
"clearable": true,
"prefix-icon": "",
"suffix-icon": "",
"maxlength": null,
"show-word-limit": false,
"readonly": false,
"disabled": false,
"__vModel__": "address"
},
{
"__config__": {
"label": "注册安全工程师",
"showLabel": true,
"labelWidth": null,
"tag": "el-select",
"tagIcon": "select",
"layout": "colFormItem",
"span": 8,
"required": true,
"regList": [],
"changeTag": true,
"document": "https://element.eleme.cn/#/zh-CN/component/select",
"formId": 103,
"renderKey": 1611047873958
},
"__slot__": {
"options": [
{
"label": "是",
"value": 1
},
{
"label": "否",
"value": 0
}
]
},
"placeholder": "请选择是否注册安全工程师",
"style": {
"width": "100%"
},
"clearable": true,
"disabled": false,
"filterable": false,
"multiple": false,
"__vModel__": "is_reg_safe_engineer"
},
{
"__config__": {
"label": "省专家库人员",
"showLabel": true,
"labelWidth": null,
"tag": "el-select",
"tagIcon": "select",
"layout": "colFormItem",
"span": 8,
"required": true,
"regList": [],
"changeTag": true,
"document": "https://element.eleme.cn/#/zh-CN/component/select",
"formId": 104,
"renderKey": 1611047879304
},
"__slot__": {
"options": [
{
"label": "是",
"value": 1
},
{
"label": "否",
"value": 0
}
]
},
"placeholder": "请选择是否省专家库人员",
"style": {
"width": "100%"
},
"clearable": true,
"disabled": false,
"filterable": false,
"multiple": false,
"__vModel__": "is_prov_exp_db_staff"
},
{
"__config__": {
"label": "毕业院校",
"labelWidth": null,
"showLabel": true,
"changeTag": true,
"tag": "el-input",
"tagIcon": "input",
"required": false,
"layout": "colFormItem",
"span": 8,
"document": "https://element.eleme.cn/#/zh-CN/component/input",
"regList": [],
"formId": 117,
"renderKey": 1608904183242
},
"__slot__": {
"prepend": "",
"append": ""
},
"placeholder": "请输入毕业院校",
"style": {
"width": "100%"
},
"clearable": true,
"prefix-icon": "",
"suffix-icon": "",
"maxlength": null,
"show-word-limit": false,
"readonly": false,
"disabled": false,
"__vModel__": "graduated_school"
},
{
"__config__": {
"label": "专业",
"labelWidth": null,
"showLabel": true,
"changeTag": true,
"tag": "el-input",
"tagIcon": "input",
"required": false,
"layout": "colFormItem",
"span": 8,
"document": "https://element.eleme.cn/#/zh-CN/component/input",
"regList": [],
"formId": 102,
"renderKey": 1611047388886
},
"__slot__": {
"prepend": "",
"append": ""
},
"placeholder": "请输入专业",
"style": {
"width": "100%"
},
"clearable": true,
"prefix-icon": "",
"suffix-icon": "",
"maxlength": null,
"show-word-limit": false,
"readonly": false,
"disabled": false,
"__vModel__": "profession"
},
{
"__config__": {
"label": "文化程度",
"labelWidth": null,
"showLabel": true,
"changeTag": true,
"tag": "el-input",
"tagIcon": "input",
"required": false,
"layout": "colFormItem",
"span": 8,
"document": "https://element.eleme.cn/#/zh-CN/component/input",
"regList": [],
"formId": 122,
"renderKey": 1608904220243
},
"__slot__": {
"prepend": "",
"append": ""
},
"placeholder": "请输入文化程度",
"style": {
"width": "100%"
},
"clearable": true,
"prefix-icon": "",
"suffix-icon": "",
"maxlength": null,
"show-word-limit": false,
"readonly": false,
"disabled": false,
"__vModel__": "education"
},
{
"__config__": {
"label": "安全职业等级",
"labelWidth": null,
"showLabel": true,
"changeTag": true,
"tag": "el-input",
"tagIcon": "input",
"required": true,
"layout": "colFormItem",
"span": 8,
"document": "https://element.eleme.cn/#/zh-CN/component/input",
"regList": [],
"formId": 123,
"renderKey": 1608904220419
},
"__slot__": {
"prepend": "",
"append": ""
},
"placeholder": "请输入安全职业等级",
"style": {
"width": "100%"
},
"clearable": true,
"prefix-icon": "",
"suffix-icon": "",
"maxlength": null,
"show-word-limit": false,
"readonly": false,
"disabled": false,
"__vModel__": "safe_occu_level"
},
{
"__config__": {
"label": "安全职业等级专业",
"labelWidth": null,
"showLabel": true,
"changeTag": true,
"tag": "el-input",
"tagIcon": "input",
"required": true,
"layout": "colFormItem",
"span": 8,
"document": "https://element.eleme.cn/#/zh-CN/component/input",
"regList": [],
"formId": 124,
"renderKey": 1608904220763
},
"__slot__": {
"prepend": "",
"append": ""
},
"placeholder": "请输入安全职业等级专业",
"style": {
"width": "100%"
},
"clearable": true,
"prefix-icon": "",
"suffix-icon": "",
"maxlength": null,
"show-word-limit": false,
"readonly": false,
"disabled": false,
"__vModel__": "safe_occu_level_profe"
},
{
"__config__": {
"label": "技术职称",
"labelWidth": null,
"showLabel": true,
"changeTag": true,
"tag": "el-input",
"tagIcon": "input",
"required": true,
"layout": "colFormItem",
"span": 8,
"document": "https://element.eleme.cn/#/zh-CN/component/input",
"regList": [],
"formId": 125,
"renderKey": 1608904220899
},
"__slot__": {
"prepend": "",
"append": ""
},
"placeholder": "请输入技术职称",
"style": {
"width": "100%"
},
"clearable": true,
"prefix-icon": "",
"suffix-icon": "",
"maxlength": null,
"show-word-limit": false,
"readonly": false,
"disabled": false,
"__vModel__": "technical_titles"
},
{
"__config__": {
"label": "评审员等级",
"labelWidth": null,
"showLabel": true,
"changeTag": true,
"tag": "el-input",
"tagIcon": "input",
"required": false,
"layout": "colFormItem",
"span": 8,
"document": "https://element.eleme.cn/#/zh-CN/component/input",
"regList": [],
"formId": 127,
"renderKey": 1608904221243
},
"__slot__": {
"prepend": "",
"append": ""
},
"placeholder": "请输入评审员等级",
"style": {
"width": "100%"
},
"clearable": true,
"prefix-icon": "",
"suffix-icon": "",
"maxlength": null,
"show-word-limit": false,
"readonly": false,
"disabled": false,
"__vModel__": "reviewer_level"
},
{
"__config__": {
"label": "评审行业",
"labelWidth": null,
"showLabel": true,
"changeTag": true,
"tag": "el-input",
"tagIcon": "input",
"required": true,
"layout": "colFormItem",
"span": 8,
"document": "https://element.eleme.cn/#/zh-CN/component/input",
"regList": [],
"formId": 128,
"renderKey": 1608904221410
},
"__slot__": {
"prepend": "",
"append": ""
},
"placeholder": "请输入评审行业",
"style": {
"width": "100%"
},
"clearable": true,
"prefix-icon": "",
"suffix-icon": "",
"maxlength": null,
"show-word-limit": false,
"readonly": false,
"disabled": false,
"__vModel__": "review_industry"
},
{
"__config__": {
"label": "评审员证书编号",
"labelWidth": null,
"showLabel": true,
"changeTag": true,
"tag": "el-input",
"tagIcon": "input",
"required": false,
"layout": "colFormItem",
"span": 8,
"document": "https://element.eleme.cn/#/zh-CN/component/input",
"regList": [],
"formId": 129,
"renderKey": 1608904221578
},
"__slot__": {
"prepend": "",
"append": ""
},
"placeholder": "请输入评审员证书编号",
"style": {
"width": "100%"
},
"clearable": true,
"prefix-icon": "",
"suffix-icon": "",
"maxlength": null,
"show-word-limit": false,
"readonly": false,
"disabled": false,
"__vModel__": "reviewer_cert_number"
},
{
"__config__": {
"label": "行业及专业",
"labelWidth": null,
"showLabel": true,
"changeTag": true,
"tag": "el-input",
"tagIcon": "input",
"required": false,
"layout": "colFormItem",
"span": 8,
"document": "https://element.eleme.cn/#/zh-CN/component/input",
"regList": [],
"formId": 131,
"renderKey": 1608904221907
},
"__slot__": {
"prepend": "",
"append": ""
},
"placeholder": "请输入行业及专业",
"style": {
"width": "100%"
},
"clearable": true,
"prefix-icon": "",
"suffix-icon": "",
"maxlength": null,
"show-word-limit": false,
"readonly": false,
"disabled": false,
"__vModel__": "industry_profession"
},
{
"__config__": {
"label": "专家证书编号",
"labelWidth": null,
"showLabel": true,
"changeTag": true,
"tag": "el-input",
"tagIcon": "input",
"required": false,
"layout": "colFormItem",
"span": 8,
"document": "https://element.eleme.cn/#/zh-CN/component/input",
"regList": [],
"formId": 132,
"renderKey": 1608904222211,
"defaultValue": ""
},
"__slot__": {
"prepend": "",
"append": ""
},
"placeholder": "请输入专家证书编号",
"style": {
"width": "100%"
},
"clearable": true,
"prefix-icon": "",
"suffix-icon": "",
"maxlength": null,
"show-word-limit": false,
"readonly": false,
"disabled": false,
"__vModel__": "exp_cert_number"
},
{
"__config__": {
"label": "所在区域",
"labelWidth": null,
"showLabel": true,
"changeTag": true,
"tag": "el-input",
"tagIcon": "input",
"required": false,
"layout": "colFormItem",
"span": 8,
"document": "https://element.eleme.cn/#/zh-CN/component/input",
"regList": [],
"formId": 133,
"renderKey": 1608904222418
},
"__slot__": {
"prepend": "",
"append": ""
},
"placeholder": "请输入所在区域",
"style": {
"width": "100%"
},
"clearable": true,
"prefix-icon": "",
"suffix-icon": "",
"maxlength": null,
"show-word-limit": false,
"readonly": false,
"disabled": false,
"__vModel__": "area"
},
{
"__config__": {
"label": "报告撰写能力",
"labelWidth": null,
"showLabel": true,
"changeTag": true,
"tag": "el-input",
"tagIcon": "input",
"required": true,
"layout": "colFormItem",
"span": 8,
"document": "https://element.eleme.cn/#/zh-CN/component/input",
"regList": [],
"formId": 134,
"renderKey": 1608904222618
},
"__slot__": {
"prepend": "",
"append": ""
},
"placeholder": "请输入报告撰写能力",
"style": {
"width": "100%"
},
"clearable": true,
"prefix-icon": "",
"suffix-icon": "",
"maxlength": null,
"show-word-limit": false,
"readonly": false,
"disabled": false,
"__vModel__": "report_writing_ability"
},
{
"__config__": {
"label": "技术专家范围",
"labelWidth": null,
"showLabel": true,
"changeTag": true,
"tag": "el-input",
"tagIcon": "input",
"required": false,
"layout": "colFormItem",
"span": 8,
"document": "https://element.eleme.cn/#/zh-CN/component/input",
"regList": [],
"formId": 135,
"renderKey": 1608904222803
},
"__slot__": {
"prepend": "",
"append": ""
},
"placeholder": "请输入技术专家范围",
"style": {
"width": "100%"
},
"clearable": true,
"prefix-icon": "",
"suffix-icon": "",
"maxlength": null,
"show-word-limit": false,
"readonly": false,
"disabled": false,
"__vModel__": "tech_experts_range"
},
{
"__config__": {
"label": "合作方式",
"labelWidth": null,
"showLabel": true,
"changeTag": true,
"tag": "el-input",
"tagIcon": "input",
"required": false,
"layout": "colFormItem",
"span": 8,
"document": "https://element.eleme.cn/#/zh-CN/component/input",
"regList": [],
"formId": 136,
"renderKey": 1608904222971
},
"__slot__": {
"prepend": "",
"append": ""
},
"placeholder": "请输入合作方式",
"style": {
"width": "100%"
},
"clearable": true,
"prefix-icon": "",
"suffix-icon": "",
"maxlength": null,
"show-word-limit": false,
"readonly": false,
"disabled": false,
"__vModel__": "cooperation_method"
},
{
"__config__": {
"label": "收费水平",
"labelWidth": null,
"showLabel": true,
"changeTag": true,
"tag": "el-input",
"tagIcon": "input",
"required": false,
"layout": "colFormItem",
"span": 8,
"document": "https://element.eleme.cn/#/zh-CN/component/input",
"regList": [],
"formId": 137,
"renderKey": 1608904223314
},
"__slot__": {
"prepend": "",
"append": ""
},
"placeholder": "请输入收费水平",
"style": {
"width": "100%"
},
"clearable": true,
"prefix-icon": "",
"suffix-icon": "",
"maxlength": null,
"show-word-limit": false,
"readonly": false,
"disabled": false,
"__vModel__": "fee_level"
},
{
"__config__": {
"label": "人员评价",
"labelWidth": null,
"showLabel": true,
"changeTag": true,
"tag": "el-input",
"tagIcon": "input",
"required": false,
"layout": "colFormItem",
"span": 8,
"document": "https://element.eleme.cn/#/zh-CN/component/input",
"regList": [],
"formId": 138,
"renderKey": 1608905150942
},
"__slot__": {
"prepend": "",
"append": ""
},
"placeholder": "请输入人员评价",
"style": {
"width": "100%"
},
"clearable": true,
"prefix-icon": "",
"suffix-icon": "",
"maxlength": null,
"show-word-limit": false,
"readonly": false,
"disabled": false,
"__vModel__": "person_evaluation"
},
{
"__config__": {
"label": "来源",
"labelWidth": null,
"showLabel": true,
"changeTag": true,
"tag": "el-input",
"tagIcon": "input",
"required": false,
"layout": "colFormItem",
"span": 8,
"document": "https://element.eleme.cn/#/zh-CN/component/input",
"regList": [],
"formId": 139,
"renderKey": 1608905153113
},
"__slot__": {
"prepend": "",
"append": ""
},
"placeholder": "请输入来源",
"style": {
"width": "100%"
},
"clearable": true,
"prefix-icon": "",
"suffix-icon": "",
"maxlength": null,
"show-word-limit": false,
"readonly": false,
"disabled": false,
"__vModel__": "origin"
},
{
"__config__": {
"label": "培训领域",
"labelWidth": null,
"showLabel": true,
"changeTag": true,
"tag": "el-input",
"tagIcon": "input",
"required": false,
"layout": "colFormItem",
"span": 8,
"document": "https://element.eleme.cn/#/zh-CN/component/input",
"regList": [],
"formId": 140,
"renderKey": 1608905180242
},
"__slot__": {
"prepend": "",
"append": ""
},
"placeholder": "请输入培训领域",
"style": {
"width": "100%"
},
"clearable": true,
"prefix-icon": "",
"suffix-icon": "",
"maxlength": null,
"show-word-limit": false,
"readonly": false,
"disabled": false,
"__vModel__": "training_field"
},
{
"__config__": {
"label": "咨询范围",
"labelWidth": null,
"showLabel": true,
"changeTag": true,
"tag": "el-input",
"tagIcon": "input",
"required": false,
"layout": "colFormItem",
"span": 8,
"document": "https://element.eleme.cn/#/zh-CN/component/input",
"regList": [],
"formId": 141,
"renderKey": 1608905180690
},
"__slot__": {
"prepend": "",
"append": ""
},
"placeholder": "请输入咨询范围",
"style": {
"width": "100%"
},
"clearable": true,
"prefix-icon": "",
"suffix-icon": "",
"maxlength": null,
"show-word-limit": false,
"readonly": false,
"disabled": false,
"__vModel__": "consult_scope"
},
{
"__config__": {
"label": "分类",
"labelWidth": null,
"showLabel": true,
"changeTag": true,
"tag": "el-input",
"tagIcon": "input",
"required": false,
"layout": "colFormItem",
"span": 16,
"document": "https://element.eleme.cn/#/zh-CN/component/input",
"regList": [],
"formId": 142,
"renderKey": 1608905206730
},
"__slot__": {
"prepend": "",
"append": ""
},
"placeholder": "请输入分类",
"style": {
"width": "100%"
},
"clearable": true,
"prefix-icon": "",
"suffix-icon": "",
"maxlength": null,
"show-word-limit": false,
"readonly": false,
"disabled": false,
"__vModel__": "category"
}
],
"formRef": "elForm",
"formModel": "formData",
"size": "medium",
"labelPosition": "right",
"labelWidth": 140,
"formRules": "rules",
"gutter": 15,
"disabled": false,
"span": 8,
"formBtns": true
}
\ No newline at end of file
<template>
<div>
<el-dialog :visible.sync="isVisible" v-bind="$attrs" v-on="$listeners" @open="onOpen" @close="onClose" :title="title" :width="width">
<formpage ref="formpage"></formpage>
<div slot="footer">
<el-button @click="close">取消</el-button>
<el-button type="primary" @click="handelConfirm">确定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import formpage from './form'
export default {
inheritAttrs: false,
components: {formpage},
props: {
visible: {
type: Boolean,
default() {
return false
}
},
title: {
type: String,
default () {
return "dialog"
}
},
width: {
type: String,
required: false,
default() {
return "50%"
}
}
},
data() {
return {}
},
computed: {
isVisible: {
get: function () {
return this.visible;
},
set: function (newValue) {
return newValue;
}
}
},
watch: {},
created() {},
mounted() {},
methods: {
update(data) {
this.$nextTick(() => {
this.$refs['formpage'].formData = data;
})
},
onOpen() {},
onClose() {
this.close()
},
close() {
this.$emit('close', this.formData)
},
handelConfirm() {
const elform = this.$refs['formpage'].$refs['elForm']
elform.validate(valid => {
if (!valid) return
this.$emit('confirm', elform.model)
this.close()
})
},
}
}
</script>
<style>
</style>
<template>
<el-form
ref="elForm"
:model="formData"
:rules="rules"
size="medium"
label-width="140px"
>
<el-col :span="8">
<el-form-item label="姓名" prop="username">
<el-input
v-model="formData.username"
placeholder="请输入姓名"
:disabled="isReadOnly"
:readonly="isReadOnly"
clearable
:style="{ width: '100%' }"
>
</el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="性别" prop="gender">
<el-select
:disabled="isReadOnly"
:style="{ width: '100%' }"
v-model="formData.gender"
placeholder="请选择性别"
>
<el-option
v-for="(item, index) in [{ label: '男' }, { label: '女' }]"
:key="index"
:label="item.label"
:value="item.label"
>
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="身份证号" prop="identity_number">
<el-input
v-model="formData.identity_number"
placeholder="请输入身份证号"
:disabled="isReadOnly"
:readonly="isReadOnly"
clearable
:style="{ width: '100%' }"
></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="联系方式" prop="contact">
<el-input
v-model="formData.contact"
placeholder="请输入联系方式"
:disabled="isReadOnly"
:readonly="isReadOnly"
clearable
:style="{ width: '100%' }"
>
</el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="邮箱" prop="email">
<el-input
v-model="formData.email"
placeholder="请输入邮箱"
:disabled="isReadOnly"
:readonly="isReadOnly"
clearable
:style="{ width: '100%' }"
>
</el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="目前住址" prop="address">
<el-input
v-model="formData.address"
placeholder="请输入目前住址"
:disabled="isReadOnly"
:readonly="isReadOnly"
clearable
:style="{ width: '100%' }"
>
</el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="注册安全工程师" prop="is_reg_safe_engineer">
<el-select
v-model="formData.is_reg_safe_engineer"
placeholder="请选择是否注册安全工程师"
clearable
:disabled="isReadOnly"
:readonly="isReadOnly"
:style="{ width: '100%' }"
>
<el-option
v-for="(item, index) in trueAndFalseSelect"
:key="index"
:label="item.label"
:value="item.value"
:disabled="item.disabled"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="为省专家库人员" prop="is_prov_exp_db_staff">
<el-select
v-model="formData.is_prov_exp_db_staff"
placeholder="请选择是否为省专家库人员"
clearable
:disabled="isReadOnly"
:readonly="isReadOnly"
:style="{ width: '100%' }"
>
<el-option
v-for="(item, index) in trueAndFalseSelect"
:key="index"
:label="item.label"
:value="item.value"
:disabled="item.disabled"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="技术职称" prop="technical_titles">
<el-input
v-model="formData.technical_titles"
placeholder="请输入技术职称"
:disabled="isReadOnly"
:readonly="isReadOnly"
clearable
:style="{ width: '100%' }"
></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="行业及专业" prop="industry_profession">
<el-input
v-model="formData.industry_profession"
placeholder="请输入行业及专业"
:disabled="isReadOnly"
:readonly="isReadOnly"
clearable
:style="{ width: '100%' }"
></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="毕业院校" prop="graduated_school">
<el-input
v-model="formData.graduated_school"
placeholder="请输入毕业院校"
:disabled="isReadOnly"
:readonly="isReadOnly"
clearable
:style="{ width: '100%' }"
></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="专业" prop="profession">
<el-input
v-model="formData.profession"
placeholder="请输入专业"
clearable
:disabled="isReadOnly"
:readonly="isReadOnly"
:style="{ width: '100%' }"
>
</el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="文化程度" prop="education">
<el-input
v-model="formData.education"
placeholder="请输入文化程度"
:disabled="isReadOnly"
:readonly="isReadOnly"
clearable
:style="{ width: '100%' }"
>
</el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="安全评价师等级" prop="safe_occu_level">
<el-input
v-model="formData.safe_occu_level"
placeholder="请输入安全评价师等级"
:disabled="isReadOnly"
:readonly="isReadOnly"
clearable
:style="{ width: '100%' }"
></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="安全评价师专业" prop="safe_occu_level_profe">
<el-input
v-model="formData.safe_occu_level_profe"
placeholder="请输入安全评价师专业"
:disabled="isReadOnly"
:readonly="isReadOnly"
clearable
:style="{ width: '100%' }"
></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="评审员等级" prop="reviewer_level">
<el-input
v-model="formData.reviewer_level"
placeholder="请输入评审员等级"
:disabled="isReadOnly"
:readonly="isReadOnly"
clearable
:style="{ width: '100%' }"
></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="评审行业" prop="review_industry">
<el-input
v-model="formData.review_industry"
placeholder="请输入评审行业"
:disabled="isReadOnly"
:readonly="isReadOnly"
clearable
:style="{ width: '100%' }"
></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="评审员证书编号" prop="reviewer_cert_number">
<el-input
v-model="formData.reviewer_cert_number"
placeholder="请输入评审员证书编号"
:disabled="isReadOnly"
:readonly="isReadOnly"
clearable
:style="{ width: '100%' }"
></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="专家证书编号" prop="exp_cert_number">
<el-input
v-model="formData.exp_cert_number"
placeholder="请输入专家证书编号"
:disabled="isReadOnly"
:readonly="isReadOnly"
clearable
:style="{ width: '100%' }"
></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="所在区域" prop="address">
<el-input
v-model="formData.address"
placeholder="请输入所在区域"
:disabled="isReadOnly"
:readonly="isReadOnly"
clearable
:style="{ width: '100%' }"
>
</el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="报告撰写能力" prop="report_writing_ability">
<el-input
v-model="formData.report_writing_ability"
placeholder="请输入报告撰写能力"
:disabled="isReadOnly"
:readonly="isReadOnly"
clearable
:style="{ width: '100%' }"
></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="技术专家范围" prop="tech_experts_range">
<el-input
v-model="formData.tech_experts_range"
placeholder="请输入技术专家范围"
:disabled="isReadOnly"
:readonly="isReadOnly"
clearable
:style="{ width: '100%' }"
></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="合作方式" prop="cooperation_method">
<el-input
v-model="formData.cooperation_method"
placeholder="请输入合作方式"
:disabled="isReadOnly"
:readonly="isReadOnly"
clearable
:style="{ width: '100%' }"
></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="收费水平" prop="fee_level">
<el-input
v-model="formData.fee_level"
placeholder="请输入收费水平"
:disabled="isReadOnly"
:readonly="isReadOnly"
clearable
:style="{ width: '100%' }"
>
</el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="人员评价" prop="person_evaluation">
<el-input
v-model="formData.person_evaluation"
placeholder="请输入人员评价"
:disabled="isReadOnly"
:readonly="isReadOnly"
clearable
:style="{ width: '100%' }"
></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="来源" prop="origin">
<el-input
v-model="formData.origin"
placeholder="请输入来源"
:disabled="isReadOnly"
:readonly="isReadOnly"
clearable
:style="{ width: '100%' }"
>
</el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="培训领域" prop="training_field">
<el-input
v-model="formData.training_field"
placeholder="请输入培训领域"
:disabled="isReadOnly"
:readonly="isReadOnly"
clearable
:style="{ width: '100%' }"
></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="咨询范围" prop="consult_scope">
<el-input
v-model="formData.consult_scope"
placeholder="请输入咨询范围"
:disabled="isReadOnly"
:readonly="isReadOnly"
clearable
:style="{ width: '100%' }"
></el-input>
</el-form-item>
</el-col>
<el-col :span="16">
<el-form-item label="分类" prop="category">
<el-input
v-model="formData.category"
placeholder="请输入分类"
:disabled="isReadOnly"
:readonly="isReadOnly"
clearable
:style="{ width: '100%' }"
></el-input>
</el-form-item>
</el-col>
</el-form>
</template>
<script>
export default {
inheritAttrs: false,
components: {},
props: {
data: {
type: Object,
},
isReadOnly: {
type: Boolean,
default: false,
},
},
data() {
return {
formData: {
username: undefined,
gender: undefined,
identity_number: undefined,
contact: undefined,
email: undefined,
address: undefined,
graduated_school: undefined,
profession: null,
education: undefined,
safe_occu_level: undefined,
safe_occu_level_profe: undefined,
technical_titles: undefined,
is_reg_safe_engineer: undefined,
reviewer_level: undefined,
review_industry: undefined,
reviewer_cert_number: undefined,
is_prov_exp_db_staff: undefined,
industry_profession: undefined,
exp_cert_number: "",
area: undefined,
report_writing_ability: undefined,
tech_experts_range: undefined,
cooperation_method: undefined,
fee_level: undefined,
person_evaluation: undefined,
origin: undefined,
training_field: undefined,
consult_scope: undefined,
category: undefined,
},
rules: {
username: [
{
required: true,
message: "请输入姓名",
trigger: "blur",
},
],
gender: [],
identity_number: [],
contact: [],
email: [
{ required: false, message: '请输入邮箱地址', trigger: 'blur' },
{ type: 'email', message: '请输入正确的邮箱地址', trigger: ['blur', 'change'] }
],
address: [],
graduated_school: [],
education: [],
safe_occu_level: [],
safe_occu_level_profe: [],
technical_titles: [],
is_reg_safe_engineer: [],
reviewer_level: [],
review_industry: [],
reviewer_cert_number: [],
is_prov_exp_db_staff: [],
industry_profession: [],
exp_cert_number: [],
area: [],
report_writing_ability: [],
tech_experts_range: [],
cooperation_method: [],
fee_level: [],
person_evaluation: [],
origin: [],
training_field: [],
consult_scope: [],
category: [],
},
trueAndFalseSelect: [
{
label: "",
value: "",
},
{
label: "",
value: "",
},
],
};
},
computed: {},
watch: {},
created() {},
mounted() {
if (this.data) this.formData = this.data;
},
methods: {},
};
</script>
<style>
</style>
<template>
<div class="app-container">
<el-form :inline="true" ref="query" :model="query" size="mini">
<el-form-item label="姓名" prop="uuid">
<el-select v-model="query.uuid" filterable placeholder="请输入姓名">
<el-option v-for="(item, index) in queryList" :key="index" :label="item.username" :value="item.uuid"></el-option>
</el-select>
</el-form-item>
<el-form-item label="专业" prop="profession">
<el-input v-model="query.profession" placeholder="请输入专业"></el-input>
</el-form-item>
<el-form-item label="技术职称" prop="technical_titles">
<el-input v-model="query.technical_titles" placeholder="请输入技术职称"></el-input>
</el-form-item>
<el-form-item label="安全评价师等级" prop="safe_occu_level">
<el-input v-model="query.safe_occu_level" placeholder="请输入安全评价师等级"></el-input>
</el-form-item>
<el-form-item label="安全评价师专业" prop="safe_occu_level_profe">
<el-input v-model="query.safe_occu_level_profe" placeholder="请输入安全评价师专业"></el-input>
</el-form-item>
<el-form-item label="注册安全工程师" prop="is_reg_safe_engineer">
<el-select v-model="query.is_reg_safe_engineer" placeholder="是否是注册安全工程师">
<el-option v-for="(item, index) in options" :key="index" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="省专家库成员" prop="is_prov_exp_db_staff">
<el-select v-model="query.is_prov_exp_db_staff" placeholder="是否是省专家库成员">
<el-option v-for="(item, index) in options" :key="index" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="评审行业" prop="review_industry">
<el-input v-model="query.review_industry" placeholder="请输入评审行业"></el-input>
</el-form-item>
<el-form-item label="报告撰写能力" prop="report_writing_ability">
<el-input v-model="query.report_writing_ability" placeholder="请输入报告撰写能力"></el-input>
</el-form-item>
<el-form-item label="培训领域" prop="training_field">
<el-input v-model="query.training_field" placeholder="请输入培训领域"></el-input>
</el-form-item>
<el-form-item label="咨询范围" prop="consult_scope">
<el-input v-model="query.consult_scope" placeholder="请输入咨询范围"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onQuery">查询</el-button>
</el-form-item>
<el-form-item>
<el-button @click="onReset('query')">重置</el-button>
</el-form-item>
<el-form-item>
<el-button type="warning" @click="onAdd">添加</el-button>
</el-form-item>
<el-form-item>
<el-popover placement="top-start" width="180" trigger="click">
<el-checkbox-group :min="1" v-model="checkList" @change="onCheckboxChange">
<el-checkbox :label="item" v-for="(item, index) in headerList" :key="index"></el-checkbox>
</el-checkbox-group>
<el-button type="success" slot="reference">表头设置</el-button>
</el-popover>
</el-form-item>
<el-form-item>
<el-button type="info" plain @click="handleDownload">导出当前数据</el-button>
</el-form-item>
</el-form>
<el-table
v-loading="isLoading"
element-loading-text="Loading"
:data="tableData"
size="mini"
border
stripe
fit
highlight-current-row
>
<el-table-column type="expand">
<template slot-scope="props">
<formpage :data="props.row" :isReadOnly="true"></formpage>
</template>
</el-table-column>
<el-table-column
v-for="(item, index) in tableHeader"
:key="index"
:prop="item.prop"
:label="item.label"
:align="item.align"
:min-width="item.width"
:show-overflow-tooltip="true"
></el-table-column>
<el-table-column label="操作" align="center" width="160" fixed="right">
<template slot-scope="scope">
<el-button
size="mini"
type="success"
@click="handleEdit(scope.$index, scope.row)"
>编辑</el-button
>
<el-button
size="mini"
type="danger"
@click="handleDelete(scope.$index, scope.row)"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
<div class="page-wrapper">
<el-pagination
@current-change="handleCurrentChange"
:current-page.sync="query.pagenum"
background
small
:page-size="query.pagesize"
:pager-count="5"
layout="pager, prev, next, total"
:total="total"
></el-pagination>
</div>
<formdialog
ref="formdialog"
:title="dialogTitle"
:visible="dialogVisible"
:width="'70%'"
@close="dialogVisible = false"
@confirm="submitForm"
></formdialog>
</div>
</template>
<script>
import request from "@/utils/request";
import { mapTrim } from "@/utils/index";
// import { formatUTCDateTime } from "@/utils/utils";
import { exportJsonToExcel } from "@/utils/excel";
import formdialog from "./dialog";
import formpage from "./form";
const fieldList = [
{ label: "姓名", prop: "username", isShow: true, align: "center", width: "150" },
{ label: "性别", prop: "gender", isShow: true, align: "center", width: "60" },
{ label: "身份证号", prop: "identity_number", isShow: true, align: "center", width: "150" },
{ label: "联系方式", prop: "contact", isShow: true, align: "center", width: "100" },
{ label: "邮箱", prop: "email", isShow: true, align: "center", width: "150" },
{ label: "目前住址", prop: "address", isShow: true, align: "center", width: "150" },
{ label: "毕业院校", prop: "graduated_school", isShow: true, align: "center", width: "150" },
{ label: "行业及专业", prop: "industry_profession", isShow: true, align: "center", width: "150" },
{ label: "文化程度", prop: "education", isShow: true, align: "center", width: "80" },
{ label: "安全评价师等级", prop: "safe_occu_level", isShow: false, align: "center", width: "150" },
{ label: "安全评价师专业", prop: "safe_occu_level_profe", isShow: false, align: "center", width: "150" },
{ label: "技术职称", prop: "technical_titles", isShow: false, align: "center", width: "150" },
{ label: "注册安全工程师", prop: "is_reg_safe_engineer", isShow: false, align: "center", width: "150" },
{ label: "评审员等级", prop: "reviewer_level", isShow: false, align: "center", width: "150" },
{ label: "评审行业", prop: "review_industry", isShow: false, align: "center", width: "150" },
{ label: "评审员证书编号", prop: "reviewer_cert_number", isShow: false, align: "center", width: "150" },
{ label: "省专家库人员", prop: "is_prov_exp_db_staff", isShow: false, align: "center", width: "150" },
{ label: "行业及专业", prop: "industry_profession", isShow: false, align: "center", width: "150" },
{ label: "专家证书编号", prop: "exp_cert_number", isShow: false, align: "center", width: "150" },
{ label: "所在区域", prop: "area", isShow: false, align: "center", width: "150" },
{ label: "报告撰写能力", prop: "report_writing_ability", isShow: false, align: "center", width: "150" },
{ label: "技术专家范围", prop: "tech_experts_range", isShow: false, align: "center", width: "150" },
{ label: "合作方式", prop: "cooperation_method", isShow: false, align: "center", width: "150" },
{ label: "收费水平", prop: "fee_level", isShow: false, align: "center", width: "150" },
{ label: "人员评价", prop: "person_evaluation", isShow: false, align: "center", width: "150" },
{ label: "来源", prop: "origin", isShow: false, align: "center", width: "150" },
{ label: "培训领域", prop: "training_field", isShow: false, align: "center", width: "150" },
{ label: "咨询范围", prop: "consult_scope", isShow: false, align: "center", width: "150" },
{ label: "分类", prop: "category", isShow: false, align: "center", width: "150" }
]
const tableHeader = fieldList.filter(item => {
if (item.isShow) return item
})
export default {
name: "Resources",
components: {
formdialog,
formpage,
},
data() {
return {
total: 0,
tableData: [],
isLoading: false,
checkList: tableHeader.map(item => item.label),
headerList: fieldList.map(item => item.label),
query: {
uuid: null,
technical_titles: null,
profession: null,
safe_occu_level: null,
safe_occu_level_profe: null,
is_reg_safe_engineer: null,
is_prov_exp_db_staff: null,
review_industry: null,
report_writing_ability: null,
training_field: null,
consult_scope: null,
pagesize: 15,
pagenum: 1,
},
dialogTitle: "",
dialogVisible: false,
queryList: [],
urlPrefix: "/api/v1/evm_store/techResources",
tableHeader: tableHeader,
options: [
{
label: "",
value: "",
},
{
label: "",
value: "",
},
]
};
},
methods: {
addItem(params) {
return request({
url: this.urlPrefix + `/add`,
method: "post",
data: params,
});
},
getItemList(params) {
return request({
url: this.urlPrefix + `/list`,
method: "post",
data: params,
});
},
updateItem(id, params) {
return request({
url: `${this.urlPrefix}/update/${id}`,
method: "post",
data: params,
});
},
deleteItem(id) {
return request({
url: `${this.urlPrefix}/delete/${id}`,
method: "post",
});
},
fetchDataList() {
this.getItemList({ "scope_type": "list" })
.then((res) => {
this.queryList = res.data
})
.catch((err) => {
console.log(err.message)
})
},
fetchData(params) {
this.isLoading = true;
this.getItemList(
Object.assign(
{
pagenum: this.query.pagenum,
pagesize: this.query.pagesize,
},
params
)
)
.then((res) => {
this.total = res.count;
this.tableData = res.data;
})
.catch((err) => {
if (err.code == 204) {
this.$message.success(err.message);
} else {
// this.$message.error(err.message)
console.log(err.message);
}
})
.finally(() => {
this.isLoading = false;
});
},
handleSizeChange(e) {
this.query.pagesize = e;
this.fetchData(mapTrim(this.query));
},
handleCurrentChange(e) {
this.query.pagenum = e;
this.fetchData(mapTrim(this.query));
},
handleEdit(index, row) {
this.dialogTitle = "编辑";
this.dialogVisible = true;
this.$refs["formdialog"].update(row);
},
handleDelete(index, row) {
this.$alert(
"您确定要删除么?删除操作将不可恢复。如需取消操作,请点击右上角关闭按钮。",
"删除提醒",
{
confirmButtonText: "确定",
callback: (action) => {
if (action == "confirm")
this.deleteItem(row.uuid)
.then((res) => {
console.log(res);
this.total -= 1;
this.$delete(this.tableData, index);
this.$message({
type: "success",
message: `成功删除第${index + 1}行`,
});
})
.catch((err) => {
this.$message.error(err.message);
});
},
}
);
},
handleDownload() {
const loading = this.$loading({
lock: true,
text: 'Loading',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
})
this.getItemList({ "scope_type": "list", "props": this.tableHeader.map(item => item.prop) })
.then((res) => {
exportJsonToExcel({
header: this.tableHeader,
headerLabel: "label",
headerProp: "prop",
jsonData: res.data,
filename: Date.now()
})
})
.catch((err) => {
this.$message.warning(err.message)
}).finally(() => {
loading.close()
})
},
submitForm(formdata) {
if (this.dialogTitle === "添加") {
formdata.area = formdata.address;
this.addItem(mapTrim(formdata))
.then((res) => {
console.log(res);
this.$message({ type: "success", message: "添加成功" });
this.fetchData();
})
.catch((err) => {
this.$message.error(err.message);
});
} else if (this.dialogTitle === "编辑") {
this.updateItem(formdata.uuid, mapTrim(formdata))
.then((res) => {
console.log(res);
this.$message({ type: "success", message: "更新成功" });
this.fetchData();
})
.catch((err) => {
this.$message.error(err.message);
});
}
},
onCheckboxChange(evt) {
let header = []
evt.forEach(f => {
for(let i = 0 ; i < fieldList.length; i++) {
if (fieldList[i].label === f) {
header.push(fieldList[i])
break
}
}
})
this.tableHeader = header
},
onAdd() {
this.dialogTitle = "添加";
this.dialogVisible = true;
},
onQuery() {
this.query.pagenum = 1;
this.query.pagesize = 15;
this.fetchData(mapTrim(this.query));
},
onReset(formName) {
this.$refs[formName].resetFields();
this.query.pagenum = 1;
this.query.pagesize = 15;
this.fetchData();
},
},
mounted() {},
created() {
this.fetchData();
this.fetchDataList();
},
};
</script>
<style lang="less" scoped>
.app-container {
& > div.page-wrapper {
margin: 10px 0px;
}
}
</style>
......@@ -25,7 +25,7 @@
<el-table-column prop="account" label="账号" align="center" width="120"></el-table-column>
<el-table-column prop="role.name" label="角色" width="120" :show-overflow-tooltip="true"></el-table-column>
<el-table-column prop="depot.name" label="部门" width="120" :show-overflow-tooltip="true"></el-table-column>
<el-table-column prop="contact" label="联系方式" width="150"></el-table-column>
<el-table-column prop="phone" label="联系方式" width="150"></el-table-column>
<el-table-column prop="birthday" label="出生年月" width="150"></el-table-column>
<el-table-column prop="email" label="邮箱" width="180" :show-overflow-tooltip="true"></el-table-column>
<el-table-column prop="hometown" label="籍贯" min-width="100"></el-table-column>
......@@ -76,8 +76,8 @@
<el-form-item label="籍贯" prop="hometown">
<el-input type="text" v-model="post.hometown" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="联系方式" prop="contact">
<el-input type="text" v-model="post.contact" autocomplete="off"></el-input>
<el-form-item label="联系方式" prop="phone">
<el-input type="text" v-model="post.phone" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="邮箱" prop="email">
<el-input type="email" v-model="post.email" autocomplete="off"></el-input>
......@@ -137,7 +137,7 @@ export default {
post: {
account: null,
username: null,
contact: null,
phone: null,
birthday: null,
gender: 1,
email: null,
......@@ -155,7 +155,7 @@ export default {
{ min: 1, max: 20, message: '字符串长度在 1 到 20 之间', trigger: 'blur' }
],
password: [{ type: 'string', required: true, message: '密码不能为空', trigger: 'blur' }, { min: 6, max: 18, message: '长度在 6 到 18 个字符', trigger: 'blur' }],
contact: [{ type: 'string', required: true, message: '手机号不能为空', trigger: 'blur' }, { len: 11, message: '手机号长度为11', trigger: 'blur' }],
phone: [{ type: 'string', required: true, message: '手机号不能为空', trigger: 'blur' }, { len: 11, message: '手机号长度为11', trigger: 'blur' }],
birthday: [{ required: false, message: '出生年月不能为空', trigger: 'blur' }],
gender: [{ type: 'number', required: true, message: '性别不能为空', trigger: 'blur' }],
email: [{ type: 'email', required: true, message: '邮箱不能为空', trigger: 'blur' }],
......@@ -208,7 +208,7 @@ export default {
handleEdit(index, row) {
this.post.account = row.account
this.post.username = row.username
this.post.contact = row.contact
this.post.phone = row.phone
this.post.birthday = row.birthday
this.post.email = row.email
this.post.hometown = row.hometown
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment