Commit c4c8f8a3 authored by Wallen姚文辉's avatar Wallen姚文辉

Merge branch 'mailmade' into 'master'

Mailmade

See merge request !2
parents 24d4980c d4ad83e9
.layout{border:1px solid #d7dde4;background:#f5f7f9;position:relative;border-radius:4px;overflow:hidden}.layout-logo{width:100px;height:30px;background:#5b6270;border-radius:3px;float:left;position:relative;top:15px;left:20px}.layout-nav{margin:0 auto;display:flex}.card{height:300px;background:rgba(103,176,185,.7);transform:translateY(90%);-webkit-backdrop-filter:blur(5px);backdrop-filter:blur(5px);border-radius:30px 5px 15px 5px;text-align:center}.login{max-width:400px;margin:0 auto!important;transform:translateY(40%)}.chart{height:100vh}.info-card{margin:10px 5px 10px 5px;background-color:#fff;border-radius:8px;box-shadow:0 0 8px 0 hsla(0,0%,71%,.58)}#my_table{text-align:left;width:90%;margin:0 10px 10px 10px;margin-right:auto;margin-left:auto}#my-table td:first-child{width:80%}#my-table td:nth-child(2){width:10%}.header_style{border-bottom:1px solid #dcdee2}.center_style{width:90%;margin:auto}.background_sytle{background-color:#f8f8f9;padding-top:.5px;padding-bottom:.5px;border-radius:8px;margin-top:2px;margin-bottom:2px}.near_left{width:25%;display:inline-block;height:100%}.near_right{width:75%;display:inline-block}.fontstyle{text-align:left}@keyframes changDeg{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.demo-spin-icon-load{color:#2b85e4;animation:changDeg 2s linear .2s infinite}a{text-decoration:none}a:hover{text-decoration:underline}.editbutton:hover{background-color:#c6e2ff}.fileBox{display:flex;flex-wrap:wrap;margin-top:20px;min-height:170px;background-color:beige}.file{height:150px;width:150px;margin:10px 10px 10px 10px;text-align:center;border-radius:10px}.pop{position:absolute;background:#fff;box-shadow:1px 1px 4px #888;font-size:12px;border-radius:5px;z-index:999}.pop>div{margin:15px 10px;cursor:pointer}#sheet{flex:1}.vertical-center-modal{display:flex;align-items:center;justify-content:center}.vertical-center-modal .ivu-modal{top:0} .layout{border:1px solid #d7dde4;background:#f5f7f9;position:relative;border-radius:4px;overflow:hidden}.layout-logo{width:100px;height:30px;background:#5b6270;border-radius:3px;float:left;position:relative;top:15px;left:20px}.layout-nav{margin:0 auto;display:flex}.card{height:300px;background:rgba(103,176,185,.7);transform:translateY(90%);-webkit-backdrop-filter:blur(5px);backdrop-filter:blur(5px);border-radius:30px 5px 15px 5px;text-align:center}.login{max-width:400px;margin:0 auto!important;transform:translateY(40%)}.chart{height:100vh}.info-card{margin:10px 5px 10px 5px;background-color:#fff;border-radius:8px;box-shadow:0 0 8px 0 hsla(0,0%,71%,.58)}#my_table{text-align:left;width:90%;margin:0 10px 10px 10px;margin-right:auto;margin-left:auto}#my-table td:first-child{width:80%}#my-table td:nth-child(2){width:10%}.header_style{border-bottom:1px solid #dcdee2}.center_style{width:90%;margin:auto}.background_sytle{background-color:#f8f8f9;padding-top:.5px;padding-bottom:.5px;border-radius:8px;margin-top:2px;margin-bottom:2px}.near_left{width:25%;display:inline-block;height:100%}.near_right{width:75%;display:inline-block}.fontstyle{text-align:left}@keyframes changDeg{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.demo-spin-icon-load{color:#2b85e4;animation:changDeg 2s linear .2s infinite}a{text-decoration:none}a:hover{text-decoration:underline}.editbutton:hover{background-color:#c6e2ff}.fileBox{display:flex;flex-wrap:wrap;margin-top:20px;min-height:170px;background-color:beige}.file{height:150px;width:150px;margin:10px 10px 10px 10px;text-align:center;border-radius:10px}.pop{position:absolute;background:#fff;box-shadow:1px 1px 4px #888;font-size:12px;border-radius:5px;z-index:999}.pop>div{margin:15px 10px;cursor:pointer}#sheet{flex:1}.phone{width:250px;height:500px;background-color:#e7f6ff;border-radius:20px;border-style:outset;border-width:10px;border-color:#18172c;text-align:center}.transition-box{margin-top:32px;width:100%;border-radius:4px;background-color:#409eff;text-align:center;color:#fff;padding:24px 0}.vertical-center-modal{display:flex;align-items:center;justify-content:center}.vertical-center-modal .ivu-modal{top:0}
\ No newline at end of file \ No newline at end of file
<!doctype html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="stylesheet" href="/dist/plugins/css/pluginsCss.css"/><link rel="stylesheet" href="/dist/plugins/plugins.css"/><link rel="stylesheet" href="/dist/css/luckysheet.css"/><link rel="stylesheet" href="/dist/assets/iconfont/iconfont.css"/><script src="/dist/plugins/js/plugin.js"></script><script src="/dist/luckysheet.umd.js"></script><title>yinhe_test</title><script defer="defer" src="/js/chunk-vendors.c7960745.js"></script><script defer="defer" src="/js/app.7a7ee3d2.js"></script><link href="/css/chunk-vendors.187ae3e6.css" rel="stylesheet"><link href="/css/app.96955a93.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but yinhe_test doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html> <!doctype html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="stylesheet" href="/dist/plugins/css/pluginsCss.css"/><link rel="stylesheet" href="/dist/plugins/plugins.css"/><link rel="stylesheet" href="/dist/css/luckysheet.css"/><link rel="stylesheet" href="/dist/assets/iconfont/iconfont.css"/><script src="/dist/plugins/js/plugin.js"></script><script src="/dist/luckysheet.umd.js"></script><title>yinhe_test</title><script defer="defer" src="/js/chunk-vendors.c8e13258.js"></script><script defer="defer" src="/js/app.f2362e6e.js"></script><link href="/css/chunk-vendors.187ae3e6.css" rel="stylesheet"><link href="/css/app.df7fa4e2.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but yinhe_test doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>
\ No newline at end of file \ No newline at end of file
"use strict";(self["webpackChunkyinhe_test"]=self["webpackChunkyinhe_test"]||[]).push([[10],{7010:function(e,n,t){t.r(n),t.d(n,{default:function(){return a}});var r=t(5796);function c(e,n,t,c,o,s){const u=(0,r.resolveComponent)("Exception");return(0,r.openBlock)(),(0,r.createBlock)(u,{type:"404"})}var o={},s=t(1241);const u=(0,s.A)(o,[["render",c]]);var a=u}}]); "use strict";(self["webpackChunkyinhe_test"]=self["webpackChunkyinhe_test"]||[]).push([[10],{7010:function(e,n,t){t.r(n),t.d(n,{default:function(){return a}});var r=t(5796);function c(e,n,t,c,o,s){const u=(0,r.resolveComponent)("Exception");return(0,r.openBlock)(),(0,r.createBlock)(u,{type:"404"})}var o={},s=t(1241);const u=(0,s.A)(o,[["render",c]]);var a=u}}]);
//# sourceMappingURL=10.877e7673.js.map //# sourceMappingURL=10.e541696a.js.map
\ No newline at end of file \ No newline at end of file
{"version":3,"file":"js/10.877e7673.js","mappings":"0QACIA,EAAAA,EAAAA,aAAwBC,EAAA,CAAbC,KAAK,O,CAGhB,OAEC,E,UCDL,MAAMC,GAA2B,OAAgB,EAAQ,CAAC,CAAC,SAASC,KAEpE,O","sources":["webpack://yinhe_test/./src/views/error/index.vue","webpack://yinhe_test/./src/views/error/index.vue?45db"],"sourcesContent":["<template>\n <Exception type=\"404\" />\n</template>\n<script>\n export default {\n \n }\n</script>","import { render } from \"./index.vue?vue&type=template&id=fda2373e\"\nimport script from \"./index.vue?vue&type=script&lang=js\"\nexport * from \"./index.vue?vue&type=script&lang=js\"\n\nimport exportComponent from \"../../../node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__"],"names":["_createBlock","_component_Exception","type","__exports__","render"],"sourceRoot":""} {"version":3,"file":"js/10.e541696a.js","mappings":"0QACIA,EAAAA,EAAAA,aAAwBC,EAAA,CAAbC,KAAK,O,CAGhB,OAEC,E,UCDL,MAAMC,GAA2B,OAAgB,EAAQ,CAAC,CAAC,SAASC,KAEpE,O","sources":["webpack://yinhe_test/./src/views/error/index.vue","webpack://yinhe_test/./src/views/error/index.vue?45db"],"sourcesContent":["<template>\n <Exception type=\"404\" />\n</template>\n<script>\n export default {\n \n }\n</script>","import { render } from \"./index.vue?vue&type=template&id=fda2373e\"\nimport script from \"./index.vue?vue&type=script&lang=js\"\nexport * from \"./index.vue?vue&type=script&lang=js\"\n\nimport exportComponent from \"../../../node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__"],"names":["_createBlock","_component_Exception","type","__exports__","render"],"sourceRoot":""}
\ No newline at end of file \ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
...@@ -14,6 +14,9 @@ import TestReport from '@/views/tool/TestReport'; ...@@ -14,6 +14,9 @@ import TestReport from '@/views/tool/TestReport';
import ReportLsit from '@/views/tool/ReportLsit'; import ReportLsit from '@/views/tool/ReportLsit';
import AduitReportList from '@/views/tool/AduitReportList'; import AduitReportList from '@/views/tool/AduitReportList';
import TestCase from '@/views/autotest/TestCase.vue'; import TestCase from '@/views/autotest/TestCase.vue';
// import RequestsTemplate from '@/views/tool/RequestsTemplate.vue';
import MailTool from '@/views/tool/MailTool.vue';
import MoveUIRun from '@/views/autotest/MoveUIRun.vue';
import CreateOrder from '@/views/tool/CreateOrder.vue'; import CreateOrder from '@/views/tool/CreateOrder.vue';
import Echarts from "vue-echarts"; import Echarts from "vue-echarts";
import 'echarts'; import 'echarts';
...@@ -86,10 +89,20 @@ const routers = [ ...@@ -86,10 +89,20 @@ const routers = [
path: 'testcase', path: 'testcase',
name: 'testcase', name: 'testcase',
component: TestCase component: TestCase
},{ }, {
path:'createorder', path: 'moveuirun',
name:'createorder', name: 'moveuirun',
component: MoveUIRun
},
{
path: 'createorder',
name: 'createorder',
component: CreateOrder component: CreateOrder
},
{
path: 'mailtool',
name: 'mailtool',
component: MailTool
} }
] ]
......
This diff is collapsed.
...@@ -22,22 +22,24 @@ ...@@ -22,22 +22,24 @@
<Col :lg="4" span="0"> <Col :lg="4" span="0">
</Col> </Col>
<Col :lg="10" span="0"> <Col :lg="10" span="0">
<Card v-if="choiceId" style="height: 600px;"> <Card v-if="choiceId" style="height: 700px">
<Form > <Form>
<FormItem> <FormItem>
<Table :show-header="false" row-key="id" :columns="menu_columns" <div style="background-color: blue;height: 600px;overflow:auto">
@on-selection-change="(a) => { select_menu = a }" :data="choicePermissions"> <Table :show-header="false" row-key="id" :columns="menu_columns"
<template #name="{ row }"> @on-selection-change="(a) => { select_menu = a }" :data="choicePermissions">
<strong>{{ row.name }}</strong> <template #name="{ row }">
</template> <strong>{{ row.name }}</strong>
<template #elements="{ row }"> </template>
<Tag v-for="item in row.elements" :key="item.id" :name="item.id" <template #elements="{ row }">
:checked="item._checked" checkable <Tag v-for="item in row.elements" :key="item.id" :name="item.id"
@on-change="(chec, name) => { elechoice(row, chec, name) }" color="primary" :checked="item._checked" checkable
style="margin-right: 5px"> @on-change="(chec, name) => { elechoice(row, chec, name) }" color="primary"
{{ item.name }}</Tag> style="margin-right: 5px">
</template> {{ item.name }}</Tag>
</Table> </template>
</Table>
</div>
</FormItem> </FormItem>
<FormItem style="text-align: right;"> <FormItem style="text-align: right;">
<Button type="primary" @click="updatePermissions(choiceId)">确认</Button> <Button type="primary" @click="updatePermissions(choiceId)">确认</Button>
...@@ -69,7 +71,7 @@ export default { ...@@ -69,7 +71,7 @@ export default {
props: ['isCollapsed',], props: ['isCollapsed',],
data() { data() {
return { return {
page_id:16, page_id: 16,
title: "角色管理", title: "角色管理",
modlShow: false, modlShow: false,
addinfo: { addinfo: {
...@@ -109,7 +111,7 @@ export default { ...@@ -109,7 +111,7 @@ export default {
align: 'center' align: 'center'
} }
], ],
elements:[] elements: []
} }
}, },
methods: { methods: {
...@@ -147,7 +149,7 @@ export default { ...@@ -147,7 +149,7 @@ export default {
this.$request("get", "/identity/meun_list", null, this, (data) => { this.allPermissions = data.data }) this.$request("get", "/identity/meun_list", null, this, (data) => { this.allPermissions = data.data })
}, },
getRolePermissions(id_) { getRolePermissions(id_) {
if (this.elements.indexOf("3-3")==-1) return if (this.elements.indexOf("3-3") == -1) return
this.$request("get", "/identity/get_permissions/" + id_, null, this, (data) => { a(data.data) }) this.$request("get", "/identity/get_permissions/" + id_, null, this, (data) => { a(data.data) })
this.select_element = [] this.select_element = []
const a = (Permissions) => { const a = (Permissions) => {
...@@ -187,7 +189,7 @@ export default { ...@@ -187,7 +189,7 @@ export default {
// } // }
// 编辑权限2,删除权限3,操作栏4 // 编辑权限2,删除权限3,操作栏4
elements(value) { elements(value) {
if (value.indexOf('3-2') != -1 && this.columns.findIndex(each=>{return each.title=='编辑'})==-1) { if (value.indexOf('3-2') != -1 && this.columns.findIndex(each => { return each.title == '编辑' }) == -1) {
this.columns.push({ this.columns.push({
title: '编辑', title: '编辑',
slot: 'action', slot: 'action',
...@@ -201,7 +203,7 @@ export default { ...@@ -201,7 +203,7 @@ export default {
} }
}, },
created() { created() {
this.$getElements(this.page_id,this,(data)=>this.elements=data.data) this.$getElements(this.page_id, this, (data) => this.elements = data.data)
this.getMenu(); this.getMenu();
this.getRole(); this.getRole();
} }
......
<template>
<PageHeader :title="title">
</PageHeader>
<div style="margin-top: 20px">
<Divider orientation="left">发送邮件</Divider>
<RadioGroup v-model="buttonSize" type="button">
<Radio label="large" @click="showMoadl('获批')">制作并发送获批信</Radio>
<Radio label="default" @click="showMoadl('拒签')">制作并发送拒签信</Radio>
<Radio label="small" @click="showMoadl('补件')">制作并发送补件信</Radio>
</RadioGroup>
<Divider orientation="left">模拟影刀</Divider>
<Button @click="modal2 = true">制作visa并发送</Button>
<Modal :title="Ty.title" v-model="modal" class-name="vertical-center-modal" @on-cancel="closeShow">
<Form ref="letterRef" :model="letterInfo" :rules="letterRule" :label-width="80">
<FormItem label="姓名" prop="name">
<Input v-model="letterInfo.name" placeholder="请输入用户姓名"></Input>
</FormItem>
<FormItem label="档案号" prop="fileNumber">
<Input v-model="letterInfo.fileNumber" placeholder="请输入档案号"></Input>
</FormItem>
<FormItem v-if="Ty.getday" :label="Ty.getday">
<DatePicker type="date" :placeholder="'请输入' + Ty.getday" v-model="letterInfo.getday"></DatePicker>
</FormItem>
<FormItem v-if="Ty.deadline" :label="Ty.deadline">
<DatePicker type="date" placeholder="请输入缴费截至日期" v-model="letterInfo.deadline"></DatePicker>
</FormItem>
<FormItem label="环境" prop="environment">
<Select v-model="letterInfo.environment">
<Option v-for="item in environment" :value="item.id" :key="item.id">{{ item.type }}</Option>
</Select>
</FormItem>
</Form>
<template #footer>
<Button @click="closeShow()">取消</Button>
<Button :disabled="letterButton" type="primary" @click="send()">发送</Button>
</template>
</Modal>
<Modal title="电子签证" v-model="modal2" class-name="vertical-center-modal" @on-cancel="closeShow2">
<Form ref="visaRef" :model="visaInfo" :rules="visaRule" :label-width="80">
<FormItem label="姓名" prop="name">
<Input v-model="visaInfo.name" placeholder="请输入用户姓名"></Input>
</FormItem>
<FormItem label="档案号" prop="file_number">
<Input v-model="visaInfo.file_number" placeholder="请输入档案号"></Input>
</FormItem>
<FormItem label="订单号" prop="order_id">
<Input v-model="visaInfo.order_id" placeholder="请输入订单号"></Input>
</FormItem>
<FormItem label="赴港证件" prop="go_type">
<Select v-model="visaInfo.go_type">
<Option v-for="item in pass" :value="item.type">{{ item.name }}</Option>
</Select>
</FormItem>
<FormItem label="缴费时间">
<DatePicker type="date" placeholder="请输入缴费时间" v-model="visaInfo.pay_time"></DatePicker>
</FormItem>
<FormItem label="签证激活截止日期">
<DatePicker type="date" placeholder="请输入签证激活截止日期(首次赴港拘留期限)" v-model="visaInfo.deadline">
</DatePicker>
</FormItem>
<FormItem label="环境" prop="environment">
<Select v-model="visaInfo.environment">
<Option v-for="item in environment" :value="item.id" :key="item.id">{{ item.type }}</Option>
</Select>
</FormItem>
</Form>
<template #footer>
<Button @click="closeShow2()">取消</Button>
<Button :disabled="visaButton" type="primary" @click="send2()">发送</Button>
</template>
</Modal>
</div>
</template>
<script setup>
import { ref, getCurrentInstance, reactive, watch } from 'vue'
const { proxy, ctx } = getCurrentInstance()
let Message = proxy.$Message
let http = proxy.$request
const page_id = ref(22)
let title = ref("邮件工具")
let modal = ref(false)
let modal2 = ref(false)
let senType = ref(null)
let letterButton=ref(false)
let visaButton=ref(false)
const Ty = reactive({
title: null,
getday: null,
deadline: null
})
const letterRef = ref(null)
const visaRef = ref(null)
const letterInfo = reactive(
{
name: null,
fileNumber: null,
deadline: null,
getday: null,
environment: 1
})
const letterRule = reactive({
name: { required: true, message: '姓名必填', trigger: 'blur' },
fileNumber: { required: true, message: '档案号必填', trigger: 'blur' },
environment: { type:"number",required: true, message: '环境必填', trigger: 'change' },
})
const visaInfo = reactive({
name: null,
file_number: null,
go_type: null,
pay_time: null,
deadline: null,
stay_month: null,
order_id: null,
environment: 1
})
const visaRule = reactive({
name: { required: true, message: '姓名必填', trigger: 'blur' },
file_number: { required: true, message: '档案号必填', trigger: 'blur' },
go_type: { required: true, message: '赴港证件类型必填', trigger: 'change' },
order_id: { required: true, message: '订单号必填', trigger: 'blur' },
environment: {type:"number",required: true, message: '环境必填', trigger: 'change' },
})
const pass = reactive([
{
name: "港澳通行证",
type: "passcard"
}, {
name: "护照",
type: "passport"
}
])
function resetletterInfo() {
Object.assign(letterInfo, {
name: null,
fileNumber: null,
deadline: null,
getday: null,
environment: 1
})
}
function resetVisaInfo() {
Object.assign(visaInfo, {
name: null,
file_number: null,
go_type: null,
pay_time: null,
deadline: null,
stay_month: null,
order_id: null,
environment: 1
})
}
watch(() => senType.value,
(newVal, oldval) => {
switch (newVal) {
case '获批':
Ty.title = '制作并发送获批信'
Ty.getday = '获批日期'
Ty.deadline = "缴费截至日期"
break
case '拒签':
Ty.title = '制作并发送拒签信'
Ty.getday = '拒签日期'
Ty.deadline = null
break
case '补件':
Ty.title = '制作并发送补件信'
Ty.getday = null
Ty.deadline = "补件日期"
break
default:
Ty.title = null
Ty.getday = null
break
}
})
const environment = reactive(
[{
type: "测试环境",
id: 1
}, {
type: "线上环境",
id: 2
}
]
)
function showMoadl(type) {
senType.value = type
modal.value = true
}
function closeShow() {
resetletterInfo()
modal.value = false
}
function closeShow2() {
resetVisaInfo()
modal2.value = false
}
function send() {
letterRef.value.validate((valid) => {
if (valid) {
letterButton.value=true
http('post', '/tool/makesendletter', { ...letterInfo, type: senType.value }, null, () => {
Message.success('发送成功');
letterButton.value=false
},()=>{
letterButton.value=false
})
} else {
this.$Message.error('请完善信息!');
}
})
}
function send2() {
visaRef.value.validate((valid) => {
if (valid) {
visaButton.value=true
http('post', '/tool/makesendvisa', visaInfo, null, () => {
Message.success('发送成功');
visaButton.value=false
},()=>{
visaButton.value=false
})
} else {
this.$Message.error('请完善信息!');
}
})
}
</script>
<style>
.vertical-center-modal {
display: flex;
align-items: center;
justify-content: center;
}
.vertical-center-modal .ivu-modal {
top: 0;
}
</style>
\ No newline at end of file
<template>
<div class="dnd-flow" @drop="onDrop" :nodes="nodes" @dragover="onDragOver" @dragleave="onDragLeave">
<VueFlow>
<div class="dropzone-background" :style="{
backgroundColor: isDragOver ? '#e7f3ff' : 'transparent',
transition: 'background-color 0.2s ease',
}">
<Background :size="2" :gap="20" pattern-color="#BDBDBD">
<div class="overlay">
<slot></slot>
</div>
</Background>
<!-- <template #node-apinode="{aprops}">
<ApiNode :data="aprops.data"></ApiNode>
</template> -->
<!-- <template #node-whilenode="props">
<WhileNode :data="props.data"></WhileNode>
</template> -->
<Controls />
<p v-if="isDragOver">移动到此处</p>
</div>
</VueFlow>
<aside>
<Tabs>
<TabPane label="节点" icon="logo-apple">
<div class="nodes">
<div class="vue-flow__node-input" :draggable="true" @dragstart="onDragStart($event, 'input')">
输入</div>
<div class="vue-flow__node-default" :draggable="true"
@dragstart="onDragStart($event, 'apinode')">接口
</div>
<div class="vue-flow__node-default" :draggable="true"
@dragstart="onDragStart($event, 'default')">数据库
</div>
<div class="vue-flow__node-default" :draggable="true"
@dragstart="onDragStart($event, 'default')">for each
</div>
<div class="vue-flow__node-output" :draggable="true" @dragstart="onDragStart($event, 'whilenode')">
循环
</div>
</div>
</TabPane>
<TabPane label="块" icon="logo-windows">标签二的内容</TabPane>
<TabPane label="线" icon="logo-tux">标签三的内容</TabPane>
<TabPane label="导出" icon="logo-tux">标签三的内容</TabPane>
</Tabs>
</aside>
</div>
</template>
<script setup>
import { ref, watch } from 'vue'
import { VueFlow, useVueFlow } from '@vue-flow/core'
import {ApiNode } from './myNodeTypes/ApiNode.vue'
import {WhileNode } from './myNodeTypes/WhileNode.vue'
import { Background } from '@vue-flow/background'
import { Controls } from '@vue-flow/controls'
// import SpecialNode from './components/SpecialNode.vue'
// import SpecialEdge from './components/SpecialEdge.vue'
const { onConnect, addEdges, addNodes, screenToFlowCoordinate, onNodesInitialized, updateNode } = useVueFlow()
const nodes = ref([])
onConnect(addEdges)
let id = 0
function getId() {
return `测试节点${id++}`
}
const state = {
draggedType: ref(null),
isDragOver: ref(false),
isDragging: ref(false)
}
const { draggedType, isDragOver, isDragging } = state
watch(isDragging, (dragging) => {
document.body.style.userSelect = dragging ? 'none' : ''
})
function onDragStart(event, type) {
if (event.dataTransfer) {
event.dataTransfer.setData('application/vueflow', type)
event.dataTransfer.effectAllowed = 'move'
}
draggedType.value = type
isDragging.value = true
document.addEventListener('drop', onDragEnd)
}
function onDragOver(e) {
e.preventDefault()
if (draggedType.value) {
isDragOver.value = true
if (e.dataTransfer) {
e.dataTransfer.dataTransfer = 'move'
}
}
}
function onDragLeave() {
isDragOver.value = false
}
function onDragEnd() {
isDragging.value = false
isDragOver.value = false
draggedType.value = null
document.removeEventListener('drop', onDragEnd)
}
function onDrop(event) {
const position = screenToFlowCoordinate({
x: event.clientX,
y: event.clientY,
})
const nodeId = getId()
const newNode = {
id: nodeId,
type: draggedType.value,
position,
data: { label: nodeId }
}
const { off } = onNodesInitialized(() => {
updateNode(nodeId, node => ({
position: { x: node.position.x - node.dimensions.width / 2, y: node.position.y - node.dimensions.height / 2 },
}))
off()
})
addNodes(newNode)
}
// these are our edges
</script>
<style>
/* import the necessary styles for Vue Flow to work */
@import '@vue-flow/core/dist/style.css';
/* import the default theme, this is optional but generally recommended */
@import '@vue-flow/core/dist/theme-default.css';
@import '@vue-flow/node-resizer/dist/style.css';
@import '@vue-flow/controls/dist/style.css';
html,
body,
#app {
margin: 0;
height: 100%;
}
/* #app {
text-transform: uppercase;
font-family: 'JetBrains Mono', monospace;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
} */
.vue-flow__minimap {
transform: scale(75%);
transform-origin: bottom right;
}
.dnd-flow {
flex-direction: column;
display: flex;
height: 100%
}
.dnd-flow aside {
color: #fff;
font-weight: 700;
border-right: 1px solid #eee;
padding: 15px 10px;
font-size: 12px;
background: #10b981bf;
-webkit-box-shadow: 0px 5px 10px 0px rgba(0, 0, 0, .3);
box-shadow: 0 5px 10px #0000004d
}
.dnd-flow aside .nodes>* {
margin-bottom: 10px;
cursor: grab;
font-weight: 500;
-webkit-box-shadow: 5px 5px 10px 2px rgba(0, 0, 0, .25);
box-shadow: 5px 5px 10px 2px #00000040
}
.dnd-flow aside .description {
margin-bottom: 10px
}
.dnd-flow .vue-flow-wrapper {
flex-grow: 1;
height: 100%
}
@media screen and (min-width: 640px) {
.dnd-flow {
flex-direction: row
}
.dnd-flow aside {
min-width: 25%
}
}
@media screen and (max-width: 639px) {
.dnd-flow aside .nodes {
display: flex;
flex-direction: row;
gap: 5px
}
}
.dropzone-background {
position: relative;
height: 100%;
width: 100%
}
.dropzone-background .overlay {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
z-index: 1;
pointer-events: none
}
</style>
\ No newline at end of file
...@@ -10,17 +10,21 @@ ...@@ -10,17 +10,21 @@
</div> </div>
</Upload> </Upload>
<div> <div>
<Select filterable v-model="project" style="width:200px" placeholder="项目"> <Select filterable v-model="project" style="width:200px" placeholder="项目" @on-change="getview">
<Option v-for="item in projects" :value="item.id" :key="item.id">{{ <Option v-for="item in projects" :value="item.id" :key="item.id">{{
item.name }}</Option> item.name }}</Option>
</Select>
<Select filterable v-model="views" style="width:200px" placeholder="面板">
<Option v-for="item in views" :value="item.id" :key="item.id">{{
item.name }}</Option>
</Select> </Select>
<Button type="primary" @click="upload()" style="margin-left: 10px;">上传</Button> <Button type="primary" @click="upload()" style="margin-left: 10px;">上传</Button>
</div> </div>
<div style="margin-top: 10px;"> <div style="margin-top: 10px;">
<Row v-for="item in uploadhistory"> <Row v-for="item in uploadhistory">
<Col span="8" offset="1">{{ item.filename + "(" + item.project + ")" + (item.case_count <Col span="8" offset="1">{{ item.filename + "(" + item.project + ")" + (item.case_count
? (" -- " + item.case_count + ? (" -- " + item.case_count +
"条") : "") }} "条") : "") }}
</Col> </Col>
<Col span="12"> <Col span="12">
<Steps :current="item.step" <Steps :current="item.step"
...@@ -38,6 +42,7 @@ ...@@ -38,6 +42,7 @@
</template> </template>
<script> <script>
export default { export default {
props: ['isCollapsed',], props: ['isCollapsed',],
data() { data() {
...@@ -46,7 +51,9 @@ export default { ...@@ -46,7 +51,9 @@ export default {
title: "上传用例", title: "上传用例",
file: null, file: null,
project: null, project: null,
view: null,
projects: [], projects: [],
views: [],
uploadhistory: [], uploadhistory: [],
runupload: [], runupload: [],
total: 0, total: 0,
...@@ -69,8 +76,10 @@ export default { ...@@ -69,8 +76,10 @@ export default {
const formData = new FormData(); const formData = new FormData();
if (!this.file) return this.$Message.error("请上传xmind用例文件"); if (!this.file) return this.$Message.error("请上传xmind用例文件");
if (!this.project) return this.$Message.error("请选择项目"); if (!this.project) return this.$Message.error("请选择项目");
if (!this.view) return this.$Message.error("请选择面板");
formData.append('file', this.file); formData.append('file', this.file);
formData.append("project", this.project); formData.append("project", this.project);
formData.append("view", this.view);
formData.append("projectName", this.projects[this.projects.findIndex(ele => { return ele.id == this.project })].name); formData.append("projectName", this.projects[this.projects.findIndex(ele => { return ele.id == this.project })].name);
this.$http.post('/tool/testcase/upload', formData, { this.$http.post('/tool/testcase/upload', formData, {
headers: { headers: {
...@@ -86,6 +95,9 @@ export default { ...@@ -86,6 +95,9 @@ export default {
getprojects() { getprojects() {
this.$request('get', '/tool/testport/getproject', null, this, (data) => { this.projects = data.data }) this.$request('get', '/tool/testport/getproject', null, this, (data) => { this.projects = data.data })
}, },
getview(project) {
this.$request('get', 'tool/testport/view/' + project, null, this, (data) => { this.views = data.data })
},
getuploadhistory() { getuploadhistory() {
this.$request('get', '/tool/testcase/uploadhistory', this.pageinfo, this, (data) => { this.uploadhistory = data.data.rows; this.total = data.data.total }) this.$request('get', '/tool/testcase/uploadhistory', this.pageinfo, this, (data) => { this.uploadhistory = data.data.rows; this.total = data.data.total })
} }
...@@ -115,6 +127,13 @@ export default { ...@@ -115,6 +127,13 @@ export default {
this.runupload = a this.runupload = a
} }
}, },
project:{
Handle(value){
if (this.view){
this.view=null
}
}
},
runupload(newvalue, oldvalue) { runupload(newvalue, oldvalue) {
newvalue.forEach(ele => { newvalue.forEach(ele => {
if (!oldvalue.includes(ele)) this.$socket.emit("join", ele) if (!oldvalue.includes(ele)) this.$socket.emit("join", ele)
......
<script setup>
import { computed } from 'vue'
import { BaseEdge, EdgeLabelRenderer, getBezierPath, useVueFlow } from '@vue-flow/core'
const props = defineProps()
const { removeEdges } = useVueFlow()
const path = computed(() => getBezierPath(props))
</script>
<script>
export default {
inheritAttrs: false,
}
</script>
<template>
<BaseEdge :path="path[0]" />
<EdgeLabelRenderer>
<div
:style="{
pointerEvents: 'all',
position: 'absolute',
transform: `translate(-50%, -50%) translate(${path[1]}px,${path[2]}px)`,
}"
class="nodrag nopan"
>
<button class="edgebutton" @click="removeEdges(id)">×</button>
</div>
</EdgeLabelRenderer>
</template>
<style>
.edgebutton {
border-radius: 999px;
cursor: pointer;
}
.edgebutton:hover {
box-shadow: 0 0 0 2px pink, 0 0 0 4px #f05f75;
}
</style>
<script setup>
import { Handle, Position } from '@vue-flow/core'
import { ref } from 'vue'
const counter = ref(0)
</script>
<template>
<div class="custom-node">
<Handle type="target" :position="Position.Top" />
<button class="increment nodrag" @click="counter++">遥远的东方</button>
<div v-if="counter > 0" class="counter">
<div class="count" v-for="count of counter" :key="`count-${count}`">{{ count }}</div>
</div>
</div>
</template>
<style>
.custom-node {
min-width: 100px;
gap: 4px;
padding: 8px;
background: white;
border: 1px solid black;
border-radius: 4px;
}
.increment {
border-radius: 4px;
background: #42b983;
font-size: 10px;
color: #fff;
cursor: pointer;
border: none;
}
.increment:hover {
box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
}
.counter {
margin-top: 8px;
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 4px;
}
.count {
font-size: 6px;
color: #ff0072;
border: 1px solid rgba(0, 0, 0, 0.3);
border-radius: 8px;
}
</style>
<script setup>
import { useVueFlow } from '@vue-flow/core'
const props = defineProps({
id: {
type: String,
required: true,
},
data: {
type: Object,
required: true,
},
})
const { updateNodeData } = useVueFlow()
function onSelect(color) {
updateNodeData(props.id, { color, isGradient: false })
const connectedEdges = getConnectedEdges(props.id)
for (const edge of connectedEdges) {
edge.style = {
stroke: color,
}
}
}
</script>
<template>
<div>接口哈哈哈</div>
</template>
\ No newline at end of file
<script setup>
import { useVueFlow,Handle,Position } from '@vue-flow/core'
const props = defineProps({
id: {
type: String,
required: true,
},
data: {
type: Object,
required: true,
},
})
const { updateNodeData } = useVueFlow()
function onSelect(color) {
updateNodeData(props.id, { color, isGradient: false })
const connectedEdges = getConnectedEdges(props.id)
for (const edge of connectedEdges) {
edge.style = {
stroke: color,
}
}
}
</script>
<template>
<div>接口哈哈哈</div>
<Handle type="target" :position="Position.Top" />
<Handle type="source" :position="Position.Bottom" />
</template>
\ No newline at end of file
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