Merge branch 'dev2' of https://dev.azure.com/alicorn-dev/KintoneAppBuilder/_git/KintoneAppBuilder into dev2
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -5,3 +5,4 @@ backend/pyvenv.cfg
|
|||||||
backend/Include/
|
backend/Include/
|
||||||
backend/Scripts/
|
backend/Scripts/
|
||||||
|
|
||||||
|
log/api.log
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ from io import BytesIO
|
|||||||
import typing as t
|
import typing as t
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
import json
|
import json
|
||||||
|
import base64
|
||||||
import httpx
|
import httpx
|
||||||
import deepdiff
|
import deepdiff
|
||||||
import app.core.config as config
|
import app.core.config as config
|
||||||
@@ -493,6 +494,17 @@ async def test(file:UploadFile= File(...),app:str=None):
|
|||||||
return test
|
return test
|
||||||
|
|
||||||
|
|
||||||
|
@r.get("/group")
|
||||||
|
async def group(request:Request,kintoneurl:str,kintoneuser:str,kintonepwd:str):
|
||||||
|
try:
|
||||||
|
auth_value = base64.b64encode(bytes(f"{kintoneuser}:{kintonepwd}","utf-8"))
|
||||||
|
headers={config.API_V1_AUTH_KEY:auth_value}
|
||||||
|
url = f"{kintoneurl}/v1/user/groups.json?code={kintoneuser}"
|
||||||
|
r = httpx.get(url,headers=headers)
|
||||||
|
return r.json()
|
||||||
|
except Exception as e:
|
||||||
|
raise APIException('kintone:group',request.url._url, f"Error occurred while get group(url:{kintoneurl} user:{kintoneuser}):",e)
|
||||||
|
|
||||||
@r.post("/download",)
|
@r.post("/download",)
|
||||||
async def download(request:Request,key,c:config.KINTONE_ENV=Depends(getkintoneenv)):
|
async def download(request:Request,key,c:config.KINTONE_ENV=Depends(getkintoneenv)):
|
||||||
try:
|
try:
|
||||||
@@ -502,7 +514,7 @@ async def download(request:Request,key,c:config.KINTONE_ENV=Depends(getkintoneen
|
|||||||
r = httpx.get(url,headers=headers,params=params)
|
r = httpx.get(url,headers=headers,params=params)
|
||||||
return r.json()
|
return r.json()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise APIException('kintone:upload',request.url._url,f"Error occurred while download file.json:",e)
|
raise APIException('kintone:download',request.url._url,f"Error occurred while download file.json:",e)
|
||||||
|
|
||||||
@r.post("/upload")
|
@r.post("/upload")
|
||||||
async def upload(request:Request,files:t.List[UploadFile] = File(...)):
|
async def upload(request:Request,files:t.List[UploadFile] = File(...)):
|
||||||
@@ -625,7 +637,17 @@ async def createapp(request:Request,name:str,env:config.KINTONE_ENV=Depends(getk
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise APIException('kintone:createapp',request.url._url, f"Error occurred while create app({env.DOMAIN_NAME}->{name}):",e)
|
raise APIException('kintone:createapp',request.url._url, f"Error occurred while create app({env.DOMAIN_NAME}->{name}):",e)
|
||||||
|
|
||||||
|
@r.get("/defaultgroup")
|
||||||
|
async def currentgroup(request:Request,env:config.KINTONE_ENV=Depends(getkintoneenv)):
|
||||||
|
try:
|
||||||
|
auth_value = env.API_V1_AUTH_VALUE
|
||||||
|
headers={config.API_V1_AUTH_KEY:auth_value}
|
||||||
|
url = f"{env.BASE_URL}/v1/user/groups.json?code={env.KINTONE_USER}"
|
||||||
|
r = httpx.get(url,headers=headers)
|
||||||
|
return r.json()
|
||||||
|
except Exception as e:
|
||||||
|
raise APIException('kintone:currentgroup',request.url._url, f"Error occurred while get default domain group(domain:{env.DOMAIN_NAME} url:{env.BASE_URL} user:{env.KINTONE_USER}):",e)
|
||||||
|
|
||||||
@r.post("/createappfromexcel",)
|
@r.post("/createappfromexcel",)
|
||||||
async def createappfromexcel(request:Request,files:t.List[UploadFile] = File(...),format:int = 0,env = Depends(getkintoneenv),db = Depends(get_db)):
|
async def createappfromexcel(request:Request,files:t.List[UploadFile] = File(...),format:int = 0,env = Depends(getkintoneenv),db = Depends(get_db)):
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -13,10 +13,14 @@ import json
|
|||||||
class LoggingMiddleware(BaseHTTPMiddleware):
|
class LoggingMiddleware(BaseHTTPMiddleware):
|
||||||
async def dispatch(self, request: Request, call_next):
|
async def dispatch(self, request: Request, call_next):
|
||||||
if request.method in ("POST", "PUT", "PATCH","DELETE"):
|
if request.method in ("POST", "PUT", "PATCH","DELETE"):
|
||||||
try:
|
content_type = request.headers.get('content-type', '')
|
||||||
request.state.body = await request.json()
|
if content_type.startswith('multipart/form-data'):
|
||||||
except json.JSONDecodeError:
|
request.state.body = None
|
||||||
request.state.body = await request.body()
|
else:
|
||||||
|
try:
|
||||||
|
request.state.body = await request.json()
|
||||||
|
except json.JSONDecodeError:
|
||||||
|
request.state.body = await request.body()
|
||||||
else:
|
else:
|
||||||
request.state.body = None
|
request.state.body = None
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from fastapi import HTTPException, status
|
from fastapi import HTTPException, status
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
|
from sqlalchemy.orm.attributes import flag_modified
|
||||||
from sqlalchemy import select,and_
|
from sqlalchemy import select,and_
|
||||||
import typing as t
|
import typing as t
|
||||||
|
|
||||||
@@ -202,6 +203,8 @@ class dbapp(crudbase):
|
|||||||
db_app = self.get_app(db, domainurl, flow.appid)
|
db_app = self.get_app(db, domainurl, flow.appid)
|
||||||
if db_app and db_app.version > 0:
|
if db_app and db_app.version > 0:
|
||||||
db_app.is_saved = True
|
db_app.is_saved = True
|
||||||
|
flag_modified(db_app, 'is_saved')
|
||||||
|
db_app.updateuserid = userid
|
||||||
db.add(db_app)
|
db.add(db_app)
|
||||||
db.commit()
|
db.commit()
|
||||||
db.refresh(db_flow)
|
db.refresh(db_flow)
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ from app.core.security import chacha20Decrypt
|
|||||||
class Base:
|
class Base:
|
||||||
id = Column(Integer, primary_key=True, index=True)
|
id = Column(Integer, primary_key=True, index=True)
|
||||||
create_time = Column(DateTime, default=datetime.now(timezone.utc))
|
create_time = Column(DateTime, default=datetime.now(timezone.utc))
|
||||||
update_time = Column(DateTime, default=datetime.now(timezone.utc), onupdate=datetime.now(timezone.utc))
|
update_time = Column(DateTime, default=datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc))
|
||||||
|
|
||||||
|
|
||||||
userrole = Table(
|
userrole = Table(
|
||||||
@@ -234,7 +234,7 @@ class OperationLog(Base):
|
|||||||
userid = mapped_column(Integer,ForeignKey("user.id"))
|
userid = mapped_column(Integer,ForeignKey("user.id"))
|
||||||
operation = mapped_column(String(200))
|
operation = mapped_column(String(200))
|
||||||
function = mapped_column(String(200))
|
function = mapped_column(String(200))
|
||||||
parameters = mapped_column(String(200))
|
parameters = mapped_column(String)
|
||||||
response = mapped_column(String(200))
|
response = mapped_column(String(200))
|
||||||
user = relationship('User')
|
user = relationship('User')
|
||||||
|
|
||||||
|
|||||||
@@ -1,211 +0,0 @@
|
|||||||
<mxfile host="app.diagrams.net" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36" version="24.9.2">
|
|
||||||
<diagram name="ページ1" id="oKiyF3b1qzm0IX1SNAWJ">
|
|
||||||
<mxGraphModel dx="1395" dy="1078" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="0" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
|
|
||||||
<root>
|
|
||||||
<mxCell id="0" />
|
|
||||||
<mxCell id="1" parent="0" />
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-73" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d0cee2;strokeColor=#56517e;" vertex="1" parent="1">
|
|
||||||
<mxGeometry x="92" y="645" width="720" height="180" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-71" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="1">
|
|
||||||
<mxGeometry x="110" y="605" width="720" height="180" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-53" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#ffcccc;strokeColor=#36393d;" vertex="1" parent="1">
|
|
||||||
<mxGeometry x="140" y="570" width="720" height="180" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-52" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#cdeb8b;strokeColor=#36393d;" vertex="1" parent="1">
|
|
||||||
<mxGeometry x="170" y="530" width="720" height="180" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-51" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#ffcc99;strokeColor=#36393d;" vertex="1" parent="1">
|
|
||||||
<mxGeometry x="210" y="490" width="720" height="180" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-49" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
|
|
||||||
<mxGeometry x="90" y="20" width="1080" height="290" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-10" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="Clf12EPbcqlM1huzJpPN-1" target="Clf12EPbcqlM1huzJpPN-9">
|
|
||||||
<mxGeometry relative="1" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-1" value="タスク開始" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
|
||||||
<mxGeometry x="120" y="215" width="90" height="50" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-45" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;dashed=1;curved=1;" edge="1" parent="1" source="Clf12EPbcqlM1huzJpPN-8" target="Clf12EPbcqlM1huzJpPN-9">
|
|
||||||
<mxGeometry relative="1" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-47" value="DBからクロールのタスクを取得する" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="Clf12EPbcqlM1huzJpPN-45">
|
|
||||||
<mxGeometry x="0.2449" y="53" relative="1" as="geometry">
|
|
||||||
<mxPoint x="17" y="-44" as="offset" />
|
|
||||||
</mxGeometry>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-79" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="Clf12EPbcqlM1huzJpPN-8" target="Clf12EPbcqlM1huzJpPN-78">
|
|
||||||
<mxGeometry relative="1" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-8" value="DB" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;fillColor=#cce5ff;strokeColor=#36393d;" vertex="1" parent="1">
|
|
||||||
<mxGeometry x="570" y="-110" width="100" height="70" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-9" value="<div style="background-color: rgb(255, 255, 254); font-family: Consolas, &quot;Courier New&quot;, monospace; font-size: 14px; line-height: 19px; white-space: pre;"><span style="">タスクスケジューラ</span></div>" style="whiteSpace=wrap;html=1;rounded=1;fontColor=default;" vertex="1" parent="1">
|
|
||||||
<mxGeometry x="260" y="217.5" width="140" height="45" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-17" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=1;entryY=0.5;entryDx=0;entryDy=0;curved=1;startArrow=block;startFill=1;endArrow=none;endFill=0;dashed=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;" edge="1" parent="1" source="Clf12EPbcqlM1huzJpPN-15" target="Clf12EPbcqlM1huzJpPN-9">
|
|
||||||
<mxGeometry relative="1" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-18" value="タスクの割り当て" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="Clf12EPbcqlM1huzJpPN-17">
|
|
||||||
<mxGeometry x="0.04" relative="1" as="geometry">
|
|
||||||
<mxPoint x="-18" y="30" as="offset" />
|
|
||||||
</mxGeometry>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-32" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.75;exitY=0;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;dashed=1;curved=1;" edge="1" parent="1" source="Clf12EPbcqlM1huzJpPN-15" target="Clf12EPbcqlM1huzJpPN-31">
|
|
||||||
<mxGeometry relative="1" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-15" value="<b>RabbitMQ</b>" style="whiteSpace=wrap;html=1;rounded=1;fillColor=#1ba1e2;fontColor=#ffffff;strokeColor=#006EAF;" vertex="1" parent="1">
|
|
||||||
<mxGeometry x="510" y="380" width="120" height="60" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-22" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="Clf12EPbcqlM1huzJpPN-19" target="Clf12EPbcqlM1huzJpPN-21">
|
|
||||||
<mxGeometry relative="1" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-19" value="MQコマンドの受信" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
|
||||||
<mxGeometry x="250" y="560" width="120" height="60" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-20" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;curved=1;dashed=1;" edge="1" parent="1" source="Clf12EPbcqlM1huzJpPN-15" target="Clf12EPbcqlM1huzJpPN-19">
|
|
||||||
<mxGeometry relative="1" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-24" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="Clf12EPbcqlM1huzJpPN-21" target="Clf12EPbcqlM1huzJpPN-23">
|
|
||||||
<mxGeometry relative="1" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-21" value="データ収集" style="whiteSpace=wrap;html=1;rounded=0;" vertex="1" parent="1">
|
|
||||||
<mxGeometry x="490" y="560" width="120" height="60" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-25" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=1;entryY=0.5;entryDx=0;entryDy=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;curved=1;dashed=1;" edge="1" parent="1" source="Clf12EPbcqlM1huzJpPN-23" target="Clf12EPbcqlM1huzJpPN-15">
|
|
||||||
<mxGeometry relative="1" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-23" value="結果をMQメッセージを変換" style="whiteSpace=wrap;html=1;rounded=0;" vertex="1" parent="1">
|
|
||||||
<mxGeometry x="740" y="560" width="170" height="60" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-33" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;exitPerimeter=0;dashed=1;curved=1;" edge="1" parent="1" source="Clf12EPbcqlM1huzJpPN-26" target="Clf12EPbcqlM1huzJpPN-31">
|
|
||||||
<mxGeometry relative="1" as="geometry">
|
|
||||||
<Array as="points">
|
|
||||||
<mxPoint x="980" y="390" />
|
|
||||||
<mxPoint x="980" y="350" />
|
|
||||||
<mxPoint x="745" y="350" />
|
|
||||||
</Array>
|
|
||||||
</mxGeometry>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-26" value="データ収集結果<br>一時保存" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;fillColor=#eeeeee;strokeColor=#36393d;" vertex="1" parent="1">
|
|
||||||
<mxGeometry x="970" y="390" width="100" height="70" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-27" value="タスクコマンド" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="1">
|
|
||||||
<mxGeometry x="340" y="450" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-28" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="1" source="Clf12EPbcqlM1huzJpPN-23" target="Clf12EPbcqlM1huzJpPN-26">
|
|
||||||
<mxGeometry relative="1" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-29" value="コンテンツなど大きい情報を一時保存" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
|
|
||||||
<mxGeometry x="950" y="500" width="230" height="30" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-30" value="収集結果通知MQ" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
|
|
||||||
<mxGeometry x="740" y="450" width="110" height="30" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-37" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="Clf12EPbcqlM1huzJpPN-31" target="Clf12EPbcqlM1huzJpPN-36">
|
|
||||||
<mxGeometry relative="1" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-31" value="メッセージキューから<div>データ受信</div>" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
|
||||||
<mxGeometry x="677" y="212.5" width="150" height="50" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-34" value="MQのキーで収集結果を取得" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
|
|
||||||
<mxGeometry x="760" y="350" width="170" height="30" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-39" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="Clf12EPbcqlM1huzJpPN-36" target="Clf12EPbcqlM1huzJpPN-38">
|
|
||||||
<mxGeometry relative="1" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-36" value="<div style="background-color: rgb(255, 255, 254); font-family: Consolas, &quot;Courier New&quot;, monospace; line-height: 19px; white-space: pre;"><span>データクリーニング<br>と重複排除</span></div>" style="whiteSpace=wrap;html=1;rounded=1;fontColor=default;fontSize=11;" vertex="1" parent="1">
|
|
||||||
<mxGeometry x="890" y="207.5" width="148" height="60" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-43" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="Clf12EPbcqlM1huzJpPN-38" target="Clf12EPbcqlM1huzJpPN-42">
|
|
||||||
<mxGeometry relative="1" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-38" value="データベースに保存" style="whiteSpace=wrap;html=1;fontSize=11;rounded=1;" vertex="1" parent="1">
|
|
||||||
<mxGeometry x="904" y="60" width="120" height="60" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-44" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="Clf12EPbcqlM1huzJpPN-42" target="Clf12EPbcqlM1huzJpPN-31">
|
|
||||||
<mxGeometry relative="1" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-42" value="収集結果からサブ項目を抽出" style="whiteSpace=wrap;html=1;fontSize=11;rounded=1;" vertex="1" parent="1">
|
|
||||||
<mxGeometry x="692" y="60" width="120" height="60" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-46" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=1;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;curved=1;dashed=1;" edge="1" parent="1" source="Clf12EPbcqlM1huzJpPN-38" target="Clf12EPbcqlM1huzJpPN-8">
|
|
||||||
<mxGeometry relative="1" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-48" value="クロール結果をDBに登録する" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="Clf12EPbcqlM1huzJpPN-46">
|
|
||||||
<mxGeometry x="0.1149" y="13" relative="1" as="geometry">
|
|
||||||
<mxPoint as="offset" />
|
|
||||||
</mxGeometry>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-50" value="<b>メインプログラム</b>" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
|
||||||
<mxGeometry x="540" y="20" width="130" height="30" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-54" value="<b>クローラー サブプログラム</b>" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
|
||||||
<mxGeometry x="485" y="490" width="185" height="30" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-55" value="<b>SharePointクローラー</b>" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
|
||||||
<mxGeometry x="220" y="640" width="130" height="30" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-60" value="MQ情報" style="swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=26;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;align=center;fontSize=14;fillColor=#dae8fc;strokeColor=#6c8ebf;gradientColor=#7ea6e0;" vertex="1" parent="1">
|
|
||||||
<mxGeometry x="1024" y="630" width="160" height="236" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-61" value="MQキー" style="text;strokeColor=none;fillColor=none;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;fontSize=12;whiteSpace=wrap;html=1;" vertex="1" parent="Clf12EPbcqlM1huzJpPN-60">
|
|
||||||
<mxGeometry y="26" width="160" height="30" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-70" value="クローラーID" style="text;strokeColor=none;fillColor=none;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;fontSize=12;whiteSpace=wrap;html=1;" vertex="1" parent="Clf12EPbcqlM1huzJpPN-60">
|
|
||||||
<mxGeometry y="56" width="160" height="30" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-62" value="分類" style="text;strokeColor=none;fillColor=none;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;fontSize=12;whiteSpace=wrap;html=1;" vertex="1" parent="Clf12EPbcqlM1huzJpPN-60">
|
|
||||||
<mxGeometry y="86" width="160" height="30" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-63" value="タイトル" style="text;strokeColor=none;fillColor=none;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;fontSize=12;whiteSpace=wrap;html=1;" vertex="1" parent="Clf12EPbcqlM1huzJpPN-60">
|
|
||||||
<mxGeometry y="116" width="160" height="30" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-64" value="URL" style="text;strokeColor=none;fillColor=none;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;fontSize=12;whiteSpace=wrap;html=1;" vertex="1" parent="Clf12EPbcqlM1huzJpPN-60">
|
|
||||||
<mxGeometry y="146" width="160" height="30" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-65" value="サブ項目" style="text;strokeColor=none;fillColor=none;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;fontSize=12;whiteSpace=wrap;html=1;" vertex="1" parent="Clf12EPbcqlM1huzJpPN-60">
|
|
||||||
<mxGeometry y="176" width="160" height="30" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-66" value="コンテンツ" style="text;strokeColor=none;fillColor=none;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;fontSize=12;whiteSpace=wrap;html=1;" vertex="1" parent="Clf12EPbcqlM1huzJpPN-60">
|
|
||||||
<mxGeometry y="206" width="160" height="30" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-67" value="" style="endArrow=none;dashed=1;html=1;dashPattern=1 3;strokeWidth=2;rounded=0;entryX=1;entryY=0.75;entryDx=0;entryDy=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;" edge="1" parent="1" source="Clf12EPbcqlM1huzJpPN-60" target="Clf12EPbcqlM1huzJpPN-23">
|
|
||||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
|
||||||
<mxPoint x="930" y="840" as="sourcePoint" />
|
|
||||||
<mxPoint x="980" y="790" as="targetPoint" />
|
|
||||||
</mxGeometry>
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-68" value="<b>OneNodeクローラー</b>" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
|
||||||
<mxGeometry x="180" y="680" width="130" height="30" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-69" value="<b>EIM クローラー</b>" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
|
||||||
<mxGeometry x="150" y="720" width="130" height="30" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-72" value="<b>Coredasuクローラー</b>" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
|
||||||
<mxGeometry x="120" y="755" width="130" height="30" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-74" value="<b>その他クローラー</b>" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
|
||||||
<mxGeometry x="92" y="795" width="130" height="30" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-75" value="PostGre SQL" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
|
|
||||||
<mxGeometry x="585" y="-40" width="90" height="30" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-76" value="再帰的な処理" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
|
||||||
<mxGeometry x="1030" y="140" width="80" height="50" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-77" value="NEO4J" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;" vertex="1" parent="1">
|
|
||||||
<mxGeometry x="570" y="-390" width="100" height="80" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-78" value="データ抽出" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
|
||||||
<mxGeometry x="560" y="-250" width="120" height="60" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
<mxCell id="Clf12EPbcqlM1huzJpPN-80" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="1" source="Clf12EPbcqlM1huzJpPN-78" target="Clf12EPbcqlM1huzJpPN-77">
|
|
||||||
<mxGeometry relative="1" as="geometry" />
|
|
||||||
</mxCell>
|
|
||||||
</root>
|
|
||||||
</mxGraphModel>
|
|
||||||
</diagram>
|
|
||||||
</mxfile>
|
|
||||||
@@ -18,6 +18,7 @@
|
|||||||
indicator-color="primary"
|
indicator-color="primary"
|
||||||
active-bg-color="primary"
|
active-bg-color="primary"
|
||||||
class="bg-grey-2 text-grey-8"
|
class="bg-grey-2 text-grey-8"
|
||||||
|
@update:model-value="() => selected = []"
|
||||||
dense
|
dense
|
||||||
>
|
>
|
||||||
<q-tab :name="cate"
|
<q-tab :name="cate"
|
||||||
|
|||||||
@@ -232,8 +232,38 @@ const onDeploy = async () => {
|
|||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deployLoading.value = true;
|
||||||
|
try {
|
||||||
|
const { data }: {data: {code: string, groups: {code: string}[]}} = await api.get('api/v1/defaultgroup');
|
||||||
|
if (data.code === 'CB_WA01') {
|
||||||
|
$q.notify({
|
||||||
|
type: 'negative',
|
||||||
|
caption: 'エラー',
|
||||||
|
message: 'ユーザーのパスワード認証に失敗しました。'
|
||||||
|
});
|
||||||
|
deployLoading.value = false;
|
||||||
|
return;
|
||||||
|
} else if (!data.groups || !data.groups.some((group: {code: string}) => group.code === 'Administrators')){
|
||||||
|
$q.notify({
|
||||||
|
type: 'negative',
|
||||||
|
caption: 'エラー',
|
||||||
|
message: 'この操作には管理者権限が必要です。'
|
||||||
|
});
|
||||||
|
deployLoading.value = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
$q.notify({
|
||||||
|
type: 'negative',
|
||||||
|
caption: 'エラー',
|
||||||
|
message: 'サーバーに接続できませんでした。'
|
||||||
|
});
|
||||||
|
deployLoading.value = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
deployLoading.value = true;
|
|
||||||
await store.deploy();
|
await store.deploy();
|
||||||
deployLoading.value = false;
|
deployLoading.value = false;
|
||||||
$q.notify({
|
$q.notify({
|
||||||
|
|||||||
@@ -53,21 +53,21 @@
|
|||||||
<div class="text-h6 q-ma-sm">Kintone Account</div>
|
<div class="text-h6 q-ma-sm">Kintone Account</div>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
|
|
||||||
<q-card-section class="q-pt-none q-mt-none">
|
<q-card-section class="q-py-none q-mt-none">
|
||||||
<div class="q-gutter-lg">
|
<div class="q-gutter-lg">
|
||||||
|
|
||||||
<q-input filled v-model="name" label="環境名 *" hint="kintoneの環境名を入力してください" lazy-rules
|
<q-input filled v-model="name" label="環境名 *" hint="kintoneの環境名を入力してください" lazy-rules
|
||||||
:rules="[val => val && val.length > 0 || 'kintoneの環境名を入力してください。']" />
|
:rules="[val => val && val.length > 0 || 'kintoneの環境名を入力してください。']" />
|
||||||
|
|
||||||
<q-input filled type="url" v-model.trim="url" label="Kintone url" hint="KintoneのURLを入力してください" lazy-rules
|
<q-input filled v-model.trim="url" :readonly="!isCreate" label="Kintone url" :hint="isCreate ? 'KintoneのURLを入力してください':'KintoneのURLは変更できません。新規作成してください。'" lazy-rules
|
||||||
:rules="[val => val && val.length > 0 || 'KintoneのURLを入力してください']" />
|
:rules="[val => val && val.length > 0 || 'KintoneのURLを入力してください']" />
|
||||||
|
|
||||||
<q-input filled v-model="kintoneuser" label="ログイン名 *" hint="Kintoneのログイン名を入力してください" lazy-rules
|
<q-input v-if="isCreate" filled v-model="kintoneuser" label="ログイン名 *" hint="Kintoneのログイン名を入力してください" lazy-rules
|
||||||
:rules="[val => val && val.length > 0 || 'Kintoneのログイン名を入力してください']" autocomplete="new-password" />
|
:rules="[val => val && val.length > 0 || 'Kintoneのログイン名を入力してください']" autocomplete="new-password" />
|
||||||
|
|
||||||
<q-input v-if="isCreate" v-model="kintonepwd" filled :type="isPwd ? 'password' : 'text'"
|
<q-input v-if="isCreate" v-model="kintonepwd" filled :type="isPwd ? 'password' : 'text'"
|
||||||
hint="パスワード" label="パスワード" :disable="!isCreate" lazy-rules
|
hint="Kintoneのパスワードを入力してください" label="パスワード" :disable="!isCreate" lazy-rules
|
||||||
:rules="[val => val && val.length > 0 || 'Please type something']" autocomplete="new-password">
|
:rules="[val => val && val.length > 0 || 'Kintoneのパスワードを入力してください']" autocomplete="new-password">
|
||||||
<template v-slot:append>
|
<template v-slot:append>
|
||||||
<q-icon :name="isPwd ? 'visibility_off' : 'visibility'" class="cursor-pointer"
|
<q-icon :name="isPwd ? 'visibility_off' : 'visibility'" class="cursor-pointer"
|
||||||
@click="isPwd = !isPwd" />
|
@click="isPwd = !isPwd" />
|
||||||
@@ -88,30 +88,51 @@
|
|||||||
|
|
||||||
<q-item tag="label" class="q-pl-sm q-pr-none q-py-xs">
|
<q-item tag="label" class="q-pl-sm q-pr-none q-py-xs">
|
||||||
<q-item-section>
|
<q-item-section>
|
||||||
<q-item-label>パスワードリセット</q-item-label>
|
<q-item-label>管理者アカウントの変更</q-item-label>
|
||||||
</q-item-section>
|
</q-item-section>
|
||||||
<q-item-section avatar>
|
<q-item-section avatar>
|
||||||
<q-toggle v-model="resetPsw" @update:model-value="updateResetPsw" />
|
<q-toggle v-model="changeAccount" @update:model-value="updateChangeAccount" />
|
||||||
</q-item-section>
|
</q-item-section>
|
||||||
</q-item>
|
</q-item>
|
||||||
|
|
||||||
<q-input v-model="kintonepwd" filled :type="isPwd ? 'password' : 'text'" hint="パスワードを入力してください"
|
<q-expansion-item
|
||||||
label="パスワード" :disable="!resetPsw" lazy-rules
|
header-class="hidden"
|
||||||
:rules="[val => val && val.length > 0 || 'Please type something']" autocomplete="new-password">
|
class="q-mt-none"
|
||||||
<template v-slot:append>
|
v-model="changeAccount"
|
||||||
<q-icon :name="isPwd ? 'visibility_off' : 'visibility'" class="cursor-pointer"
|
>
|
||||||
@click="isPwd = !isPwd" />
|
<q-input filled v-model="kintoneuser" label="ログイン名 *" hint="Kintoneのログイン名を入力してください" :disable="!changeAccount"
|
||||||
</template>
|
:rules="[val => val && val.length > 0 || 'Kintoneのログイン名を入力してください']" lazy-rules class="q-mt-md"/>
|
||||||
</q-input>
|
|
||||||
<!-- <q-btn label="asdf"/> -->
|
<q-input v-model="kintonepwd" filled :type="isPwd ? 'password' : 'text'" hint="Kintoneのパスワードを入力してください"
|
||||||
|
label="パスワード" :disable="!changeAccount" lazy-rules class="q-mt-lg q-mb-md"
|
||||||
|
:rules="[val => val && val.length > 0 || 'Kintoneのパスワードを入力してください']" autocomplete="new-password">
|
||||||
|
<template v-slot:append>
|
||||||
|
<q-icon :name="isPwd ? 'visibility_off' : 'visibility'" class="cursor-pointer"
|
||||||
|
@click="isPwd = !isPwd" />
|
||||||
|
</template>
|
||||||
|
</q-input>
|
||||||
|
<!-- <q-btn label="asdf"/> -->
|
||||||
|
</q-expansion-item>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
<q-card-actions align="right" class="text-primary q-mb-md q-mx-sm">
|
|
||||||
<q-btn :loading="addEditLoading" label="保存" type="submit" color="primary" />
|
<div class="q-mt-none">
|
||||||
<q-btn label="キャンセル" type="cancel" color="primary" flat class="q-ml-sm" @click="closeDg()" />
|
<q-banner dense :class="['text-white q-mt-sm q-py-xs q-mx-md', testResult?.success ? 'bg-green':'bg-red', testResult?.msg ? '':'invisible']">
|
||||||
</q-card-actions>
|
{{ testResult?.msg }}
|
||||||
|
</q-banner>
|
||||||
|
<q-card-actions class="text-primary q-mb-md q-mx-sm relative-position">
|
||||||
|
<q-btn v-if="isCreate || changeAccount" :disable="!isConnectable" :loading="!!connectLoading" padding="xs md" :label="!!connectLoading ? '確認中...' : '接続確認'"
|
||||||
|
color="primary" outline @click="tryConnect()"/>
|
||||||
|
<q-btn v-if="!!connectLoading" label="停止" color="negative" flat class="q-ml-sm" @click="stopConnect" />
|
||||||
|
<q-space />
|
||||||
|
<q-btn :loading="addEditLoading" padding="xs md" label="保存" type="submit" color="primary" />
|
||||||
|
<q-btn label="キャンセル" type="cancel" color="primary" flat class="q-ml-sm" @click="closeDg()" />
|
||||||
|
</q-card-actions>
|
||||||
|
</div>
|
||||||
</q-form>
|
</q-form>
|
||||||
</q-card>
|
</q-card>
|
||||||
|
|
||||||
@@ -187,12 +208,14 @@ const pagination = ref({ sortBy: 'id', descending: true, rowsPerPage: 20 });
|
|||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const addEditLoading = ref(false);
|
const addEditLoading = ref(false);
|
||||||
const deleteLoadingState = ref<number>(-1); // -2: deleteLoading, -1: loading, 0: allow, > 0: user count
|
const deleteLoadingState = ref<number>(-1); // -2: deleteLoading, -1: loading, 0: allow, > 0: user count
|
||||||
|
const connectLoading = ref<AbortController|null>(null);
|
||||||
|
|
||||||
const filter = ref('');
|
const filter = ref('');
|
||||||
const rows = ref<IDomainOwnerDisplay[]>([]);
|
const rows = ref<IDomainOwnerDisplay[]>([]);
|
||||||
const show = ref(false);
|
const show = ref(false);
|
||||||
const confirm = ref(false);
|
const confirm = ref(false);
|
||||||
const resetPsw = ref(false);
|
const changeAccount = ref(false);
|
||||||
|
const testResult = ref<{msg: string, success?: boolean}|null>(null);
|
||||||
|
|
||||||
const currentDomainId = computed(() => authStore.currentDomain.id);
|
const currentDomainId = computed(() => authStore.currentDomain.id);
|
||||||
// const tenantid = ref(authStore.currentDomain.id);
|
// const tenantid = ref(authStore.currentDomain.id);
|
||||||
@@ -200,8 +223,8 @@ const name = ref('');
|
|||||||
const url = ref('');
|
const url = ref('');
|
||||||
const isPwd = ref(true);
|
const isPwd = ref(true);
|
||||||
const kintoneuser = ref('');
|
const kintoneuser = ref('');
|
||||||
|
const kintoneuserBK = ref('');
|
||||||
const kintonepwd = ref('');
|
const kintonepwd = ref('');
|
||||||
const kintonepwdBK = ref('');
|
|
||||||
const domainActive = ref(true);
|
const domainActive = ref(true);
|
||||||
const isCreate = ref(true);
|
const isCreate = ref(true);
|
||||||
let editId = ref(0);
|
let editId = ref(0);
|
||||||
@@ -316,19 +339,20 @@ function editRow(row: any) {
|
|||||||
name.value = row.name;
|
name.value = row.name;
|
||||||
url.value = row.url;
|
url.value = row.url;
|
||||||
kintoneuser.value = row.user;
|
kintoneuser.value = row.user;
|
||||||
kintonepwd.value = row.password;
|
kintoneuserBK.value = row.user;
|
||||||
|
kintonepwd.value = ''
|
||||||
domainActive.value = row.domainActive;
|
domainActive.value = row.domainActive;
|
||||||
isPwd.value = true;
|
isPwd.value = true;
|
||||||
show.value = true;
|
show.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateResetPsw = (value: boolean) => {
|
const updateChangeAccount = () => {
|
||||||
if (value === true) {
|
kintoneuser.value = kintoneuserBK.value;
|
||||||
kintonepwd.value = ''
|
kintonepwd.value = ''
|
||||||
isPwd.value = true
|
connectLoading.value = null
|
||||||
} else {
|
isPwd.value = true
|
||||||
kintonepwd.value = kintonepwdBK.value
|
stopConnect();
|
||||||
}
|
testResult.value = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const closeDg = () => {
|
const closeDg = () => {
|
||||||
@@ -336,8 +360,61 @@ const closeDg = () => {
|
|||||||
onReset();
|
onReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
const onSubmit = () => {
|
const tryConnect = async (isTest = true) => {
|
||||||
|
testResult.value = null;
|
||||||
|
if (isTest) {
|
||||||
|
connectLoading.value = new AbortController();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const { data }: {data: {code: string, groups: {code: string}[]}} = await api.get('api/v1/group', {
|
||||||
|
params:{
|
||||||
|
kintoneurl: ensureHttps(url.value),
|
||||||
|
kintoneuser: kintoneuser.value,
|
||||||
|
kintonepwd: kintonepwd.value,
|
||||||
|
},
|
||||||
|
signal: (isTest && connectLoading.value) ? connectLoading.value.signal : undefined
|
||||||
|
});
|
||||||
|
if (data.code === 'CB_WA01') {
|
||||||
|
testResult.value = { msg: 'ユーザーのパスワード認証に失敗しました。' }
|
||||||
|
} else if (data.groups && data.groups.some((group: {code: string}) => group.code === 'Administrators')){
|
||||||
|
testResult.value = { success: true, msg: isTest ? 'kintoneの管理者アカウントで接続に成功しました。' : '' }
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
testResult.value = { msg: 'このアカウントはkintoneの管理者アカウントではありません。' }
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
} catch (e) {
|
||||||
|
const error = e as { code?: string };
|
||||||
|
if (error.code === 'ERR_CANCELED') {
|
||||||
|
console.log('Aborted');
|
||||||
|
} else {
|
||||||
|
testResult.value = { msg: 'サーバーに接続できませんでした。' }
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
} finally {
|
||||||
|
connectLoading.value = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const ensureHttps = (url: string) => {
|
||||||
|
return !/^https?:\/\//i.test(url) ? 'https://' + url : url;
|
||||||
|
}
|
||||||
|
|
||||||
|
const stopConnect = () => {
|
||||||
|
if (!connectLoading.value) return;
|
||||||
|
connectLoading.value?.abort();
|
||||||
|
connectLoading.value = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const onSubmit = async () => {
|
||||||
addEditLoading.value = true;
|
addEditLoading.value = true;
|
||||||
|
try {
|
||||||
|
await tryConnect(false);
|
||||||
|
} catch (e) {
|
||||||
|
addEditLoading.value = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
const method = editId.value !== 0 ? 'put' : 'post';
|
const method = editId.value !== 0 ? 'put' : 'post';
|
||||||
const param: IDomainSubmit = {
|
const param: IDomainSubmit = {
|
||||||
'id': editId.value,
|
'id': editId.value,
|
||||||
@@ -345,7 +422,7 @@ const onSubmit = () => {
|
|||||||
'name': name.value,
|
'name': name.value,
|
||||||
'url': url.value,
|
'url': url.value,
|
||||||
'kintoneuser': kintoneuser.value,
|
'kintoneuser': kintoneuser.value,
|
||||||
'kintonepwd': ((isCreate.value && editId.value == 0) || resetPsw.value) ? kintonepwd.value : '',
|
'kintonepwd': ((isCreate.value && editId.value == 0) || changeAccount.value) ? kintonepwd.value : '',
|
||||||
'is_active': domainActive.value,
|
'is_active': domainActive.value,
|
||||||
'ownerid': authStore.userId || ''
|
'ownerid': authStore.userId || ''
|
||||||
}
|
}
|
||||||
@@ -374,17 +451,24 @@ function openShareDg(type: typeof SHARE_MANAGE|typeof SHARE_USE, row: IDomainOwn
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const isConnectable = computed(()=> {
|
||||||
|
return url.value && kintoneuser.value && kintonepwd.value
|
||||||
|
})
|
||||||
|
|
||||||
const onReset = () => {
|
const onReset = () => {
|
||||||
name.value = '';
|
name.value = '';
|
||||||
url.value = '';
|
url.value = '';
|
||||||
kintoneuser.value = '';
|
kintoneuser.value = '';
|
||||||
|
kintoneuserBK.value = '';
|
||||||
kintonepwd.value = '';
|
kintonepwd.value = '';
|
||||||
isPwd.value = true;
|
isPwd.value = true;
|
||||||
editId.value = 0;
|
editId.value = 0;
|
||||||
isCreate.value = true;
|
isCreate.value = true;
|
||||||
domainActive.value = true;
|
domainActive.value = true;
|
||||||
resetPsw.value = false
|
changeAccount.value = false;
|
||||||
addEditLoading.value = false;
|
addEditLoading.value = false;
|
||||||
|
connectLoading.value = null
|
||||||
|
testResult.value = null;
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
|||||||
@@ -80,14 +80,14 @@
|
|||||||
|
|
||||||
<q-input v-if="isCreate" v-model="pwd" filled :type="isPwd ? 'password' : 'text'" hint="パスワード"
|
<q-input v-if="isCreate" v-model="pwd" filled :type="isPwd ? 'password' : 'text'" hint="パスワード"
|
||||||
label="パスワード" :disable="!isCreate" lazy-rules
|
label="パスワード" :disable="!isCreate" lazy-rules
|
||||||
:rules="[val => val && val.length > 0 || 'Please type something']" autocomplete="new-password">
|
:rules="[val => val && val.length > 0 || 'パスワードを入力してください']" autocomplete="new-password">
|
||||||
<template v-slot:append>
|
<template v-slot:append>
|
||||||
<q-icon :name="isPwd ? 'visibility_off' : 'visibility'" class="cursor-pointer"
|
<q-icon :name="isPwd ? 'visibility_off' : 'visibility'" class="cursor-pointer"
|
||||||
@click="isPwd = !isPwd" />
|
@click="isPwd = !isPwd" />
|
||||||
</template>
|
</template>
|
||||||
</q-input>
|
</q-input>
|
||||||
|
|
||||||
<q-item tag="label" class="q-pl-sm q-pr-none q-py-xs">
|
<q-item tag="label" v-if="authStore.isSuperAdmin" class="q-pl-sm q-pr-none q-py-xs">
|
||||||
<q-item-section>
|
<q-item-section>
|
||||||
<q-item-label>システム管理者</q-item-label>
|
<q-item-label>システム管理者</q-item-label>
|
||||||
</q-item-section>
|
</q-item-section>
|
||||||
@@ -118,7 +118,7 @@
|
|||||||
</q-item>
|
</q-item>
|
||||||
|
|
||||||
<q-input v-model="pwd" filled :type="isPwd ? 'password' : 'text'" hint="パスワードを入力してください" label="パスワード"
|
<q-input v-model="pwd" filled :type="isPwd ? 'password' : 'text'" hint="パスワードを入力してください" label="パスワード"
|
||||||
:disable="!resetPsw" lazy-rules :rules="[val => val && val.length > 0 || 'Please type something']"
|
:disable="!resetPsw" lazy-rules :rules="[val => val && val.length > 0 || 'パスワードを入力してください']"
|
||||||
autocomplete="new-password">
|
autocomplete="new-password">
|
||||||
<template v-slot:append>
|
<template v-slot:append>
|
||||||
<q-icon :name="isPwd ? 'visibility_off' : 'visibility'" class="cursor-pointer"
|
<q-icon :name="isPwd ? 'visibility_off' : 'visibility'" class="cursor-pointer"
|
||||||
@@ -131,7 +131,7 @@
|
|||||||
|
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
<q-card-actions align="right" class="text-primary q-mb-md q-mx-sm">
|
<q-card-actions align="right" class="text-primary q-mb-md q-mx-sm">
|
||||||
<q-btn :loading="addEditLoading" label="保存" type="submit" color="primary" />
|
<q-btn :loading="addEditLoading" padding="xs md" label="保存" type="submit" color="primary" />
|
||||||
<q-btn label="キャンセル" type="cancel" color="primary" flat class="q-ml-sm" @click="closeDg()" />
|
<q-btn label="キャンセル" type="cancel" color="primary" flat class="q-ml-sm" @click="closeDg()" />
|
||||||
</q-card-actions>
|
</q-card-actions>
|
||||||
</q-form>
|
</q-form>
|
||||||
@@ -160,10 +160,12 @@
|
|||||||
import { ref, onMounted, computed } from 'vue';
|
import { ref, onMounted, computed } from 'vue';
|
||||||
import TableActionMenu from 'components/TableActionMenu.vue';
|
import TableActionMenu from 'components/TableActionMenu.vue';
|
||||||
import { useUserStore } from 'stores/useUserStore';
|
import { useUserStore } from 'stores/useUserStore';
|
||||||
|
import { useAuthStore } from 'stores/useAuthStore';
|
||||||
import { IUserDisplay, IUserRolesDisplay } from 'src/types/UserTypes';
|
import { IUserDisplay, IUserRolesDisplay } from 'src/types/UserTypes';
|
||||||
import { Actions } from 'boot/permissions';
|
import { Actions } from 'boot/permissions';
|
||||||
|
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
|
const authStore = useAuthStore();
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{ name: 'id', label: 'ID', field: 'id', align: 'left', sortable: true },
|
{ name: 'id', label: 'ID', field: 'id', align: 'left', sortable: true },
|
||||||
|
|||||||
52
scripts/kintoneToolDB_20250516_update.sql
Normal file
52
scripts/kintoneToolDB_20250516_update.sql
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
SET statement_timeout = 0;
|
||||||
|
SET lock_timeout = 0;
|
||||||
|
SET idle_in_transaction_session_timeout = 0;
|
||||||
|
SET client_encoding = 'UTF8';
|
||||||
|
SET standard_conforming_strings = on;
|
||||||
|
SELECT pg_catalog.set_config('search_path', '', false);
|
||||||
|
SET check_function_bodies = false;
|
||||||
|
SET xmloption = content;
|
||||||
|
SET client_min_messages = warning;
|
||||||
|
SET row_security = off;
|
||||||
|
|
||||||
|
-- event テーブルに欠落している app.record.index.delete.submit を追加します。
|
||||||
|
DO $$
|
||||||
|
DECLARE
|
||||||
|
max_id INTEGER;
|
||||||
|
BEGIN
|
||||||
|
SELECT MAX(id) INTO max_id FROM public."event";
|
||||||
|
PERFORM pg_catalog.setval('public.event_id_seq', max_id, true);
|
||||||
|
|
||||||
|
INSERT INTO public."event" (create_time, update_time, category, "type", eventid, "function", mobile)
|
||||||
|
VALUES(NOW(), NOW(), 'Kintone', 'レコード一覧画面', 'app.record.index.delete.submit', 'レコードを削除するとき', true)
|
||||||
|
ON CONFLICT (eventid) DO NOTHING;
|
||||||
|
END $$;
|
||||||
|
|
||||||
|
|
||||||
|
-- eventaction テーブル
|
||||||
|
DO $$
|
||||||
|
DECLARE
|
||||||
|
max_id INTEGER;
|
||||||
|
BEGIN
|
||||||
|
-- constraint: unique_eventid_actionid
|
||||||
|
IF NOT EXISTS (
|
||||||
|
SELECT 1
|
||||||
|
FROM pg_constraint
|
||||||
|
WHERE conrelid = 'public.eventaction'::regclass
|
||||||
|
AND conname = 'unique_eventid_actionid'
|
||||||
|
) THEN
|
||||||
|
ALTER TABLE public.eventaction
|
||||||
|
ADD CONSTRAINT unique_eventid_actionid UNIQUE (eventid, actionid);
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
SELECT MAX(id) INTO max_id FROM public.eventaction;
|
||||||
|
PERFORM pg_catalog.setval('public.eventaction_id_seq', max_id, true);
|
||||||
|
|
||||||
|
-- /must-input.ts
|
||||||
|
INSERT INTO public.eventaction (create_time, update_time, eventid, actionid)
|
||||||
|
VALUES(NOW(), NOW(), 'app.record.detail.delete.submit', 1)
|
||||||
|
, (NOW(), NOW(), 'app.record.index.delete.submit', 1)
|
||||||
|
ON CONFLICT (eventid, actionid) DO NOTHING;
|
||||||
|
|
||||||
|
END $$;
|
||||||
|
|
||||||
Reference in New Issue
Block a user