Commit 30ec7c09 authored by 陈浩玮's avatar 陈浩玮

Merge branch 'feature/shuiluo' into 'master'

feat: 任务中心进度页面完成

See merge request product/kim3-web-vue/starter-web-vue!35
parents 010a1519 8e6cac78
...@@ -24,7 +24,6 @@ ...@@ -24,7 +24,6 @@
"core-js": "^3.6.5", "core-js": "^3.6.5",
"crypto-js": "^4.0.0", "crypto-js": "^4.0.0",
"date-fns": "^2.14.0", "date-fns": "^2.14.0",
"enquire.js": "^2.1.6",
"highlight.js": "^10.2.1", "highlight.js": "^10.2.1",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"mockjs": "^1.1.0", "mockjs": "^1.1.0",
...@@ -41,12 +40,12 @@ ...@@ -41,12 +40,12 @@
}, },
"devDependencies": { "devDependencies": {
"@ant-design/colors": "^4.0.1", "@ant-design/colors": "^4.0.1",
"@babel/eslint-parser": "^7.14.7",
"@vue/cli-plugin-babel": "^4.4.0", "@vue/cli-plugin-babel": "^4.4.0",
"@vue/cli-plugin-eslint": "^4.4.0", "@vue/cli-plugin-eslint": "^4.4.0",
"@vue/cli-service": "^4.4.0", "@vue/cli-service": "^4.4.0",
"@vuepress/plugin-back-to-top": "^1.5.2", "@vuepress/plugin-back-to-top": "^1.5.2",
"autoprefixer": "^9.8.6", "autoprefixer": "^9.8.6",
"babel-eslint": "^10.1.0",
"babel-plugin-transform-remove-console": "^6.9.4", "babel-plugin-transform-remove-console": "^6.9.4",
"babel-polyfill": "^6.26.0", "babel-polyfill": "^6.26.0",
"compression-webpack-plugin": "^2.0.0", "compression-webpack-plugin": "^2.0.0",
...@@ -74,7 +73,7 @@ ...@@ -74,7 +73,7 @@
"eslint:recommended" "eslint:recommended"
], ],
"parserOptions": { "parserOptions": {
"parser": "babel-eslint" "parser": "@babel/eslint-parser"
}, },
"rules": { "rules": {
"no-unused-vars": "off" "no-unused-vars": "off"
......
This diff is collapsed.
...@@ -5,9 +5,9 @@ ...@@ -5,9 +5,9 @@
</template> </template>
<script> <script>
import { enquireScreen } from './utils/commonUtil'; import { mapState } from 'vuex';
import { mapState, mapMutations } from 'vuex';
import { changeThemeColor } from '@/utils/themeUtil'; import { changeThemeColor } from '@/utils/themeUtil';
import langUtils from '@/utils/langUtils';
export default { export default {
name: 'App', name: 'App',
...@@ -18,15 +18,10 @@ export default { ...@@ -18,15 +18,10 @@ export default {
}, },
created() { created() {
this.setHtmlTitle(); this.setHtmlTitle();
this.setLanguage(this.lang); this.setLanguage();
enquireScreen(isMobile => this.setDevice(isMobile));
}, },
watch: { watch: {
lang(val) {
this.setLanguage(val);
this.setHtmlTitle();
},
$route() { $route() {
this.setHtmlTitle(); this.setHtmlTitle();
}, },
...@@ -44,12 +39,11 @@ export default { ...@@ -44,12 +39,11 @@ export default {
}, },
computed: { computed: {
//setting = mapStore.name //setting = mapStore.name
...mapState('settingModule', ['layout', 'theme', 'lang']), ...mapState('settingModule', ['layout', 'theme']),
}, },
methods: { methods: {
...mapMutations('settingModule', ['setDevice']), setLanguage() {
const lang = langUtils.get();
setLanguage(lang) {
this.$i18n.locale = lang; this.$i18n.locale = lang;
switch (lang) { switch (lang) {
case 'zh_CN': case 'zh_CN':
......
import { postReq, putReq } from '@/utils'; import { getReq, postReq, putReq } from '@/utils';
export function addTaskApi(data) { export function addTaskApi(data) {
return postReq('/api/v1/schedules', data); return postReq('/api/v1/schedules', data);
...@@ -7,3 +7,7 @@ export function addTaskApi(data) { ...@@ -7,3 +7,7 @@ export function addTaskApi(data) {
export function updateTaskApi(data) { export function updateTaskApi(data) {
return putReq('/api/v1/schedules', data); return putReq('/api/v1/schedules', data);
} }
export function getRangerInspectionTaskDetailApi(id) {
return getReq(`/ranger/inspection/api/v1/jobs/tasks/${id}`);
}
<template> <template>
<a-select <a-select
show-search show-search
class="tw-w-full"
placeholder="input search text" placeholder="input search text"
:default-active-first-option="false" :default-active-first-option="false"
:show-arrow="false" :show-arrow="false"
......
<template> <template>
<a-layout-sider <a-layout-sider
:theme="sideTheme" :theme="sideTheme"
:class="['side-menu', 'beauty-scroll', isMobile ? null : 'shadow']" :class="['side-menu', 'beauty-scroll']"
width="256px" width="256px"
:collapsible="collapsible" :collapsible="collapsible"
v-model="collapsed" v-model="collapsed"
...@@ -49,15 +49,12 @@ export default { ...@@ -49,15 +49,12 @@ export default {
sideTheme() { sideTheme() {
return this.theme == 'light' ? this.theme : 'dark'; return this.theme == 'light' ? this.theme : 'dark';
}, },
...mapState('settingModule', ['isMobile', 'systemName']), ...mapState('settingModule', ['systemName']),
}, },
}; };
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.shadow {
box-shadow: 2px 0 6px rgba(0, 21, 41, 0.35);
}
.side-menu { .side-menu {
min-height: 100vh; min-height: 100vh;
overflow-y: auto; overflow-y: auto;
......
<template>
<div class="tw-flex tw-items-center tw-flex-1 tw-pr-3" :class="$style.container">
<label :class="$style.label">{{ label }}</label>
<slot />
</div>
</template>
<script>
export default {
props: {
label: String,
},
};
</script>
<style module lang="less">
.container:last-child {
min-width: 250px;
}
.label {
color: rgba(0, 0, 0, 0.85);
width: 6em;
text-align: right;
margin-right: 1em;
&::after {
content: ':';
}
}
</style>
<template> <template>
<div> <div :style="`min-width: ${width}px`" class="tw-overflow-x-auto">
<my-card v-if="$scopedSlots.search" class="tw-mb-2.5"> <my-card v-if="$scopedSlots.search" class="tw-mb-2.5">
<a-form-model :model="queryForm" layout="horizontal"> <div class="tw-flex">
<a-row :gutter="16">
<slot name="search" :query="queryForm" /> <slot name="search" :query="queryForm" />
</a-row> </div>
</a-form-model>
<div class="tw-text-right tw-mt-2"> <div class="tw-text-right tw-mt-2">
<a-space> <a-space>
<a-popover v-if="$scopedSlots.moreSearch" trigger="click">
<template slot="content">
<div :class="$style.moreSearch">
<slot name="moreSearch" :query="queryForm" />
</div>
</template>
<a-button>更多查询</a-button>
</a-popover>
<a-button @click="reset">重置</a-button> <a-button @click="reset">重置</a-button>
<a-button type="primary" @click="getData">查询</a-button> <a-button type="primary" @click="getData">查询</a-button>
</a-space> </a-space>
</div> </div>
</my-card> </my-card>
<my-card> <my-card :class="noPadding ? 'tw-p-0' : ''">
<a-space class="tw-mb-2"> <a-space class="tw-mb-2">
<a-button type="primary" v-if="newBtn" @click="addBtnClick"> <a-button type="primary" v-if="newBtn" @click="addBtnClick">
{{ newBtn.text || '新增' }} {{ newBtn.text || '新增' }}
...@@ -27,32 +33,39 @@ ...@@ -27,32 +33,39 @@
:data-source="data" :data-source="data"
:loading="loading" :loading="loading"
v-bind="$attrs" v-bind="$attrs"
:scroll="scroll"
:rowKey="rowKey" :rowKey="rowKey"
:pagination="pagination" :pagination="pagination"
@change="pageChange" @change="pageChange"
:row-selection="selected ? rowSelection : undefined" :row-selection="selected ? rowSelection : undefined"
> >
<slot /> <slot />
<a-table-column title="操作" v-if="buttons"> <a-table-column
:title="newButtons.title"
v-if="this.newButtons"
v-bind="this.newButtons.options"
>
<template #default="row"> <template #default="row">
<my-ac-btn :row="row" :buttons="buttons" /> <my-ac-btn :row="row" :buttons="newButtons.data" />
</template> </template>
</a-table-column> </a-table-column>
</a-table> </a-table>
</my-card> </my-card>
<a-drawer <a-drawer
v-if="$scopedSlots.drawer"
placement="right" placement="right"
:visible="visible" :visible="visible"
:drawerStyle="drawerStyle" :drawerStyle="drawerStyle"
:bodyStyle="bodyStyle" :bodyStyle="bodyStyle"
destroyOnClose destroyOnClose
:width="600" :width="drawerWidth"
@close="hidden" @close="hidden"
:maskClosable="false" :maskClosable="false"
:title="title" :title="title"
:afterVisibleChange="afterVisibleChange"
> >
<slot name="drawer" :hidden="hidden" :refresh="getData" /> <slot name="drawer" :hidden="hidden" :refresh="getData" :type="type" :row="row" />
</a-drawer> </a-drawer>
</div> </div>
</template> </template>
...@@ -60,6 +73,8 @@ ...@@ -60,6 +73,8 @@
<script> <script>
import { request, METHOD } from '@/utils/requestUtil'; import { request, METHOD } from '@/utils/requestUtil';
const assign = Object.assign;
const initQuery = { const initQuery = {
pageSize: 10, pageSize: 10,
pageNum: 1, pageNum: 1,
...@@ -71,11 +86,18 @@ export default { ...@@ -71,11 +86,18 @@ export default {
props: { props: {
url: String, url: String,
addBtn: [Object, Boolean], addBtn: [Object, Boolean],
buttons: Array, buttons: [Array, Object],
noPage: Boolean, noPage: Boolean,
formatData: Function, formatData: Function,
rowKey: [String, Function], rowKey: [String, Function],
selected: Array, selected: Array,
drawerWidth: {
type: Number,
default: 600,
},
noPadding: Boolean,
scroll: Object,
width: { type: Number, default: 900 },
}, },
data() { data() {
...@@ -99,6 +121,8 @@ export default { ...@@ -99,6 +121,8 @@ export default {
flex: 1, flex: 1,
overflow: 'hidden', overflow: 'hidden',
}, },
type: null,
row: null,
}; };
}, },
...@@ -110,6 +134,13 @@ export default { ...@@ -110,6 +134,13 @@ export default {
newBtn() { newBtn() {
return this.addBtn ? (typeof this.addBtn === 'object' ? this.addBtn : {}) : this.addBtn; return this.addBtn ? (typeof this.addBtn === 'object' ? this.addBtn : {}) : this.addBtn;
}, },
newButtons() {
return this.buttons
? Array.isArray(this.buttons)
? { data: this.buttons, title: '操作' }
: this.buttons
: null;
},
pagination() { pagination() {
return this.noPage return this.noPage
? false ? false
...@@ -160,12 +191,18 @@ export default { ...@@ -160,12 +191,18 @@ export default {
hidden() { hidden() {
this.visible = false; this.visible = false;
},
afterVisibleChange(visible) {
if (!visible) {
this.title = this.addBtn?.title ?? defaultTitle; this.title = this.addBtn?.title ?? defaultTitle;
this.type = null;
this.row = null;
}
}, },
show({ title } = {}) { show(params) {
this.visible = true; this.visible = true;
if (title) this.title = title; assign(this, params);
}, },
reset() { reset() {
...@@ -177,12 +214,22 @@ export default { ...@@ -177,12 +214,22 @@ export default {
addBtnClick() { addBtnClick() {
const { click } = typeof this.addBtn === 'object' ? this.addBtn : {}; const { click } = typeof this.addBtn === 'object' ? this.addBtn : {};
click && click(); click && click();
this.type = 'add';
this.visible = true; this.visible = true;
}, },
getFormRef(ref) {
console.log(ref);
},
}, },
}; };
</script> </script>
<style module lang="less">
.moreSearch {
display: flex;
flex-direction: column;
width: 400px;
padding: 15px 0 0 0;
> div {
@apply tw-mb-3;
}
}
</style>
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
<a-divider /> <a-divider />
<a-space class="tw-justify-end"> <a-space class="tw-justify-end">
<a-button @click="cancel">取消</a-button> <a-button @click="cancel">取消</a-button>
<slot name="footer"> <slot name="footer" v-if="!noFooter">
<a-button type="primary" @click="ok" :loading="loading">确认</a-button> <a-button type="primary" @click="ok" :loading="loading">确认</a-button>
</slot> </slot>
</a-space> </a-space>
...@@ -35,6 +35,10 @@ export default { ...@@ -35,6 +35,10 @@ export default {
type: Function, type: Function,
default: EMPTY_FUN, default: EMPTY_FUN,
}, },
noFooter: {
type: Boolean,
default: false,
},
}, },
data: () => ({ data: () => ({
loading: false, loading: false,
......
<template> <template>
<a-layout-header :class="[headerTheme, 'admin-header']"> <a-layout-header :class="[headerTheme, 'admin-header']">
<div :class="['admin-header-wide', layout, pageWidth]"> <div :class="['admin-header-wide', layout, pageWidth]">
<router-link <router-link v-if="layout === 'head'" to="/" :class="['logo', 'pc', headerTheme]">
v-if="isMobile || layout === 'head'"
to="/"
:class="['logo', isMobile ? null : 'pc', headerTheme]"
>
<img width="32" src="@/assets/img/logo.png" /> <img width="32" src="@/assets/img/logo.png" />
<h1 v-if="!isMobile">{{ systemName }}</h1> <h1>{{ systemName }}</h1>
</router-link> </router-link>
<a-icon <a-icon
...@@ -16,11 +12,7 @@ ...@@ -16,11 +12,7 @@
:type="collapsed ? 'menu-unfold' : 'menu-fold'" :type="collapsed ? 'menu-unfold' : 'menu-fold'"
@click="toggleCollapse" @click="toggleCollapse"
/> />
<div <div v-if="layout !== 'side'" class="admin-header-menu" :style="`width: ${menuWidth};`">
v-if="layout !== 'side' && !isMobile"
class="admin-header-menu"
:style="`width: ${menuWidth};`"
>
<i-menu <i-menu
class="head-menu" class="head-menu"
:theme="headerTheme" :theme="headerTheme"
...@@ -53,9 +45,9 @@ export default { ...@@ -53,9 +45,9 @@ export default {
return {}; return {};
}, },
computed: { computed: {
...mapState('settingModule', ['theme', 'isMobile', 'layout', 'systemName', 'pageWidth']), ...mapState('settingModule', ['theme', 'layout', 'systemName', 'pageWidth']),
headerTheme() { headerTheme() {
if (this.layout == 'side' && this.theme.mode == 'dark' && !this.isMobile) { if (this.layout == 'side' && this.theme.mode == 'dark') {
return 'light'; return 'light';
} }
return this.theme.mode; return this.theme.mode;
...@@ -67,7 +59,7 @@ export default { ...@@ -67,7 +59,7 @@ export default {
return `calc(${headWidth} - ${extraWidth})`; return `calc(${headWidth} - ${extraWidth})`;
}, },
showToggleCollapse() { showToggleCollapse() {
if (this.layout !== 'head' && this.isMobile === false) { if (this.layout !== 'head') {
return true; return true;
} else { } else {
return false; return false;
......
<template> <template>
<a-layout :class="['admin-layout', 'beauty-scroll']"> <a-layout :class="['admin-layout', 'beauty-scroll']">
<drawer v-if="isMobile" v-model="drawerOpen">
<side-menu
:theme="theme.mode"
:menuData="menuData"
:collapsed="false"
:collapsible="false"
@menuSelect="onMenuSelect"
/>
</drawer>
<side-menu <side-menu
:class="[fixedSideBar ? 'fixed-side' : '']" :class="[fixedSideBar ? 'fixed-side' : '']"
:theme="theme.mode" :theme="theme.mode"
v-else-if="layout === 'side' || layout === 'mix'" v-if="layout === 'side' || layout === 'mix'"
:menuData="sideMenuData" :menuData="sideMenuData"
:collapsed="collapsed" :collapsed="collapsed"
:collapsible="true" :collapsible="true"
/> />
<div <div
v-if="fixedSideBar && !isMobile" v-if="fixedSideBar"
:style="`width: ${sideMenuWidth}; min-width: ${sideMenuWidth};max-width: ${sideMenuWidth};`" :style="`width: ${sideMenuWidth}; min-width: ${sideMenuWidth};max-width: ${sideMenuWidth};`"
class="virtual-side" class="virtual-side"
/> />
...@@ -73,7 +63,6 @@ export default { ...@@ -73,7 +63,6 @@ export default {
minHeight: window.innerHeight - 64 - 122, minHeight: window.innerHeight - 64 - 122,
collapsed: false, collapsed: false,
showSetting: false, showSetting: false,
drawerOpen: false,
menuData: [], menuData: [],
firstMenu: [], firstMenu: [],
subMenu: [], subMenu: [],
...@@ -86,18 +75,12 @@ export default { ...@@ -86,18 +75,12 @@ export default {
}; };
}, },
watch: { watch: {
isMobile(val) {
if (!val) {
this.drawerOpen = false;
}
},
layout(layout) { layout(layout) {
this.updateSildeMenu(layout); this.updateSildeMenu(layout);
}, },
}, },
computed: { computed: {
...mapState('settingModule', [ ...mapState('settingModule', [
'isMobile',
'theme', 'theme',
'layout', 'layout',
'footerLinks', 'footerLinks',
...@@ -120,9 +103,7 @@ export default { ...@@ -120,9 +103,7 @@ export default {
}, },
headerStyle() { headerStyle() {
let width = let width =
this.fixedHeader && this.layout !== 'head' && !this.isMobile this.fixedHeader && this.layout !== 'head' ? `calc(100% - ${this.sideMenuWidth})` : '100%';
? `calc(100% - ${this.sideMenuWidth})`
: '100%';
let position = this.fixedHeader ? 'fixed' : 'static'; let position = this.fixedHeader ? 'fixed' : 'static';
return `width: ${width}; position: ${position};`; return `width: ${width}; position: ${position};`;
}, },
...@@ -147,11 +128,11 @@ export default { ...@@ -147,11 +128,11 @@ export default {
updateSildeMenu(layout) { updateSildeMenu(layout) {
if (layout === 'mix') { if (layout === 'mix') {
const { path } = this.$route; const { path } = this.$route;
let currentMenu = this.menuList.find(i => i.menuUrl === path); let currentMenu = this.menuList.find((i) => i.menuUrl === path);
let parentMenuId = currentMenu.parentMenuId; let parentMenuId = currentMenu.parentMenuId;
while (parentMenuId !== 0) { while (parentMenuId !== 0) {
currentMenu = this.menuList.find(i => i.menuId === parentMenuId); currentMenu = this.menuList.find((i) => i.menuId === parentMenuId);
parentMenuId = currentMenu.parentMenuId; parentMenuId = currentMenu.parentMenuId;
} }
this.subMenu = currentMenu.children || []; this.subMenu = currentMenu.children || [];
...@@ -161,7 +142,7 @@ export default { ...@@ -161,7 +142,7 @@ export default {
menuSelect(obj) { menuSelect(obj) {
// 拿到 菜单id // 拿到 菜单id
const menuId = obj.key; const menuId = obj.key;
const currentMenu = this.menuList.find(i => i.menuId === menuId); const currentMenu = this.menuList.find((i) => i.menuId === menuId);
if (currentMenu.menuType === 'MENU') { if (currentMenu.menuType === 'MENU') {
this.subMenu = []; this.subMenu = [];
...@@ -177,7 +158,7 @@ export default { ...@@ -177,7 +158,7 @@ export default {
const menuData = convertListToTree(menuList || [], false, true); const menuData = convertListToTree(menuList || [], false, true);
this.menuData = menuData; this.menuData = menuData;
this.menuList = menuList; this.menuList = menuList;
this.firstMenu = JSON.parse(JSON.stringify(menuData)).map(i => { this.firstMenu = JSON.parse(JSON.stringify(menuData)).map((i) => {
delete i.children; delete i.children;
return i; return i;
}); });
......
<template> <template>
<div class="page-layout"> <div class="page-layout tw-overflow-x-auto">
<page-header <page-header
ref="pageHeader" ref="pageHeader"
:style="`margin-top: ${multiPage ? 0 : -24}px`" :style="`margin-top: ${multiPage ? 0 : -24}px`"
...@@ -79,11 +79,11 @@ export default { ...@@ -79,11 +79,11 @@ export default {
...mapMutations('settingModule', ['correctPageMinHeight']), ...mapMutations('settingModule', ['correctPageMinHeight']),
getRouteBreadcrumb() { getRouteBreadcrumb() {
const path = this.$route.path; const path = this.$route.path;
const currentMenu = this.menuList.find(m => m.menuUrl === path); const currentMenu = this.menuList.find((m) => m.menuUrl === path);
let parentMenuId = currentMenu.parentMenuId; let parentMenuId = currentMenu.parentMenuId;
const breadcrumb = [currentMenu.menuName]; const breadcrumb = [currentMenu.menuName];
while (parentMenuId !== 0) { while (parentMenuId !== 0) {
const parentMenu = this.menuList.find(m => m.menuId === parentMenuId); const parentMenu = this.menuList.find((m) => m.menuId === parentMenuId);
breadcrumb.unshift(parentMenu.menuName); breadcrumb.unshift(parentMenu.menuName);
parentMenuId = parentMenu.parentMenuId; parentMenuId = parentMenu.parentMenuId;
} }
......
...@@ -12,7 +12,6 @@ const customTitles = (customTitlesStr && JSON.parse(customTitlesStr)) || []; ...@@ -12,7 +12,6 @@ const customTitles = (customTitlesStr && JSON.parse(customTitlesStr)) || [];
export default { export default {
namespaced: true, namespaced: true,
state: { state: {
isMobile: false,
animates: globalConfig.animates.preset, animates: globalConfig.animates.preset,
palettes: globalConfig.palettes, palettes: globalConfig.palettes,
pageMinHeight: 0, pageMinHeight: 0,
...@@ -36,7 +35,7 @@ export default { ...@@ -36,7 +35,7 @@ export default {
if (menuData.length > 0 && !menuData[0].fullPath) { if (menuData.length > 0 && !menuData[0].fullPath) {
formatFullPath(menuData); formatFullPath(menuData);
} }
return menuData.map(item => { return menuData.map((item) => {
const menuItem = { ...item }; const menuItem = { ...item };
delete menuItem.children; delete menuItem.children;
return menuItem; return menuItem;
...@@ -44,9 +43,6 @@ export default { ...@@ -44,9 +43,6 @@ export default {
}, },
}, },
mutations: { mutations: {
setDevice(state, isMobile) {
state.isMobile = isMobile;
},
setTheme(state, theme) { setTheme(state, theme) {
state.theme = theme; state.theme = theme;
}, },
...@@ -92,7 +88,7 @@ export default { ...@@ -92,7 +88,7 @@ export default {
}, },
setCustomTitle(state, { path, title }) { setCustomTitle(state, { path, title }) {
if (title) { if (title) {
const obj = state.customTitles.find(item => item.path === path); const obj = state.customTitles.find((item) => item.path === path);
if (obj) { if (obj) {
obj.title = title; obj.title = title;
} else { } else {
......
...@@ -89,11 +89,23 @@ export default { ...@@ -89,11 +89,23 @@ export default {
checked: true, checked: true,
logging: false, logging: false,
form: this.$form.createForm(this), form: this.$form.createForm(this),
back: null,
}; };
}, },
created() { created() {
clearToken(); clearToken();
}, },
beforeRouteEnter(to, from, next) {
const {
query: { back },
} = to;
const { fullPath } = from;
next((vm) => {
if (back) vm.back = fullPath;
});
},
computed: { computed: {
applicationName() { applicationName() {
return this.$store.state.settingModule.systemName; return this.$store.state.settingModule.systemName;
...@@ -102,7 +114,7 @@ export default { ...@@ -102,7 +114,7 @@ export default {
methods: { methods: {
onSubmit(e) { onSubmit(e) {
e.preventDefault(); e.preventDefault();
this.form.validateFields(async err => { this.form.validateFields(async (err) => {
if (!err) { if (!err) {
this.logging = true; this.logging = true;
const userName = this.form.getFieldValue('userName'); const userName = this.form.getFieldValue('userName');
...@@ -113,7 +125,7 @@ export default { ...@@ -113,7 +125,7 @@ export default {
setToken(token); setToken(token);
setUserId(userId); setUserId(userId);
await setUserInfoByRequest(); await setUserInfoByRequest();
this.$router.replace('/'); this.$router.replace(this.back ? this.back : '/');
} catch (error) { } catch (error) {
// todo // todo
} }
......
<template> <template>
<page-layout :desc="desc" :linkList="linkList"> <page-layout :desc="desc" :linkList="linkList">
<div v-if="this.extraImage && !isMobile" slot="extra" :class="$style.extraImg"> <div v-if="extraImage" slot="extra" :class="$style.extraImg">
<img :src="extraImage" /> <img :src="extraImage" />
</div> </div>
<router-view ref="page" /> <router-view ref="page" />
...@@ -20,7 +20,7 @@ export default { ...@@ -20,7 +20,7 @@ export default {
}; };
}, },
computed: { computed: {
...mapState('settingModule', ['isMobile', 'multiPage']), ...mapState('settingModule', ['multiPage']),
desc() { desc() {
return this.page?.desc; return this.page?.desc;
}, },
......
<template>
<Wraper :hidden="hidden" noFooter>
<Table
:url="tableUrl"
rowKey="taskId"
noPadding
:buttons="buttons"
:scroll="scroll"
:width="600"
ref="table"
>
<template #search="{ query }">
<MoreItem label="开始时间">
<a-date-picker
class="tw-w-full"
show-time
v-model="query.startTime"
valueFormat="YYYY-MM-DD HH:mm:ss"
/>
</MoreItem>
<MoreItem label="结束时间">
<a-date-picker
class="tw-w-full"
show-time
v-model="query.endTime"
valueFormat="YYYY-MM-DD HH:mm:ss"
/>
</MoreItem>
</template>
<template #moreSearch="{ query }">
<MoreItem label="开始时间">
<a-date-picker
class="tw-w-full"
show-time
v-model="query.startTime"
valueFormat="YYYY-MM-DD HH:mm:ss"
/>
</MoreItem>
<MoreItem label="结束时间">
<a-date-picker
class="tw-w-full"
show-time
v-model="query.endTime"
valueFormat="YYYY-MM-DD HH:mm:ss"
/>
</MoreItem>
<MoreItem label="地点">
<UrlSelect
v-model="query.placeId"
:url="`/ranger/inspection/api/v1/place/regions/${row.regionId}/list`"
labelFiled="placeName"
valueFiled="placeId"
/>
</MoreItem>
<MoreItem label="单元">
<UrlSelect
v-model="query.unitId"
:url="
query.placeId
? `/ranger/inspection/api/v1/units/places/${query.placeId}/list`
: ''
"
labelFiled="unitName"
valueFiled="unitId"
/>
</MoreItem>
<MoreItem label="项目">
<UrlSelect
v-model="query.itemId"
:url="
query.unitId ? `/ranger/inspection/api/v1/items/units/${query.unitId}/list` : ''
"
labelFiled="itemName"
valueFiled="itemId"
/>
</MoreItem>
<MoreItem label="巡检状态">
<UrlSelect
v-model="query.inspectionState"
:url="zhuangTaiUrl"
labelFiled="paramName"
valueFiled="paramValue"
/>
</MoreItem>
<MoreItem label="巡查结果">
<UrlSelect
:url="xunChaJieGuoUrl"
v-model="query.inspectionResultName"
labelFiled="paramName"
valueFiled="paramValue"
/>
</MoreItem>
<MoreItem label="巡检人">
<SearchSelect
url="/api/v1/users/searching"
searchField="userName"
v-model="query.lastInspectionStaffId"
labelFiled="userName"
valueFiled="userId"
/>
</MoreItem>
</template>
<template #drawer="drawer">
<ViewDetailCom v-bind="drawer" />
</template>
<a-table-column title="巡检项目" data-index="taskName" />
<a-table-column title="参考值" data-index="referenceValue" width="150px" />
<a-table-column title="采集数据" data-index="value" width="150px" />
<a-table-column title="巡查结果" data-index="inspectionResultName" width="100px" />
<a-table-column title="巡查时间" data-index="inspectionTime" width="200px" />
<a-table-column title="巡检人" data-index="inspectionStaffName" width="100px" />
<a-table-column title="状态" data-index="inspectionStateName" width="100px" />
</Table>
</Wraper>
</template>
<script>
import Table from '@/components/table/table.vue';
import Wraper from '@/components/table/wraper.vue';
import UrlSelect from '@/components/MySelect/url_select.vue';
import SearchSelect from '@/components/MySelect/search_select.vue';
import langUtils from '@/utils/langUtils';
import MoreItem from '@/components/table/more_item.vue';
import ViewDetailCom from './view_detail.vue';
export default {
props: { hidden: Function, row: Object },
components: { Table, Wraper, SearchSelect, UrlSelect, MoreItem, ViewDetailCom },
data() {
return {
scroll: { x: 1200 },
buttons: {
title: '备注 & 附件',
options: {
fixed: 'right',
width: 150,
},
data: [
{
label: '查看',
click: this.viewDetail,
},
],
},
};
},
computed: {
tableUrl() {
return `/ranger/inspection/api/v1/jobs/tasks?jobId=${this.row.jobId}`;
},
xunChaJieGuoUrl() {
return `/api/v1/parameters/business/list?paramModule=rpis_task&paramCode=inspection_result&paramLocale=${langUtils.get()}`;
},
zhuangTaiUrl() {
return `/api/v1/parameters/business/list?paramModule=rpis_route_schedule&paramCode=inspection_state&paramLocale=${langUtils.get()}`;
},
},
methods: {
viewDetail(row) {
console.log(row);
this.$refs.table.show({ row, title: '备注 & 附件' });
},
},
};
</script>
...@@ -5,33 +5,63 @@ ...@@ -5,33 +5,63 @@
rowKey="jobId" rowKey="jobId"
:addBtn="addBtn" :addBtn="addBtn"
:selected.sync="selected" :selected.sync="selected"
ref="table"
:drawerWidth="800"
> >
<template #search="{query}"> <template #search="{ query }">
<my-form-item label="开始时间"> <MoreItem label="开始时间">
<a-date-picker <a-date-picker
class="tw-w-full" class="tw-w-full"
show-time show-time
v-model="query.startTime" v-model="query.startTime"
valueFormat="YYYY-MM-DD HH:mm:ss" valueFormat="YYYY-MM-DD HH:mm:ss"
/> />
</my-form-item> </MoreItem>
<my-form-item label="结束时间">
<MoreItem label="结束时间">
<a-date-picker <a-date-picker
class="tw-w-full" class="tw-w-full"
show-time show-time
v-model="query.endTime" v-model="query.endTime"
valueFormat="YYYY-MM-DD HH:mm:ss" valueFormat="YYYY-MM-DD HH:mm:ss"
/> />
</my-form-item> </MoreItem>
<my-form-item label="地区"> <MoreItem label="地区">
<RequestSelect <RequestSelect
:request="getAreaListDataApi" :request="getAreaListDataApi"
v-model="query.regionId" v-model="query.regionId"
labelFiled="regionName" labelFiled="regionName"
valueFiled="regionId" valueFiled="regionId"
/> />
</my-form-item> </MoreItem>
<my-form-item label="专业"> </template>
<template #moreSearch="{ query }">
<MoreItem label="开始时间">
<a-date-picker
class="tw-w-full"
show-time
v-model="query.startTime"
valueFormat="YYYY-MM-DD HH:mm:ss"
/>
</MoreItem>
<MoreItem label="结束时间">
<a-date-picker
class="tw-w-full"
show-time
v-model="query.endTime"
valueFormat="YYYY-MM-DD HH:mm:ss"
/>
</MoreItem>
<MoreItem label="地区">
<RequestSelect
:request="getAreaListDataApi"
v-model="query.regionId"
labelFiled="regionName"
valueFiled="regionId"
/>
</MoreItem>
<MoreItem label="专业">
<UrlSelect <UrlSelect
:url=" :url="
query.regionId query.regionId
...@@ -42,8 +72,8 @@ ...@@ -42,8 +72,8 @@
labelFiled="specialityName" labelFiled="specialityName"
valueFiled="specialityId" valueFiled="specialityId"
/> />
</my-form-item> </MoreItem>
<my-form-item label="线路"> <MoreItem label="线路">
<UrlSelect <UrlSelect
:url=" :url="
query.regionId query.regionId
...@@ -54,32 +84,32 @@ ...@@ -54,32 +84,32 @@
valueFiled="routeId" valueFiled="routeId"
v-model="query.routeId" v-model="query.routeId"
/> />
</my-form-item> </MoreItem>
<my-form-item label="班组"> <MoreItem label="班组">
<RequestSelect <RequestSelect
:request="getBanZuListApi" :request="getBanZuListApi"
v-model="query.shiftType" v-model="query.shiftType"
labelFiled="paramName" labelFiled="paramName"
valueFiled="paramValue" valueFiled="paramValue"
/> />
</my-form-item> </MoreItem>
<my-form-item label="巡检状态"> <MoreItem label="巡检状态">
<RequestSelect <RequestSelect
:request="getBusinessListApi" :request="getBusinessListApi"
v-model="query.inspectionState" v-model="query.inspectionState"
labelFiled="paramName" labelFiled="paramName"
valueFiled="paramValue" valueFiled="paramValue"
/> />
</my-form-item> </MoreItem>
<my-form-item label="任务类型"> <MoreItem label="任务类型">
<RequestSelect <RequestSelect
:request="getTaskTypeApi" :request="getTaskTypeApi"
v-model="query.jobType" v-model="query.jobType"
labelFiled="paramName" labelFiled="paramName"
valueFiled="paramValue" valueFiled="paramValue"
/> />
</my-form-item> </MoreItem>
<my-form-item label="巡检人"> <MoreItem label="巡检人">
<SearchSelect <SearchSelect
url="/api/v1/users/searching" url="/api/v1/users/searching"
searchField="userName" searchField="userName"
...@@ -87,15 +117,17 @@ ...@@ -87,15 +117,17 @@
labelFiled="userName" labelFiled="userName"
valueFiled="userId" valueFiled="userId"
/> />
</my-form-item> </MoreItem>
</template> </template>
<template #operation> <template #operation>
<a-button @click="download">导出</a-button> <a-button @click="download">导出</a-button>
</template> </template>
<template #drawer="drawer"> <template #drawer="{ hidden, refresh, type, row }">
<Form v-bind="drawer" /> <Form :hidden="hidden" :refresh="refresh" v-if="type === 'add'" />
<Progress v-if="type === 'progress'" :hidden="hidden" :row="row" />
<Detail v-if="type === 'detail'" :hidden="hidden" :row="row" />
</template> </template>
<a-table-column title="线路名称" data-index="routeName" /> <a-table-column title="线路名称" data-index="routeName" />
...@@ -120,9 +152,21 @@ import { downloadFileByUrl } from '@/utils'; ...@@ -120,9 +152,21 @@ import { downloadFileByUrl } from '@/utils';
import RequestSelect from '@/components/MySelect/RequestSelect.vue'; import RequestSelect from '@/components/MySelect/RequestSelect.vue';
import SearchSelect from '@/components/MySelect/search_select.vue'; import SearchSelect from '@/components/MySelect/search_select.vue';
import { getAreaListDataApi, getBusinessListApi, getBanZuListApi, getTaskTypeApi } from '@/api'; import { getAreaListDataApi, getBusinessListApi, getBanZuListApi, getTaskTypeApi } from '@/api';
import Progress from './progress.vue';
import Detail from './detail.vue';
import MoreItem from '@/components/table/more_item.vue';
export default { export default {
components: { Table, Form, RequestSelect, UrlSelect, SearchSelect }, components: {
Table,
Form,
RequestSelect,
UrlSelect,
SearchSelect,
Progress,
Detail,
MoreItem,
},
data() { data() {
return { return {
getAreaListDataApi, getAreaListDataApi,
...@@ -135,9 +179,14 @@ export default { ...@@ -135,9 +179,14 @@ export default {
buttons: [ buttons: [
{ {
label: '详情', label: '详情',
click: this.viewDetail,
},
{ label: '进度', click: this.viewProgress },
{
type: 'confirm',
url: (row) => `/ranger/inspection/api/v1/jobs/${row.jobId}`,
after: this.refresh,
}, },
{ label: '进度' },
{ type: 'confirm' },
], ],
selected: [], selected: [],
}; };
...@@ -148,6 +197,15 @@ export default { ...@@ -148,6 +197,15 @@ export default {
const url = await getXunJianDownloadUrlApi(this.selected[0]); const url = await getXunJianDownloadUrlApi(this.selected[0]);
downloadFileByUrl(`${this.$fileUrl}${url}`); downloadFileByUrl(`${this.$fileUrl}${url}`);
}, },
refresh() {
this.$refs['table'].getData();
},
viewProgress(row) {
this.$refs.table.show({ title: '任务进度', type: 'progress', row });
},
viewDetail(row) {
this.$refs.table.show({ title: '任务明细', type: 'detail', row });
},
}, },
}; };
</script> </script>
<template>
<Wraper noFooter :hidden="hidden">
<a-space class="tw-mb-6" size="large">
<span>
地点
<span class="tw-text-blue-500 tw-mx-1">{{ row.placeNum }}</span>
</span>
<span>
单元
<span class="tw-text-blue-500 tw-mx-1">{{ row.unitNum }}</span>
</span>
<span>
项目
<span class="tw-text-blue-500 tw-mx-1">{{ row.itemNum }}</span>
</span>
<span>
异常
<span class="tw-text-red-500 tw-mx-1">{{ row.abnormalNum }}</span>
</span>
<span>
完成率
<span class="tw-text-blue-500 tw-mx-1">
{{ row.unitNum ? (row.finishedNum / row.unitNum).toFixed(2) : 0 }}
</span>
</span>
</a-space>
<Table :url="tableUrl" rowKey="progressId" noPadding>
<a-table-column title="地点名称" data-index="placeName" />
<a-table-column title="开始时间" data-index="inspectionStartTime" />
<a-table-column title="结束时间" data-index="inspectionEndTime" />
<a-table-column title="状态" data-index="inspectionStateName" />
</Table>
</Wraper>
</template>
<script>
import Wraper from '@/components/table/wraper.vue';
import Table from '@/components/table/table.vue';
export default {
props: { hidden: Function, row: Object },
components: { Wraper, Table },
mounted() {
console.log(this.row);
},
computed: {
tableUrl() {
return `/ranger/inspection/api/v1/jobs/progress?jobId=${this.row.jobId}`;
},
},
};
</script>
<template>
<Wraper noFooter :hidden="hidden">
<span>备注:</span>
<div style="min-height: 100px" class="tw-font-medium tw-mt-2">{{ detailData.inspectionRemark }}</div>
<a-tabs>
<!-- Todo -->
<a-tab-pane key="1" tab="图片"></a-tab-pane>
<a-tab-pane key="2" tab="视频"></a-tab-pane>
</a-tabs>
</Wraper>
</template>
<script>
import Wraper from '@/components/table/wraper.vue';
import { getRangerInspectionTaskDetailApi } from '@/api';
export default {
props: { hidden: Function, row: Object },
components: { Wraper },
data() {
return {
detailData: {},
};
},
async mounted() {
this.detailData = await getRangerInspectionTaskDetailApi(this.row.taskId);
console.log(this.detailData);
},
};
</script>
//enquire.js 纯 JavaScript 实现的 CSS 媒体查询库
import enquireJs from "enquire.js";
export function isDef(v) { export function isDef(v) {
return v !== undefined && v !== null; return v !== undefined && v !== null;
} }
...@@ -18,19 +15,7 @@ export function remove(arr, item) { ...@@ -18,19 +15,7 @@ export function remove(arr, item) {
} }
export function isRegExp(v) { export function isRegExp(v) {
return _toString.call(v) === "[object RegExp]"; return _toString.call(v) === '[object RegExp]';
}
export function enquireScreen(call) {
const handler = {
match: function() {
call && call(true);
},
unmatch: function() {
call && call(false);
},
};
enquireJs.register("only screen and (max-width: 767.99px)", handler);
} }
const _toString = Object.prototype.toString; const _toString = Object.prototype.toString;
...@@ -18,7 +18,7 @@ axios.defaults.baseURL = '/api'; ...@@ -18,7 +18,7 @@ axios.defaults.baseURL = '/api';
*/ */
function loadResponseInterceptor({ router }) { function loadResponseInterceptor({ router }) {
axios.interceptors.request.use( axios.interceptors.request.use(
function(config) { function (config) {
// 在发送请求之前做些什么 // 在发送请求之前做些什么
config.headers = { config.headers = {
...config.headers, ...config.headers,
...@@ -27,7 +27,7 @@ function loadResponseInterceptor({ router }) { ...@@ -27,7 +27,7 @@ function loadResponseInterceptor({ router }) {
}; };
return config; return config;
}, },
function(error) { function (error) {
// 对请求错误做些什么 // 对请求错误做些什么
return Promise.reject(error); return Promise.reject(error);
}, },
...@@ -35,7 +35,7 @@ function loadResponseInterceptor({ router }) { ...@@ -35,7 +35,7 @@ function loadResponseInterceptor({ router }) {
// 添加响应拦截器 // 添加响应拦截器
axios.interceptors.response.use( axios.interceptors.response.use(
function(response) { function (response) {
const { data } = response; const { data } = response;
// 2xx 范围内的状态码都会触发该函数。 // 2xx 范围内的状态码都会触发该函数。
// 对响应数据做点什么 // 对响应数据做点什么
...@@ -44,21 +44,21 @@ function loadResponseInterceptor({ router }) { ...@@ -44,21 +44,21 @@ function loadResponseInterceptor({ router }) {
} }
if (data.code === 'error.system.authc') { if (data.code === 'error.system.authc') {
router.push('/login'); router.push({ path: '/login', query: { back: true } });
} }
notification.error({ notification.error({
message: data.code, message: data.code,
description: h => h('pre', data.message), description: (h) => h('pre', data.message),
}); });
return Promise.reject(data.message); return Promise.reject(data.message);
}, },
function(error) { function (error) {
// 超出 2xx 范围的状态码都会触发该函数。 // 超出 2xx 范围的状态码都会触发该函数。
// 对响应错误做点什么 // 对响应错误做点什么
notification.error({ notification.error({
message: `${error.response.status} ${error.response.statusText}`, message: `${error.response.status} ${error.response.statusText}`,
description: h => h('pre', error.message), description: (h) => h('pre', error.message),
}); });
return Promise.reject(error); return Promise.reject(error);
}, },
......
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