提交 cdf371a7 编写于 作者: m0_58228130's avatar m0_58228130

Merge remote-tracking branch 'origin/main' into main

......@@ -27,19 +27,19 @@ compile_all: compile_win64 compile_win32 compile_linux compile_mac
compile_win64:
@echo 'start compile win64'
@CGO_ENABLED=1 GOOS=windows GOARCH=amd64 go build -o ${BIN_WIN64}ztf.exe cmd/server/main.go
@CGO_ENABLED=1 CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++ GOOS=windows GOARCH=amd64 go build -x -v -ldflags "-s -w" -o ${BIN_WIN64}${BINARY}.exe cmd/server/main.go
compile_win32:
@echo 'start compile win32'
@CGO_ENABLED=1 GOOS=windows GOARCH=386 go build -o ${BIN_WIN32}ztf.exe cmd/server/main.go
@CGO_ENABLED=1 CC=i686-w64-mingw32-gcc CXX=i686-w64-mingw32-g++ GOOS=windows GOARCH=386 go build -x -v -ldflags "-s -w" -o ${BIN_WIN32}${BINARY}.exe cmd/server/main.go
compile_linux:
@echo 'start compile linux'
CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build -o ${BIN_LINUX}ztf cmd/server/main.go
CGO_ENABLED=1 GOOS=linux GOARCH=amd64 CC=/usr/local/gcc-4.8.1-for-linux64/bin/x86_64-pc-linux-gcc CXX=/usr/local/gcc-4.8.1-for-linux64/bin/x86_64-pc-linux-g++ go build -o ${BIN_LINUX}${BINARY} cmd/server/main.go
compile_mac:
@echo 'start compile mac'
@CGO_ENABLED=1 GOOS=darwin GOARCH=amd64 go build -o ${BIN_MAC}ztf cmd/server/main.go
@CGO_ENABLED=1 GOOS=darwin GOARCH=amd64 go build -o ${BIN_MAC}${BINARY} cmd/server/main.go
copy_files:
@echo 'start copy files'
......
......@@ -9,7 +9,7 @@ module.exports = {
{
name: '@electron-forge/maker-squirrel',
config: {
name: 'ztf_client'
name: 'ztf'
}
},
{
......
此差异已折叠。
......@@ -7,6 +7,10 @@
"scripts": {
"start": "NODE_ENV=development electron-forge start",
"package": "electron-forge package",
"package-mac": "npm run package",
"package-linux": "npm run package -- --platform=linux",
"package-win64": "npm run package -- --platform=win32 --arch=ia32",
"package-win32": "npm run package -- --platform=win32 --arch=x64",
"make": "electron-forge make",
"publish": "electron-forge publish",
"lint": "echo \"No linting configured\""
......@@ -30,6 +34,7 @@
"@vercel/webpack-asset-relocator-loader": "^1.7.0",
"css-loader": "^6.5.1",
"electron": "16.0.6",
"electron-packager": "^15.4.0",
"node-loader": "^2.0.0",
"style-loader": "^3.3.1"
},
......
......@@ -9,9 +9,9 @@ var (
LanguageEn = "en"
Language = LanguageZh
Verbose = true
IsRelease bool
ExeDir string
Verbose = true
IsRelease bool
//ExeDir string
WorkDir string
ExecLogDir string
LogDir string
......
......@@ -21,7 +21,7 @@ func LoadScriptTree(dir string) (asset serverDomain.TestAsset, err error) {
return
}
commonUtils.ChangeScriptForDebug(&dir)
//commonUtils.ChangeScriptForDebug(&dir)
asset = serverDomain.TestAsset{Path: dir, Title: fileUtils.GetDirName(dir), IsDir: true, Slots: iris.Map{"icon": "icon"}}
LoadScriptNodesInDir(dir, &asset, 0)
......
......@@ -33,7 +33,7 @@ func GetCasesByModule(productId int, moduleId int, projectPath string) (cases []
caseIdMap[id] = ""
}
commonUtils.ChangeScriptForDebug(&projectPath)
//commonUtils.ChangeScriptForDebug(&projectPath)
scriptUtils.GetScriptByIdsInDir(projectPath, caseIdMap, &cases)
return
......@@ -54,7 +54,7 @@ func GetCasesBySuite(productId int, suiteId int, projectPath string) (cases []st
caseIdMap[id] = ""
}
commonUtils.ChangeScriptForDebug(&projectPath)
//commonUtils.ChangeScriptForDebug(&projectPath)
scriptUtils.GetScriptByIdsInDir(projectPath, caseIdMap, &cases)
return
......@@ -75,7 +75,7 @@ func GetCasesByTask(productId int, taskId int, projectPath string) (cases []stri
caseIdMap[id] = ""
}
commonUtils.ChangeScriptForDebug(&projectPath)
//commonUtils.ChangeScriptForDebug(&projectPath)
scriptUtils.GetScriptByIdsInDir(projectPath, caseIdMap, &cases)
return
......
......@@ -7,13 +7,11 @@ import (
"github.com/aaronchen2k/deeptest/internal/pkg/consts"
commonUtils "github.com/aaronchen2k/deeptest/internal/pkg/lib/common"
"github.com/aaronchen2k/deeptest/internal/pkg/lib/display"
fileUtils "github.com/aaronchen2k/deeptest/internal/pkg/lib/file"
i118Utils "github.com/aaronchen2k/deeptest/internal/pkg/lib/i118"
logUtils "github.com/aaronchen2k/deeptest/internal/pkg/lib/log"
stdinUtils "github.com/aaronchen2k/deeptest/internal/pkg/lib/stdin"
"github.com/aaronchen2k/deeptest/internal/server/modules/v1/repo"
"github.com/fatih/color"
"os"
"reflect"
)
......@@ -21,16 +19,16 @@ type ConfigCtrl struct {
ProjectRepo *repo.ProjectRepo `inject:""`
}
func CheckConfigPermission() {
//err := syscall.Access(vari.ExeDir, syscall.O_RDWR)
err := fileUtils.MkDirIfNeeded(commConsts.ExeDir + "conf")
if err != nil {
msg := i118Utils.Sprintf("perm_deny", commConsts.ExeDir)
logUtils.ExecConsolef(color.FgRed, msg)
os.Exit(0)
}
}
//func CheckConfigPermission() {
// //err := syscall.Access(vari.ExeDir, syscall.O_RDWR)
//
// err := fileUtils.MkDirIfNeeded(commConsts.ExeDir + "conf")
// if err != nil {
// msg := i118Utils.Sprintf("perm_deny", commConsts.ExeDir)
// logUtils.ExecConsolef(color.FgRed, msg)
// os.Exit(0)
// }
//}
func InitScreenSize() {
w, h := display.GetScreenSize()
......
......@@ -13,7 +13,7 @@ func InitConfig() {
serverConfig.Init()
serverConfig.InitLog()
commandConfig.CheckConfigPermission()
//commandConfig.CheckConfigPermission()
// screen size
commandConfig.InitScreenSize()
......
......@@ -136,11 +136,11 @@ func AddSlashForUrl(url string) string {
return url
}
func ChangeScriptForDebug(dir *string) {
if !IsRelease() { // debug in ide
*dir = filepath.Join(*dir, "demo", "sample")
}
}
//func ChangeScriptForDebug(dir *string) {
// if !IsRelease() { // debug in ide
// *dir = filepath.Join(*dir, "demo", "sample")
// }
//}
func GetDebugParamForRun(args []string) (debug string, ret []string) {
index := -1
......
......@@ -213,39 +213,42 @@ func GetWorkDir() string { // where we run file in
return dir
}
func GetExeDir(workDir string) string { // where zd.exe file in
var dir string
arg1 := strings.ToLower(os.Args[0])
name := filepath.Base(arg1)
if strings.Index(name, "zd") == 0 && strings.Index(arg1, "go-build") < 0 {
p, _ := exec.LookPath(os.Args[0])
if strings.Index(p, string(os.PathSeparator)) > -1 {
dir = p[:strings.LastIndex(p, string(os.PathSeparator))]
}
} else { // debug
dir = workDir
}
dir, _ = filepath.Abs(dir)
dir = AddSepIfNeeded(dir)
return dir
}
func GetUserHome() (string, error) {
//func GetExeDir(workDir string) string { // where zd.exe file in
// var dir string
// arg1 := strings.ToLower(os.Args[0])
//
// name := filepath.Base(arg1)
// if strings.Index(name, "zd") == 0 && strings.Index(arg1, "go-build") < 0 {
// p, _ := exec.LookPath(os.Args[0])
// if strings.Index(p, string(os.PathSeparator)) > -1 {
// dir = p[:strings.LastIndex(p, string(os.PathSeparator))]
// }
// } else { // debug
// dir = workDir
// }
//
// dir, _ = filepath.Abs(dir)
// dir = AddSepIfNeeded(dir)
//
// return dir
//}
func GetUserHome() (dir string, err error) {
user, err := user.Current()
if nil == err {
return user.HomeDir, nil
}
dir = user.HomeDir
} else { // cross compile support
// cross compile support
if "windows" == runtime.GOOS {
return homeWindows()
if "windows" == runtime.GOOS { // windows
dir, err = homeWindows()
} else { // Unix-like system, so just assume Unix
dir, err = homeUnix()
}
}
// Unix-like system, so just assume Unix
return homeUnix()
dir = AddSepIfNeeded(dir)
return
}
func homeUnix() (string, error) {
......
......@@ -14,11 +14,15 @@ import (
func Init() {
commConsts.IsRelease = commonUtils.IsRelease()
commConsts.WorkDir = fileUtils.GetWorkDir()
commConsts.ExeDir = fileUtils.GetExeDir(commConsts.WorkDir)
//commConsts.ExeDir = fileUtils.GetExeDir(commConsts.WorkDir)
commConsts.WorkDir = GetServerWorDir()
if commConsts.IsRelease {
commConsts.Verbose = true
}
if commConsts.Verbose {
fmt.Printf("\nlaunch %s%s in %s\n", commConsts.ExeDir, commConsts.App, commConsts.WorkDir)
fmt.Printf("\nlaunch %s%s in %s\n", "", commConsts.App, commConsts.WorkDir)
}
v := viper.New()
......@@ -38,3 +42,13 @@ func Init() {
return
}
func GetServerWorDir() (ret string) {
home, _ := fileUtils.GetUserHome()
ret = filepath.Join(home, commConsts.App)
ret = fileUtils.AddPathSepIfNeeded(ret)
fileUtils.MkDirIfNeeded(ret)
return
}
......@@ -20,10 +20,15 @@ var (
// GetDB 数据库单例
func GetDB() *gorm.DB {
if db != nil {
return db
}
conn := DBFile()
dialector := sqlite.Open(conn)
db, err := gorm.Open(dialector, &gorm.Config{
var err error
db, err = gorm.Open(dialector, &gorm.Config{
SkipDefaultTransaction: false,
Logger: logger.Default.LogMode(logger.Info),
NamingStrategy: schema.NamingStrategy{
......
......@@ -2,6 +2,7 @@ package controller
import (
commConsts "github.com/aaronchen2k/deeptest/internal/comm/consts"
commDomain "github.com/aaronchen2k/deeptest/internal/comm/domain"
serverDomain "github.com/aaronchen2k/deeptest/internal/server/modules/v1/domain"
"github.com/aaronchen2k/deeptest/internal/server/modules/v1/model"
"github.com/aaronchen2k/deeptest/internal/server/modules/v1/service"
......@@ -17,25 +18,6 @@ func NewProjectCtrl() *ProjectCtrl {
return &ProjectCtrl{}
}
// Query 分页列表
func (c *ProjectCtrl) List(ctx iris.Context) {
var req serverDomain.ProjectReqPaginate
err := ctx.ReadQuery(&req)
if err != nil {
ctx.JSON(c.ErrResp(commConsts.ParamErr, err.Error()))
return
}
req.ConvertParams()
data, err := c.ProjectService.Paginate(req)
if err != nil {
ctx.JSON(c.ErrResp(commConsts.Failure, err.Error()))
return
}
ctx.JSON(c.SuccessResp(data))
}
// Create 添加
func (c *ProjectCtrl) Create(ctx iris.Context) {
req := model.Project{}
......@@ -75,7 +57,13 @@ func (c *ProjectCtrl) GetByUser(ctx iris.Context) {
projectPath := ctx.URLParam("currProject")
if projectPath == "" {
projectPath = commConsts.WorkDir
data := iris.Map{"projects": make([]model.Project, 0),
"currProject": model.Project{},
"currConfig": commDomain.ProjectConf{},
"scriptTree": serverDomain.TestAsset{}}
ctx.JSON(c.SuccessResp(data))
return
}
projects, currProject, currProjectConfig, scriptTree, err := c.ProjectService.GetByUser(projectPath)
......
......@@ -2,6 +2,7 @@ package controller
import (
commConsts "github.com/aaronchen2k/deeptest/internal/comm/consts"
serverDomain "github.com/aaronchen2k/deeptest/internal/server/modules/v1/domain"
"github.com/aaronchen2k/deeptest/internal/server/modules/v1/service"
"github.com/kataras/iris/v12"
)
......@@ -19,6 +20,11 @@ func NewTestExecCtrl() *TestExecCtrl {
func (c *TestExecCtrl) List(ctx iris.Context) {
projectPath := ctx.URLParam("currProject")
if projectPath == "" {
ctx.JSON(c.SuccessResp(make([]serverDomain.TestReportSummary, 0)))
return
}
data, err := c.TestExecService.List(projectPath)
if err != nil {
ctx.JSON(c.ErrResp(commConsts.Failure, err.Error()))
......
......@@ -4,6 +4,7 @@ import (
commConsts "github.com/aaronchen2k/deeptest/internal/comm/consts"
commDomain "github.com/aaronchen2k/deeptest/internal/comm/domain"
zentaoUtils "github.com/aaronchen2k/deeptest/internal/comm/helper/zentao"
serverDomain "github.com/aaronchen2k/deeptest/internal/server/modules/v1/domain"
"github.com/kataras/iris/v12"
)
......@@ -17,6 +18,10 @@ func NewZentaoCtrl() *ZentaoCtrl {
func (c *ZentaoCtrl) ListProduct(ctx iris.Context) {
projectPath := ctx.URLParam("currProject")
if projectPath == "" {
ctx.JSON(c.SuccessResp(make([]serverDomain.ZentaoProduct, 0)))
return
}
data, err := zentaoUtils.ListProduct(projectPath)
if err != nil {
......
......@@ -20,7 +20,6 @@ func (m *ProjectModule) Party() module.WebModule {
handler := func(index iris.Party) {
index.Use(middleware.InitCheck())
index.Get("/", m.ProjectCtrl.List).Name = "项目列表"
index.Post("/", m.ProjectCtrl.Create).Name = "创建项目"
index.Delete("/", m.ProjectCtrl.Delete).Name = "删除项目"
......
......@@ -99,7 +99,7 @@ func (s *ProjectService) GetByUser(currProjectPath string) (
}
name := fileUtils.GetDirName(currProjectPath)
newLocalProject := model.Project{Path: currProjectPath, Name: name}
newLocalProject := model.Project{Path: currProjectPath, Name: name, Type: commConsts.TestFunc}
_, err = s.ProjectRepo.Create(newLocalProject)
if err != nil {
......
<template>
<div>
<a-dropdown class="dropdown" :trigger="['click']">
<a class=" t-link-btn" @click.prevent>
<div v-if="projects.length == 0" class="create-link" @click="selectProject('')">
{{ t('create_project') }}
</div>
<a-dropdown v-if="projects.length > 0" class="dropdown">
<a class="t-link-btn" @click.prevent>
<span class="name">{{currProject.name}}</span>
<DownOutlined />
</a>
......@@ -21,7 +25,7 @@
<a-menu-divider />
<a-menu-item key="">
<div class="t-link name" @click="selectProject('')">{{ t('create') }}</div>
<div class="t-link name" @click="selectProject('')">{{ t('create_project') }}</div>
</a-menu-item>
</a-menu>
</template>
......@@ -145,6 +149,12 @@ export default defineComponent({
</script>
<style lang="less">
.create-link {
padding: 14px 10px;
width: 150px;
cursor: pointer;
text-align: right;
}
.dropdown {
display: inline-block;
padding: 13px 0;
......
......@@ -88,7 +88,6 @@ export default defineComponent({
// 右侧顶部是否固定
const headFixed = computed<boolean>(()=> store.state.global.headFixed);
// 左侧选择菜单key
const selectedKeys = computed<string[]>(()=>{
const selectedKey = getSelectLeftMenuPath(routeItem.value);
......
......@@ -81,6 +81,8 @@ export default {
'save_fail': 'Save failed.',
'wrong_url': 'Please input right ZenTao URL.',
'create_project': 'Create Project',
'pls_create_project': 'Please create project to continue.',
'pls_product': 'Please select product.',
'pls_lang': 'Please select language.',
'sync_success': 'Sync successfully.',
......
......@@ -82,6 +82,8 @@ export default {
'expand_all': '展开全部',
'collapse_all': '收缩全部',
'wrong_url': '请输入正确的的URL地址,以http或https开头。',
'create_project': '新建项目',
'pls_create_project': '请点击右上角链接新建项目',
'pls_product': '请选择产品',
'pls_lang': '请选择语言',
'sync_success': '同步成功',
......
<template>
<div v-if="!currProject.path">
<a-empty :image="simpleImage" :description="t('pls_create_project')"/>
</div>
<a-card :title="t('edit_config')">
<a-card v-if="currProject.path" :title="t('edit_config')">
<a-form :label-col="labelCol" :wrapper-col="wrapperCol">
<a-form-item :label="t('zentao_url')" v-bind="validateInfos.url">
<a-input v-model:value="model.url"
......@@ -75,7 +78,7 @@ import {defineComponent, ref, reactive, computed, watch, ComputedRef, Ref, toRaw
import { useI18n } from "vue-i18n";
import { Props, validateInfos } from 'ant-design-vue/lib/form/useForm';
import {message, Form, notification} from 'ant-design-vue';
import {message, Form, notification, Empty} from 'ant-design-vue';
import _ from "lodash";
const useForm = Form.useForm;
......@@ -122,6 +125,7 @@ interface ConfigFormSetupData {
deleteInterpreter: (item) => void;
updateFormCancel: () => void;
updateSubmit: (values: any, resetFields: (newValues?: Props | undefined) => void) => Promise<void>;
simpleImage: any
}
export default defineComponent({
......@@ -274,6 +278,7 @@ export default defineComponent({
editInterpreter,
deleteInterpreter,
updateSubmit,
simpleImage: Empty.PRESENTED_IMAGE_SIMPLE,
}
}
......
<template>
<div class="indexlayout-main-conent">
<a-card :bordered="false">
<template #title>
{{ t('test_exec') }}
</template>
<template #extra>
<div class="opt">
<template v-if="currProject.type === 'func'">
<a-button @click="execCase" type="primary">{{t('exec')}}{{t('case')}}</a-button>
<a-button @click="execModule" type="primary">{{t('exec')}}{{t('module')}}</a-button>
<a-button @click="execSuite" type="primary">{{t('exec')}}{{t('suite')}}</a-button>
<a-button @click="execTask" type="primary">{{t('exec')}}{{t('task')}}</a-button>
</template>
<template v-if="currProject.type === 'unit'">
<a-button @click="execUnit" type="primary">{{t('execute_unit_or_automated')}}</a-button>
</template>
</div>
</template>
<div>
<a-table
row-key="seq"
:columns="columns"
:data-source="models"
:loading="loading"
:pagination="false"
>
<template #seq="{ text }">
{{text}}
</template>
<template #execBy="{ record }">
{{ execBy(record) }}
</template>
<template #startTime="{ record }">
<span v-if="record.startTime">{{ momentTime(record.startTime) }}</span>
</template>
<template #duration="{ record }">
{{record.duration}}
</template>
<template #result="{ record }">
合计{{record.total}}
<span class="t-pass">{{record.pass}}{{percent(record.pass, record.total)}}{{ t('pass') }}</span>
<span class="t-fail">{{record.fail}}{{percent(record.fail, record.total)}}{{ t('fail') }}</span>
<span class="t-skip">{{record.skip}}{{percent(record.skip, record.total)}}{{ t('ignore') }}</span>
</template>
<template #action="{ record }">
<a-button @click="() => viewResult(record)" type="link" size="small">{{ t('view') }}</a-button>
<a-button @click="() => deleteExec(record)" type="link" size="small"
:loading="deleteLoading.includes(record.seq)">{{ t('delete') }}</a-button>
</template>
</a-table>
</div>
</a-card>
</div>
<div v-if="!currProject.path">
<a-empty :image="simpleImage" :description="t('pls_create_project')"/>
</div>
<div v-if="currProject.path" class="indexlayout-main-conent">
<a-card :bordered="false">
<template #title>
{{ t('test_exec') }}
</template>
<template #extra>
<div class="opt">
<template v-if="currProject.type === 'func'">
<a-button @click="execCase" type="primary">{{ t('exec') }}{{ t('case') }}</a-button>
<a-button @click="execModule" type="primary">{{ t('exec') }}{{ t('module') }}</a-button>
<a-button @click="execSuite" type="primary">{{ t('exec') }}{{ t('suite') }}</a-button>
<a-button @click="execTask" type="primary">{{ t('exec') }}{{ t('task') }}</a-button>
</template>
<template v-if="currProject.type === 'unit'">
<a-button @click="execUnit" type="primary">{{ t('execute_unit_or_automated') }}</a-button>
</template>
</div>
</template>
<div>
<a-table
row-key="seq"
:columns="columns"
:data-source="models"
:loading="loading"
:pagination="false"
>
<template #seq="{ text }">
{{ text }}
</template>
<template #execBy="{ record }">
{{ execBy(record) }}
</template>
<template #startTime="{ record }">
<span v-if="record.startTime">{{ momentTime(record.startTime) }}</span>
</template>
<template #duration="{ record }">
{{ record.duration }}
</template>
<template #result="{ record }">
合计{{ record.total }}
<span class="t-pass">{{ record.pass }}{{ percent(record.pass, record.total) }}{{ t('pass') }}</span>
<span class="t-fail">{{ record.fail }}{{ percent(record.fail, record.total) }}{{ t('fail') }}</span>
<span class="t-skip">{{ record.skip }}{{ percent(record.skip, record.total) }}{{ t('ignore') }}</span>
</template>
<template #action="{ record }">
<a-button @click="() => viewResult(record)" type="link" size="small">{{ t('view') }}</a-button>
<a-button @click="() => deleteExec(record)" type="link" size="small"
:loading="deleteLoading.includes(record.seq)">{{ t('delete') }}
</a-button>
</template>
</a-table>
</div>
</a-card>
</div>
</template>
<script lang="ts">
import {ComputedRef, defineComponent, ref, Ref, reactive, computed, onMounted, watch} from "vue";
import {computed, ComputedRef, defineComponent, onMounted, ref, Ref, watch} from "vue";
import {Execution} from '../data.d';
import {useStore} from "vuex";
import { message, Modal, Form } from "ant-design-vue";
const useForm = Form.useForm;
import {Empty, Form, message, Modal} from "ant-design-vue";
import {StateType} from "../store";
import {useRouter} from "vue-router";
import {momentTimeDef, percentDef} from "@/utils/datetime";
......@@ -74,6 +77,8 @@ import {hideMenu} from "@/utils/dom";
import throttle from "lodash.debounce";
import {useI18n} from "vue-i18n";
const useForm = Form.useForm;
interface ListExecSetupData {
t: (key: string | number) => string;
currProject: ComputedRef;
......@@ -81,168 +86,169 @@ interface ListExecSetupData {
columns: any;
models: ComputedRef<Execution[]>;
loading: Ref<boolean>;
list: () => void
list: () => void
viewResult: (item) => void;
deleteLoading: Ref<string[]>;
deleteExec: (item) => void;
deleteExec: (item) => void;
execCase: () => void;
execModule: () => void;
execSuite: () => void;
execTask: () => void;
execUnit: () => void;
execCase: () => void;
execModule: () => void;
execSuite: () => void;
execTask: () => void;
execUnit: () => void;
execBy: (item) => string;
momentTime: (tm) => string;
percent: (numb, total) => string;
simpleImage: any
}
export default defineComponent({
name: 'ExecListPage',
components: {
},
setup(): ListExecSetupData {
const { t } = useI18n();
const projectStore = useStore<{ project: ProjectData }>();
const currProject = computed<any>(() => projectStore.state.project.currProject);
const execBy = execByDef
const momentTime = momentTimeDef
const percent = percentDef
const columns =[
{
title: t('index'),
dataIndex: 'index',
width: 150,
customRender: ({text, index}: { text: any; index: number}) => index + 1,
},
{
title: t('exec_type'),
dataIndex: 'execBy',
slots: { customRender: 'execBy' },
},
{
title: t('exec_type'),
dataIndex: 'seq',
},
{
title: t('start_time'),
dataIndex: 'startTime',
slots: { customRender: 'startTime' },
},
{
title: t('duration'),
dataIndex: 'duration',
slots: { customRender: 'duration' },
},
{
title: t('result'),
dataIndex: 'result',
slots: { customRender: 'result' },
},
{
title: t('opt'),
key: 'action',
width: 260,
slots: { customRender: 'action' },
},
];
const router = useRouter();
const store = useStore<{ History: StateType}>();
const models = computed<any[]>(() => store.state.History.items);
const loading = ref<boolean>(true);
const list = throttle(async () => {
loading.value = true;
await store.dispatch('History/list', {});
loading.value = false;
}, 600)
list();
watch(currProject, (newProject, oldVal) => {
console.log('watch currProject', newProject)
list()
}, {deep: true})
onMounted(() => {
console.log('onMounted')
hideMenu(currProject.value) // jump from not available page for unittest
})
// 查看
const viewResult = (item) => {
router.push(`/exec/history/${item.testType}/${item.seq}`)
}
// 删除
const deleteLoading = ref<string[]>([]);
const deleteExec = (item) => {
Modal.confirm({
title: t('confirm_to_delete_result'),
okText: t('confirm'),
cancelText: t('cancel'),
onOk: async () => {
deleteLoading.value = [item.seq];
const res: boolean = await store.dispatch('History/delete', item.seq);
if (res === true) {
message.success(t('delete_success'));
await list();
}
deleteLoading.value = [];
name: 'ExecListPage',
components: {},
setup(): ListExecSetupData {
const {t} = useI18n();
const projectStore = useStore<{ project: ProjectData }>();
const currProject = computed<any>(() => projectStore.state.project.currProject);
const execBy = execByDef
const momentTime = momentTimeDef
const percent = percentDef
const columns = [
{
title: t('index'),
dataIndex: 'index',
width: 150,
customRender: ({text, index}: { text: any; index: number }) => index + 1,
},
{
title: t('exec_type'),
dataIndex: 'execBy',
slots: {customRender: 'execBy'},
},
{
title: t('exec_type'),
dataIndex: 'seq',
},
{
title: t('start_time'),
dataIndex: 'startTime',
slots: {customRender: 'startTime'},
},
{
title: t('duration'),
dataIndex: 'duration',
slots: {customRender: 'duration'},
},
{
title: t('result'),
dataIndex: 'result',
slots: {customRender: 'result'},
},
{
title: t('opt'),
key: 'action',
width: 260,
slots: {customRender: 'action'},
},
];
const router = useRouter();
const store = useStore<{ History: StateType }>();
const models = computed<any[]>(() => store.state.History.items);
const loading = ref<boolean>(true);
const list = throttle(async () => {
loading.value = true;
await store.dispatch('History/list', {});
loading.value = false;
}, 600)
list();
watch(currProject, (newProject, oldVal) => {
console.log('watch currProject', newProject)
list()
}, {deep: true})
onMounted(() => {
console.log('onMounted')
hideMenu(currProject.value) // jump from not available page for unittest
})
// 查看
const viewResult = (item) => {
router.push(`/exec/history/${item.testType}/${item.seq}`)
}
// 删除
const deleteLoading = ref<string[]>([]);
const deleteExec = (item) => {
Modal.confirm({
title: t('confirm_to_delete_result'),
okText: t('confirm'),
cancelText: t('cancel'),
onOk: async () => {
deleteLoading.value = [item.seq];
const res: boolean = await store.dispatch('History/delete', item.seq);
if (res === true) {
message.success(t('delete_success'));
await list();
}
});
}
const execCase = () => {
console.log("execCase")
router.push(`/exec/run/case/-/-`)
}
const execModule = () => {
console.log("execModule")
router.push(`/exec/run/module/0/0/-/-`)
}
const execSuite = () => {
console.log("execSuite")
router.push(`/exec/run/suite/0/0/-/-`)
}
const execTask = () => {
console.log("execSuite")
router.push(`/exec/run/task/0/0/-/-`)
}
const execUnit = () => {
console.log("execUnit")
router.push(`/exec/run/unit`)
}
return {
t,
currProject,
columns,
models,
loading,
list,
viewResult,
deleteLoading,
deleteExec,
execCase,
execModule,
execSuite,
execTask,
execUnit,
execBy,
momentTime,
percent,
}
deleteLoading.value = [];
}
});
}
const execCase = () => {
console.log("execCase")
router.push(`/exec/run/case/-/-`)
}
const execModule = () => {
console.log("execModule")
router.push(`/exec/run/module/0/0/-/-`)
}
const execSuite = () => {
console.log("execSuite")
router.push(`/exec/run/suite/0/0/-/-`)
}
const execTask = () => {
console.log("execSuite")
router.push(`/exec/run/task/0/0/-/-`)
}
const execUnit = () => {
console.log("execUnit")
router.push(`/exec/run/unit`)
}
return {
t,
currProject,
columns,
models,
loading,
list,
viewResult,
deleteLoading,
deleteExec,
execCase,
execModule,
execSuite,
execTask,
execUnit,
execBy,
momentTime,
percent,
simpleImage: Empty.PRESENTED_IMAGE_SIMPLE,
}
}
})
</script>
......
<template>
TEST
</template>
<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({
name: 'Test',
components: {},
setup(props) {
return
}
})
</script>
<style lang="less" scoped>
</style>
\ No newline at end of file
<template>
<div class="indexlayout-main-conent">
<div v-if="!currProject.path">
<a-empty :image="simpleImage" :description="t('pls_create_project')"/>
</div>
<div v-if="currProject.path" class="indexlayout-main-conent">
<div v-if="currProject.type === 'unit'" class="panel">
{{ t('no_script_for_unittest') }}
</div>
......@@ -56,7 +60,7 @@ import {ProjectData} from "@/store/project";
import {ScriptData} from "../store";
import {resizeWidth} from "@/utils/dom";
import throttle from "lodash.debounce";
import {message, notification} from "ant-design-vue";
import {Empty, message, notification} from "ant-design-vue";
import {useI18n} from "vue-i18n";
interface ListScriptPageSetupData {
......@@ -74,6 +78,7 @@ interface ListScriptPageSetupData {
expandAll: (e) => void;
extract: () => void;
expandedKeys: Ref<string[]>
simpleImage: any
}
export default defineComponent({
......@@ -170,6 +175,7 @@ export default defineComponent({
tree,
expandedKeys,
script,
simpleImage: Empty.PRESENTED_IMAGE_SIMPLE,
}
}
......
<template>
<div v-if="currProject.type === 'unit'" class="panel">
{{ t('no_sync_for_unittest') }}
<div v-if="!currProject.path">
<a-empty :image="simpleImage" :description="t('pls_create_project')"/>
</div>
<div class="main" v-if="currProject.type === 'func'">
<a-card :title="t('sync_from_zentao')">
<a-form :label-col="labelCol" :wrapper-col="wrapperCol">
<a-form-item :label="t('product')" v-bind="validateInfos.productId">
<a-select v-model:value="model.productId" @change="selectProduct">
<a-select-option key="" value="">&nbsp;</a-select-option>
<a-select-option v-for="item in products" :key="item.id" :value="item.id">{{ item.name }}</a-select-option>
</a-select>
</a-form-item>
<a-form-item :label="t('module')" v-bind="validateInfos.moduleId">
<a-select v-model:value="model.moduleId">
<a-select-option key="" value="">&nbsp;</a-select-option>
<a-select-option v-for="item in modules" :key="item.id" :value="item.id"><span v-html="item.name"></span>
</a-select-option>
</a-select>
</a-form-item>
<a-form-item :label="t('suite')" v-bind="validateInfos.suiteId">
<a-select v-model:value="model.suiteId">
<a-select-option key="" value="">&nbsp;</a-select-option>
<a-select-option v-for="item in suites" :key="item.id" :value="item.id">{{ item.name }}</a-select-option>
</a-select>
</a-form-item>
<a-form-item :label="t('task')" v-bind="validateInfos.taskId">
<a-select v-model:value="model.taskId">
<a-select-option key="" value="">&nbsp;</a-select-option>
<a-select-option v-for="item in tasks" :key="item.id" :value="item.id">{{ item.name }}</a-select-option>
</a-select>
</a-form-item>
<a-form-item :label="t('lang')" v-bind="validateInfos.lang">
<a-select v-model:value="model.lang">
<a-select-option v-for="item in langs" :key="item.code" :value="item.code">{{ item.name }}</a-select-option>
</a-select>
</a-form-item>
<a-form-item :label="t('independent_expect')">
<a-switch v-model:checked="model.independentFile"/>
</a-form-item>
<a-form-item :wrapper-col="{ span: 14, offset: 4 }">
<a-button type="primary" @click.prevent="syncFromZentaoSubmit">{{ t('submit') }}</a-button>
<a-button style="margin-left: 10px" @click="resetFieldsFrom">{{ t('reset') }}</a-button>
</a-form-item>
</a-form>
</a-card>
<a-card :title="t('sync_to_zentao')">
<a-form :label-col="labelCol" :wrapper-col="wrapperCol">
<a-form-item :label="t('product')" v-bind="validateInfosCommit.productId">
<a-select v-model:value="modelCommit.productId">
<a-select-option key="" value="">&nbsp;</a-select-option>
<a-select-option v-for="item in products" :key="item.id" :value="item.id">{{ item.name }}</a-select-option>
</a-select>
</a-form-item>
<a-form-item :wrapper-col="{ span: 14, offset: 4 }">
<a-button type="primary" @click.prevent="syncToZentaoSubmit">{{ t('submit') }}</a-button>
<a-button style="margin-left: 10px" @click="resetFieldsTo">{{ t('reset') }}</a-button>
</a-form-item>
</a-form>
</a-card>
<div v-if="currProject.path">
<div v-if="currProject.type === 'unit'" class="panel">
{{ t('no_sync_for_unittest') }}
</div>
<div class="main" v-if="currProject.type === 'func'">
<a-card :title="t('sync_from_zentao')">
<a-form :label-col="labelCol" :wrapper-col="wrapperCol">
<a-form-item :label="t('product')" v-bind="validateInfos.productId">
<a-select v-model:value="model.productId" @change="selectProduct">
<a-select-option key="" value="">&nbsp;</a-select-option>
<a-select-option v-for="item in products" :key="item.id" :value="item.id">{{ item.name }}</a-select-option>
</a-select>
</a-form-item>
<a-form-item :label="t('module')" v-bind="validateInfos.moduleId">
<a-select v-model:value="model.moduleId">
<a-select-option key="" value="">&nbsp;</a-select-option>
<a-select-option v-for="item in modules" :key="item.id" :value="item.id"><span v-html="item.name"></span>
</a-select-option>
</a-select>
</a-form-item>
<a-form-item :label="t('suite')" v-bind="validateInfos.suiteId">
<a-select v-model:value="model.suiteId">
<a-select-option key="" value="">&nbsp;</a-select-option>
<a-select-option v-for="item in suites" :key="item.id" :value="item.id">{{ item.name }}</a-select-option>
</a-select>
</a-form-item>
<a-form-item :label="t('task')" v-bind="validateInfos.taskId">
<a-select v-model:value="model.taskId">
<a-select-option key="" value="">&nbsp;</a-select-option>
<a-select-option v-for="item in tasks" :key="item.id" :value="item.id">{{ item.name }}</a-select-option>
</a-select>
</a-form-item>
<a-form-item :label="t('lang')" v-bind="validateInfos.lang">
<a-select v-model:value="model.lang">
<a-select-option v-for="item in langs" :key="item.code" :value="item.code">{{ item.name }}</a-select-option>
</a-select>
</a-form-item>
<a-form-item :label="t('independent_expect')">
<a-switch v-model:checked="model.independentFile"/>
</a-form-item>
<a-form-item :wrapper-col="{ span: 14, offset: 4 }">
<a-button type="primary" @click.prevent="syncFromZentaoSubmit">{{ t('submit') }}</a-button>
<a-button style="margin-left: 10px" @click="resetFieldsFrom">{{ t('reset') }}</a-button>
</a-form-item>
</a-form>
</a-card>
<a-card :title="t('sync_to_zentao')">
<a-form :label-col="labelCol" :wrapper-col="wrapperCol">
<a-form-item :label="t('product')" v-bind="validateInfosCommit.productId">
<a-select v-model:value="modelCommit.productId">
<a-select-option key="" value="">&nbsp;</a-select-option>
<a-select-option v-for="item in products" :key="item.id" :value="item.id">{{ item.name }}</a-select-option>
</a-select>
</a-form-item>
<a-form-item :wrapper-col="{ span: 14, offset: 4 }">
<a-button type="primary" @click.prevent="syncToZentaoSubmit">{{ t('submit') }}</a-button>
<a-button style="margin-left: 10px" @click="resetFieldsTo">{{ t('reset') }}</a-button>
</a-form-item>
</a-form>
</a-card>
</div>
</div>
</template>
<script lang="ts">
......@@ -70,13 +75,14 @@ import {computed, ComputedRef, defineComponent, reactive, ref, watch} from "vue"
import {useI18n} from "vue-i18n";
import {validateInfos} from 'ant-design-vue/lib/form/useForm';
import {Form, notification} from 'ant-design-vue';
import {Empty, Form, notification} from 'ant-design-vue';
import {SyncSettings} from './data.d';
import {useStore} from "vuex";
import {ProjectData} from "@/store/project";
import {ZentaoData} from "@/store/zentao";
import {syncFromZentao, syncToZentao} from "@/views/sync/service";
import throttle from "lodash.debounce";
import {useRouter} from "vue-router";
const useForm = Form.useForm;
......@@ -108,6 +114,7 @@ interface ConfigFormSetupData {
validateCommit: any
validateInfosCommit: validateInfos
resetFieldsTo: () => void;
simpleImage: any
}
export default defineComponent({
......@@ -115,6 +122,7 @@ export default defineComponent({
components: {},
setup(props): ConfigFormSetupData {
const {t} = useI18n();
const router = useRouter();
const storeProject = useStore<{ project: ProjectData }>();
const currConfig = computed<any>(() => storeProject.state.project.currConfig);
......@@ -129,7 +137,9 @@ export default defineComponent({
const fetchProducts = throttle((): void => {
store.dispatch('zentao/fetchLangs')
store.dispatch('zentao/fetchProducts')
store.dispatch('zentao/fetchProducts').catch((error) => {
if (error.response.data.code === 2000) router.push(`/config`)
})
}, 600)
fetchProducts()
watch(currConfig, () => {
......@@ -257,6 +267,7 @@ export default defineComponent({
validateInfosCommit,
resetFieldsTo,
syncToZentaoSubmit,
simpleImage: Empty.PRESENTED_IMAGE_SIMPLE,
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册