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
{
"name": "vue-antd-admin",
"version": "0.7.2",
"homepage": "https://iczer.github.io/vue-antd-admin",
"private": true,
"scripts": {
"start": "vue-cli-service serve",
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
"predeploy": "yarn build",
"deploy": "gh-pages -d dist -b pages -r https://gitee.com/iczer/vue-antd-admin.git",
"docs:dev": "vuepress dev docs",
"docs:build": "vuepress build docs",
"docs:deploy": "vuepress build docs && gh-pages -d docs/.vuepress/dist -b master -r https://gitee.com/iczer/vue-antd-admin-docs.git"
},
"dependencies": {
"@antv/data-set": "^0.11.4",
"@tailwindcss/postcss7-compat": "^2.2.2",
"animate.css": "^4.1.0",
"ant-design-vue": "1.7.2",
"axios": "^0.21.1",
"clipboard": "^2.0.6",
"core-js": "^3.6.5",
"crypto-js": "^4.0.0",
"date-fns": "^2.14.0",
"enquire.js": "^2.1.6",
"highlight.js": "^10.2.1",
"lodash": "^4.17.21",
"mockjs": "^1.1.0",
"moment": "^2.29.1",
"nprogress": "^0.2.0",
"regenerator-runtime": "^0.13.7",
"tailwindcss": "npm:@tailwindcss/postcss7-compat@^2.2.2",
"viser-vue": "^2.4.8",
"vue": "^2.6.11",
"vue-i18n": "^8.18.2",
"vue-router": "^3.3.4",
"vuedraggable": "^2.23.2",
"vuex": "^3.4.0"
},
"devDependencies": {
"@ant-design/colors": "^4.0.1",
"@vue/cli-plugin-babel": "^4.4.0",
"@vue/cli-plugin-eslint": "^4.4.0",
"@vue/cli-service": "^4.4.0",
"@vuepress/plugin-back-to-top": "^1.5.2",
"autoprefixer": "^9.8.6",
"babel-eslint": "^10.1.0",
"babel-plugin-transform-remove-console": "^6.9.4",
"babel-polyfill": "^6.26.0",
"compression-webpack-plugin": "^2.0.0",
"deepmerge": "^4.2.2",
"eslint": "^6.7.2",
"eslint-plugin-prettier": "3.3.1",
"eslint-plugin-vue": "^6.2.2",
"fast-deep-equal": "^3.1.3",
"gh-pages": "^3.1.0",
"less-loader": "^6.1.1",
"style-resources-loader": "^1.3.2",
"vue-cli-plugin-style-resources-loader": "^0.1.4",
"vue-template-compiler": "^2.6.11",
"vuepress": "^1.5.2",
"webpack-theme-color-replacer": "^1.3.12",
"whatwg-fetch": "^3.0.0"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
"name": "vue-antd-admin",
"version": "0.7.2",
"homepage": "https://iczer.github.io/vue-antd-admin",
"private": true,
"scripts": {
"start": "vue-cli-service serve",
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
"predeploy": "yarn build",
"deploy": "gh-pages -d dist -b pages -r https://gitee.com/iczer/vue-antd-admin.git",
"docs:dev": "vuepress dev docs",
"docs:build": "vuepress build docs",
"docs:deploy": "vuepress build docs && gh-pages -d docs/.vuepress/dist -b master -r https://gitee.com/iczer/vue-antd-admin-docs.git"
},
"extends": [
"plugin:vue/essential",
"eslint:recommended"
],
"parserOptions": {
"parser": "babel-eslint"
"dependencies": {
"@antv/data-set": "^0.11.4",
"@tailwindcss/postcss7-compat": "^2.2.2",
"animate.css": "^4.1.0",
"ant-design-vue": "1.7.2",
"axios": "^0.21.1",
"clipboard": "^2.0.6",
"core-js": "^3.6.5",
"crypto-js": "^4.0.0",
"date-fns": "^2.14.0",
"highlight.js": "^10.2.1",
"lodash": "^4.17.21",
"mockjs": "^1.1.0",
"moment": "^2.29.1",
"nprogress": "^0.2.0",
"regenerator-runtime": "^0.13.7",
"tailwindcss": "npm:@tailwindcss/postcss7-compat@^2.2.2",
"viser-vue": "^2.4.8",
"vue": "^2.6.11",
"vue-i18n": "^8.18.2",
"vue-router": "^3.3.4",
"vuedraggable": "^2.23.2",
"vuex": "^3.4.0"
},
"devDependencies": {
"@ant-design/colors": "^4.0.1",
"@babel/eslint-parser": "^7.14.7",
"@vue/cli-plugin-babel": "^4.4.0",
"@vue/cli-plugin-eslint": "^4.4.0",
"@vue/cli-service": "^4.4.0",
"@vuepress/plugin-back-to-top": "^1.5.2",
"autoprefixer": "^9.8.6",
"babel-plugin-transform-remove-console": "^6.9.4",
"babel-polyfill": "^6.26.0",
"compression-webpack-plugin": "^2.0.0",
"deepmerge": "^4.2.2",
"eslint": "^6.7.2",
"eslint-plugin-prettier": "3.3.1",
"eslint-plugin-vue": "^6.2.2",
"fast-deep-equal": "^3.1.3",
"gh-pages": "^3.1.0",
"less-loader": "^6.1.1",
"style-resources-loader": "^1.3.2",
"vue-cli-plugin-style-resources-loader": "^0.1.4",
"vue-template-compiler": "^2.6.11",
"vuepress": "^1.5.2",
"webpack-theme-color-replacer": "^1.3.12",
"whatwg-fetch": "^3.0.0"
},
"rules": {
"no-unused-vars": "off"
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/essential",
"eslint:recommended"
],
"parserOptions": {
"parser": "@babel/eslint-parser"
},
"rules": {
"no-unused-vars": "off"
}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 10"
],
"lint-staged": {
"*.{js,jsx,vue}": [
"vue-cli-service lint",
"git add"
]
}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 10"
],
"lint-staged": {
"*.{js,jsx,vue}": [
"vue-cli-service lint",
"git add"
]
}
}
This diff is collapsed.
......@@ -5,9 +5,9 @@
</template>
<script>
import { enquireScreen } from './utils/commonUtil';
import { mapState, mapMutations } from 'vuex';
import { mapState } from 'vuex';
import { changeThemeColor } from '@/utils/themeUtil';
import langUtils from '@/utils/langUtils';
export default {
name: 'App',
......@@ -18,15 +18,10 @@ export default {
},
created() {
this.setHtmlTitle();
this.setLanguage(this.lang);
enquireScreen(isMobile => this.setDevice(isMobile));
this.setLanguage();
},
watch: {
lang(val) {
this.setLanguage(val);
this.setHtmlTitle();
},
$route() {
this.setHtmlTitle();
},
......@@ -44,12 +39,11 @@ export default {
},
computed: {
//setting = mapStore.name
...mapState('settingModule', ['layout', 'theme', 'lang']),
...mapState('settingModule', ['layout', 'theme']),
},
methods: {
...mapMutations('settingModule', ['setDevice']),
setLanguage(lang) {
setLanguage() {
const lang = langUtils.get();
this.$i18n.locale = lang;
switch (lang) {
case 'zh_CN':
......
import { postReq, putReq } from '@/utils';
import { getReq, postReq, putReq } from '@/utils';
export function addTaskApi(data) {
return postReq('/api/v1/schedules', data);
......@@ -7,3 +7,7 @@ export function addTaskApi(data) {
export function updateTaskApi(data) {
return putReq('/api/v1/schedules', data);
}
export function getRangerInspectionTaskDetailApi(id) {
return getReq(`/ranger/inspection/api/v1/jobs/tasks/${id}`);
}
<template>
<a-select
show-search
class="tw-w-full"
placeholder="input search text"
:default-active-first-option="false"
:show-arrow="false"
......
<template>
<a-layout-sider
:theme="sideTheme"
:class="['side-menu', 'beauty-scroll', isMobile ? null : 'shadow']"
:class="['side-menu', 'beauty-scroll']"
width="256px"
:collapsible="collapsible"
v-model="collapsed"
......@@ -49,15 +49,12 @@ export default {
sideTheme() {
return this.theme == 'light' ? this.theme : 'dark';
},
...mapState('settingModule', ['isMobile', 'systemName']),
...mapState('settingModule', ['systemName']),
},
};
</script>
<style lang="less" scoped>
.shadow {
box-shadow: 2px 0 6px rgba(0, 21, 41, 0.35);
}
.side-menu {
min-height: 100vh;
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>
<div>
<div :style="`min-width: ${width}px`" class="tw-overflow-x-auto">
<my-card v-if="$scopedSlots.search" class="tw-mb-2.5">
<a-form-model :model="queryForm" layout="horizontal">
<a-row :gutter="16">
<slot name="search" :query="queryForm" />
</a-row>
</a-form-model>
<div class="tw-flex">
<slot name="search" :query="queryForm" />
</div>
<div class="tw-text-right tw-mt-2">
<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 type="primary" @click="getData">查询</a-button>
</a-space>
</div>
</my-card>
<my-card>
<my-card :class="noPadding ? 'tw-p-0' : ''">
<a-space class="tw-mb-2">
<a-button type="primary" v-if="newBtn" @click="addBtnClick">
{{ newBtn.text || '新增' }}
......@@ -27,32 +33,39 @@
:data-source="data"
:loading="loading"
v-bind="$attrs"
:scroll="scroll"
:rowKey="rowKey"
:pagination="pagination"
@change="pageChange"
:row-selection="selected ? rowSelection : undefined"
>
<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">
<my-ac-btn :row="row" :buttons="buttons" />
<my-ac-btn :row="row" :buttons="newButtons.data" />
</template>
</a-table-column>
</a-table>
</my-card>
<a-drawer
v-if="$scopedSlots.drawer"
placement="right"
:visible="visible"
:drawerStyle="drawerStyle"
:bodyStyle="bodyStyle"
destroyOnClose
:width="600"
:width="drawerWidth"
@close="hidden"
:maskClosable="false"
:title="title"
:afterVisibleChange="afterVisibleChange"
>
<slot name="drawer" :hidden="hidden" :refresh="getData" />
<slot name="drawer" :hidden="hidden" :refresh="getData" :type="type" :row="row" />
</a-drawer>
</div>
</template>
......@@ -60,6 +73,8 @@
<script>
import { request, METHOD } from '@/utils/requestUtil';
const assign = Object.assign;
const initQuery = {
pageSize: 10,
pageNum: 1,
......@@ -71,11 +86,18 @@ export default {
props: {
url: String,
addBtn: [Object, Boolean],
buttons: Array,
buttons: [Array, Object],
noPage: Boolean,
formatData: Function,
rowKey: [String, Function],
selected: Array,
drawerWidth: {
type: Number,
default: 600,
},
noPadding: Boolean,
scroll: Object,
width: { type: Number, default: 900 },
},
data() {
......@@ -99,6 +121,8 @@ export default {
flex: 1,
overflow: 'hidden',
},
type: null,
row: null,
};
},
......@@ -110,6 +134,13 @@ export default {
newBtn() {
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() {
return this.noPage
? false
......@@ -160,12 +191,18 @@ export default {
hidden() {
this.visible = false;
this.title = this.addBtn?.title ?? defaultTitle;
},
afterVisibleChange(visible) {
if (!visible) {
this.title = this.addBtn?.title ?? defaultTitle;
this.type = null;
this.row = null;
}
},
show({ title } = {}) {
show(params) {
this.visible = true;
if (title) this.title = title;
assign(this, params);
},
reset() {
......@@ -177,12 +214,22 @@ export default {
addBtnClick() {
const { click } = typeof this.addBtn === 'object' ? this.addBtn : {};
click && click();
this.type = 'add';
this.visible = true;
},
getFormRef(ref) {
console.log(ref);
},
},
};
</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 @@
<a-divider />
<a-space class="tw-justify-end">
<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>
</slot>
</a-space>
......@@ -35,6 +35,10 @@ export default {
type: Function,
default: EMPTY_FUN,
},
noFooter: {
type: Boolean,
default: false,
},
},
data: () => ({
loading: false,
......
<template>
<a-layout-header :class="[headerTheme, 'admin-header']">
<div :class="['admin-header-wide', layout, pageWidth]">
<router-link
v-if="isMobile || layout === 'head'"
to="/"
:class="['logo', isMobile ? null : 'pc', headerTheme]"
>
<router-link v-if="layout === 'head'" to="/" :class="['logo', 'pc', headerTheme]">
<img width="32" src="@/assets/img/logo.png" />
<h1 v-if="!isMobile">{{ systemName }}</h1>
<h1>{{ systemName }}</h1>
</router-link>
<a-icon
......@@ -16,11 +12,7 @@
:type="collapsed ? 'menu-unfold' : 'menu-fold'"
@click="toggleCollapse"
/>
<div
v-if="layout !== 'side' && !isMobile"
class="admin-header-menu"
:style="`width: ${menuWidth};`"
>
<div v-if="layout !== 'side'" class="admin-header-menu" :style="`width: ${menuWidth};`">
<i-menu
class="head-menu"
:theme="headerTheme"
......@@ -53,9 +45,9 @@ export default {
return {};
},
computed: {
...mapState('settingModule', ['theme', 'isMobile', 'layout', 'systemName', 'pageWidth']),
...mapState('settingModule', ['theme', 'layout', 'systemName', 'pageWidth']),
headerTheme() {
if (this.layout == 'side' && this.theme.mode == 'dark' && !this.isMobile) {
if (this.layout == 'side' && this.theme.mode == 'dark') {
return 'light';
}
return this.theme.mode;
......@@ -67,7 +59,7 @@ export default {
return `calc(${headWidth} - ${extraWidth})`;
},
showToggleCollapse() {
if (this.layout !== 'head' && this.isMobile === false) {
if (this.layout !== 'head') {
return true;
} else {
return false;
......
<template>
<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
:class="[fixedSideBar ? 'fixed-side' : '']"
:theme="theme.mode"
v-else-if="layout === 'side' || layout === 'mix'"
v-if="layout === 'side' || layout === 'mix'"
:menuData="sideMenuData"
:collapsed="collapsed"
:collapsible="true"
/>
<div
v-if="fixedSideBar && !isMobile"
v-if="fixedSideBar"
:style="`width: ${sideMenuWidth}; min-width: ${sideMenuWidth};max-width: ${sideMenuWidth};`"
class="virtual-side"
/>
......@@ -73,7 +63,6 @@ export default {
minHeight: window.innerHeight - 64 - 122,
collapsed: false,
showSetting: false,
drawerOpen: false,
menuData: [],
firstMenu: [],
subMenu: [],
......@@ -86,18 +75,12 @@ export default {
};
},
watch: {
isMobile(val) {
if (!val) {
this.drawerOpen = false;
}
},
layout(layout) {
this.updateSildeMenu(layout);
},
},
computed: {
...mapState('settingModule', [
'isMobile',
'theme',
'layout',
'footerLinks',
......@@ -120,9 +103,7 @@ export default {
},
headerStyle() {
let width =
this.fixedHeader && this.layout !== 'head' && !this.isMobile
? `calc(100% - ${this.sideMenuWidth})`
: '100%';
this.fixedHeader && this.layout !== 'head' ? `calc(100% - ${this.sideMenuWidth})` : '100%';
let position = this.fixedHeader ? 'fixed' : 'static';
return `width: ${width}; position: ${position};`;
},
......@@ -147,11 +128,11 @@ export default {
updateSildeMenu(layout) {
if (layout === 'mix') {
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;
while (parentMenuId !== 0) {
currentMenu = this.menuList.find(i => i.menuId === parentMenuId);
currentMenu = this.menuList.find((i) => i.menuId === parentMenuId);
parentMenuId = currentMenu.parentMenuId;
}
this.subMenu = currentMenu.children || [];
......@@ -161,7 +142,7 @@ export default {
menuSelect(obj) {
// 拿到 菜单id
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') {
this.subMenu = [];
......@@ -177,7 +158,7 @@ export default {
const menuData = convertListToTree(menuList || [], false, true);
this.menuData = menuData;
this.menuList = menuList;
this.firstMenu = JSON.parse(JSON.stringify(menuData)).map(i => {
this.firstMenu = JSON.parse(JSON.stringify(menuData)).map((i) => {
delete i.children;
return i;
});
......
<template>
<div class="page-layout">
<div class="page-layout tw-overflow-x-auto">
<page-header
ref="pageHeader"
:style="`margin-top: ${multiPage ? 0 : -24}px`"
......@@ -79,11 +79,11 @@ export default {
...mapMutations('settingModule', ['correctPageMinHeight']),
getRouteBreadcrumb() {
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;
const breadcrumb = [currentMenu.menuName];
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);
parentMenuId = parentMenu.parentMenuId;
}
......
......@@ -12,7 +12,6 @@ const customTitles = (customTitlesStr && JSON.parse(customTitlesStr)) || [];
export default {
namespaced: true,
state: {
isMobile: false,
animates: globalConfig.animates.preset,
palettes: globalConfig.palettes,
pageMinHeight: 0,
......@@ -36,7 +35,7 @@ export default {
if (menuData.length > 0 && !menuData[0].fullPath) {
formatFullPath(menuData);
}
return menuData.map(item => {
return menuData.map((item) => {
const menuItem = { ...item };
delete menuItem.children;
return menuItem;
......@@ -44,9 +43,6 @@ export default {
},
},
mutations: {
setDevice(state, isMobile) {
state.isMobile = isMobile;
},
setTheme(state, theme) {
state.theme = theme;
},
......@@ -92,7 +88,7 @@ export default {
},
setCustomTitle(state, { path, title }) {
if (title) {
const obj = state.customTitles.find(item => item.path === path);
const obj = state.customTitles.find((item) => item.path === path);
if (obj) {
obj.title = title;
} else {
......
......@@ -89,11 +89,23 @@ export default {
checked: true,
logging: false,
form: this.$form.createForm(this),
back: null,
};
},
created() {
clearToken();
},
beforeRouteEnter(to, from, next) {
const {
query: { back },
} = to;
const { fullPath } = from;
next((vm) => {
if (back) vm.back = fullPath;
});
},
computed: {
applicationName() {
return this.$store.state.settingModule.systemName;
......@@ -102,7 +114,7 @@ export default {
methods: {
onSubmit(e) {
e.preventDefault();
this.form.validateFields(async err => {
this.form.validateFields(async (err) => {
if (!err) {
this.logging = true;
const userName = this.form.getFieldValue('userName');
......@@ -113,7 +125,7 @@ export default {
setToken(token);
setUserId(userId);
await setUserInfoByRequest();
this.$router.replace('/');
this.$router.replace(this.back ? this.back : '/');
} catch (error) {
// todo
}
......
<template>
<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" />
</div>
<router-view ref="page" />
......@@ -20,7 +20,7 @@ export default {
};
},
computed: {
...mapState('settingModule', ['isMobile', 'multiPage']),
...mapState('settingModule', ['multiPage']),
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 @@
rowKey="jobId"
:addBtn="addBtn"
:selected.sync="selected"
ref="table"
:drawerWidth="800"
>
<template #search="{query}">
<my-form-item label="开始时间">
<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"
/>
</my-form-item>
<my-form-item label="结束时间">
</MoreItem>
<MoreItem label="结束时间">
<a-date-picker
class="tw-w-full"
show-time
v-model="query.endTime"
valueFormat="YYYY-MM-DD HH:mm:ss"
/>
</my-form-item>
<my-form-item label="地区">
</MoreItem>
<MoreItem label="地区">
<RequestSelect
:request="getAreaListDataApi"
v-model="query.regionId"
labelFiled="regionName"
valueFiled="regionId"
/>
</my-form-item>
<my-form-item label="专业">
</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="地区">
<RequestSelect
:request="getAreaListDataApi"
v-model="query.regionId"
labelFiled="regionName"
valueFiled="regionId"
/>
</MoreItem>
<MoreItem label="专业">
<UrlSelect
:url="
query.regionId
......@@ -42,8 +72,8 @@
labelFiled="specialityName"
valueFiled="specialityId"
/>
</my-form-item>
<my-form-item label="线路">
</MoreItem>
<MoreItem label="线路">
<UrlSelect
:url="
query.regionId
......@@ -54,32 +84,32 @@
valueFiled="routeId"
v-model="query.routeId"
/>
</my-form-item>
<my-form-item label="班组">
</MoreItem>
<MoreItem label="班组">
<RequestSelect
:request="getBanZuListApi"
v-model="query.shiftType"
labelFiled="paramName"
valueFiled="paramValue"
/>
</my-form-item>
<my-form-item label="巡检状态">
</MoreItem>
<MoreItem label="巡检状态">
<RequestSelect
:request="getBusinessListApi"
v-model="query.inspectionState"
labelFiled="paramName"
valueFiled="paramValue"
/>
</my-form-item>
<my-form-item label="任务类型">
</MoreItem>
<MoreItem label="任务类型">
<RequestSelect
:request="getTaskTypeApi"
v-model="query.jobType"
labelFiled="paramName"
valueFiled="paramValue"
/>
</my-form-item>
<my-form-item label="巡检人">
</MoreItem>
<MoreItem label="巡检人">
<SearchSelect
url="/api/v1/users/searching"
searchField="userName"
......@@ -87,15 +117,17 @@
labelFiled="userName"
valueFiled="userId"
/>
</my-form-item>
</MoreItem>
</template>
<template #operation>
<a-button @click="download">导出</a-button>
</template>
<template #drawer="drawer">
<Form v-bind="drawer" />
<template #drawer="{ hidden, refresh, type, row }">
<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>
<a-table-column title="线路名称" data-index="routeName" />
......@@ -120,9 +152,21 @@ import { downloadFileByUrl } from '@/utils';
import RequestSelect from '@/components/MySelect/RequestSelect.vue';
import SearchSelect from '@/components/MySelect/search_select.vue';
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 {
components: { Table, Form, RequestSelect, UrlSelect, SearchSelect },
components: {
Table,
Form,
RequestSelect,
UrlSelect,
SearchSelect,
Progress,
Detail,
MoreItem,
},
data() {
return {
getAreaListDataApi,
......@@ -135,9 +179,14 @@ export default {
buttons: [
{
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: [],
};
......@@ -148,6 +197,15 @@ export default {
const url = await getXunJianDownloadUrlApi(this.selected[0]);
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>
<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) {
return v !== undefined && v !== null;
}
......@@ -18,19 +15,7 @@ export function remove(arr, item) {
}
export function isRegExp(v) {
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);
return _toString.call(v) === '[object RegExp]';
}
const _toString = Object.prototype.toString;
......@@ -18,7 +18,7 @@ axios.defaults.baseURL = '/api';
*/
function loadResponseInterceptor({ router }) {
axios.interceptors.request.use(
function(config) {
function (config) {
// 在发送请求之前做些什么
config.headers = {
...config.headers,
......@@ -27,7 +27,7 @@ function loadResponseInterceptor({ router }) {
};
return config;
},
function(error) {
function (error) {
// 对请求错误做些什么
return Promise.reject(error);
},
......@@ -35,7 +35,7 @@ function loadResponseInterceptor({ router }) {
// 添加响应拦截器
axios.interceptors.response.use(
function(response) {
function (response) {
const { data } = response;
// 2xx 范围内的状态码都会触发该函数。
// 对响应数据做点什么
......@@ -44,21 +44,21 @@ function loadResponseInterceptor({ router }) {
}
if (data.code === 'error.system.authc') {
router.push('/login');
router.push({ path: '/login', query: { back: true } });
}
notification.error({
message: data.code,
description: h => h('pre', data.message),
description: (h) => h('pre', data.message),
});
return Promise.reject(data.message);
},
function(error) {
function (error) {
// 超出 2xx 范围的状态码都会触发该函数。
// 对响应错误做点什么
notification.error({
message: `${error.response.status} ${error.response.statusText}`,
description: h => h('pre', error.message),
description: (h) => h('pre', error.message),
});
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