Commit 461a5ae7 authored by 张耀's avatar 张耀

feat:

工单管理页面开发
parent 265f2a0b
This diff is collapsed.
:root { :root {
--font-color: #404a62; --font-color: #404a62;
/* --el-color-primary-light-9: #f7f7f9; */ /* --el-color-primary-light-9: #f7f7f9; */
--el-color-white: #ffffff; --el-color-white: #ffffff;
--el-color-black: #1a1a1a; --el-color-black: #1a1a1a;
--el-color-primary: #2b4695; --el-color-primary: #2b4695;
...@@ -68,38 +67,49 @@ ...@@ -68,38 +67,49 @@
--el-fill-color-darker: #e6e8eb; --el-fill-color-darker: #e6e8eb;
--el-fill-color-blank: #ffffff; --el-fill-color-blank: #ffffff;
} }
[v-cloak] { [v-cloak] {
display: none; display: none;
} }
/* 新增按钮颜色 */ /* 新增按钮颜色 */
.form-group .el-button--primary { .form-group .el-button--primary {
background-color: #264dd9 !important; background-color: #264dd9 !important;
border-color: #264dd9 !important; border-color: #264dd9 !important;
} }
/* 返回按钮颜色 */ /* 返回按钮颜色 */
.from_return>.el-button--primary { .from_return>.el-button--primary {
background-color: #edf0ff !important; background-color: #edf0ff !important;
border-color: #edf0ff !important; border-color: #edf0ff !important;
color: #264dd9 !important; color: #264dd9 !important;
} }
/* 取消按钮颜色 */ /* 取消按钮颜色 */
.form_c { .form_c {
background-color: #dde4ff !important; background-color: #dde4ff !important;
border-color: #dde4ff !important; border-color: #dde4ff !important;
color: #264dd9 !important; color: #264dd9 !important;
} }
/* 确定按钮颜色 */ /* 确定按钮颜色 */
.form_t { .form_t {
background-color: #264dd9 !important; background-color: #264dd9 !important;
border-color: #264dd9 !important; border-color: #264dd9 !important;
color: #f4f7fc !important; color: #f4f7fc !important;
} }
/* 搜索框颜色 */ /* 搜索框颜色 */
.form-group .el-input__inner { .form-group .el-input__inner {
border-radius: 28px !important; border-radius: 28px !important;
border: 1px solid #bcc1d0 !important; border: 1px solid #bcc1d0 !important;
...@@ -114,7 +124,9 @@ ...@@ -114,7 +124,9 @@
color: #8890a7 !important; color: #8890a7 !important;
} }
/* 多行文本框样式 */ /* 多行文本框样式 */
.jbxx_desc textarea { .jbxx_desc textarea {
height: 150px !important; height: 150px !important;
border-radius: 8px !important; border-radius: 8px !important;
...@@ -123,19 +135,25 @@ ...@@ -123,19 +135,25 @@
resize: none !important; resize: none !important;
} }
/* 面包屑文字大小 */ /* 面包屑文字大小 */
.el-breadcrumb { .el-breadcrumb {
font-size: 14px; font-size: 14px;
color: #898d9e; color: #898d9e;
} }
/* 编辑颜色*/ /* 编辑颜色*/
.primary-edit { .primary-edit {
color: #264dd9; color: #264dd9;
cursor: pointer; cursor: pointer;
} }
/* 删除颜色 */ /* 删除颜色 */
.primary-del { .primary-del {
color: #264dd9; color: #264dd9;
cursor: pointer; cursor: pointer;
...@@ -143,10 +161,13 @@ ...@@ -143,10 +161,13 @@
.space_bet {} .space_bet {}
/* reset */ /* reset */
html {} html {}
html,body { html,
body {
margin: 0; margin: 0;
font-family: Microsoft YaHei, sans-serif; font-family: Microsoft YaHei, sans-serif;
/* font-size: 17px; */ /* font-size: 17px; */
...@@ -171,16 +192,19 @@ h5 { ...@@ -171,16 +192,19 @@ h5 {
font-weight: normal; font-weight: normal;
} }
h1{ h1 {
font-size: 32px; font-size: 32px;
} }
h2{
h2 {
font-size: 24px; font-size: 24px;
} }
h3{
h3 {
font-size: 18.7px; font-size: 18.7px;
} }
h4{
h4 {
font-size: 16px; font-size: 16px;
} }
...@@ -188,9 +212,13 @@ div { ...@@ -188,9 +212,13 @@ div {
box-sizing: border-box; box-sizing: border-box;
} }
/* reset end */ /* reset end */
/* common */ /* common */
/* #app { /* #app {
height: 100%; height: 100%;
overflow: hidden; overflow: hidden;
...@@ -260,7 +288,9 @@ div { ...@@ -260,7 +288,9 @@ div {
padding: 0 20px; padding: 0 20px;
} }
/* 设置抽屉的样式 */ /* 设置抽屉的样式 */
.el-drawer__header { .el-drawer__header {
display: none; display: none;
} }
...@@ -304,10 +334,11 @@ div { ...@@ -304,10 +334,11 @@ div {
font-size: 11px; font-size: 11px;
} }
/* 设置提示弹窗的样式 */ /* 设置提示弹窗的样式 */
.el-dialog { .el-dialog {
border-radius: 6px; border-radius: 6px;
margin-top: 240px;
} }
.el-dialog__header { .el-dialog__header {
...@@ -349,19 +380,26 @@ div { ...@@ -349,19 +380,26 @@ div {
text-align: center; text-align: center;
padding: 0 16px; padding: 0 16px;
} }
.dialog_box .el-dialog__body { .dialog_box .el-dialog__body {
padding: 24px; padding: 24px;
} }
.dialog_box .el-dialog__footer { .dialog_box .el-dialog__footer {
padding: 16px; padding: 16px;
} }
.result_box .el-dialog__body { .result_box .el-dialog__body {
padding: 0px; padding: 0px;
} }
.sold_up_dialog .el-dialog__body { .sold_up_dialog .el-dialog__body {
padding: 24px 24px 4px; padding: 24px 24px 4px;
} }
/* 设置tab切换的样式 */ /* 设置tab切换的样式 */
.el-tabs__item.is-disabled { .el-tabs__item.is-disabled {
color: #8890a7 !important; color: #8890a7 !important;
} }
...@@ -371,12 +409,16 @@ div { ...@@ -371,12 +409,16 @@ div {
color: #404a62; color: #404a62;
line-height: 14px !important; line-height: 14px !important;
} }
/* .el-tabs__nav-scroll { /* .el-tabs__nav-scroll {
height: 35px; height: 35px;
} */ } */
.el-tabs__nav-scroll .el-tabs__nav { .el-tabs__nav-scroll .el-tabs__nav {
height: 40px; height: 40px;
} }
.el-tabs__nav-scroll .el-tabs__item { .el-tabs__nav-scroll .el-tabs__item {
line-height: 14px !important; line-height: 14px !important;
height: 40px !important; height: 40px !important;
...@@ -401,10 +443,14 @@ div { ...@@ -401,10 +443,14 @@ div {
background-color: #edf0ff; background-color: #edf0ff;
} }
/* 设置tree的样式 */ /* 设置tree的样式 */
.el-tree-node__content{
.el-tree-node__content {
height: 36px; height: 36px;
} }
/* .usrrole .el-tree-node:focus>.el-tree-node__content{ /* .usrrole .el-tree-node:focus>.el-tree-node__content{
background: rgb(248, 249, 253) !important; background: rgb(248, 249, 253) !important;
} }
...@@ -446,7 +492,10 @@ border-radius:8px; ...@@ -446,7 +492,10 @@ border-radius:8px;
border-bottom-left-radius:0; border-bottom-left-radius:0;
border-bottom-right-radius:0; border-bottom-right-radius:0;
} */ } */
/* 左右布局 */ /* 左右布局 */
.flex { .flex {
height: 100%; height: 100%;
display: -webkit-box; display: -webkit-box;
...@@ -506,26 +555,33 @@ border-radius:8px; ...@@ -506,26 +555,33 @@ border-radius:8px;
width: 1202px !important; width: 1202px !important;
} }
/* .el-form-item.is-required:not(.is-no-asterisk) .el-form-item__label-wrap>.el-form-item__label:before, /* .el-form-item.is-required:not(.is-no-asterisk) .el-form-item__label-wrap>.el-form-item__label:before,
.el-form-item.is-required:not(.is-no-asterisk)>.el-form-item__label:before { .el-form-item.is-required:not(.is-no-asterisk)>.el-form-item__label:before {
content: ""; content: "";
} */ } */
/* 设置switch的样式 */ /* 设置switch的样式 */
.switchStyle1 .el-switch__label { .switchStyle1 .el-switch__label {
position: absolute; position: absolute;
display: none; display: none;
color: #fff; color: #fff;
} }
/*打开时文字位置设置*/ /*打开时文字位置设置*/
.switchStyle1 .el-switch__label--right { .switchStyle1 .el-switch__label--right {
z-index: 1; z-index: 1;
right: -10px; right: -10px;
top: 1px; top: 1px;
} }
/*关闭时文字位置设置*/ /*关闭时文字位置设置*/
.switchStyle1 .el-switch__label--left { .switchStyle1 .el-switch__label--left {
z-index: 1; z-index: 1;
left: 28px; left: 28px;
...@@ -590,7 +646,10 @@ border-radius:8px; ...@@ -590,7 +646,10 @@ border-radius:8px;
opacity: 0.8; opacity: 0.8;
} }
/* 自定义图表提示框小三角 */ /* 自定义图表提示框小三角 */
/* .div-tip-warp { /* .div-tip-warp {
position: relative; position: relative;
line-height: 22px; line-height: 22px;
...@@ -611,6 +670,7 @@ border-radius:8px; ...@@ -611,6 +670,7 @@ border-radius:8px;
.triangle-position { .triangle-position {
margin-left: 35px; margin-left: 35px;
} */ } */
.el-input__inner { .el-input__inner {
border-radius: 6px; border-radius: 6px;
} }
...@@ -630,10 +690,12 @@ border-radius:8px; ...@@ -630,10 +690,12 @@ border-radius:8px;
z-index: 20000 !important; z-index: 20000 !important;
} }
/* /*
下拉选样式 下拉选样式
此处勿删,apaasV3下拉选择样式统一用这个 此处勿删,apaasV3下拉选择样式统一用这个
*/ */
.el-select-dropdown { .el-select-dropdown {
border-radius: 8px; border-radius: 8px;
} }
...@@ -673,13 +735,16 @@ border-radius:8px; ...@@ -673,13 +735,16 @@ border-radius:8px;
border-top-color: transparent; border-top-color: transparent;
} }
/* 单选激活样式 */ /* 单选激活样式 */
.el-radio__input .el-radio__inner { .el-radio__input .el-radio__inner {
border-color: #dadee7; border-color: #dadee7;
background-color: #fff; background-color: #fff;
width: 16px; width: 16px;
height: 16px; height: 16px;
} }
.el-radio__input.is-checked .el-radio__inner { .el-radio__input.is-checked .el-radio__inner {
border-color: #dadee7; border-color: #dadee7;
background-color: #fff; background-color: #fff;
...@@ -703,7 +768,9 @@ border-radius:8px; ...@@ -703,7 +768,9 @@ border-radius:8px;
border-color: #2b4695; border-color: #2b4695;
} }
/* 面包屑样式 */ /* 面包屑样式 */
.bread_crumb { .bread_crumb {
margin: 20px; margin: 20px;
font-size: 14px; font-size: 14px;
...@@ -730,14 +797,18 @@ border-radius:8px; ...@@ -730,14 +797,18 @@ border-radius:8px;
color: #898d9e !important; color: #898d9e !important;
} }
/* 应用超市详情页公共样式 */ /* 应用超市详情页公共样式 */
.sevice_detail { .sevice_detail {
max-width: 1340px; max-width: 1340px;
padding-top: 1px; padding-top: 1px;
margin: 0 auto; margin: 0 auto;
} }
/* common */ /* common */
.apass_breadcrumb>.el-breadcrumb { .apass_breadcrumb>.el-breadcrumb {
padding: 10px 0; padding: 10px 0;
} }
...@@ -822,7 +893,6 @@ border-radius:8px; ...@@ -822,7 +893,6 @@ border-radius:8px;
border-color: #ebeef5; border-color: #ebeef5;
} }
.apass_table .el-table th>.cell { .apass_table .el-table th>.cell {
color: #1a2236; color: #1a2236;
} }
...@@ -949,7 +1019,9 @@ border-radius:8px; ...@@ -949,7 +1019,9 @@ border-radius:8px;
border: 4px solid rgba(0, 0, 0, 0); border: 4px solid rgba(0, 0, 0, 0);
} }
/* 详情页公共样式 by xuyiming */ /* 详情页公共样式 by xuyiming */
.apaas_detail_container { .apaas_detail_container {
padding: 0 20px; padding: 0 20px;
} }
...@@ -1078,7 +1150,7 @@ border-radius:8px; ...@@ -1078,7 +1150,7 @@ border-radius:8px;
} }
.filter_list>.filter_item { .filter_list>.filter_item {
margin-right:34px; margin-right: 34px;
} }
.filter_list>.filter_item>* { .filter_list>.filter_item>* {
...@@ -1178,11 +1250,14 @@ border-radius:8px; ...@@ -1178,11 +1250,14 @@ border-radius:8px;
white-space: nowrap; white-space: nowrap;
} }
/* 详情页公共样式 by xuyiming ~~~end */ /* 详情页公共样式 by xuyiming ~~~end */
/* /*
form_content form_content
*/ */
.from_content1 { .from_content1 {
width: calc(100% - 40px); width: calc(100% - 40px);
background-color: rgba(255, 255, 255, 1); background-color: rgba(255, 255, 255, 1);
...@@ -1222,7 +1297,9 @@ border-radius:8px; ...@@ -1222,7 +1297,9 @@ border-radius:8px;
margin-bottom: 20px; margin-bottom: 20px;
} }
/* 时间控件样式 */ /* 时间控件样式 */
.el-picker-panel { .el-picker-panel {
background-color: #fff !important; background-color: #fff !important;
border-radius: 8px !important; border-radius: 8px !important;
...@@ -1231,13 +1308,10 @@ border-radius:8px; ...@@ -1231,13 +1308,10 @@ border-radius:8px;
box-shadow: 0 !important; box-shadow: 0 !important;
border: none !important; border: none !important;
} }
.el-date-editor.el-input__wrapper { .el-date-editor.el-input__wrapper {
background-color: #fff; background-color: #fff;
} }
.el-picker-panel__footer {
border-top: 1px solid #3f4864 !important;
background-color: #242c43 !important;
}
.el-picker-panel__icon-btn { .el-picker-panel__icon-btn {
color: #202531; color: #202531;
...@@ -1265,16 +1339,12 @@ border-radius:8px; ...@@ -1265,16 +1339,12 @@ border-radius:8px;
.el-picker-panel__body .el-input__inner { .el-picker-panel__body .el-input__inner {
height: 24px !important; height: 24px !important;
line-height: 24px !important; line-height: 24px !important;
background-color: #1a2236 !important;
border-radius: 12px !important; border-radius: 12px !important;
border: solid 1px #3f4864 !important;
color: #e3e5ef !important;
font-size: 12px; font-size: 12px;
} }
.el-picker-panel__footer .el-button { .el-picker-panel__footer .el-button {
background-color: #264dd9; background-color: #264dd9;
border-radius: 12px;
padding: 5px 12px; padding: 5px 12px;
color: #f4f7fc; color: #f4f7fc;
font-size: 12px; font-size: 12px;
...@@ -1339,10 +1409,12 @@ border-radius:8px; ...@@ -1339,10 +1409,12 @@ border-radius:8px;
.el-date-table.is-week-mode .el-date-table__row:hover div { .el-date-table.is-week-mode .el-date-table__row:hover div {
background-color: #eff2fa!important; background-color: #eff2fa!important;
} }
.el-date-table td.end-date .el-date-table-cell__text, .el-date-table td.end-date .el-date-table-cell__text,
.el-date-table td.start-date .el-date-table-cell__text { .el-date-table td.start-date .el-date-table-cell__text {
background-color: #3759be!important; background-color: #3759be!important;
} }
.el-date-table td.end-date span, .el-date-table td.end-date span,
.el-date-table td.start-date span { .el-date-table td.start-date span {
background-color: #264dd9; background-color: #264dd9;
...@@ -1358,7 +1430,9 @@ border-radius:8px; ...@@ -1358,7 +1430,9 @@ border-radius:8px;
color: #202531; color: #202531;
} }
/* table select window */ /* table select window */
.el-checkbox__input.is-checked .el-checkbox__inner, .el-checkbox__input.is-checked .el-checkbox__inner,
.el-checkbox__input.is-indeterminate .el-checkbox__inner { .el-checkbox__input.is-indeterminate .el-checkbox__inner {
background-color: #3759be; background-color: #3759be;
...@@ -1508,16 +1582,21 @@ border-radius:8px; ...@@ -1508,16 +1582,21 @@ border-radius:8px;
text-overflow: ellipsis; text-overflow: ellipsis;
word-break: break-all; word-break: break-all;
} }
.close_reason { .close_reason {
padding: 2px 5px; padding: 2px 5px;
background-color: #dedede; background-color: #dedede;
display: inline-block; display: inline-block;
margin-top: 10px; margin-top: 10px;
} }
.pointer { .pointer {
cursor: pointer; cursor: pointer;
} }
.pr-1 { .pr-1 {
padding-right: 10px; padding-right: 10px;
} }
/* test */ /* test */
\ No newline at end of file
...@@ -8,10 +8,10 @@ ...@@ -8,10 +8,10 @@
justify-content: flex-start; justify-content: flex-start;
align-items: stretch; align-items: stretch;
} }
.page_content { .page_content {
background-color: #fff; background-color: #fff;
height: calc(100% - 46px - 20px); height: calc(100% - 46px - 20px);
box-shadow: 0px 1px 4px 0px box-shadow: 0px 1px 4px 0px rgba(0, 7, 101, 0.15);
rgba(0, 7, 101, 0.15);
border-radius: 6px; border-radius: 6px;
} }
\ No newline at end of file
<template>
<div class="gap-title">
<span>{{title}}</span>
</div>
</template>
<script>
export default {
props: {
title:{
type:String,
default:""
}
},
components: {
},
data() {
return {
};
},
watch: {
},
computed: {
},
created() {
},
mounted() {
},
methods: {
},
};
</script>
<style scoped>
.gap-title{
font-size: 18px;
font-weight: 600;
color: #202531;
display: flex;
align-items: center;
}
.gap-title::before{
content:'';
display: inline-block;
margin-right: 8px;
width: 4px;
height: 16px;
background-color: #2b4695;
border-radius: 2px;
}
</style>
// 通知方式
export const METHODS = {
1: '钉钉',
2: '短信'
}
// 可以新增的数量
export const ADD_NUM = 5
\ No newline at end of file
<template>
<el-form
:model="state.form"
ref="form"
:rules="state.rules"
label-width="80px"
:disabled="disabled"
>
<el-form-item label="通知方式" prop="method">
<el-checkbox-group v-model="state.form.method">
<el-checkbox v-for="(value, key) in METHODS" :key="key" :label="key">
{{ value }}
</el-checkbox>
</el-checkbox-group>
</el-form-item>
<el-form-item label="" prop="lists" class="user-table bg-scroll">
<el-table :data="state.form.lists" stripe border>
<el-table-column type="index" label="序号" width="60px">
</el-table-column>
<el-table-column
v-for="header in headers"
:prop="header.prop"
:key="header.prop"
:label="header.label"
:width="header.width"
>
<template #default="{ $index }">
<div v-if="header.prop == 'user_id'">
<el-select
v-model="state.form.lists[$index].user_id"
placeholder="请选择"
filterable
@change="($event) => chooseUser($event, $index)"
>
<el-option
v-for="item in userOptions($index)"
:key="item.user_id"
:label="item.user_id"
:value="item.user_id"
>
</el-option>
</el-select>
</div>
<div v-else>
<el-input
v-model="state.form.lists[$index][header.prop]"
placeholder="请输入"
></el-input>
</div>
</template>
</el-table-column>
<el-table-column prop="" label="操作" width="125px">
<template #default="{ $index }">
<div class="table-operation">
<el-button
link
type="primary"
@click="Add($index)"
:disabled="
userLists.length <= state.form.lists.length ||
addTrue >= ADD_NUM
"
>
新增
</el-button>
<span class="line"></span>
<el-button
link
type="primary"
@click="Remove($index)"
:disabled="state.form.lists.length == 1"
>
删除
</el-button>
</div>
</template>
</el-table-column>
</el-table>
</el-form-item>
</el-form>
</template>
<script setup>
import { reactive, watch, ref, computed } from "vue";
import { METHODS, ADD_NUM } from "./env";
const props = defineProps({
disabled: {
type: Boolean,
default: false,
},
});
const form = ref(null);
// 表单数据
const state = reactive({
form: {
method: [],
lists: [],
},
rules: {
method: [
{
type: "array",
required: true,
message: "请至少选择一个通知方式",
trigger: "change",
},
],
},
});
// 已选中的用户id列表
const selectedUser = computed(() => {
return state.form.lists.map((e) => e.user_id) || [];
});
// 表头
const headers = [
{
prop: "user_id",
label: "账号",
},
{
prop: "user_name",
label: "姓名",
},
{
prop: "phone",
label: "联系方式",
},
];
// 立即下发
const Submit = (cb = null) => {
form.value.validate((valid) => {
if (valid) {
console.log(state.form);
cb && cb();
} else {
return false;
}
});
};
// 已经新增的数量记录
const addTrue = ref(0);
// 获取远程用户列表
const userLists = ref([]);
const getUserLists = () => {
userLists.value = [
{
user_id: 1,
user_name: 11,
phone: 13000000001,
},
{
user_id: 2,
user_name: 22,
phone: 13000000002,
},
{
user_id: 3,
user_name: 33,
phone: 13000000003,
},
{
user_id: 4,
user_name: 44,
phone: 13000000004,
},
{
user_id: 5,
user_name: 55,
phone: 13000000005,
},
{
user_id: 6,
user_name: 66,
phone: 13000000006,
},
{
user_id: 7,
user_name: 77,
phone: 13000000007,
},
];
};
// 格式化处理用户下拉列表,去除已经选择的用户,并将当前选中的也显示到列表中
const userOptions = computed(() => {
return (index) => {
let user_id = state.form.lists[index].user_id;
let s_u_ids = [...selectedUser.value];
if (user_id) {
let i = s_u_ids.findIndex((e) => e == user_id);
s_u_ids.splice(i, 1);
}
return userLists.value.filter((e) => !s_u_ids.includes(e.user_id));
};
});
// 表格新增
const Add = (index) => {
// 新增上限
if (addTrue.value >= ADD_NUM) return;
state.form.lists.splice(index + 1, 0, {
user_id: "",
user_name: "",
phone: "",
});
addTrue.value += 1;
};
// 表格删除
const Remove = (index) => {
state.form.lists.splice(index, 1);
addTrue.value -= 1;
};
// 初始化加载基础数据和获取用户下拉列表
const init = (history) => {
getUserLists();
state.form.method = history?.method || [];
state.form.lists = history?.lists || [];
// 如果没有默认下发用户则创建一条空数据
if (state.form.lists.length == 0) {
Add(0);
}
setTimeout(() => {
form.value.clearValidate();
});
};
// 选择用户操作
const chooseUser = ($event, index) => {
let user = userLists.value.find(
(e) => e.user_id == state.form.lists[index].user_id
);
state.form.lists[index].user_name = user.user_name;
state.form.lists[index].phone = user.phone;
};
defineExpose({
Submit,
form,
init,
});
watch(
() => state.form.lists,
(n) => {
console.log(n);
},
{ deep: true }
);
</script>
<style lang="scss" scoped>
.table-operation {
display: flex;
align-items: center;
.line {
width: 1px;
height: 14px;
background-color: #c1c7d7;
margin: 0 16px;
display: inline-block;
}
}
.user-table {
max-height: 345px;
:deep(.el-form-item__content) {
margin-left: 0 !important;
.el-table thead th {
background-color: #f5f6f9;
}
}
}
</style>
<template>
<el-dialog
v-model="show"
width="804px"
top="10vh"
:close-on-click-modal="false"
:before-close="beforeClose"
>
<template #header>
<GapTitle title="手动下发"></GapTitle>
</template>
<div class="manual-distribution">
<Form ref="form" />
</div>
<template #footer>
<el-button size="default" @click="Close">关闭</el-button>
<el-button type="primary" size="default" @click="Submit">
立即下发
</el-button>
</template>
</el-dialog>
</template>
<script setup>
import GapTitle from "@/components/gap-title.vue";
import Form from "./form.vue";
import { computed, nextTick, ref, watch } from "vue";
const props = defineProps({
// 显示隐藏开关
visible: {
type: Boolean,
default: false,
},
// 关闭前调用
beforeClose: {
type: Function,
default: null,
},
// 默认数据展示
/*
{
methd:['1','2'],
lists:[
{
user_id:'1111',
user_name:'11111111',
phone:'13011111111'
}
]
}
*/
history: {
type: Object,
default: null,
},
});
const emits = defineEmits(["update:visible"]);
const form = ref(null);
// 关闭调用
const Close = async () => {
form.value.form.resetFields();
emits("update:visible", false);
};
const show = computed({
get() {
return props.visible;
},
set() {
Close();
},
});
// 监听是否开启弹窗,并将已经填写的数据配置
watch(
() => show.value,
async (n) => {
if (!n) return;
await nextTick();
form.value.init(props.history);
},
{
immediate: true,
}
);
// 关闭前调用
const beforeClose = () => {
props.beforeClose && props.beforeClose();
Close();
};
// 立即下发
const Submit = () => {
form.value.Submit(() => {
Close();
});
};
</script>
<style lang="scss" scoped>
.manual-distribution {
text-align: left;
padding: 16px 16px 0;
}
</style>
<template>
<div
class="bg-filters"
:style="{
'border-bottom': showFlag ? 'none' : '',
'padding-bottom': showFlag ? '8px' : '16px',
}"
>
<div class="top-filter">
<div class="left-slot">
<slot name="left_action"></slot>
</div>
<div class="right-filter">
<el-input
v-model.trim="modelValue"
:placeholder="placeholder"
clearable
>
<template #append>
<div
class="append-btn"
style="margin-top: 1px"
@click="keywordAction"
>
<el-icon><Search /></el-icon>
</div>
</template>
</el-input>
<div
v-if="options.length > 0"
class="more-btn"
:class="showFlag ? 'more-btn1' : ''"
>
<el-button type="default" class="more-filter" @click="moreFilter">
高级搜索
<el-icon
v-if="!showFlag"
style="
font-weight: 900 !important;
color: #404a62;
margin-left: 8px;
"
><ArrowUp
/></el-icon>
<el-icon
v-else
style="
font-weight: 900 !important;
color: #404a62;
margin-left: 8px;
"
><ArrowDown
/></el-icon>
</el-button>
</div>
</div>
</div>
<div v-if="showFlag" class="filter-group">
<ul class="bg-flex-fs-c filters-list">
<li
v-for="(item, index) in options"
:key="`opt_${index}`"
class="bg-flex-fs-c"
>
<span v-if="item.label" class="filter-name">{{ item.label }}</span>
<!-- 下拉选 select -->
<el-select
v-if="item.type === 'select'"
v-model="filters[item.prop]"
:placeholder="item.placeholder || '请选择'"
:clearable="item.clearable !== false"
>
<el-option
v-for="(v, i) in item.options"
:key="`opt_${index}_v_${i}`"
:label="v.label"
:value="v.value"
/>
</el-select>
<!-- 年月日 daterange-->
<el-date-picker
v-else-if="item.type === 'daterange'"
v-model="filters[item.prop]"
type="daterange"
start-placeholder="开始日期"
range-separator="至"
end-placeholder="结束日期"
value-format="yyyy-MM-DD"
:picker-options="{ disabledDate: item.disabledDate }"
:clearable="item.clearable !== false"
/>
<!-- 年月日时分秒 datetimerange :shortcuts="shortcuts"(显示快捷键)-->
<el-date-picker
v-else-if="item.type === 'datetimerange'"
v-model="filters[item.prop]"
type="datetimerange"
start-placeholder="开始时间"
range-separator="至"
end-placeholder="结束时间"
value-format="YYYY-MM-DD HH:mm:ss"
:picker-options="{ disabledDate: item.disabledDate }"
:clearable="item.clearable !== false"
:shortcuts="item.shortcuts"
/>
<!-- 单选 -->
<el-cascader
v-else-if="item.type === 'cascader'"
v-model="filters[item.prop]"
:options="item.options"
:props="item.props"
:placeholder="item.placeholder || '请选择'"
collapse-tags
collapse-tags-tooltip
/>
<!-- 多选 -->
<el-cascader
v-else-if="item.type === 'collapse-cascader'"
v-model="filters[item.prop]"
:options="item.options"
:props="{
multiple: true,
}"
:placeholder="item.placeholder || '请选择'"
/>
<el-input
v-else
v-model="filters[item.prop]"
:placeholder="item.placeholder || '请输入'"
:clearable="item.clearable !== false"
prefix-icon="Search"
>
</el-input>
</li>
</ul>
<div class="filters-action">
<el-button type="primary" @click="searchAction"> 查询 </el-button>
<el-button type="default" @click="resetAction"> 重置 </el-button>
</div>
</div>
</div>
</template>
<script setup>
import {
defineProps,
defineEmits,
onBeforeMount,
reactive,
watch,
ref,
computed,
toRefs,
onMounted,
nextTick,
} from "vue";
let props = defineProps({
options: {
type: Array,
default: () => [],
},
immediately: {
type: Boolean,
default: true,
},
placeholder: {
type: String,
default: "请输入",
},
});
let emits = defineEmits([
"filters",
"filtersChange",
"keyword",
"keywordChange",
]);
let filters = reactive({});
let state = reactive({
showFlag: false,
modelValue: "",
});
onBeforeMount(() => {
if (props.immediately) {
initFilters();
}
});
onMounted(() => {
if (props.immediately) {
searchAction();
}
});
watch(
() => state.modelValue,
(newValue) => {
emits("keywordChange", newValue);
}
);
watch(filters, (newVal) => {
emits("filtersChange", newVal);
});
const initFilters = () => {
props.options.forEach(({ type, prop, defaultValue }) => {
let value = defaultValue || "";
if ((type === "daterange" || type === "datetimerange") && value === "") {
value = ["", ""];
}
if (type === "cascader" && value === "") {
value = [];
}
filters[prop] = value;
});
};
const keywordAction = () => {
emits("keyword", state.modelValue, filters);
};
const resetAction = () => {
initFilters();
nextTick(() => {
searchAction();
});
};
const searchAction = () => {
emits("filters", filters, state.modelValue);
};
const moreFilter = () => {
state.showFlag = !state.showFlag;
};
const reset = () => {
state.modelValue = "";
resetAction();
};
defineExpose({ reset });
const { modelValue, showFlag } = toRefs(state);
</script>
<style lang="scss" scoped>
// 列表筛选
.bg-filters {
width: 100%;
padding: 16px;
border-bottom: 1px solid #e6e9ef;
.top-filter {
width: 100%;
display: flex;
.left-slot {
flex: 1;
}
.right-filter {
width: 398px;
justify-content: end;
display: flex;
:deep(.el-input-group__append) {
padding: 0;
border-radius: 0;
}
.el-input {
width: 280px;
height: 36px;
.el-input-group__append {
border-radius: 0 4px 4px 0;
background-color: #f7f7f9;
padding: 0;
.append-btn {
padding: 0 16px;
cursor: pointer;
}
}
}
.more-btn {
margin-left: 16px;
width: 102px;
box-sizing: border-box;
border: 1px solid #e6e9ef;
border-radius: 4px;
height: 36px;
.more-filter {
width: 100px;
border: none;
height: 34px;
padding: 10px 15px;
line-height: 1;
&:active,
&:hover {
background-color: #fff;
color: #3759be;
}
&:focus {
background-color: #fff;
}
}
}
.more-btn1 {
height: 53px;
border-bottom: 1px solid #fff;
border-radius: 4px 4px 0 0;
margin-bottom: -1px;
}
}
}
.filter-group {
display: flex;
align-items: flex-end;
border-radius: 4px 0 4px 4px;
width: 100%;
border: 1px solid #e6e9ef;
padding: 24px 16px 8px;
}
.filters-list {
display: flex;
justify-content: flex-start;
align-items: center;
flex-grow: 1;
flex-wrap: wrap;
li {
margin: 0 48px 16px 0;
display: flex;
justify-content: flex-start;
align-items: center;
.filter-name {
font-size: 14px;
// font-weight: bolder;
line-height: 20px;
color: #202531;
white-space: nowrap;
margin-right: 8px;
width: 90px;
text-align: right;
& + * {
margin-left: 0;
}
}
.el-input {
width: 240px;
height: 36px;
}
.el-select {
width: 240px;
height: 36px;
}
.el-range-editor {
width: 320px;
height: 36px;
&.el-date-editor--datetimerange {
width: 360px;
height: 36px;
}
}
}
}
.filters-action {
flex-shrink: 0;
padding-bottom: 16px;
}
}
</style>
<template>
<el-pagination
layout="total,sizes ,prev, pager, next,jumper"
:page-size="pagination.rowsPerPage"
:current-page="pagination.page"
:total="pagination.total"
:page-sizes="[15, 30, 50]"
@current-change="handleCurrentChange"
@size-change="handleSizeChange"
></el-pagination>
</template>
<script setup>
import { defineProps, defineEmits } from 'vue'
let props = defineProps({
pagination: {
type: Object,
default() {
return {
rowsPerPage: 15,
page: 1,
total: 0,
}
},
}, // 表格数据
})
const emits = defineEmits(['current', 'sizechange'])
const handleCurrentChange = (val) => {
emits('current', val)
}
const handleSizeChange = (val) => {
emits('sizechange', val)
}
</script>
<template>
<div class="href" @click="goTo">{{ label }}</div>
</template>
<script setup>
import { computed } from "vue";
import { useRouter } from "vue-router";
const router = useRouter();
const props = defineProps({
row: {
type: Object,
default: () => ({}),
},
header: {
type: Object,
default: () => ({}),
},
});
const label = computed(() => props.row[props.header.prop]);
const href = computed(() => {
const { baseurl: path, params } = props.header.href;
const query = {};
Object.keys(params).forEach((key) => {
query[key] = props.row[params[key]];
});
return {
path,
query,
};
});
const goTo = () => {
router.push(href.value);
};
</script>
<style lang="scss" scoped>
.href {
font-size: 14px;
color: #3759be;
cursor: pointer;
}
</style>
<template>
<div class="bg-table-list" v-bind="$attrs">
<div v-if="$slots.tabs" class="bg-list-tabs">
<slot name="tabs" />
</div>
<!-- 筛选条件 -->
<div v-if="$slots.filter" class="bg-list-filters">
<slot name="filter" />
</div>
<!-- 列表 -->
<main v-if="$slots.main" class="bg-container-main">
<div>
<slot name="main" />
</div>
</main>
<!-- 分页 -->
<footer v-if="$slots.footer" class="bg-container-footer">
<slot name="footer" />
</footer>
<!-- </div> -->
</div>
<slot />
</template>
<script>
export default {
name: "BgTableList",
};
</script>
<style lang="scss" scoped>
.bg-table-list {
height: 100%;
width: 100%;
display: flex;
flex-direction: column;
align-content: stretch;
}
.bg-container-main {
margin: 0 16px;
flex: 1;
position: relative;
& > div {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
:deep(.el-table__body-wrapper) {
height: calc(100% - 46px);
}
}
}
.bg-container-footer {
padding: 16px;
:deep(.el-pagination) {
justify-content: flex-end;
}
}
</style>
<template>
<el-table
ref="bgTable"
:data="tablerows"
style="width: 100%"
class="bg-table"
:height="height"
stripe
tooltip-effect="light"
:border="border"
@selection-change="selectAction"
@sort-change="sortChange"
>
<!-- 多选框 -->
<el-table-column
v-if="isSelect"
type="selection"
:selectable="selectables"
width="50"
align="center"
>
</el-table-column>
<el-table-column
v-if="isIndex"
type="index"
:label="indexLabel"
width="50"
>
<!-- 序号 -->
</el-table-column>
<el-table-column
v-for="(header, index) in headers"
:key="'col_' + index"
:width="header.width"
:min-width="header.minWidth"
:align="header.align"
:show-overflow-tooltip="showOverflowTooltip"
:sortable="header.sortable ? 'custom' : null"
:prop="header.prop"
>
<template #header>
<p class="text-header">{{ header.label }}</p>
</template>
<template #default="scope">
<slot
v-if="$slots[header.prop]"
:index="scope.$index"
:name="header.prop"
:row="scope.row"
:header="header"
/>
<template v-else>
{{ scope.row[header.prop] || "-" }}
</template>
</template>
</el-table-column>
</el-table>
</template>
<script setup>
import {
defineProps,
onMounted,
computed,
defineEmits,
watch,
getCurrentInstance,
} from "vue";
const { proxy } = getCurrentInstance();
let props = defineProps({
headers: { type: Array, default: () => [] }, // 表头
rows: { type: Array, default: () => [] }, // 表格数据
//标签列是要展开所有内容
showOverflowTooltip: {
type: Boolean,
default: true,
},
//table高度
height: {
type: String,
default: undefined,
},
// 是否有多选列
isSelect: {
type: Boolean,
default: false,
},
// 是否有border
border: {
type: Boolean,
default: false,
},
isIndex: {
type: Boolean,
default: false,
},
indexLabel: {
type: String,
default: "序号",
},
});
const emits = defineEmits(["select", "sortchange"]);
// 权限展示列的时候计算属性
let tablerows = computed(() => {
return props.rows;
});
watch(
props.rows,
(newValue) => {
toggleRowSelection(newValue);
},
{ immediate: false, deep: true }
);
// ***********多选框功能start
// 选中项
const selectAction = (selection) => {
emits("select", selection);
};
// 后端返回数据带选中内容
const toggleRowSelection = (rows) => {
rows.forEach((row) => {
if (row.isSelet == true) {
proxy.$nextTick(function () {
proxy.$refs.bgTable.toggleRowSelection(row, true);
});
}
});
};
// *********多选是否禁用**********
const selectables = (row) => {
if (row.state !== 2) {
return true;
}
};
// ***********多选框功能end
const clearSelection = () => {
proxy.$refs.bgTable.clearSelection();
};
const sortChange = (column) => {
emits("sortchange", column);
};
defineExpose({ clearSelection });
</script>
<template>
<el-dialog
v-model="show"
width="774px"
top="10vh"
:before-close="beforeClose"
:close-on-click-modal="false"
>
<template #header>
<GapTitle title="关闭工单"></GapTitle>
</template>
<div class="feedback-body">
<el-form
:model="state.form"
ref="form"
:rules="state.rules"
label-width="80px"
>
<el-form-item label="关闭原因" prop="reason">
<el-input
type="textarea"
v-model="state.form.reason"
rows="5"
placeholder="请输入关闭原因"
></el-input>
</el-form-item>
</el-form>
</div>
<template #footer>
<el-button size="default" @click="Close">关闭</el-button>
<el-button type="primary" size="default" @click="Submit">提交</el-button>
</template>
</el-dialog>
</template>
<script setup>
import { computed, reactive, ref } from "vue";
import GapTitle from "@/components/gap-title.vue";
const props = defineProps({
visible: {
type: Boolean,
default: false,
},
beforeClose: {
type: Function,
default: () => {},
},
active_row: {
type: Object,
default: null,
},
});
const state = reactive({
form: {
reason: "",
},
rules: {
reason: [{ required: true, message: "请输入关闭原因", trigger: "blur" }],
},
});
const emits = defineEmits(["update:visible"]);
const form = ref(null);
const Close = () => {
form.value.resetFields();
emits("update:visible", false);
};
const show = computed({
get() {
return props.visible;
},
set() {
Close();
},
});
const beforeClose = () => {
props.beforeClose();
Close();
};
const Submit = () => {
form.value.validate((valid) => {
if (valid) {
console.log(state.form);
} else {
return false;
}
});
};
</script>
<style lang="scss" scoped>
.feedback-body {
text-align: left;
padding: 24px 16px 0;
}
</style>
<template>
<div class="my-alert">
<div class="breadcrumb"></div>
<div class="content">
<bg-table-list>
<template #filter>
<bg-filter-form
:keyword="search"
placeholder="请输入任务名称"
:options="filter_data"
@keyword="keywordAction"
@filters="get_filter_list"
>
</bg-filter-form>
</template>
<template #main>
<bg-table
ref="listtable"
:headers="headers"
:rows="rows"
height="100%"
:isIndex="true"
:stripe="true"
>
<template #work_order_name="{ row, header }">
<BgTableHref
:row="row"
:header="header"
></BgTableHref>
</template>
<template #operation="{ row }">
<span class="primary-edit" @click="operation(row)">
关闭工单
</span>
</template>
</bg-table>
</template>
<template #footer>
<bg-pagination
:pagination="pagination"
@sizechange="sizechange"
@current="current"
>
</bg-pagination>
</template>
</bg-table-list>
<!-- <el-button type="primary" size="default" @click="feedback">
处置反馈
</el-button> -->
<!-- <ManualDistributionForm ref="form" :disabled="true" /> -->
<CloseWorkOrder v-model:visible="visible" :active_row="active_row" />
<!-- <ManualDistribution v-model:visible="visible" /> -->
</div>
</div>
</template>
<script setup>
// import { nextTick, onBeforeMount, onMounted, ref } from "vue";
// import ManualDistribution from "@/components/manual-distribution/index.vue";
// import ManualDistributionForm from "@/components/manual-distribution/form.vue";
// const form = ref(null);
// onMounted(async () => {
// await nextTick();
// form.value.init({
// method: ["1", "2"],
// lists: [
// {
// user_id: 1,
// user_name: 1111,
// phone: "13011111111",
// },
// ],
// });
// });
import { ref, reactive, onMounted, nextTick } from "vue";
import bgTableList from "@/components/table/bg-table-list.vue";
import BgTableHref from "@/components/table/bg-table-href.vue";
import bgFilterForm from "@/components/table/bg-filter-form.vue";
import bgPagination from "@/components/table/bg-pagination.vue";
import bgTable from '@/components/table/bg-table.vue'
import CloseWorkOrder from "./close-work-order.vue";
let search = ref("");
let filter_data = reactive([
{
label: "工单等级",
prop: "work_order_level",
type: "select",
options: [
{
value: "",
label: "全部",
},
],
},
{
label: "状态",
prop: "status",
type: "select",
options: [
{
value: "",
label: "全部",
},
],
},
{
label: "创建时间",
prop: "create_time",
type: "datetimerange",
},
{
label: "完成时间",
prop: "finish_time",
type: "datetimerange",
},
]);
let headers = reactive([
{
label: "工单名称",
prop: "work_order_name",
align: "left",
href: {
baseurl: "/work-order/my-business-detail",
params: { id: "id", name: "work_order_name" },
},
},
{
label: "工单等级",
prop: "work_order_level",
align: "left",
},
{
label: "工单状态",
prop: "work_order_status",
align: "left",
},
{
label: "下发对象",
prop: "distribute_target",
align: "left",
},
{
label: "创建人",
prop: "create_by",
align: "left",
},
{
label: "创建时间",
prop: "create_time",
align: "left",
},
{
label: "完成时间",
prop: "finish_time",
align: "left",
},
{
label: "操作",
prop: "operation",
align: "left",
width: "80px",
},
]);
let rows = ref([
{ work_order_name: 11, id: 111 },
{ work_order_name: 22, id: 222 },
{ work_order_name: 33, id: 333 },
]);
const pagination = reactive({
rowsPerPage: 15,
page: 1,
total: 0,
});
let searchData = reactive({
create_time: [],
finish_time: [],
work_order_level:"",
status: "",
});
// *********分页start
const sizechange = (val) => {
pagination.page = 1;
pagination.rowsPerPage = val;
init();
};
const current = (val) => {
pagination.page = val;
init();
};
onMounted(() => {
init();
});
//搜索内容
const get_filter_list = (
{ create_time, finish_time, work_order_level, status },
val
) => {
pagination.rowsPerPage = 15;
pagination.page = 1;
searchData.create_time = create_time || [];
searchData.finish_time = finish_time || [];
searchData.work_order_level = work_order_level;
searchData.status = status;
search.value = val.value;
init();
};
const init = async () => {
let [createStartTime, createEndTime] = searchData.create_time;
let [finishStartTime, finishEndTime] = searchData.finish_time;
let urlParams = {
keyword: search.value || "",
createStartTime,
createEndTime,
finishStartTime,
finishEndTime,
work_order_level: searchData.work_order_level,
status: searchData.status,
page: pagination.page,
limit: pagination.rowsPerPage,
};
// const { data, total } = await instanceList(urlParams);
// rows.value = data.list || [];
// pagination.total = data.total_count;
};
const keywordAction = async (val) => {
search.value = val;
init();
};
// 处置反馈
const visible = ref(false);
const active_row = ref(null);
const operation = (row) => {
active_row.value = row;
visible.value = true;
};
</script>
<style lang="scss" scoped>
.my-alert {
width: 100%;
height: 100%;
padding: 0 24px 16px;
.breadcrumb {
width: 100%;
height: 46px;
}
.content {
width: 100%;
height: calc(100% - 46px);
background-color: #ffffff;
box-shadow: 0px 1px 4px 0px rgba(0, 7, 101, 0.15);
border-radius: 6px;
}
}
</style>
<template>
<div>
business-manage-detail
</div>
</template>
<script setup>
</script>
<style lang="scss" scoped>
</style>
\ No newline at end of file
<template>
<div class="my-alert">
<div class="breadcrumb"></div>
<div class="content">
<bg-table-list>
<template #filter>
<bg-filter-form
:keyword="search"
placeholder="请输入任务名称"
:options="filter_data"
@keyword="keywordAction"
@filters="get_filter_list"
>
<template #left_action>
<div class="left_action">
<el-button type="primary" @click="AddWorkOrder">
新增
</el-button>
<el-button type="danger" @click="delBatch">
批量删除
</el-button>
<span class="select-num">
已选择
<span>{{ selectedItems.length }}</span>
</span>
<el-button type="primary" link @click="clearSelected"
>清空</el-button
>
</div>
</template>
</bg-filter-form>
</template>
<template #main>
<bg-table
ref="listtable"
:headers="headers"
:rows="rows"
height="100%"
:isIndex="true"
:isSelect="true"
:stripe="true"
@select="selectRows"
>
<template #work_order_name="{ row, header }">
<BgTableHref :row="row" :header="header"></BgTableHref>
</template>
<template #status="{ row }">
<span>
<span>{{ status[row.status] }}</span>
<span v-if="row.status != 3">
{{ row.finish }}/{{ row.all }}
</span>
</span>
</template>
<template #operation="{ row }">
<div class="table-operation">
<span class="primary-edit" @click="operation(row)">
手动下发
</span>
<span class="line"></span>
<span class="primary-edit" @click="Edit(row)"> 编辑 </span>
<span class="line"></span>
<span class="primary-edit" @click="Delete(row)"> 删除 </span>
</div>
</template>
</bg-table>
</template>
<template #footer>
<bg-pagination
:pagination="pagination"
@sizechange="sizechange"
@current="current"
>
</bg-pagination>
</template>
</bg-table-list>
<ManualDistribution v-model:visible="visible" :active_row="active_row" />
</div>
</div>
</template>
<script setup>
import { ref, reactive, onMounted, nextTick, computed } from "vue";
import bgTableList from "@/components/table/bg-table-list.vue";
import BgTableHref from "@/components/table/bg-table-href.vue";
import bgFilterForm from "@/components/table/bg-filter-form.vue";
import bgPagination from "@/components/table/bg-pagination.vue";
import bgTable from "@/components/table/bg-table.vue";
import ManualDistribution from "@/components/manual-distribution/index.vue";
const status = {
1: "已完成",
2: "待处置",
3: "已关闭",
};
let search = ref("");
let filter_data = reactive([
{
label: "工单等级",
prop: "work_order_level",
type: "select",
options: [
{
value: "",
label: "全部",
},
],
},
{
label: "状态",
prop: "status",
type: "select",
options: [
{
value: "",
label: "全部",
},
],
},
{
label: "创建时间",
prop: "create_time",
type: "datetimerange",
},
{
label: "完成时间",
prop: "finish_time",
type: "datetimerange",
},
]);
let headers = reactive([
{
label: "工单名称",
prop: "work_order_name",
align: "left",
href: {
baseurl: "/work-order/business-manage-detail",
params: { id: "id", name: "work_order_name" },
},
},
{
label: "工单等级",
prop: "work_order_level",
align: "left",
},
{
label: "实例工单数",
prop: "example_work_order_num",
align: "left",
},
{
label: "下发对象",
prop: "distribute_target",
align: "left",
},
{
label: "定时规则",
prop: "timing_rules",
align: "left",
},
{
label: "定时是否启用",
prop: "status",
align: "left",
width: 150,
},
{
label: "创建人",
prop: "create_by",
align: "left",
},
{
label: "创建时间",
prop: "create_time",
align: "left",
},
{
label: "操作",
prop: "operation",
align: "left",
width: "200px",
},
]);
let rows = ref([
{ work_order_name: 11, id: 111, status: 1, finish: 10, all: 10 },
{ work_order_name: 22, id: 222, status: 2, finish: 5, all: 10 },
{ work_order_name: 33, id: 333, status: 3, finish: 0, all: 10 },
]);
const pagination = reactive({
rowsPerPage: 15,
page: 1,
total: 0,
});
let searchData = reactive({
create_time: [],
finish_time: [],
work_order_level: "",
status: "",
});
// *********分页start
const sizechange = (val) => {
pagination.page = 1;
pagination.rowsPerPage = val;
init();
};
const current = (val) => {
pagination.page = val;
init();
};
//搜索内容
const get_filter_list = (
{ create_time, finish_time, work_order_level, status },
val
) => {
pagination.rowsPerPage = 15;
pagination.page = 1;
searchData.create_time = create_time || [];
searchData.finish_time = finish_time || [];
searchData.work_order_level = work_order_level;
searchData.status = status;
search.value = val.value;
init();
};
const init = async () => {
let [createStartTime, createEndTime] = searchData.create_time;
let [finishStartTime, finishEndTime] = searchData.finish_time;
let urlParams = {
keyword: search.value || "",
createStartTime,
createEndTime,
finishStartTime,
finishEndTime,
work_order_level: searchData.work_order_level,
status: searchData.status,
page: pagination.page,
limit: pagination.rowsPerPage,
};
// const { data, total } = await instanceList(urlParams);
// rows.value = data.list || [];
// pagination.total = data.total_count;
};
const keywordAction = async (val) => {
search.value = val;
init();
};
// 手动下发
const visible = ref(false);
const active_row = ref(null);
const operation = (row) => {
active_row.value = row;
visible.value = true;
};
// 编辑调用
const Edit = (row) => {
active_row.value = row;
};
// 删除调用
const selectedItems = ref([]);
const Delete = (row) => {
selectedItems.value = [row];
console.log(del_ids.value);
};
const del_ids = computed(() => {
return selectedItems.value.map((e) => e.id) || [];
});
// 表格选中
const selectRows = (items) => {
selectedItems.value = items;
};
// 新增
const AddWorkOrder = () => {};
// 批量删除
const delBatch = () => {
console.log(del_ids.value);
};
// 清空选中
const listtable = ref(null);
const clearSelected = () => {
listtable.value.clearSelection();
};
onMounted(() => {
init();
});
</script>
<style lang="scss" scoped>
.my-alert {
width: 100%;
height: 100%;
padding: 0 24px 16px;
.breadcrumb {
width: 100%;
height: 46px;
}
.content {
width: 100%;
height: calc(100% - 46px);
background-color: #ffffff;
box-shadow: 0px 1px 4px 0px rgba(0, 7, 101, 0.15);
border-radius: 6px;
.select-num {
margin: 0 40px 0 24px;
font-size: 14px;
color: #404a62;
span {
font-weight: bold;
}
}
.table-operation {
display: flex;
align-items: center;
.line {
width: 1px;
height: 14px;
background-color: #c1c7d7;
margin: 0 16px;
display: inline-block;
}
}
}
}
</style>
<template>
<div>detail</div>
</template>
<script setup></script>
<style lang="scss" scoped></style>
<template>
<el-dialog
v-model="show"
width="774px"
top="10vh"
:before-close="beforeClose"
:close-on-click-modal="false"
>
<template #header>
<GapTitle title="处置反馈"></GapTitle>
</template>
<div class="feedback-body">
<el-form
:model="state.form"
ref="form"
:rules="state.rules"
label-width="80px"
>
<el-form-item label="预警状态" prop="status">
<el-radio-group v-model="state.form.status">
<el-radio v-for="(value, key) in status" :key="key" :label="key">
{{ value }}
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="结果反馈" prop="result">
<el-input
type="textarea"
v-model="state.form.result"
rows="5"
placeholder="请输入结果反馈"
></el-input>
</el-form-item>
</el-form>
</div>
<template #footer>
<el-button size="default" @click="Close">关闭</el-button>
<el-button type="primary" size="default" @click="Submit">保存</el-button>
</template>
</el-dialog>
</template>
<script setup>
import { computed, reactive, ref } from "vue";
import GapTitle from "@/components/gap-title.vue";
const props = defineProps({
visible: {
type: Boolean,
default: false,
},
beforeClose: {
type: Function,
default: () => {},
},
active_row: {
type: Object,
default: null,
},
});
const state = reactive({
form: {
status: "",
result: "",
},
rules: {
status: [{ required: true, message: "请选择预警状态", trigger: "change" }],
result: [{ required: true, message: "请输入结果反馈", trigger: "blur" }],
},
});
const status = {
1: "未恢复",
2: "已恢复",
};
const emits = defineEmits(["update:visible"]);
const form = ref(null);
const Close = () => {
form.value.resetFields();
emits("update:visible", false);
};
const show = computed({
get() {
return props.visible;
},
set() {
Close();
},
});
const beforeClose = () => {
props.beforeClose();
Close();
};
const Submit = () => {
form.value.validate((valid) => {
if (valid) {
console.log(state.form);
} else {
return false;
}
});
};
</script>
<style lang="scss" scoped>
.feedback-body {
text-align: left;
padding: 24px 16px 0;
}
</style>
<template>
<div>
my-alert-detail
</div>
</template>
<script setup>
</script>
<style lang="scss" scoped>
</style>
\ No newline at end of file
<template>
<div class="my-alert">
<div class="breadcrumb"></div>
<div class="content">
<bg-table-list>
<template #filter>
<bg-filter-form
:keyword="search"
placeholder="请输入预警点"
:options="filter_data"
@keyword="keywordAction"
@filters="get_filter_list"
>
</bg-filter-form>
</template>
<template #main>
<bg-table
ref="listtable"
:headers="headers"
:rows="rows"
height="100%"
:isIndex="true"
:stripe="true"
>
<template #warning_point="{ row, header }">
<BgTableHref :row="row" :header="header"></BgTableHref>
</template>
<template #operation="{ row }">
<span class="primary-edit" @click="operation(row)">
处置反馈
</span>
</template>
</bg-table>
</template>
<template #footer>
<bg-pagination
:pagination="pagination"
@sizechange="sizechange"
@current="current"
>
</bg-pagination>
</template>
</bg-table-list>
<!-- <el-button type="primary" size="default" @click="feedback">
处置反馈
</el-button> -->
<!-- <ManualDistributionForm ref="form" :disabled="true" /> -->
<FeedBack v-model:visible="visible" :active_row="active_row" />
<!-- <ManualDistribution v-model:visible="visible" /> -->
</div>
</div>
</template>
<script setup>
// import { nextTick, onBeforeMount, onMounted, ref } from "vue";
// import ManualDistribution from "@/components/manual-distribution/index.vue";
// import ManualDistributionForm from "@/components/manual-distribution/form.vue";
// const form = ref(null);
// onMounted(async () => {
// await nextTick();
// form.value.init({
// method: ["1", "2"],
// lists: [
// {
// user_id: 1,
// user_name: 1111,
// phone: "13011111111",
// },
// ],
// });
// });
import { ref, reactive, onMounted, nextTick } from "vue";
import bgTableList from "@/components/table/bg-table-list.vue";
import BgTableHref from "@/components/table/bg-table-href.vue";
import bgFilterForm from "@/components/table/bg-filter-form.vue";
import bgPagination from "@/components/table/bg-pagination.vue";
import bgTable from '@/components/table/bg-table.vue'
import FeedBack from "../modules/feedback.vue";
let search = ref("");
let filter_data = reactive([
{
label: "预警分类",
prop: "waining_type",
type: "select",
options: [
{
value: "",
label: "全部",
},
],
},
{
label: "预警指标",
prop: "warning_index",
type: "select",
options: [
{
value: "",
label: "全部",
},
],
},
{
label: "风险等级",
prop: "risk_level",
type: "select",
options: [
{
value: "",
label: "全部",
},
],
},
{
label: "状态",
prop: "status",
type: "select",
options: [
{
value: "",
label: "全部",
},
],
},
{
label: "预警时段",
prop: "date",
type: "datetimerange",
},
]);
let headers = reactive([
{
label: "预警点",
prop: "warning_point",
align: "left",
href: {
baseurl: "/work-order/my-alert-detail",
params: { id: "warning_point" },
},
},
{
label: "预警时间",
prop: "warning_time",
align: "left",
},
{
label: "预警分类",
prop: "warning_type",
align: "left",
},
{
label: "预警指标",
prop: "warning_index",
align: "left",
},
{
label: "风险等级",
prop: "risk_level",
align: "left",
},
{
label: "当前报警值",
prop: "current_alarm_value",
align: "left",
},
{
label: "预警阀值",
prop: "warning_threshold",
align: "left",
},
{
label: "推送次数",
prop: "push_num",
align: "left",
},
{
label: "最近推送时间",
prop: "push_time",
align: "left",
},
{
label: "状态",
prop: "status",
align: "left",
},
{
label: "操作",
prop: "operation",
align: "left",
width: "80px",
},
]);
let rows = ref([{
warning_point:1
}]);
const pagination = reactive({
rowsPerPage: 15,
page: 1,
total: 0,
});
let searchData = reactive({
date: [],
waining_type: "",
warning_index: "",
risk_level: "",
status: "",
});
// *********分页start
const sizechange = (val) => {
pagination.page = 1;
pagination.rowsPerPage = val;
init();
};
const current = (val) => {
pagination.page = val;
init();
};
onMounted(() => {
init();
});
//搜索内容
const get_filter_list = (
{ date, waining_type, warning_index, risk_level, status },
val
) => {
pagination.rowsPerPage = 15;
pagination.page = 1;
searchData.date = date || [];
searchData.waining_type = waining_type;
searchData.warning_index = warning_index;
searchData.risk_level = risk_level;
searchData.status = status;
search.value = val.value;
init();
};
const init = async () => {
let [startTime, endTime] = searchData.date;
let urlParams = {
keyword: search.value || "",
startTime,
endTime,
waining_type: searchData.waining_type,
warning_index: searchData.warning_index,
risk_level: searchData.risk_level,
status: searchData.status,
page: pagination.page,
limit: pagination.rowsPerPage,
};
// const { data, total } = await instanceList(urlParams);
// rows.value = data.list || [];
// pagination.total = data.total_count;
};
const keywordAction = async (val) => {
search.value = val;
init();
};
// 处置反馈
const visible = ref(false);
const active_row = ref(null);
const operation = (row) => {
active_row.value = row;
visible.value = true;
};
</script>
<style lang="scss" scoped>
.my-alert {
width: 100%;
height: 100%;
padding: 0 24px 16px;
.breadcrumb {
width: 100%;
height: 46px;
}
.content {
width: 100%;
height: calc(100% - 46px);
background-color: #ffffff;
box-shadow: 0px 1px 4px 0px rgba(0, 7, 101, 0.15);
border-radius: 6px;
}
}
</style>
<template>
<div>my-business-detail</div>
</template>
<script setup></script>
<style lang="scss" scoped></style>
<template>
<div class="my-alert">
<div class="breadcrumb"></div>
<div class="content">
<bg-table-list>
<template #filter>
<bg-filter-form
:keyword="search"
placeholder="请输入任务名称"
:options="filter_data"
@keyword="keywordAction"
@filters="get_filter_list"
>
</bg-filter-form>
</template>
<template #main>
<bg-table
ref="listtable"
:headers="headers"
:rows="rows"
height="100%"
:isIndex="true"
:stripe="true"
>
<template #work_order_name="{ row, header }">
<BgTableHref
:row="row"
:header="header"
></BgTableHref>
</template>
<template #operation="{ row }">
<span class="primary-edit" @click="operation(row)">
处置反馈
</span>
</template>
</bg-table>
</template>
<template #footer>
<bg-pagination
:pagination="pagination"
@sizechange="sizechange"
@current="current"
>
</bg-pagination>
</template>
</bg-table-list>
<!-- <el-button type="primary" size="default" @click="feedback">
处置反馈
</el-button> -->
<!-- <ManualDistributionForm ref="form" :disabled="true" /> -->
<FeedBack v-model:visible="visible" :active_row="active_row" />
<!-- <ManualDistribution v-model:visible="visible" /> -->
</div>
</div>
</template>
<script setup>
// import { nextTick, onBeforeMount, onMounted, ref } from "vue";
// import ManualDistribution from "@/components/manual-distribution/index.vue";
// import ManualDistributionForm from "@/components/manual-distribution/form.vue";
// const form = ref(null);
// onMounted(async () => {
// await nextTick();
// form.value.init({
// method: ["1", "2"],
// lists: [
// {
// user_id: 1,
// user_name: 1111,
// phone: "13011111111",
// },
// ],
// });
// });
import { ref, reactive, onMounted, nextTick } from "vue";
import bgTableList from "@/components/table/bg-table-list.vue";
import BgTableHref from "@/components/table/bg-table-href.vue";
import bgFilterForm from "@/components/table/bg-filter-form.vue";
import bgPagination from "@/components/table/bg-pagination.vue";
import bgTable from '@/components/table/bg-table.vue'
import FeedBack from "../modules/feedback.vue";
let search = ref("");
let filter_data = reactive([
{
label: "工单等级",
prop: "work_order_level",
type: "select",
options: [
{
value: "",
label: "全部",
},
],
},
{
label: "状态",
prop: "status",
type: "select",
options: [
{
value: "",
label: "全部",
},
],
},
{
label: "创建时间",
prop: "create_time",
type: "datetimerange",
},
{
label: "完成时间",
prop: "finish_time",
type: "datetimerange",
},
]);
let headers = reactive([
{
label: "工单名称",
prop: "work_order_name",
align: "left",
href: {
baseurl: "/work-order/my-business-detail",
params: { id: "id", name: "work_order_name" },
},
},
{
label: "工单等级",
prop: "work_order_level",
align: "left",
},
{
label: "工单状态",
prop: "work_order_status",
align: "left",
},
{
label: "下发对象",
prop: "distribute_target",
align: "left",
},
{
label: "创建人",
prop: "create_by",
align: "left",
},
{
label: "创建时间",
prop: "create_time",
align: "left",
},
{
label: "完成时间",
prop: "finish_time",
align: "left",
},
{
label: "操作",
prop: "operation",
align: "left",
width: "80px",
},
]);
let rows = ref([
{ work_order_name: 11, id: 111 },
{ work_order_name: 22, id: 222 },
{ work_order_name: 33, id: 333 },
]);
const pagination = reactive({
rowsPerPage: 15,
page: 1,
total: 0,
});
let searchData = reactive({
date: [],
waining_type: "",
warning_index: "",
risk_level: "",
status: "",
});
// *********分页start
const sizechange = (val) => {
pagination.page = 1;
pagination.rowsPerPage = val;
init();
};
const current = (val) => {
pagination.page = val;
init();
};
onMounted(() => {
init();
});
//搜索内容
const get_filter_list = (
{ create_time, finish_time, work_order_level, status },
val
) => {
pagination.rowsPerPage = 15;
pagination.page = 1;
searchData.create_time = create_time || [];
searchData.finish_time = finish_time || [];
searchData.work_order_level = work_order_level;
searchData.status = status;
search.value = val.value;
init();
};
const init = async () => {
let [createStartTime, createEndTime] = searchData.create_time;
let [finishStartTime, finishEndTime] = searchData.finish_time;
let urlParams = {
keyword: search.value || "",
createStartTime,
createEndTime,
finishStartTime,
finishEndTime,
work_order_level: searchData.work_order_level,
status: searchData.status,
page: pagination.page,
limit: pagination.rowsPerPage,
};
// const { data, total } = await instanceList(urlParams);
// rows.value = data.list || [];
// pagination.total = data.total_count;
};
const keywordAction = async (val) => {
search.value = val;
init();
};
// 处置反馈
const visible = ref(false);
const active_row = ref(null);
const operation = (row) => {
active_row.value = row;
visible.value = true;
};
</script>
<style lang="scss" scoped>
.my-alert {
width: 100%;
height: 100%;
padding: 0 24px 16px;
.breadcrumb {
width: 100%;
height: 46px;
}
.content {
width: 100%;
height: calc(100% - 46px);
background-color: #ffffff;
box-shadow: 0px 1px 4px 0px rgba(0, 7, 101, 0.15);
border-radius: 6px;
}
}
</style>
//路由前端原则可以不写,但是需要在recorder中记录,防止以后忘记 //路由前端原则可以不写,但是需要在recorder中记录,防止以后忘记
//不用新建父路由的文件,父路由全部由parent/parent.vue来支撑 //不用新建父路由的文件,父路由全部由parent/parent.vue来支撑
import {createRouter, createWebHashHistory} from "vue-router"; import { createRouter, createWebHashHistory } from "vue-router";
import store from '../store' import store from '../store'
let work_order = [{
path: '/work-order',
name: 'work-order',
component: () =>
import ("../page/parent/parent.vue"),
redirect: "/work-order/my-alert",
children: [{
path: '/work-order/my-alert',
name: 'my-alert',
show: true,
component: () =>
import ("../page/main/work-order/my-alert-work-order/index.vue")
},
{
path: '/work-order/my-alert-detail',
name: 'my-alert-detail',
show: true,
component: () =>
import ("../page/main/work-order/my-alert-work-order/detail.vue")
},
{
path: '/work-order/my-business',
name: 'my-business',
show: true,
component: () =>
import ("../page/main/work-order/my-business-work-order/index.vue")
},
{
path: '/work-order/my-business-detail',
name: 'my-business-detail',
show: true,
component: () =>
import ("../page/main/work-order/my-business-work-order/detail.vue")
},
{
path: '/work-order/business-list',
name: 'business-list',
show: true,
component: () =>
import ("../page/main/work-order/business-work-order-list/index.vue")
},
{
path: '/work-order/business-manage',
name: 'business-manage',
show: true,
component: () =>
import ("../page/main/work-order/business-work-order-manage/index.vue")
},
{
path: '/work-order/business-manage-detail',
name: 'business-manage-detail',
show: true,
component: () =>
import ("../page/main/work-order/business-work-order-manage/detail.vue")
},
]
}]
//写入初始必须有的路由 //写入初始必须有的路由
//或者隐藏式路由,不会表现在菜单上,但是需要存在的路由 //或者隐藏式路由,不会表现在菜单上,但是需要存在的路由
const routes = [ const routes = [{
{
path: '/login', path: '/login',
name: 'login', name: 'login',
show:true, show: true,
component: () => import('../page/login/index.vue') component: () =>
import ('../page/login/index.vue')
}, },
{ {
path: '/', path: '/',
name: 'index', name: 'index',
component: () => import('../page/welcom.vue'), component: () =>
import ('../page/welcom.vue'),
}, },
{ {
path: '/404', path: '/404',
show:true, show: true,
component: () => import('../page/404.vue') component: () =>
import ('../page/404.vue')
}, },
...work_order
] ]
//重新创建router //重新创建router
function newRouterFunc(){ function newRouterFunc() {
return createRouter({ return createRouter({
history: createWebHashHistory(), history: createWebHashHistory(),
routes routes
...@@ -51,8 +111,8 @@ router.beforeEach((to, from, next) => { ...@@ -51,8 +111,8 @@ router.beforeEach((to, from, next) => {
const userInfo = store.state.userInfo const userInfo = store.state.userInfo
//已登录不可跳转登陆页 //已登录不可跳转登陆页
if(userInfo&&to.path=='/login'){ if (userInfo && to.path == '/login') {
next({path:from.path}) next({ path: from.path })
} }
// 检查to.path是否存在于免登陆白名单 // 检查to.path是否存在于免登陆白名单
...@@ -62,13 +122,13 @@ router.beforeEach((to, from, next) => { ...@@ -62,13 +122,13 @@ router.beforeEach((to, from, next) => {
// 判断是否已经登录,未登录则重定向到首页或其他页面(通过query传参记录原来的路径) // 判断是否已经登录,未登录则重定向到首页或其他页面(通过query传参记录原来的路径)
// 根据配置判断是否跳转第三方登录,跳转第三方登录则不跳login // 根据配置判断是否跳转第三方登录,跳转第三方登录则不跳login
// axios封装中也需要对是否登录过期进行判断,如果登录过期,则跳转登录页,具体跳转地址根据配置来· // axios封装中也需要对是否登录过期进行判断,如果登录过期,则跳转登录页,具体跳转地址根据配置来·
if (!userInfo) { // if (!userInfo) {
next({ // next({
path: '/login', // path: '/login',
}) // })
} else { // } else {
} // }
} }
//判读是否匹配,否则跳转404 //判读是否匹配,否则跳转404
...@@ -85,11 +145,11 @@ router.beforeEach((to, from, next) => { ...@@ -85,11 +145,11 @@ router.beforeEach((to, from, next) => {
// router.onReady(() => { // router.onReady(() => {
// generateRoutes() // generateRoutes()
// }) // })
function addRoute(router,routers){ function addRoute(router, routers) {
routers.forEach(e => { routers.forEach(e => {
router.addRoute(e) router.addRoute(e)
if(e.children&&e.children.length){ if (e.children && e.children.length) {
addRoute(router,e.children) addRoute(router, e.children)
} }
}); });
} }
...@@ -100,15 +160,13 @@ export function generateRoutes() { ...@@ -100,15 +160,13 @@ export function generateRoutes() {
if (_asyncRoutes) { if (_asyncRoutes) {
//动态添加路由 //动态添加路由
addRoute(router,_asyncRoutes) addRoute(router, _asyncRoutes)
} }
router.addRoute( router.addRoute({
{
path: '/:pathMatch(.*)', path: '/:pathMatch(.*)',
redirect: '/404' redirect: '/404'
} })
)
console.log(router.getRoutes()); console.log(router.getRoutes());
......
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