From e978661202170bff25b478792cc64e6b6ffd86fe Mon Sep 17 00:00:00 2001
From: 罗广辉 <guanghui.luo@foxmail.com>
Date: Wed, 04 Feb 2026 10:26:18 +0800
Subject: [PATCH] feat: 删除无用代码
---
applications/mobile-web-view/src/main.js | 14 --------------
/dev/null | 8 --------
applications/mobile-web-view/src/page/login/index.vue | 8 --------
applications/mobile-web-view/src/router/page/index.js | 12 ------------
4 files changed, 0 insertions(+), 42 deletions(-)
diff --git a/applications/mobile-web-view/src/components/basic-block/main.vue b/applications/mobile-web-view/src/components/basic-block/main.vue
deleted file mode 100644
index 6f69fc1..0000000
--- a/applications/mobile-web-view/src/components/basic-block/main.vue
+++ /dev/null
@@ -1,128 +0,0 @@
-<template>
- <div class="basic-block" :style="styleName">
- <div class="box" :style="boxStyleName">
- <router-link :to="to">
- <span v-text="text"></span>
- <p v-text="dept"></p>
- <i :class="icon"></i>
- </router-link>
- </div>
- </div>
-</template>
-
-<script>
-export default {
- name: 'basicBlock',
- props: {
- icon: {
- type: String,
- },
- background: {
- type: String,
- },
- to: {
- type: Object,
- default: () => {
- return {};
- },
- },
- text: {
- type: String,
- },
- dept: {
- type: String,
- },
- time: {
- type: [Number, String],
- },
- gutter: {
- type: [Number, String],
- default: 5,
- },
- color: {
- type: String,
- },
- width: {
- type: [Number, String],
- },
- height: {
- type: [Number, String],
- },
- },
- computed: {
- styleName() {
- return {
- animationDelay: `${this.time / 25}s`,
- width: `${this.width}px`,
- height: `${this.height}px`,
- margin: `${this.gutter}px`,
- };
- },
- boxStyleName() {
- return {
- backgroundColor: this.color,
- backgroundImage: `url('${this.background}')`,
- };
- },
- },
-};
-</script>
-
-<style lang="scss">
-.basic-block {
- opacity: 0;
-
- box-sizing: border-box;
- color: #fff;
- animation: mymove 1s;
- animation-fill-mode: forwards;
-
- .box {
- position: relative;
- box-sizing: border-box;
- padding: 15px;
- width: 100%;
- height: 100%;
- transition: all 1s;
- background-size: cover;
-
- &:hover {
- transform: rotateY(360deg);
- }
- }
-
- a {
- color: #fff;
- }
-
- span {
- display: block;
- font-size: 16px;
- }
-
- p {
- width: 80%;
- font-size: 10px;
- color: #eee;
- line-height: 22px;
- }
-
- i {
- position: absolute;
- bottom: 15px;
- right: 15px;
- font-size: 50px !important;
- }
-
- @keyframes mymove {
- from {
- opacity: 0;
- transform: scale(0);
- }
- to {
- opacity: 1;
- transform: scale(1);
- }
- }
-}
-</style>
diff --git a/applications/mobile-web-view/src/components/basic-container/main.vue b/applications/mobile-web-view/src/components/basic-container/main.vue
deleted file mode 100644
index e98f520..0000000
--- a/applications/mobile-web-view/src/components/basic-container/main.vue
+++ /dev/null
@@ -1,57 +0,0 @@
-<template>
- <div class="basic-container" :style="styleName" :class="{ 'basic-container--block': block }">
- <el-card class="basic-container__card">
- <slot></slot>
- </el-card>
- </div>
-</template>
-
-<script>
-export default {
- name: 'basicContainer',
- props: {
- radius: {
- type: [String, Number],
- default: 10,
- },
- background: {
- type: String,
- },
- block: {
- type: Boolean,
- default: false,
- },
- },
- computed: {
- styleName() {
- return {
- borderRadius: `${this.radius}px`,
- background: this.background,
- };
- },
- },
-};
-</script>
-
-<style lang="scss">
-.basic-container {
- padding: 10px 6px;
- box-sizing: border-box;
-
- &--block {
- height: 100%;
-
- .basic-container__card {
- height: 100%;
- }
- }
-
- &__card {
- width: 100%;
- }
-
- &:first-child {
- padding-top: 0;
- }
-}
-</style>
diff --git a/applications/mobile-web-view/src/components/basic-video/main.vue b/applications/mobile-web-view/src/components/basic-video/main.vue
deleted file mode 100644
index 6b0089f..0000000
--- a/applications/mobile-web-view/src/components/basic-video/main.vue
+++ /dev/null
@@ -1,140 +0,0 @@
-<template>
- <div :style="styleName" class="basic-video">
- <div class="basic-video__border">
- <span :style="borderStyleName"></span>
- <span :style="borderStyleName"></span>
- <span :style="borderStyleName"></span>
- <span :style="borderStyleName"></span>
- </div>
- <img :style="imgStyleName" class="basic-video__img" :src="background" />
- <video class="basic-video__main" ref="main" autoplay muted></video>
- </div>
-</template>
-
-<script>
-import RecordVideo from './plugin';
-
-export default {
- name: 'basic-video',
- props: {
- background: {
- type: String,
- },
- width: {
- type: [String, Number],
- default: 500,
- },
- },
- computed: {
- styleName() {
- return {
- width: `${this.width}px`,
- };
- },
- imgStyleName() {
- return {
- width: `${this.width / 2}px`,
- };
- },
- borderStyleName() {
- return {
- width: `${this.width / 15}px`,
- height: `${this.width / 15}px`,
- borderWidth: `${5}px`,
- };
- },
- },
- data() {
- return {
- videoObj: null,
- };
- },
- mounted() {
- this.init();
- },
- methods: {
- init() {
- this.videoObj = new RecordVideo(this.$refs.main);
- const videoPromise = this.videoObj.init();
- videoPromise.then(() => {
- this.videoObj.mediaRecorder.addEventListener('stop', this.getData, false);
- });
- },
- startRecord() {
- this.videoObj.startRecord();
- },
- stopRecord() {
- this.videoObj.stopRecord();
- },
- getData() {
- const blob = new Blob(this.videoObj.chunks, {
- type: 'video/mp4',
- });
- const reader = new FileReader();
- reader.readAsDataURL(blob);
- reader.addEventListener('loadend', () => {
- var video_base64 = reader.result;
- this.$emit('data-change', video_base64);
- });
- },
- },
-};
-</script>
-<style lang="scss" scoped>
-.basic-video {
- margin: 0 auto;
- position: relative;
- overflow: hidden;
-
- &__border {
- span {
- position: absolute;
- width: 30px;
- height: 30px;
- border-width: 4px;
- color: #0073eb;
- border-style: solid;
-
- &:nth-child(1) {
- left: 15px;
- top: 15px;
- border-right: 0;
- border-bottom: 0;
- }
-
- &:nth-child(2) {
- right: 15px;
- top: 15px;
- border-left: 0;
- border-bottom: 0;
- }
-
- &:nth-child(3) {
- bottom: 15px;
- left: 15px;
- border-right: 0;
- border-top: 0;
- }
-
- &:nth-child(4) {
- bottom: 15px;
- right: 15px;
- border-left: 0;
- border-top: 0;
- }
- }
- }
-
- &__img {
- width: 100px;
- position: absolute;
- left: 50%;
- top: 50%;
- transform: translate(-50%, -50%);
- }
-
- &__main {
- width: 100%;
- }
-}
-</style>
diff --git a/applications/mobile-web-view/src/components/basic-video/plugin.js b/applications/mobile-web-view/src/components/basic-video/plugin.js
deleted file mode 100644
index 3ba258d..0000000
--- a/applications/mobile-web-view/src/components/basic-video/plugin.js
+++ /dev/null
@@ -1,88 +0,0 @@
-export default class RecordVideo {
- /**
- * 构造函数
- *
- * @param {Object} videoObj 视频对象
- */
- constructor(videoObj) {
- this.video = videoObj
- this.mediaRecorder = null
- this.chunks = []
- }
-
- /**
- * 初始化
- *
- * @return {Object} promise
- */
- init() {
- // 返回Promise对象
- // resolve 正常处理
- // reject 处理异常情况
- return new Promise((resovle, reject) => {
- navigator.mediaDevices
- .getUserMedia({
- audio: true,
- video: true,
- // video: {
- // width: this.videoWidth,
- // height: this.videoHeight
- // }
- })
- // 返回一个媒体内容的流
- .then(stream => {
- // 检测是否支持 srcObject,该属性在新的浏览器支持
- if ('srcObject' in this.video) {
- this.video.srcObject = stream
- } else {
- // 兼容旧的浏览器
- this.video.src = window.URL.createObjectURL(stream)
- }
-
- // 当视频的元数据已经加载时触发
- this.video.addEventListener('loadmetadata', () => {
- this.video.play()
- })
- this.mediaRecorder = new MediaRecorder(stream)
- this.mediaRecorder.addEventListener('dataavailable', e => {
- this.chunks.push(e.data)
- })
- resovle()
- })
- // 异常抓取,包括用于禁用麦克风、摄像头
- .catch(error => {
- reject(error)
- })
- })
- }
-
- /**
- * 视频开始录制
- */
- startRecord() {
- if (this.mediaRecorder.state === 'inactive') {
- this.mediaRecorder.start()
- }
- }
-
- /**
- * 视频结束录制
- */
- stopRecord() {
- if (this.mediaRecorder.state === 'recording') {
- this.mediaRecorder.stop()
- }
- }
-
- /**
- * 检测当前浏览器对否支持
- *
- * @return {boolean} 当前浏览器是否支持
- */
- isSupport() {
- const flag = navigator.mediaDevices && navigator.mediaDevices.getUserMedia
- if (flag) {
- return true
- }
- }
-}
diff --git a/applications/mobile-web-view/src/components/flow-design-step/main.vue b/applications/mobile-web-view/src/components/flow-design-step/main.vue
deleted file mode 100644
index 081c714..0000000
--- a/applications/mobile-web-view/src/components/flow-design-step/main.vue
+++ /dev/null
@@ -1,194 +0,0 @@
-<template>
- <div v-if="componentLoaded">
- <el-dialog
- v-if="website.design.designMode"
- title="流程配置"
- append-to-body
- destroy-on-close
- v-model="visible"
- :close-on-press-escape="false"
- :fullscreen="true"
- :before-close="handleNutflowClose"
- class="nf-dialog"
- >
- <nf-design-base
- v-if="nutflowOption.step === 1"
- class="animated fadeIn"
- style="height: calc(100vh - 108px)"
- ref="nf-design"
- :options="nutflowOption.step1"
- ></nf-design-base>
- <nf-design-base
- v-if="nutflowOption.step === 2"
- class="animated fadeIn"
- style="height: calc(100vh - 108px)"
- ref="nf-design-view"
- :options="nutflowOption.step2"
- ></nf-design-base>
- <template #footer>
- <span class="avue-dialog__footer">
- <el-button @click="handleNutflowClose(() => {}, true)">取 消</el-button>
- <el-button v-if="nutflowOption.step === 1" type="success" @click="handleStep(1)"
- >下 一 步</el-button
- >
- <el-button v-if="nutflowOption.step === 2" type="success" @click="handleStep(-1)"
- >上 一 步</el-button
- >
- <el-button v-if="nutflowOption.step === 2" type="primary" @click="handleSubmitModel"
- >确 定</el-button
- >
- </span>
- </template>
- </el-dialog>
- </div>
-</template>
-
-<script>
-import { loadFlowModule } from '@/utils/module';
-import { submitModel } from '@/api/flow/flow';
-
-export default {
- name: 'flowDesign',
- props: {
- isDisplay: {
- type: Boolean,
- default: false,
- },
- },
- data() {
- return {
- visible: false,
- componentLoaded: false,
- nutflowOption: {
- process: {},
- step: 1,
- step1: {
- toolbar: [
- 'open',
- 'create',
- 'fit',
- 'zoom-in',
- 'zoom-out',
- 'undo',
- 'redo',
- 'import',
- 'preview',
- ],
- },
- step2: {
- mode: 'view',
- simulation: true,
- minimap: true,
- },
- },
- };
- },
- created() {
- // 懒加载流程设计器模块
- loadFlowModule(this.$app).then(() => {
- this.componentLoaded = true;
- });
- },
- watch: {
- isDisplay: {
- handler(val) {
- this.visible = val;
- },
- immediate: true,
- },
- visible: {
- handler(val) {
- this.$emit('update:is-display', val);
- },
- },
- },
- methods: {
- handleSubmitModel() {
- const registry = this.$refs['nf-design-view'].getElementRegistry().getAll();
- const { businessObject } = registry[0];
- const { id, name, documentation } = businessObject;
- const description = documentation && documentation.length > 0 ? documentation[0].text : null;
- const params = {
- ...this.nutflowOption.process,
- modelKey: id,
- name,
- description,
- modelEditorXml: this.nutflowOption.process.xml,
- };
- submitModel(params).then(() => {
- this.$message.success('操作成功');
- this.handleNutflowClose();
- this.$emit('loadData');
- });
- },
- handleStep(step) {
- if (step === 1) {
- // 下一步
- this.$refs['nf-design'].getData('xml').then(data => {
- this.nutflowOption.step1.xml = data;
- this.nutflowOption.step2.xml = data;
- this.nutflowOption.process.xml = data;
- this.nutflowOption.step = 2;
- });
- } else this.nutflowOption.step = 1;
- },
- handleNutflowClose(done, flag) {
- const initOption = {
- process: {},
- step: 1,
- step1: {
- toolbar: [
- 'open',
- 'create',
- 'fit',
- 'zoom-in',
- 'zoom-out',
- 'undo',
- 'redo',
- 'import',
- 'preview',
- ],
- },
- step2: {
- mode: 'view',
- simulation: true,
- minimap: true,
- },
- };
- if (done || flag) {
- this.$confirm('确定要关闭吗?关闭未保存的修改都会丢失。', '警告', {
- type: 'warning',
- })
- .then(() => {
- this.nutflowOption = initOption;
- if (typeof done == 'function') done();
- this.visible = false;
- })
- .catch(() => {});
- } else {
- this.nutflowOption = initOption;
- this.visible = false;
- }
- },
- },
-};
-</script>
-
-<style lang="scss">
-.flow-design-dialog {
- display: flex;
- flex-direction: column;
- margin: 0 !important;
- position: absolute;
- top: 40%;
- left: 50%;
- transform: translate(-50%, -40%);
- max-height: calc(100% - 30px);
- max-width: calc(100% - 30px);
-
- .el-dialog__body {
- flex: 1;
- overflow: auto;
- }
-}
-</style>
diff --git a/applications/mobile-web-view/src/components/flow-design/main.vue b/applications/mobile-web-view/src/components/flow-design/main.vue
deleted file mode 100644
index 11d8666..0000000
--- a/applications/mobile-web-view/src/components/flow-design/main.vue
+++ /dev/null
@@ -1,133 +0,0 @@
-<template>
- <div v-if="componentLoaded">
- <el-dialog
- v-if="isDialog"
- v-model="visible"
- append-to-body
- destroy-on-close
- title="流程图展示"
- width="70%"
- class="flow-design-dialog"
- >
- <nf-design-base ref="bpmn" style="height: 60vh" :options="option"></nf-design-base>
- </el-dialog>
- <div v-else>
- <nf-design-base
- v-if="visible"
- ref="bpmn"
- style="height: 60vh"
- :options="option"
- ></nf-design-base>
- </div>
- </div>
-</template>
-
-<script>
-import { loadFlowModule } from '@/utils/module';
-import { modelView } from '@/api/flow/flow';
-
-export default {
- name: 'flowDesign',
- props: {
- isDialog: {
- type: Boolean,
- default: false,
- },
- isDisplay: {
- type: Boolean,
- default: false,
- },
- processInstanceId: String,
- processDefinitionId: String,
- },
- data() {
- return {
- visible: false,
- componentLoaded: false,
- option: {
- mode: 'view',
- },
- };
- },
- created() {
- // 懒加载流程设计器模块
- loadFlowModule(this.$app).then(() => {
- this.componentLoaded = true;
- });
- },
- watch: {
- isDisplay: {
- handler(val) {
- this.visible = val;
- },
- immediate: true,
- },
- visible: {
- handler(val) {
- this.$emit('update:is-display', val);
- },
- },
- processInstanceId: {
- handler(val) {
- if (!val) return;
- this.getDetail({ processInstanceId: this.processInstanceId });
- },
- immediate: true,
- },
- processDefinitionId: {
- handler(val) {
- if (!val) return;
- this.getDetail({ processDefinitionId: this.processDefinitionId });
- },
- immediate: true,
- },
- },
- methods: {
- getDetail(params) {
- modelView(params).then(res => {
- const data = res.data.data;
- const { xml, flow } = data;
- this.option.xml = xml;
- if (flow) {
- const flows = [];
- flow.forEach(f => {
- let { endTime } = f;
-
- const ff = {
- id: f.historyActivityId,
- class: !endTime && f.historyActivityType !== 'candidate' ? 'nodePrimary' : '',
- };
-
- if (f.historyActivityType === 'sequenceFlow') ff.class = 'lineWarn';
- else if (!ff.class && f.historyActivityType !== 'candidate') ff.class = 'nodeSuccess';
-
- const index = flows.findIndex(fl => fl.id === f.historyActivityId);
- if (index !== -1) flows.splice(index, 1, ff);
- else flows.push(ff);
- });
- this.option.flows = flows;
- }
- });
- },
- },
-};
-</script>
-
-<style lang="scss">
-.flow-design-dialog {
- display: flex;
- flex-direction: column;
- margin: 0 !important;
- position: absolute;
- top: 40%;
- left: 50%;
- transform: translate(-50%, -40%);
- max-height: calc(100% - 30px);
- max-width: calc(100% - 30px);
-
- .el-dialog__body {
- flex: 1;
- overflow: auto;
- }
-}
-</style>
diff --git a/applications/mobile-web-view/src/components/global/publicTitle.vue b/applications/mobile-web-view/src/components/global/publicTitle.vue
deleted file mode 100644
index 56fb848..0000000
--- a/applications/mobile-web-view/src/components/global/publicTitle.vue
+++ /dev/null
@@ -1,33 +0,0 @@
-<!--
- * @Author: shuishen 1109946754@qq.com
- * @Date: 2024-10-25 18:41:39
- * @LastEditors: shuishen 1109946754@qq.com
- * @LastEditTime: 2025-04-02 18:26:00
- * @FilePath: \mobile-web-view\src\components\publicTitle\publicTitle.vue
- * @Description:
- *
- * Copyright (c) 2024 by shuishen, All Rights Reserved.
--->
-<template>
- <div class="title-box">
- <div class="title">
- <slot name="titleName"></slot>
- </div>
- </div>
-</template>
-
-<style lang="scss" scoped>
-.title {
- margin-left: 30px;
- text-align: left;
- font-size: 18px;
- font-family: Alibaba PuHuiTi;
- font-weight: 700;
- font-style: italic;
- color: transparent;
- text-shadow: 0 2px 8px rgba(5, 28, 55, .42);
- background-image: linear-gradient(180deg, rgba(14, 197, 236, .36) 5%, rgba(49, 190, 255, .36) 20%, #fff 40%);
- -webkit-background-clip: text;
- -webkit-text-fill-color: transparen;
-}
-</style>
diff --git a/applications/mobile-web-view/src/components/iframe/main.vue b/applications/mobile-web-view/src/components/iframe/main.vue
deleted file mode 100644
index d11b344..0000000
--- a/applications/mobile-web-view/src/components/iframe/main.vue
+++ /dev/null
@@ -1,82 +0,0 @@
-<template>
- <basic-container>
- <iframe :src="src" class="iframe" ref="iframe" />
- </basic-container>
-</template>
-
-<script>
-import NProgress from 'nprogress'; // progress bar
-import 'nprogress/nprogress.css'; // progress bar style
-export default {
- name: 'AvueIframe',
- data() {
- return {};
- },
- created() {
- NProgress.configure({ showSpinner: false });
- },
- mounted() {
- this.load();
- },
- watch: {
- $route: function () {
- this.load();
- },
- },
- computed: {
- src() {
- return this.$route.query.url.replace(/#/g, '&');
- },
- },
- methods: {
- // 显示等待框
- show() {
- NProgress.start();
- },
- // 隐藏等待狂
- hide() {
- NProgress.done();
- },
- // 加载组件
- load() {
- this.show();
- //超时3s自动隐藏等待狂,加强用户体验
- let time = 3;
- const timeFunc = setInterval(() => {
- time--;
- if (time == 0) {
- this.hide();
- clearInterval(timeFunc);
- }
- }, 1000);
- this.iframeInit();
- },
- //iframe窗口初始化
- iframeInit() {
- const iframe = this.$refs.iframe;
- const clientHeight = document.documentElement.clientHeight - 150;
- if (!iframe) return;
- iframe.style.height = `${clientHeight}px`;
- if (iframe.attachEvent) {
- iframe.attachEvent('onload', () => {
- this.hide();
- });
- } else {
- iframe.onload = () => {
- this.hide();
- };
- }
- },
- },
-};
-</script>
-
-<style lang="scss">
-.iframe {
- width: 100%;
- height: 100%;
- border: 0;
- overflow: hidden;
- box-sizing: border-box;
-}
-</style>
diff --git a/applications/mobile-web-view/src/components/third-register/main.vue b/applications/mobile-web-view/src/components/third-register/main.vue
deleted file mode 100644
index 32767cf..0000000
--- a/applications/mobile-web-view/src/components/third-register/main.vue
+++ /dev/null
@@ -1,129 +0,0 @@
-<template>
- <el-dialog
- title="账号注册"
- append-to-body
- v-model="accountBox"
- :close-on-click-modal="false"
- :close-on-press-escape="false"
- :show-close="false"
- width="20%"
- >
- <el-form :model="form" ref="form" label-width="80px">
- <el-form-item v-if="tenantMode" label="租户编号">
- <el-input v-model="form.tenantId" placeholder="请输入租户编号"></el-input>
- </el-form-item>
- <el-form-item label="用户姓名">
- <el-input v-model="form.name" placeholder="请输入用户姓名"></el-input>
- </el-form-item>
- <el-form-item label="账号名称">
- <el-input v-model="form.account" placeholder="请输入账号名称"></el-input>
- </el-form-item>
- <el-form-item label="账号密码">
- <el-input v-model="form.password" placeholder="请输入账号密码"></el-input>
- </el-form-item>
- <el-form-item label="确认密码">
- <el-input v-model="form.password2" placeholder="请输入确认密码"></el-input>
- </el-form-item>
- </el-form>
- <template #footer>
- <span class="dialog-footer">
- <el-button type="primary" :loading="loading" @click="handleRegister">确 定</el-button>
- </span>
- </template>
- </el-dialog>
-</template>
-
-<script>
-import { mapGetters } from 'vuex';
-import { validatenull } from 'utils/validate';
-import { registerGuest } from '@/api/user';
-import { getTopUrl } from 'utils/util';
-import { info } from '@/api/system/tenant';
-import { resetRouter } from '@/router/index';
-
-export default {
- name: 'thirdRegister',
- data() {
- return {
- form: {
- tenantId: '',
- name: '',
- account: '',
- password: '',
- password2: '',
- },
- loading: false,
- tenantMode: true,
- accountBox: false,
- };
- },
- computed: {
- ...mapGetters(['userInfo']),
- },
- created() {
- this.getTenant();
- },
- mounted() {
- // 若未登录则弹出框进行绑定
- if (validatenull(this.userInfo.userId) || this.userInfo.userId < 0) {
- this.form.name = this.userInfo.userName;
- this.form.account = this.userInfo.account;
- this.accountBox = true;
- }
- },
- methods: {
- handleRegister() {
- if (this.form.tenantId === '') {
- this.$message.warning('请先输入租户编号');
- return;
- }
- if (this.form.account === '') {
- this.$message.warning('请先输入账号名称');
- return;
- }
- if (this.form.password === '' || this.form.password2 === '') {
- this.$message.warning('请先输入密码');
- return;
- }
- if (this.form.password !== this.form.password2) {
- this.$message.warning('两次密码输入不一致');
- return;
- }
- this.loading = true;
- registerGuest(this.form, this.userInfo.oauthId).then(
- res => {
- this.loading = false;
- const data = res.data;
- if (data.success) {
- this.accountBox = false;
- this.$alert('注册申请已提交,请耐心等待管理员通过!', '注册提示').then(() => {
- this.$store.dispatch('LogOut').then(() => {
- resetRouter();
- this.$router.push({ path: '/login' });
- });
- });
- } else {
- this.$message.error(data.msg || '提交失败');
- }
- },
- error => {
- window.console.log(error);
- this.loading = false;
- }
- );
- },
- getTenant() {
- let domain = getTopUrl();
- // 临时指定域名,方便测试
- //domain = "https://bladex.cn";
- info(domain).then(res => {
- const data = res.data;
- if (data.success && data.data.tenantId) {
- this.form.tenantId = data.data.tenantId;
- this.tenantMode = false;
- }
- });
- },
- },
-};
-</script>
diff --git a/applications/mobile-web-view/src/main.js b/applications/mobile-web-view/src/main.js
index fb5412e..3b629cd 100644
--- a/applications/mobile-web-view/src/main.js
+++ b/applications/mobile-web-view/src/main.js
@@ -40,12 +40,7 @@
// 系统组件
import debug from './debug'
import VueClipboard from 'vue3-clipboard'
-import basicBlock from './components/basic-block/main.vue'
-import basicContainer from './components/basic-container/main.vue'
import SvgIcon from './components/SvgIcon.vue'
-import thirdRegister from './components/third-register/main.vue'
-import flowDesign from './components/flow-design/main.vue'
-import flowDesignStep from './components/flow-design-step/main.vue'
// 全局组件
import globalComponents from '@/components'
import globalDirections from '@/directive'
@@ -63,16 +58,7 @@
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
app.component(key, component)
}
-app.component('basicContainer', basicContainer)
-app.component('basicBlock', basicBlock)
-app.component('thirdRegister', thirdRegister)
-app.component('flowDesign', flowDesign)
-app.component('flowDesignStep', flowDesignStep)
app.component('SvgIcon', SvgIcon)
-// app.component('codeSetting', codeSetting);
-// app.component('formSetting', formSetting);
-// app.component('tenantPackage', tenantPackage);
-// app.component('tenantDatasource', tenantDatasource);
app.config.globalProperties.$app = app
app.config.globalProperties.$dayjs = dayjs
app.config.globalProperties.website = website
diff --git a/applications/mobile-web-view/src/page/index/layout.vue b/applications/mobile-web-view/src/page/index/layout.vue
deleted file mode 100644
index 0439730..0000000
--- a/applications/mobile-web-view/src/page/index/layout.vue
+++ /dev/null
@@ -1,7 +0,0 @@
-<template>
- <router-view #="{ Component }">
- <keep-alive :include="$store.getters.tagsKeep">
- <component :is="Component" />
- </keep-alive>
- </router-view>
-</template>
diff --git a/applications/mobile-web-view/src/page/index/logo.vue b/applications/mobile-web-view/src/page/index/logo.vue
deleted file mode 100644
index 8963ecc..0000000
--- a/applications/mobile-web-view/src/page/index/logo.vue
+++ /dev/null
@@ -1,44 +0,0 @@
-<template>
- <div class="avue-logo">
- <transition name="fade">
- <span v-if="getScreen(isCollapse)" class="avue-logo_subtitle" key="0">
- <img class="logo-img" src="/img/logo.png" />
- </span>
- </transition>
- <transition-group name="fade">
- <template v-if="getScreen(!isCollapse)">
- <span class="logo-title" key="1">{{ website.indexTitle }} </span>
- </template>
- </transition-group>
- </div>
-</template>
-
-<script>
-import { mapGetters } from 'vuex';
-
-export default {
- name: 'logo',
- data() {
- return {};
- },
- created() {},
- computed: {
- ...mapGetters(['isCollapse']),
- },
- methods: {},
-};
-</script>
-<style scoped>
-.logo-title {
- font-size: 20px;
- background-image: linear-gradient(120deg, #54b6d0 16%, #3f8bdb, #2c77f1);
- -webkit-background-clip: text;
- -webkit-text-fill-color: transparent;
- font-weight: 700;
- padding-left: 30px;
-}
-.logo-img {
- width: 40px;
- margin-top: 5px;
-}
-</style>
diff --git a/applications/mobile-web-view/src/page/index/search.vue b/applications/mobile-web-view/src/page/index/search.vue
deleted file mode 100644
index 0efc90e..0000000
--- a/applications/mobile-web-view/src/page/index/search.vue
+++ /dev/null
@@ -1,178 +0,0 @@
-<template>
- <div class="avue-searchs" @click.self="handleEsc">
- <div class="avue-searchs__title">菜单搜索</div>
- <div class="avue-searchs__content">
- <div class="avue-searchs__form">
- <el-input :placeholder="$t('search')" v-model="value" @keydown.esc="handleEsc">
- <template #append>
- <el-button icon="el-icon-search"></el-button>
- </template>
- </el-input>
- <p>
- <el-tag>你可以使用快捷键esc 关闭</el-tag>
- </p>
- </div>
- <div class="avue-searchs__list">
- <el-scrollbar class="avue-searchs__scrollbar">
- <div
- class="avue-searchs__item"
- v-for="(item, index) in menus"
- :key="index"
- @click="handleSelect(item)"
- >
- <i :class="[item[iconKey], 'avue-searchs__item-icon']"></i>
- <span class="avue-searchs__item-title">{{ item[labelKey] }}</span>
- <div class="avue-searchs__item-path">
- {{ item[pathKey] }}
- </div>
- </div>
- </el-scrollbar>
- </div>
- </div>
- </div>
-</template>
-
-<script>
-import { mapGetters } from 'vuex';
-
-export default {
- data() {
- return {
- value: '',
- menus: [],
- menuList: [],
- };
- },
- created() {
- this.getMenuList();
- },
- watch: {
- value() {
- this.querySearch();
- },
- menu() {
- this.getMenuList();
- },
- },
- computed: {
- labelKey() {
- return this.website.menu.label;
- },
- pathKey() {
- return this.website.menu.path;
- },
- iconKey() {
- return this.website.menu.icon;
- },
- childrenKey() {
- return this.website.menu.children;
- },
- ...mapGetters(['menu']),
- },
- methods: {
- handleEsc() {
- this.$store.commit('SET_IS_SEARCH', false);
- },
- getMenuList() {
- const findMenu = list => {
- for (let i = 0; i < list.length; i++) {
- const ele = Object.assign({}, list[i]);
- if (this.validatenull(ele[this.childrenKey])) {
- this.menuList.push(ele);
- } else {
- findMenu(ele[this.childrenKey]);
- }
- }
- };
- this.menuList = [];
- findMenu(this.menu);
- this.menus = this.menuList;
- },
- querySearch() {
- var restaurants = this.menuList;
- var queryString = this.value;
- this.menus = queryString ? this.menuList.filter(this.createFilter(queryString)) : restaurants;
- },
- createFilter(queryString) {
- return restaurant => {
- return restaurant[this.labelKey].toLowerCase().indexOf(queryString.toLowerCase()) === 0;
- };
- },
- handleSelect(item) {
- this.value = '';
- this.$router.push({
- path: item[this.pathKey],
- query: item.query,
- });
- },
- },
-};
-</script>
-
-<style lang="scss" scoped>
-.avue-searchs {
- padding-top: 50px;
- width: 100%;
- height: 100%;
- background-color: #fff;
- z-index: 1024;
-
- &__title {
- margin-bottom: 60px;
- text-align: center;
- font-size: 42px;
- font-weight: bold;
- letter-spacing: 2px;
- text-indent: 2px;
- }
-
- &__form {
- margin: 0 auto 50px auto;
- width: 50%;
- text-align: center;
-
- p {
- margin-top: 20px;
- }
- }
-
- &__scrollbar {
- height: 400px;
- }
-
- &__list {
- box-sizing: border-box;
- padding: 20px 30px;
- margin: 0 auto;
- width: 70%;
- border-radius: 4px;
- border: 1px solid #ebeef5;
- background-color: #fff;
- overflow: hidden;
- color: #303133;
- transition: 0.3s;
- box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
- }
-
- &__item {
- padding: 5px 0;
- border-bottom: 1px dashed #eee;
-
- &-icon {
- margin-right: 5px;
- font-size: 18px;
- }
-
- &-title {
- font-size: 20px;
- font-weight: 500;
- color: #333;
- }
-
- &-path {
- line-height: 30px;
- color: #666;
- }
- }
-}
-</style>
diff --git a/applications/mobile-web-view/src/page/index/setting.vue b/applications/mobile-web-view/src/page/index/setting.vue
deleted file mode 100644
index 1000fa7..0000000
--- a/applications/mobile-web-view/src/page/index/setting.vue
+++ /dev/null
@@ -1,173 +0,0 @@
-<template>
- <el-button
- @click="show = true"
- class="setting-icon"
- type="primary"
- icon="el-icon-setting"
- circle
- ></el-button>
- <el-drawer append-to-body :with-header="false" v-model="show" size="30%">
- <div class="setting">
- <h5>导航模式</h5>
- <div class="setting-checkbox">
- <el-tooltip class="item" effect="dark" content="侧边菜单布局" placement="top">
- <div
- @click="setting.sidebar = 'vertical'"
- class="setting-checkbox-item setting-checkbox-item--side"
- ></div>
- </el-tooltip>
- <el-tooltip class="item" effect="dark" content="顶部菜单布局" placement="top">
- <div
- @click="setting.sidebar = 'horizontal'"
- class="setting-checkbox-item setting-checkbox-item--top"
- ></div>
- </el-tooltip>
- </div>
- <h5>页面布局</h5>
- <div class="setting-checkbox">
- <div class="setting-item" v-for="(item, index) in list1" :key="index">
- {{ item.label }}:
- <el-switch v-model="setting[item.value]"></el-switch>
- </div>
- </div>
- <h5>功能调试</h5>
- <div class="setting-checkbox">
- <div class="setting-item" v-for="(item, index) in list2" :key="index">
- {{ item.label }}:
- <el-switch v-model="setting[item.value]"></el-switch>
- </div>
- </div>
- </div>
- </el-drawer>
-</template>
-
-<script>
-import { mapGetters } from 'vuex';
-
-export default {
- data() {
- return {
- show: false,
- list1: [
- {
- label: '导航标签',
- value: 'tag',
- },
- {
- label: '菜单折叠',
- value: 'collapse',
- },
- {
- label: '菜单搜索',
- value: 'search',
- },
- {
- label: '屏幕全屏',
- value: 'fullscreen',
- },
- {
- label: '主题选择',
- value: 'theme',
- },
- {
- label: '顶部菜单',
- value: 'menu',
- },
- ],
- list2: [
- {
- label: '日志调试',
- value: 'debug',
- },
- {
- label: '屏幕锁定',
- value: 'lock',
- },
- ],
- };
- },
- computed: {
- ...mapGetters(['isHorizontal', 'setting']),
- },
-};
-</script>
-
-<style lang="scss">
-.setting {
- &-icon {
- color: #666;
- position: fixed;
- bottom: 200px;
- right: 20px;
- z-index: 2048;
- }
-
- &-item {
- display: flex;
- justify-content: space-between;
- font-size: 14px;
- margin-bottom: 8px;
- }
-
- &-checkbox {
- &--check {
- position: absolute;
- color: var(--el-color-primary);
- left: 50%;
- top: 50%;
- transform: translate(-50%, -50%);
- }
-
- &-item {
- display: inline-block;
- position: relative;
- width: 44px;
- height: 36px;
- margin-right: 16px;
- overflow: hidden;
- background-color: #f0f2f5;
- border-radius: 4px;
- box-shadow: 0 1px 2.5px 0 rgba(0, 0, 0, 0.18);
- cursor: pointer;
-
- &:before {
- position: absolute;
- top: 0;
- left: 0;
- width: 33%;
- height: 100%;
- background-color: #fff;
- content: '';
- }
-
- &:after {
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 25%;
- background-color: #fff;
- content: '';
- }
-
- &--side {
- &:before {
- z-index: 1;
- background-color: #001529;
- content: '';
- }
-
- &:after {
- background-color: #fff;
- }
- }
-
- &--top {
- &:after {
- background-color: #001529;
- }
- }
- }
- }
-}
-</style>
diff --git a/applications/mobile-web-view/src/page/index/sidebar/index.vue b/applications/mobile-web-view/src/page/index/sidebar/index.vue
deleted file mode 100644
index 557cb99..0000000
--- a/applications/mobile-web-view/src/page/index/sidebar/index.vue
+++ /dev/null
@@ -1,41 +0,0 @@
-<template>
- <el-scrollbar class="avue-menu">
- <div v-if="menu && menu.length == 0 && !isHorizontal" class="avue-sidebar--tip">
- {{ $t('menuTip') }}
- </div>
- <el-menu
- unique-opened
- :default-active="activeMenu"
- :mode="setting.sidebar"
- :collapse="getScreen(isCollapse)"
- >
- <sidebar-item :menu="menu"></sidebar-item>
- </el-menu>
- </el-scrollbar>
-</template>
-
-<script>
-import { mapGetters } from 'vuex';
-import sidebarItem from './sidebarItem.vue';
-
-export default {
- name: 'sidebar',
- components: { sidebarItem },
- inject: ['index'],
- created() {
- this.index.openMenu();
- },
- computed: {
- ...mapGetters(['isHorizontal', 'setting', 'menu', 'tag', 'isCollapse', 'menuId']),
- activeMenu() {
- const route = this.$route;
- const { meta, path } = route;
- if (meta.activeMenu) {
- return meta.activeMenu;
- }
- return path;
- },
- },
-};
-</script>
-<style lang="scss" scoped></style>
diff --git a/applications/mobile-web-view/src/page/index/sidebar/sidebarItem.vue b/applications/mobile-web-view/src/page/index/sidebar/sidebarItem.vue
deleted file mode 100644
index 1442c69..0000000
--- a/applications/mobile-web-view/src/page/index/sidebar/sidebarItem.vue
+++ /dev/null
@@ -1,92 +0,0 @@
-<template>
- <template v-for="item in menu">
- <el-menu-item
- v-if="validatenull(item[childrenKey]) && validRoles(item)"
- :index="getPath(item)"
- @click="open(item)"
- :key="item[labelKey]"
- >
- <i :class="item[iconKey]"></i>
- <template #title>
- <span :alt="item[pathKey]">{{ getTitle(item) }}</span>
- </template>
- </el-menu-item>
- <el-sub-menu
- v-else-if="!validatenull(item[childrenKey]) && validRoles(item)"
- :index="getPath(item)"
- :key="item[labelKey]"
- >
- <template #title>
- <i :class="item[iconKey]"></i>
- <span>{{ getTitle(item) }}</span>
- </template>
- <template v-for="(child, cindex) in item[childrenKey]" :key="child[labelKey]">
- <el-menu-item
- :index="getPath(child)"
- @click="open(child)"
- v-if="validatenull(child[childrenKey])"
- >
- <i :class="child[iconKey]"></i>
- <template #title>
- <span>{{ getTitle(child) }}</span>
- </template>
- </el-menu-item>
- <sidebar-item v-else :menu="[child]" :key="cindex"></sidebar-item>
- </template>
- </el-sub-menu>
- </template>
-</template>
-<script>
-import { mapGetters } from 'vuex';
-import { validatenull } from 'utils/validate';
-import website from '@/config/website';
-
-export default {
- name: 'sidebarItem',
- data() {
- return {
- props: website.menu,
- };
- },
- props: {
- menu: Array,
- },
- computed: {
- ...mapGetters(['roles']),
- labelKey() {
- return this.props.label;
- },
- pathKey() {
- return this.props.path;
- },
- queryKey() {
- return this.props.query;
- },
- iconKey() {
- return this.props.icon;
- },
- childrenKey() {
- return this.props.children;
- },
- },
- methods: {
- validatenull,
- getPath(item) {
- return item[this.pathKey];
- },
- getTitle(item) {
- return this.$router.$avueRouter.generateTitle(item, this.props);
- },
- validRoles(item) {
- item.meta = item.meta || {};
- return item.meta.roles ? item.meta.roles.includes(this.roles) : true;
- },
- open(item) {
- this.$router.push({
- path: item[this.pathKey],
- query: item[this.queryKey],
- });
- },
- },
-};
-</script>
diff --git a/applications/mobile-web-view/src/page/index/tags.vue b/applications/mobile-web-view/src/page/index/tags.vue
deleted file mode 100644
index e975be3..0000000
--- a/applications/mobile-web-view/src/page/index/tags.vue
+++ /dev/null
@@ -1,192 +0,0 @@
-<template>
- <div class="avue-tags" v-if="setting.tag" @click="contextmenuFlag = false">
- <!-- tag盒子 -->
- <div
- v-if="contextmenuFlag"
- class="avue-tags__contentmenu"
- :style="{ left: contentmenuX + 'px', top: contentmenuY + 'px' }"
- >
- <div class="item" @click="closeOthersTags">{{ $t('tagsView.closeOthers') }}</div>
- <div class="item" @click="closeAllTags">{{ $t('tagsView.closeAll') }}</div>
- <div class="item" @click="clearCacheTags">{{ $t('tagsView.clearCache') }}</div>
- </div>
- <div class="avue-tags__box">
- <el-tabs
- v-model="active"
- type="card"
- @contextmenu="handleContextmenu"
- :closable="tagLen !== 1"
- @tab-click="openTag"
- @edit="menuTag"
- >
- <el-tab-pane
- v-for="(item, index) in tagList"
- :key="index"
- :label="generateTitle(item)"
- :name="item.fullPath"
- >
- <template #label>
- <span>
- {{ generateTitle(item) }}
- <i
- class="el-icon-refresh"
- :class="{ turn: refresh }"
- @click="handleRefresh"
- v-if="active === item.fullPath"
- ></i>
- </span>
- </template>
- </el-tab-pane>
- </el-tabs>
- <el-dropdown class="avue-tags__menu">
- <el-button type="primary">
- {{ $t('tagsView.menu') }}
- <i class="el-icon-arrow-down el-icon--right"></i>
- </el-button>
- <template #dropdown>
- <el-dropdown-menu>
- <el-dropdown-item @click="openSearch"
- ><i class="icon-fangda" /> {{ $t('tagsView.search') }}</el-dropdown-item
- >
- <el-dropdown-item @click="closeOthersTags"
- ><i class="icon-fangkuai1" /> {{ $t('tagsView.closeOthers') }}
- </el-dropdown-item>
- <el-dropdown-item @click="closeAllTags"
- ><i class="icon-cuowukongxin" /> {{ $t('tagsView.closeAll') }}</el-dropdown-item
- >
- <el-dropdown-item @click="clearCacheTags"
- ><i class="icon-dingwei" /> {{ $t('tagsView.clearCache') }}
- </el-dropdown-item>
- </el-dropdown-menu>
- </template>
- </el-dropdown>
- </div>
- </div>
-</template>
-<script>
-import { mapGetters } from 'vuex';
-import { clearCache } from '@/api/user';
-
-export default {
- name: 'tags',
- data() {
- return {
- refresh: false,
- active: '',
- contentmenuX: '',
- contentmenuY: '',
- contextmenuFlag: false,
- };
- },
- watch: {
- tag: {
- handler(val) {
- this.active = val.fullPath;
- },
- immediate: true,
- },
- contextmenuFlag() {
- window.addEventListener('mousedown', this.watchContextmenu);
- },
- },
- computed: {
- ...mapGetters(['tagWel', 'tagList', 'tag', 'setting']),
- tagLen() {
- return this.tagList.length || 0;
- },
- },
- methods: {
- openSearch() {
- this.$store.commit('SET_IS_SEARCH', true);
- },
- handleRefresh() {
- this.refresh = true;
- this.$store.commit('SET_IS_REFRESH', false);
- setTimeout(() => {
- this.$store.commit('SET_IS_REFRESH', true);
- }, 100);
- setTimeout(() => {
- this.refresh = false;
- }, 500);
- },
- generateTitle(item) {
- return this.$router.$avueRouter.generateTitle({
- ...item,
- ...{
- label: item.name,
- },
- });
- },
- watchContextmenu(event) {
- if (!this.$el.contains(event.target) || event.button !== 0) {
- this.contextmenuFlag = false;
- }
- window.removeEventListener('mousedown', this.watchContextmenu);
- },
- handleContextmenu(event) {
- let target = event.target;
- let flag = false;
- if (target.className.indexOf('el-tabs__item') > -1) flag = true;
- else if (target.parentNode.className.indexOf('el-tabs__item') > -1) {
- target = target.parentNode;
- flag = true;
- }
- if (flag) {
- event.preventDefault();
- event.stopPropagation();
- this.contentmenuX = event.clientX;
- this.contentmenuY = event.clientY;
- this.tagName = target.getAttribute('aria-controls').slice(5);
- this.contextmenuFlag = true;
- }
- },
- menuTag(value, action) {
- if (action === 'remove') {
- let { tag, key } = this.findTag(value);
- this.$store.commit('DEL_TAG', tag);
- if (tag.fullPath === this.tag.fullPath) {
- tag = this.tagList[key - 1];
- this.$router.push({
- path: tag.path,
- query: tag.query,
- });
- }
- }
- },
- openTag(item) {
- let value = item.props.name;
- let { tag } = this.findTag(value);
- this.$router.push({
- path: tag.path,
- query: tag.query,
- });
- },
- findTag(fullPath) {
- let tag = this.tagList.find(item => item.fullPath === fullPath);
- let key = this.tagList.findIndex(item => item.fullPath === fullPath);
- return { tag, key };
- },
- closeOthersTags() {
- this.contextmenuFlag = false;
- this.$store.commit('DEL_TAG_OTHER');
- },
- closeAllTags() {
- this.contextmenuFlag = false;
- this.$store.commit('DEL_ALL_TAG');
- this.$router.push(this.tagWel);
- },
- clearCacheTags() {
- this.$confirm('是否需要清除缓存?', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning',
- }).then(() => {
- clearCache().then(() => {
- this.contextmenuFlag = false;
- this.$message.success('清除完毕');
- });
- });
- },
- },
-};
-</script>
diff --git a/applications/mobile-web-view/src/page/index/top/index.vue b/applications/mobile-web-view/src/page/index/top/index.vue
deleted file mode 100644
index c51abfc..0000000
--- a/applications/mobile-web-view/src/page/index/top/index.vue
+++ /dev/null
@@ -1,123 +0,0 @@
-<template>
- <div class="avue-top">
- <div class="top-bar__left">
- <div
- class="avue-breadcrumb"
- :class="[{ 'avue-breadcrumb--active': isCollapse }]"
- v-if="setting.collapse && !isHorizontal"
- >
- <i class="icon-navicon" @click="setCollapse"></i>
- </div>
- </div>
- <div class="top-bar__title">
- <top-menu ref="topMenu" v-if="setting.menu"></top-menu>
- <top-search class="top-bar__item" v-if="setting.search"></top-search>
- </div>
- <div class="top-bar__right">
- <!-- <div v-if="setting.color" class="top-bar__item">
- <top-color></top-color>
- </div>
- <div v-if="setting.theme" class="top-bar__item">
- <top-theme></top-theme>
- </div> -->
- <div v-if="setting.lock" class="top-bar__item">
- <top-lock></top-lock>
- </div>
- <!-- <div class="top-bar__item">
- <top-lang></top-lang>
- </div> -->
- <div class="top-bar__item" v-if="setting.fullscreen">
- <top-full></top-full>
- </div>
- <!-- <div class="top-bar__item" v-if="setting.debug">
- <top-logs></top-logs>
- </div> -->
- <div class="top-user">
- <img class="top-bar__img" :src="userInfo.avatar" />
- <el-dropdown>
- <span class="el-dropdown-link">
- {{ userInfo.user_name }}
- <el-icon class="el-icon--right">
- <arrow-down />
- </el-icon>
- </span>
- <template #dropdown>
- <el-dropdown-menu>
- <el-dropdown-item>
- <router-link to="/">{{ $t('navbar.dashboard') }}</router-link>
- </el-dropdown-item>
- <el-dropdown-item>
- <router-link to="/info/index">{{ $t('navbar.userinfo') }}</router-link>
- </el-dropdown-item>
- <el-dropdown-item @click="logout" divided>{{ $t('navbar.logOut') }}</el-dropdown-item>
- </el-dropdown-menu>
- </template>
- </el-dropdown>
- <top-setting></top-setting>
- </div>
- </div>
- </div>
-</template>
-<script>
-import { mapGetters } from 'vuex'
-import topLock from './top-lock.vue'
-import topMenu from './top-menu.vue'
-import topSearch from './top-search.vue'
-import topTheme from './top-theme.vue'
-import topLogs from './top-logs.vue'
-import topColor from './top-color.vue'
-import topLang from './top-lang.vue'
-import topFull from './top-full.vue'
-import topSetting from '../setting.vue'
-
-export default {
- components: {
- topLock,
- topMenu,
- topSearch,
- topTheme,
- topLogs,
- topColor,
- topLang,
- topFull,
- topSetting,
- },
- name: 'top',
- data() {
- return {}
- },
- filters: {},
- created() {},
- computed: {
- ...mapGetters([
- 'setting',
- 'userInfo',
- 'tagWel',
- 'tagList',
- 'isCollapse',
- 'tag',
- 'logsLen',
- 'logsFlag',
- 'isHorizontal',
- ]),
- },
- methods: {
- setCollapse() {
- this.$store.commit('SET_COLLAPSE')
- },
- logout() {
- this.$confirm(this.$t('logoutTip'), this.$t('tip'), {
- confirmButtonText: this.$t('submitText'),
- cancelButtonText: this.$t('cancelText'),
- type: 'warning',
- }).then(() => {
- this.$store.dispatch('LogOut').then(() => {
- this.$router.push({ path: '/login' })
- })
- })
- },
- },
-}
-</script>
-
-<style lang="scss" scoped></style>
diff --git a/applications/mobile-web-view/src/page/index/top/top-color.vue b/applications/mobile-web-view/src/page/index/top/top-color.vue
deleted file mode 100644
index 429ff13..0000000
--- a/applications/mobile-web-view/src/page/index/top/top-color.vue
+++ /dev/null
@@ -1,75 +0,0 @@
-<template>
- <el-color-picker
- size="small"
- class="theme-picker"
- popper-class="theme-picker-dropdown"
- v-model="themeVal"
- ></el-color-picker>
-</template>
-
-<script>
-import { mapGetters } from 'vuex'; // default color
-export default {
- name: 'topColor',
- data() {
- return {
- themeVal: '',
- };
- },
- created() {
- this.themeVal = this.colorName || '#2C77F1';
- },
- watch: {
- themeVal(val, oldVal) {
- this.$store.commit('SET_COLOR_NAME', val);
- this.updateTheme(val, oldVal);
- },
- },
- computed: {
- ...mapGetters(['colorName']),
- },
- methods: {
- hexToRgb(str) {
- let hexs = '';
- str = str.replace('#', '');
- hexs = str.match(/../g);
- for (let i = 0; i < 3; i++) hexs[i] = parseInt(hexs[i], 16);
- return hexs;
- },
- // r 代表红色 | g 代表绿色 | b 代表蓝色
- rgbToHex(r, g, b) {
- let hexs = [r.toString(16), g.toString(16), b.toString(16)];
- for (let i = 0; i < 3; i++) if (hexs[i].length == 1) hexs[i] = `0${hexs[i]}`;
- return `#${hexs.join('')}`;
- },
-
- getDarkColor(color, level) {
- let rgb = this.hexToRgb(color);
- for (let i = 0; i < 3; i++) rgb[i] = Math.floor(rgb[i] * (1 - level));
- return this.rgbToHex(rgb[0], rgb[1], rgb[2]);
- },
-
- // color 颜色值字符串 | level 加深的程度,限0-1之间
- getLightColor(color, level) {
- let rgb = this.hexToRgb(color);
- for (let i = 0; i < 3; i++) rgb[i] = Math.floor((255 - rgb[i]) * level + rgb[i]);
- return this.rgbToHex(rgb[0], rgb[1], rgb[2]);
- },
-
- updateTheme(e) {
- if (!e) return;
- // e就是选择了的颜色
- const pre = '--el-color-primary';
- const el = document.documentElement;
- el.style.setProperty(pre, e);
- // 这里是覆盖原有颜色的核心代码
- for (let i = 1; i < 10; i += 1) {
- document.documentElement.style.setProperty(
- `${pre}-light-${i}`,
- `${this.getLightColor(e, i / 10)}`
- );
- }
- },
- },
-};
-</script>
diff --git a/applications/mobile-web-view/src/page/index/top/top-full.vue b/applications/mobile-web-view/src/page/index/top/top-full.vue
deleted file mode 100644
index 099d698..0000000
--- a/applications/mobile-web-view/src/page/index/top/top-full.vue
+++ /dev/null
@@ -1,24 +0,0 @@
-<template>
- <i :class="isFullScren ? 'icon-tuichuquanping' : 'icon-quanping'" @click="handleScreen"></i>
-</template>
-<script>
-import { mapGetters } from 'vuex';
-import { fullscreenToggel, listenfullscreen } from 'utils/util';
-
-export default {
- computed: {
- ...mapGetters(['isFullScren']),
- },
- mounted() {
- listenfullscreen(this.setScreen);
- },
- methods: {
- setScreen() {
- this.$store.commit('SET_FULLSCREN');
- },
- handleScreen() {
- fullscreenToggel();
- },
- },
-};
-</script>
diff --git a/applications/mobile-web-view/src/page/index/top/top-lang.vue b/applications/mobile-web-view/src/page/index/top/top-lang.vue
deleted file mode 100644
index 8e45557..0000000
--- a/applications/mobile-web-view/src/page/index/top/top-lang.vue
+++ /dev/null
@@ -1,40 +0,0 @@
-<template>
- <el-dropdown trigger="click" @command="handleSetLanguage">
- <i class="icon-zhongyingwen"></i>
- <template #dropdown>
- <el-dropdown-menu>
- <el-dropdown-item :disabled="language === 'zh-cn'" command="zh-cn">中文</el-dropdown-item>
- <el-dropdown-item :disabled="language === 'en'" command="en">English</el-dropdown-item>
- </el-dropdown-menu>
- </template>
- </el-dropdown>
-</template>
-
-<script>
-import { mapGetters } from 'vuex';
-
-export default {
- name: 'top-lang',
- data() {
- return {};
- },
- created() {},
- mounted() {},
- computed: {
- ...mapGetters(['language', 'tag']),
- },
- props: [],
- methods: {
- handleSetLanguage(lang) {
- this.$i18n.locale = lang;
- this.$store.commit('SET_LANGUAGE', lang);
- let tag = this.tag;
- let title = this.$router.$avueRouter.generateTitle(tag);
- //根据当前的标签也获取label的值动态设置浏览器标题
- this.$router.$avueRouter.setTitle(title);
- },
- },
-};
-</script>
-
-<style lang="scss" scoped></style>
diff --git a/applications/mobile-web-view/src/page/index/top/top-lock.vue b/applications/mobile-web-view/src/page/index/top/top-lock.vue
deleted file mode 100644
index cd70b5c..0000000
--- a/applications/mobile-web-view/src/page/index/top/top-lock.vue
+++ /dev/null
@@ -1,67 +0,0 @@
-<template>
- <span v-if="text" @click="handleLock">{{ text }}</span>
- <i v-else class="icon-suoping" @click="handleLock"></i>
- <el-dialog title="设置锁屏密码" v-model="box" width="30%" append-to-body>
- <el-form :model="form" ref="form" label-width="80px">
- <el-form-item
- label="锁屏密码"
- prop="passwd"
- :rules="[{ required: true, message: '锁屏密码不能为空' }]"
- >
- <el-input v-model="form.passwd" placeholder="请输入锁屏密码">
- <template #append>
- <el-button @click="handleSetLock" icon="el-icon-lock"></el-button>
- </template>
- </el-input>
- </el-form-item>
- </el-form>
- </el-dialog>
-</template>
-
-<script>
-import { validatenull } from 'utils/validate';
-import { mapGetters } from 'vuex';
-
-export default {
- name: 'top-lock',
- data() {
- return {
- box: false,
- form: {
- passwd: '',
- },
- };
- },
- created() {},
- mounted() {},
- computed: {
- ...mapGetters(['lockPasswd']),
- },
- props: {
- text: String,
- },
- methods: {
- handleSetLock() {
- this.$refs['form'].validate(valid => {
- if (valid) {
- this.$store.commit('SET_LOCK_PASSWD', this.form.passwd);
- this.handleLock();
- }
- });
- },
- handleLock() {
- if (validatenull(this.lockPasswd)) {
- this.box = true;
- return;
- }
- this.$store.commit('SET_LOCK');
- setTimeout(() => {
- this.$router.push({ path: '/lock' });
- }, 100);
- },
- },
- components: {},
-};
-</script>
-
-<style lang="scss" scoped></style>
diff --git a/applications/mobile-web-view/src/page/index/top/top-logs.vue b/applications/mobile-web-view/src/page/index/top/top-logs.vue
deleted file mode 100644
index 1c22381..0000000
--- a/applications/mobile-web-view/src/page/index/top/top-logs.vue
+++ /dev/null
@@ -1,86 +0,0 @@
-<template>
- <span @click="logsFlag ? '' : handleOpen()">
- <el-badge :value="logsFlag ? '' : logsLen" :max="99">
- <i class="icon-rizhi1"></i>
- </el-badge>
- <el-dialog title="日志" v-model="box" width="60%" append-to-body>
- <el-button type="primary" icon="el-icon-upload" @click="send">上传服务器</el-button>
- <el-button type="danger" icon="el-icon-delete" @click="clear">清空本地日志</el-button>
- <el-table :data="logsList">
- <el-table-column prop="type" label="类型" width="50px"> </el-table-column>
- <el-table-column prop="url" label="地址" show-overflow-tooltip width="180">
- </el-table-column>
- <el-table-column prop="message" show-overflow-tooltip label="内容"> </el-table-column>
- <el-table-column prop="stack" show-overflow-tooltip label="错误堆栈"> </el-table-column>
- <el-table-column prop="time" label="时间"> </el-table-column>
- </el-table>
- </el-dialog>
- </span>
-</template>
-
-<script>
-import { mapGetters } from 'vuex';
-
-export default {
- name: 'top-logs',
- data() {
- return {
- box: false,
- };
- },
- created() {},
- mounted() {},
- computed: {
- ...mapGetters(['logsList', 'logsFlag', 'logsLen']),
- },
- props: [],
- methods: {
- handleOpen() {
- this.box = true;
- },
- send() {
- this.$confirm('确定上传本地日志到服务器?', '提示', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning',
- })
- .then(() => {
- this.$store.dispatch('SendLogs').then(() => {
- this.box = false;
- this.$message({
- type: 'success',
- message: '发送成功!',
- });
- });
- })
- .catch(() => {});
- },
- clear() {
- this.$confirm('确定清空本地日志记录?', '提示', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning',
- })
- .then(() => {
- this.$store.commit('CLEAR_LOGS');
- this.box = false;
- this.$message({
- type: 'success',
- message: '清空成功!',
- });
- })
- .catch(() => {});
- },
- },
-};
-</script>
-
-<style lang="scss" scoped>
-.code {
- font-size: 12px;
- display: block;
- font-family: monospace;
- white-space: pre;
- margin: 1em 0px;
-}
-</style>
diff --git a/applications/mobile-web-view/src/page/index/top/top-menu.vue b/applications/mobile-web-view/src/page/index/top/top-menu.vue
deleted file mode 100644
index bd351a6..0000000
--- a/applications/mobile-web-view/src/page/index/top/top-menu.vue
+++ /dev/null
@@ -1,58 +0,0 @@
-<template>
- <el-menu class="top-menu" :default-active="activeIndex" mode="horizontal" text-color="#333">
- <el-menu-item index="0" @click="openHome(itemHome)">
- <template #title>
- <i :class="itemHome.source" style="padding-right: 5px"></i>
- <span>{{ itemHome.name }}</span>
- </template>
- </el-menu-item>
-
- <template v-for="(item, index) in items" :key="index">
- <el-menu-item :index="item.id + ''" @click="openMenu(item)">
- <template #title>
- <i :class="item.source" style="padding-right: 5px"></i>
- <span>{{ item.name }}</span>
- </template>
- </el-menu-item>
- </template>
- </el-menu>
-</template>
-
-<script>
-import { mapGetters } from 'vuex';
-
-export default {
- name: 'top-menu',
- data() {
- return {
- itemHome: {
- name: '首页',
- source: 'iconfont iconicon_work',
- },
- activeIndex: '0',
- items: [],
- };
- },
- inject: ['index'],
- created() {
- this.getMenu();
- },
- computed: {
- ...mapGetters(['tagCurrent', 'menu', 'tagWel']),
- },
- methods: {
- openMenu(item) {
- this.index.openMenu(item);
- },
- openHome(itemHome) {
- this.index.openMenu(itemHome);
- this.$router.push(this.tagWel);
- },
- getMenu() {
- this.$store.dispatch('GetTopMenu').then(res => {
- this.items = res;
- });
- },
- },
-};
-</script>
diff --git a/applications/mobile-web-view/src/page/index/top/top-search.vue b/applications/mobile-web-view/src/page/index/top/top-search.vue
deleted file mode 100644
index a3da15d..0000000
--- a/applications/mobile-web-view/src/page/index/top/top-search.vue
+++ /dev/null
@@ -1,120 +0,0 @@
-<template>
- <el-autocomplete
- class="top-search"
- popper-class="my-autocomplete"
- v-model="value"
- :fetch-suggestions="querySearch"
- :placeholder="$t('search')"
- @select="handleSelect"
- >
- <template #="{ item }">
- <i :class="[item[iconKey], 'icon']"></i>
- <div class="name">{{ item[labelKey] }}</div>
- <div class="addr">{{ item[pathKey] }}</div>
- </template>
- </el-autocomplete>
-</template>
-
-<script>
-import { mapGetters } from 'vuex';
-
-export default {
- data() {
- return {
- value: '',
- menuList: [],
- };
- },
- created() {
- this.getMenuList();
- },
-
- watch: {
- menu() {
- this.getMenuList();
- },
- },
- computed: {
- labelKey() {
- return this.website.menu.label;
- },
- pathKey() {
- return this.website.menu.path;
- },
- iconKey() {
- return this.website.menu.icon;
- },
- childrenKey() {
- return this.website.menu.children;
- },
- ...mapGetters(['menu']),
- },
- methods: {
- getMenuList() {
- const findMenu = list => {
- for (let i = 0; i < list.length; i++) {
- const ele = Object.assign({}, list[i]);
- if (this.validatenull(ele[this.childrenKey])) {
- this.menuList.push(ele);
- } else {
- findMenu(ele[this.childrenKey]);
- }
- }
- };
- this.menuList = [];
- findMenu(this.menu);
- },
- querySearch(queryString, cb) {
- var restaurants = this.menuList;
- var results = queryString ? restaurants.filter(this.createFilter(queryString)) : restaurants;
- // 调用 callback 返回建议列表的数据
- cb(results);
- },
- createFilter(queryString) {
- return restaurant => {
- return restaurant[this.labelKey].toLowerCase().indexOf(queryString.toLowerCase()) === 0;
- };
- },
- handleSelect(item) {
- this.value = '';
- this.$router.push({
- path: item[this.pathKey],
- query: item.query,
- });
- },
- },
-};
-</script>
-
-<style lang="scss">
-.my-autocomplete {
- li {
- line-height: normal !important;
- padding: 7px !important;
-
- .icon {
- margin-right: 5px;
- display: inline-block;
- vertical-align: middle;
- }
-
- .name {
- display: inline-block;
- text-overflow: ellipsis;
- overflow: hidden;
- vertical-align: middle;
- }
-
- .addr {
- padding-top: 5px;
- width: 100%;
- font-size: 12px;
- color: #b4b4b4;
- }
-
- .highlighted .addr {
- color: #ddd;
- }
- }
-}
-</style>
diff --git a/applications/mobile-web-view/src/page/index/top/top-theme.vue b/applications/mobile-web-view/src/page/index/top/top-theme.vue
deleted file mode 100644
index 1e2b93d..0000000
--- a/applications/mobile-web-view/src/page/index/top/top-theme.vue
+++ /dev/null
@@ -1,119 +0,0 @@
-<template>
- <div>
- <el-dialog title="选择" v-model="box" width="50%">
- <el-radio-group v-model="text" class="list">
- <el-row :span="24">
- <el-col v-for="(item, index) in list" :key="index" :md="4" :xs="12" :sm="4">
- <el-radio :label="item.value">{{ item.name }}</el-radio>
- </el-col>
- </el-row>
- </el-radio-group>
- </el-dialog>
-
- <span>
- <i class="icon-zhuti" @click="open"></i>
- </span>
- </div>
-</template>
-
-<script>
-import { setTheme } from 'utils/util';
-import { mapGetters } from 'vuex';
-
-export default {
- data() {
- return {
- box: false,
- text: '',
- list: [
- {
- name: '默认主题',
- value: 'default',
- },
- {
- name: '白色主题',
- value: 'theme-white',
- },
- {
- name: '黑色主题',
- value: 'theme-dark',
- },
- {
- name: 'go主题',
- value: 'theme-go',
- },
- {
- name: 'hey主题',
- value: 'theme-hey',
- },
- {
- name: '炫彩主题',
- value: 'theme-star',
- },
- {
- name: 'vip主题',
- value: 'theme-vip',
- },
- {
- name: '智能工厂主题',
- value: 'theme-bule',
- },
- {
- name: 'iview主题',
- value: 'theme-iview',
- },
- {
- name: 'cool主题',
- value: 'theme-cool',
- },
- {
- name: 'd2主题',
- value: 'theme-d2',
- },
- {
- name: 'lte主题',
- value: 'theme-lte',
- },
- {
- name: 'beautiful主题',
- value: 'theme-beautiful',
- },
- {
- name: 'Mac OS主题',
- value: 'mac-os',
- },
- ],
- };
- },
- watch: {
- text: function (val) {
- this.$store.commit('SET_THEME_NAME', val);
- setTheme(val);
- if (this.$store.getters.isMacOs) {
- this.$router.push(this.tagWel);
- setTimeout(() => location.reload());
- }
- },
- },
- computed: {
- ...mapGetters(['themeName', 'tagWel']),
- },
- mounted() {
- this.text = this.themeName;
- if (!this.text) {
- this.text = '';
- }
- },
- methods: {
- open() {
- this.box = true;
- },
- },
-};
-</script>
-
-<style lang="scss" scoped>
-.list {
- width: 100%;
-}
-</style>
diff --git a/applications/mobile-web-view/src/page/index/wechat.vue b/applications/mobile-web-view/src/page/index/wechat.vue
deleted file mode 100644
index 6a1a08d..0000000
--- a/applications/mobile-web-view/src/page/index/wechat.vue
+++ /dev/null
@@ -1,59 +0,0 @@
-<template>
- <el-dialog
- center
- :show-close="false"
- :close-on-press-escape="false"
- :close-on-click-modal="false"
- append-to-body
- v-model="dialogVisible"
- title="人机识别"
- width="400px"
- >
- <center>
- <span>
- 扫码下方二维码,回复<b>【验证码】</b><br />
- <span style="color: red">获得「验证码 + 交流群(一起摸🐟)」</span>
- </span>
- <br />
- <br />
- <img width="200" src="https://avuejs.com/images/icon/wechat.png" />
- <br />
- <br />
- <el-input v-model="value" placeholder="请输入验证码"></el-input>
- </center>
- <template #footer>
- <span class="dialog-footer">
- <el-button type="primary" @click="submit">确 认</el-button>
- </span>
- </template>
- </el-dialog>
-</template>
-<script>
-export default {
- data() {
- return {
- value: '',
- dialogVisible: false,
- };
- },
- created() {
- if (window.localStorage.getItem('avue_lock')) {
- return;
- }
- this.dialogVisible = true;
- },
- methods: {
- submit() {
- if (this.value == '') {
- this.$message.error('验证码不能为空');
- return;
- } else if (this.value != 'avue') {
- this.$message.error('验证码不正确');
- return;
- }
- this.dialogVisible = false;
- window.localStorage.setItem('avue_lock', true);
- },
- },
-};
-</script>
diff --git a/applications/mobile-web-view/src/page/login/authredirect.vue b/applications/mobile-web-view/src/page/login/authredirect.vue
deleted file mode 100644
index 67a8588..0000000
--- a/applications/mobile-web-view/src/page/login/authredirect.vue
+++ /dev/null
@@ -1,18 +0,0 @@
-<template>
- <div></div>
-</template>
-
-<script>
-export default {
- name: 'authredirect',
- created() {
- window.close();
- const params = this.$route.query;
- const state = params.state;
- const code = params.code;
- window.opener.location.href = `${window.location.origin}/#/login?state=${state}&code=${code}`;
- },
-};
-</script>
-
-<style></style>
diff --git a/applications/mobile-web-view/src/page/login/codelogin.vue b/applications/mobile-web-view/src/page/login/codelogin.vue
deleted file mode 100644
index ba7cf60..0000000
--- a/applications/mobile-web-view/src/page/login/codelogin.vue
+++ /dev/null
@@ -1,193 +0,0 @@
-<template>
- <el-form
- class="login-form"
- status-icon
- :rules="loginRules"
- ref="loginForm"
- :model="loginForm"
- label-width="0"
- >
- <el-form-item v-if="tenantMode" prop="tenantId">
- <el-input
- @keyup.enter="handleLogin"
- v-model="loginForm.tenantId"
- auto-complete="off"
- :placeholder="$t('login.tenantId')"
- >
- <template #prefix>
- <i class="icon-quanxian" />
- </template>
- </el-input>
- </el-form-item>
- <el-form-item prop="phone">
- <el-input
- @keyup.enter="handleLogin"
- v-model="loginForm.phone"
- auto-complete="off"
- :placeholder="$t('login.phone')"
- >
- <template #prefix>
- <i class="icon-shouji" />
- </template>
- </el-input>
- </el-form-item>
- <el-form-item prop="code">
- <el-input
- @keyup.enter="handleLogin"
- v-model="loginForm.codeValue"
- auto-complete="off"
- :placeholder="$t('login.code')"
- >
- <template #prefix>
- <i class="icon-yanzhengma"></i>
- </template>
- <template #append>
- <span @click="handleSend" class="msg-text" :class="[{ display: msgKey }]">{{
- msgText
- }}</span>
- </template>
- </el-input>
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click.prevent="handleLogin" class="login-submit">{{
- $t('login.submit')
- }}</el-button>
- </el-form-item>
- </el-form>
-</template>
-
-<script>
-import { isvalidatemobile } from '@/utils/validate';
-import { mapGetters } from 'vuex';
-import { sendSms } from '@/api/user';
-import { getTopUrl } from '@/utils/util';
-import { info } from '@/api/system/tenant';
-import { encrypt } from '@/utils/sm2';
-
-export default {
- name: 'codelogin',
- data() {
- const validatePhone = (rule, value, callback) => {
- if (isvalidatemobile(value)[0]) {
- callback(new Error(isvalidatemobile(value)[1]));
- } else {
- callback();
- }
- };
- return {
- tenantMode: this.website.tenantMode,
- msgText: '',
- msgTime: '',
- msgKey: false,
- loginForm: {
- tenantId: '000000',
- phone: '',
- codeValue: '',
- codeId: '',
- },
- loginRules: {
- phone: [{ required: true, trigger: 'blur', validator: validatePhone }],
- codeValue: [{ required: true, trigger: 'blur' }],
- },
- };
- },
- created() {
- this.getTenant();
- this.getMsg();
- },
- mounted() {},
- computed: {
- ...mapGetters(['tagWel']),
- config() {
- return {
- MSGINIT: this.$t('login.msgText'),
- MSGSCUCCESS: this.$t('login.msgSuccess'),
- MSGTIME: 60,
- };
- },
- },
- props: [],
- methods: {
- handleSend() {
- this.$refs.loginForm.validate(valid => {
- if (valid) {
- if (this.msgKey) return;
- this.msgText = this.msgTime + this.config.MSGSCUCCESS;
- this.msgKey = true;
- const time = setInterval(() => {
- this.msgTime--;
- this.msgText = this.msgTime + this.config.MSGSCUCCESS;
- if (this.msgTime === 0) {
- this.msgTime = this.config.MSGTIME;
- this.msgText = this.config.MSGINIT;
- this.msgKey = false;
- clearInterval(time);
- }
- }, 1000);
- sendSms(this.loginForm.tenantId, encrypt(this.loginForm.phone)).then(res => {
- const data = res.data;
- if (data.success) {
- this.loginForm.codeId = data.data.id;
- this.$message.success(data.msg);
- } else {
- this.$message.error(data.msg);
- }
- });
- }
- });
- },
- handleLogin() {
- this.$refs.loginForm.validate(valid => {
- if (valid) {
- const loading = this.$loading({
- lock: true,
- text: '登录中,请稍后',
- background: 'rgba(0, 0, 0, 0.7)',
- });
- this.$store
- .dispatch('LoginByPhone', this.loginForm)
- .then(() => {
- loading.close();
- this.$router.push(this.tagWel);
- })
- .catch(err => {
- console.log(err);
- loading.close();
- });
- }
- });
- },
- getMsg() {
- this.msgText = this.config.MSGINIT;
- this.msgTime = this.config.MSGTIME;
- },
- getTenant() {
- let domain = getTopUrl();
- // 临时指定域名,方便测试
- //domain = "https://bladex.cn";
- info(domain).then(res => {
- const data = res.data;
- if (data.success && data.data.tenantId) {
- this.tenantMode = false;
- this.loginForm.tenantId = data.data.tenantId;
- this.$parent.$refs.login.style.backgroundImage = `url(${data.data.backgroundUrl})`;
- }
- });
- },
- },
-};
-</script>
-
-<style>
-.msg-text {
- display: block;
- width: 60px;
- font-size: 12px;
- text-align: center;
- cursor: pointer;
-}
-
-.msg-text.display {
- color: #ccc;
-}
-</style>
diff --git a/applications/mobile-web-view/src/page/login/facelogin.vue b/applications/mobile-web-view/src/page/login/facelogin.vue
deleted file mode 100644
index e1da201..0000000
--- a/applications/mobile-web-view/src/page/login/facelogin.vue
+++ /dev/null
@@ -1,39 +0,0 @@
-<template>
- <basic-video ref="video" :width="350"></basic-video>
-</template>
-
-<script>
-import { mapGetters } from 'vuex';
-import basicVideo from '@/components/basic-video/main.vue';
-
-export default {
- components: {
- basicVideo,
- },
- data() {
- return {
- loginForm: {
- username: 'admin',
- password: '123456',
- },
- };
- },
- created() {
- setTimeout(() => {
- this.handleLogin();
- }, 6000);
- },
- computed: {
- ...mapGetters(['tagWel']),
- },
- methods: {
- handleLogin() {
- this.$store.dispatch('LoginByUsername', this.loginForm).then(() => {
- this.$router.push(this.tagWel);
- });
- },
- },
-};
-</script>
-
-<style></style>
diff --git a/applications/mobile-web-view/src/page/login/index.vue b/applications/mobile-web-view/src/page/login/index.vue
index 7fdbe43..2b3ae72 100644
--- a/applications/mobile-web-view/src/page/login/index.vue
+++ b/applications/mobile-web-view/src/page/login/index.vue
@@ -7,12 +7,8 @@
</template>
<script>
import userLogin from './userlogin.vue'
-import registerLogin from './registerlogin.vue'
-import codeLogin from './codelogin.vue'
-import thirdLogin from './thirdlogin.vue'
import { mapGetters } from 'vuex'
import { validatenull } from '@/utils/validate'
-import topLang from '@/page/index/top/top-lang.vue'
import { getQueryString, getTopUrl } from '@/utils/util'
import website from '@/config/website'
@@ -24,10 +20,6 @@
name: 'login',
components: {
userLogin,
- registerLogin,
- codeLogin,
- thirdLogin,
- topLang,
},
data() {
return {
diff --git a/applications/mobile-web-view/src/page/login/registerlogin.vue b/applications/mobile-web-view/src/page/login/registerlogin.vue
deleted file mode 100644
index 7e5c6b4..0000000
--- a/applications/mobile-web-view/src/page/login/registerlogin.vue
+++ /dev/null
@@ -1,216 +0,0 @@
-<template>
- <el-form
- class="login-form"
- status-icon
- :rules="loginRules"
- ref="loginForm"
- :model="loginForm"
- label-width="0"
- >
- <el-form-item v-if="tenantMode" prop="tenantId">
- <el-input
- @keyup.enter="handleRegister"
- v-model="loginForm.tenantId"
- auto-complete="off"
- :placeholder="$t('login.tenantId')"
- >
- <template #prefix>
- <i class="icon-quanxian" />
- </template>
- </el-input>
- </el-form-item>
- <el-form-item prop="name">
- <el-input
- @keyup.enter="handleRegister"
- v-model="loginForm.name"
- auto-complete="off"
- :placeholder="$t('login.name')"
- >
- <template #prefix>
- <i class="icon-zhanghaoquanxianguanli" />
- </template>
- </el-input>
- </el-form-item>
- <el-form-item prop="account">
- <el-input
- @keyup.enter="handleRegister"
- v-model="loginForm.account"
- auto-complete="off"
- :placeholder="$t('login.username')"
- >
- <template #prefix>
- <i class="icon-yonghu" />
- </template>
- </el-input>
- </el-form-item>
- <el-form-item prop="phone">
- <el-input
- @keyup.enter="handleRegister"
- v-model="loginForm.phone"
- auto-complete="off"
- :placeholder="$t('login.phone')"
- >
- <template #prefix>
- <i class="icon-shouji" />
- </template>
- </el-input>
- </el-form-item>
- <el-form-item prop="email">
- <el-input
- @keyup.enter="handleRegister"
- v-model="loginForm.email"
- auto-complete="off"
- :placeholder="$t('login.email')"
- >
- <template #prefix>
- <i class="icon-xiaoxitongzhi" />
- </template>
- </el-input>
- </el-form-item>
- <el-form-item prop="password">
- <el-input
- @keyup.enter="handleRegister"
- type="password"
- show-password
- v-model="loginForm.password"
- auto-complete="off"
- :placeholder="$t('login.password')"
- >
- <template #prefix>
- <i class="icon-mima" />
- </template>
- </el-input>
- </el-form-item>
- <el-form-item prop="password1">
- <el-input
- @keyup.enter="handleRegister"
- type="password"
- show-password
- v-model="loginForm.password1"
- auto-complete="off"
- :placeholder="$t('login.password1')"
- >
- <template #prefix>
- <i class="icon-mima" />
- </template>
- </el-input>
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click.prevent="handleRegister" class="login-submit"
- >{{ $t('login.register') }}
- </el-button>
- <el-button @click.prevent="handleBack" class="register-submit"
- >{{ $t('login.back') }}
- </el-button>
- </el-form-item>
- </el-form>
-</template>
-
-<script>
-import { mapGetters } from 'vuex';
-import { info } from '@/api/system/tenant';
-import { getTopUrl } from '@/utils/util';
-
-export default {
- name: 'userlogin',
- data() {
- return {
- tenantMode: this.website.tenantMode,
- captchaMode: this.website.captchaMode,
- registerMode: this.website.oauth2.registerMode,
- loginForm: {
- //租户ID
- tenantId: '',
- //部门ID
- deptId: '',
- //角色ID
- roleId: '',
- //用户名
- account: '',
- //手机号
- phone: '',
- //邮箱
- email: '',
- //密码
- password: '',
- //确认密码
- password1: '',
- //账号类型
- type: 'account',
- //预加载白色背景
- image: 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7',
- },
- loginRules: {
- tenantId: [{ required: true, message: '请输入租户ID', trigger: 'blur' }],
- name: [{ required: true, message: '请输入密码', trigger: 'blur' }],
- account: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
- phone: [{ required: true, message: '请输入手机号', trigger: 'blur' }],
- email: [{ required: true, message: '请输入邮箱', trigger: 'blur' }],
- password: [{ required: true, message: '请输入密码', trigger: 'blur' }],
- password1: [{ required: true, message: '请输入确认密码', trigger: 'blur' }],
- },
- passwordType: 'password',
- };
- },
- created() {
- this.getTenant();
- },
- mounted() {
- this.$nextTick(() => {});
- },
- watch: {},
- computed: {
- ...mapGetters(['tagWel', 'userInfo']),
- },
- props: [],
- methods: {
- handleRegister() {
- if (this.loginForm.password !== this.loginForm.password1) {
- this.$message.error('两次密码输入不一致');
- return;
- }
- this.$refs.loginForm.validate(valid => {
- if (valid) {
- const loading = this.$loading({
- lock: true,
- text: '注册中,请稍后',
- background: 'rgba(0, 0, 0, 0.7)',
- });
- this.$store
- .dispatch('RegisterUser', this.loginForm)
- .then(() => {
- this.$alert('注册成功,请耐心等待管理员审核后分配权限', '注册成功', {
- confirmButtonText: '确定',
- callback: () => {
- this.$parent.activeName = 'user';
- },
- });
- })
- .catch(err => {
- console.log(err);
- });
- loading.close();
- }
- });
- },
- handleBack() {
- this.$parent.activeName = 'user';
- },
- getTenant() {
- let domain = getTopUrl();
- // 临时指定域名,方便测试
- //domain = "https://bladex.cn";
- info(domain).then(res => {
- const data = res.data;
- if (data.success && data.data.tenantId) {
- this.tenantMode = false;
- this.loginForm.tenantId = data.data.tenantId;
- this.$parent.$refs.login.style.backgroundImage = `url(${data.data.backgroundUrl})`;
- }
- });
- },
- },
-};
-</script>
-
-<style></style>
diff --git a/applications/mobile-web-view/src/page/login/thirdlogin.vue b/applications/mobile-web-view/src/page/login/thirdlogin.vue
deleted file mode 100644
index 53360bb..0000000
--- a/applications/mobile-web-view/src/page/login/thirdlogin.vue
+++ /dev/null
@@ -1,67 +0,0 @@
-<template>
- <div class="social-container">
- <div @click="handleClick('github')">
- <span class="container" :style="{ backgroundColor: '#61676D' }">
- <i icon-class="github" class="iconfont icongithub"></i>
- </span>
- </div>
- <div @click="handleClick('gitee')">
- <span class="container" :style="{ backgroundColor: '#c35152' }">
- <i icon-class="gitee" class="iconfont icongitee2"></i>
- </span>
- </div>
- <div @click="handleClick('wechat_open')">
- <span class="container" :style="{ backgroundColor: '#8dc349' }">
- <i icon-class="wechat" class="iconfont icon-weixin" />
- </span>
- </div>
- <div @click="handleClick('qq')">
- <span class="container" :style="{ backgroundColor: '#6ba2d6' }">
- <i icon-class="qq" class="iconfont icon-qq" />
- </span>
- </div>
- </div>
-</template>
-
-<script>
-import website from '@/config/website';
-
-export default {
- name: 'thirdLogin',
- methods: {
- handleClick(source) {
- window.location.href = `${website.oauth2.authUrl}/${source}`;
- },
- },
-};
-</script>
-
-<style rel="stylesheet/scss" lang="scss" scoped>
-.social-container {
- margin: 20px 0;
- display: flex;
- align-items: center;
- justify-content: space-around;
-
- .iconfont {
- color: #fff;
- font-size: 30px;
- }
-
- .container {
- $height: 50px;
- cursor: pointer;
- display: inline-block;
- width: $height;
- height: $height;
- line-height: $height;
- text-align: center;
- border-radius: 4px;
- margin-bottom: 10px;
- }
-
- .title {
- text-align: center;
- }
-}
-</style>
diff --git a/applications/mobile-web-view/src/page/work/index.vue b/applications/mobile-web-view/src/page/work/index.vue
deleted file mode 100644
index 86bd430..0000000
--- a/applications/mobile-web-view/src/page/work/index.vue
+++ /dev/null
@@ -1,352 +0,0 @@
-<template>
- <div class="eventTickets">
- <div class="searchTop">
- <van-search
- placeholder="请输入关键字搜索"
- :animation="true"
- v-model="listParams.keyword"
- :show-action="false"
- @search="onSearch"
- ></van-search>
- <div class="Hamburger" @click="selectag"><img src="/src/appDataSource/appwork/hbb.svg" alt="" /></div>
- </div>
- <div v-if="!showhanbao">
- <van-tabs v-model:active="currentTab" @change="handleChange">
- <van-tab
- v-for="tab in tabList"
- :key="tab.key"
- :name="tab.key"
- :title="tab.name"
- :badge="tab.badge.value"
- ></van-tab>
- </van-tabs>
- <div class="eventBox">
- <div class="eventItem" v-for="(item, index) in dataList" :key="index">
- <img :src="item.photo_url" alt="" @click="detailHandle(item)" />
- <div class="itemTitle">{{ item.event_name }}</div>
- <div class="itemContent">
- <div class="itemStatus">
- <span v-if="item.status === 0" style="background-color: #ff7411"></span>
- <span v-else-if="item.status === 2" style="background-color: #ff472f"></span>
- <span v-else-if="item.status === 3" style="background-color: #ffc300"></span>
- <span v-else-if="item.status === 4" style="background-color: #06d957"></span>
- <p>{{ formatDate(item.create_time) }}</p>
- </div>
- <div class="fullBtn"><img src="/src/appDataSource/appwork/fullscreen.svg" alt="" /></div>
- </div>
- </div>
- </div>
- </div>
- <div class="selectContainer" v-else>
- <div class="leftTab">
- <div
- class="tabitem"
- v-for="(item, index) in leftTabList"
- :key="index"
- @click="handleTabClick(item)"
- :class="{ 'active': activeTab === item }"
- >
- {{ item }}
- </div>
- </div>
- <div class="rightContent">
- <div
- v-for="(item, index) in rightDataList[activeTab]"
- :key="index"
- class="contentItem"
- @click="filteringAlgorithms(item)"
- >
- <div class="imagediv"><img :src="`${baseUrl}/后台-算法仓库/${item.name}.png`" /></div>
- {{ item.name }}
- </div>
- </div>
- </div>
- </div>
-</template>
-<script setup>
-import { getList, getstatusCount, getDictionaryByCode, getChildList } from '/src/api/work/index.js'
-import dayjs from 'dayjs'
-import { useRoute } from 'vue-router'
-import { useStore } from 'vuex'
-const baseUrl = import.meta.env.VITE_APP_PICTURE_URL
-const store = useStore()
-const route = useRoute()
-const userInfo = computed(() => store?.state?.user?.userInfo)
-let AlgorithmData = ref([])
-const dataList = ref([])
-const currentTab = ref('myTickets')
-const tabList = ref([
- {
- name: '我的工单',
- key: 'myTickets',
- badge: {
- value: 1,
- },
- },
- {
- name: '全部状态',
- key: 'all',
- badge: {
- value: 2,
- },
- status: null,
- },
- {
- name: '待审核',
- key: 'pending',
- badge: {
- value: 3,
- },
- status: '2',
- },
- {
- name: '待处理',
- key: 'processing',
- badge: {
- value: 4,
- },
- status: '0',
- },
- {
- name: '处理中',
- key: 'inProgress',
- badge: {
- value: 5,
- },
- status: '3',
- },
- {
- name: '已完成',
- key: 'completed',
- badge: {
- value: 6,
- },
- status: '4',
- },
-])
-const formatDate = dateString => {
- return dayjs(dateString).format('MM/DD HH:mm')
-}
-const listParams = ref({
- status: null,
- current: 1,
- size: 9999,
- source: 1,
- department: '',
- keyword: '',
- parentId: '1905161774696075265',
-})
-const getDataList = () => {
- const params = {
- current: 1,
- size: 9999,
- source: 1,
- status: listParams.value.status,
- event_name: listParams.value.keyword,
- user_id: currentTab.value === 'myTickets' ? userInfo.value.user_id : undefined,
- }
-
- getList(params).then(res => {
- const response = res.data.data.records
- dataList.value = response
- })
-}
-const getstatusCountData = () => {
- getstatusCount().then(res => {
- const response = res.data.data
- const { statusCount, totalCount, userCount } = response
- tabList.value.forEach(tab => {
- if (tab.key === 'all') {
- tab.badge.value = totalCount || 0
- } else if (tab.key === 'myTickets') {
- tab.badge.value = userCount || 0
- } else {
- tab.badge.value = statusCount[String(tab.status)] || 0
- }
- })
- })
-}
-
-const handleChange = key => {
- // 找到当前选中的标签
- const currentTabItem = tabList.value.find(tab => tab.key === key)
- if (currentTabItem) {
- currentTab.value = key
- listParams.value.status = currentTabItem.status
- getDataList()
- }
-}
-const detailHandle = val => {
- uni.navigateTo({
- url: `/subPackages/workDetail/index?eventNum=${val.event_num}`,
- })
-}
-const onSearch = () => {
- getDataList()
-}
-
-const showhanbao = ref(false)
-const selectag = () => {
- showhanbao.value = !showhanbao.value
-}
-// 筛选
-const activeTab = ref('全部')
-const leftTabList = ref(['全部'])
-const rightDataList = ref({
- '全部': [],
-})
-const handleTabClick = tab => {
- activeTab.value = tab
-}
-// 算法
-const requestDictionary = () => {
- getChildList(listParams.value.current, listParams.value.size, listParams.value.parentId).then(res => {
- AlgorithmData.value = res.data.data
- const processedData = { '全部': [] }
- const leftTabs = ['全部']
-
- AlgorithmData.value.forEach(category => {
- const categoryName = category.dictValue
- leftTabs.push(categoryName)
-
- processedData[categoryName] = []
- if (category.children && category.children.length) {
- const secondLevelData = category.children.map(item => ({
- name: item.dictValue,
- }))
-
- processedData[categoryName] = secondLevelData
- processedData['全部'] = [...processedData['全部'], ...secondLevelData]
- }
- })
-
- rightDataList.value = processedData
- leftTabList.value = leftTabs
- })
-}
-const filteringAlgorithms = val => {
- currentTab.value = 'all'
- listParams.value.keyword = val.name
- showhanbao.value = !showhanbao.value
- getDataList()
-}
-onMounted(() => {
- getDataList()
- getstatusCountData()
- requestDictionary()
-})
-</script>
-<style scoped lang="scss">
-.eventTickets {
- padding: 0 10px;
-
- .searchTop {
- display: flex;
- align-items: center;
- justify-content: space-between;
- margin-top: 10px;
- width: 100%;
-
- .Hamburger {
- width: 20%;
- width: 20px;
- height: 20px;
- img {
- width: 100%;
- height: 100%;
- }
- }
- }
-
- :deep(.van-badge) {
- background-color: #1d6fe9 !important;
- }
-
- .eventBox {
- display: flex;
- flex-wrap: wrap;
- gap: 10px;
- padding: 10px 0;
- background-color: #ebeff2;
-
- .eventItem {
- width: calc(50% - 5px);
- background-color: #fff;
- border-radius: 5px;
- overflow: hidden;
-
- img {
- width: 100%;
- height: 100px;
- border-radius: 5px;
- overflow: hidden;
- }
-
- .itemTitle {
- padding: 0 5px;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- }
-
- .itemContent {
- display: flex;
- justify-content: space-between;
- align-items: center;
- padding: 5px;
-
- .itemStatus {
- display: flex;
- align-items: center;
-
- span {
- display: inline-block;
- width: 10px;
- height: 10px;
- border-radius: 50%;
- margin-right: 5px;
- }
- }
- .fullBtn {
- img {
- width: 14px;
- height: 14px;
- }
- }
- }
- }
- }
- .selectContainer {
- display: flex;
- justify-content: space-between;
- .active {
- color: #1d6fe9;
- }
- .tabitem {
- margin-bottom: 30px;
- }
- .leftTab {
- white-space: nowrap;
- margin-right: 20px;
- }
- .rightContent {
- width: 100%;
- display: grid;
- grid-template-columns: repeat(3, 1fr); // 3 columns
- gap: 10px; // spacing between items
- height: 90px;
- .contentItem {
- .imagediv {
- width: 58px;
- height: 58px;
-
- img {
- width: 100%;
- height: 100%;
- }
- }
- }
- }
- }
-}
-</style>
diff --git a/applications/mobile-web-view/src/page/work/workDetail/addWork/index.vue b/applications/mobile-web-view/src/page/work/workDetail/addWork/index.vue
deleted file mode 100644
index b78d0eb..0000000
--- a/applications/mobile-web-view/src/page/work/workDetail/addWork/index.vue
+++ /dev/null
@@ -1,8 +0,0 @@
-<!-- 新建工单 -->
-<template>
- <view> 基础 </view>
-</template>
-
-<script setup></script>
-
-<style lang="scss" scoped></style>
diff --git a/applications/mobile-web-view/src/page/work/workDetail/index.vue b/applications/mobile-web-view/src/page/work/workDetail/index.vue
deleted file mode 100644
index 2dd5ac4..0000000
--- a/applications/mobile-web-view/src/page/work/workDetail/index.vue
+++ /dev/null
@@ -1,837 +0,0 @@
-<!-- 工单详情 - 包含待审核、待处理、处理中、已完成 -->
-<template>
- <div class="workDetailContainer">
- <div class="detailTop">
- <div class="image-container">
- <van-image class="detailImage" :src="currentDetail.photo_url" fit="cover" width="100%" height="200px" />
- <div class="detailTitle">
- <div class="titleText">
- <div class="itemStatus">
- <span v-if="currentDetail.status === 0" style="background-color: #ff7411"></span>
- <span v-else-if="currentDetail.status === 2" style="background-color: #ff472f"></span>
- <span v-else-if="currentDetail.status === 3" style="background-color: #ffc300"></span>
- <span v-else-if="currentDetail.status === 4" style="background-color: #06d957"></span>
- <div>{{ currentDetail.event_name }}</div>
- </div>
- <div class="timeNavigation">
- <p>{{ formatDate(currentDetail.create_time) }}</p>
- <img src="/src/appDataSource/appwork/navigation.svg" alt="" />
- </div>
- </div>
- </div>
- </div>
- </div>
- <!-- 步骤条 -->
- <div class="stepContainer">
- <van-steps direction="vertical" :active="currentStep">
- <van-step v-for="(step, index) in displayedSteps" :key="step.status">
- <div class="horizontal-step">
- <span class="step-title" :class="getStatusClass(index)">{{ step.title }}</span>
-
- <div class="step-desc" v-if="stepResponse[index]">
- <span>{{ stepResponse[index].name || '' }}</span>
- <span>{{ stepResponse[index].create_time || '' }}</span>
- </div>
- </div>
- </van-step>
- </van-steps>
- </div>
- <!-- 工单内容 -->
- <div class="workOrderContent">
- <div class="workOrderTitle">工单内容</div>
- <div class="workOrderContainer">
- <div class="orderRow">
- <span class="required-mark" v-if="isEditable">*</span>
- <div class="rowTitle">工单名称</div>
-
- <div v-if="!isEditable">{{ currentDetail.event_name }}</div>
-
- <van-field
- v-else
- v-model="currentDetail.event_name"
- name="event_name"
- required
- placeholder="请输入工单名称"
- />
- </div>
- <div class="orderRow">
- <div class="rowTitle">工单类型</div>
- <div>{{ workOrderTypeName }}</div>
- </div>
- <div class="orderRow">
- <div class="rowTitle">关联任务</div>
- <div>{{ currentDetail.job_name }}</div>
- </div>
- <div class="orderRow">
- <div class="rowTitle">工单创建人</div>
- <div>{{ currentDetail.event_num?.slice(0, 2) === 'AI' ? 'AI 小飞' : currentDetail.create_user }}</div>
- </div>
- <div class="orderRow">
- <div class="rowTitle">事件地址</div>
- <div class="rowAddress">{{ currentDetail.address }}</div>
- >
- </div>
-
- <div class="orderRow">
- <div class="guanlian">
- <span class="required-mark" v-if="isEditable">*</span>
- <div class="rowTitle">关联算法</div>
- </div>
- <div v-if="!isEditable">{{ currentDetail.ai_types }}</div>
- <div v-else>
- <span @click="openselect" class="selectTrigger">{{ currentDetail.ai_types }} ></span>
-
- <van-popup v-model:show="showPicker" destroy-on-close position="bottom" :close-on-click-overlay="true">
- <van-picker
- v-model="selectedValues"
- title="选择关联算法"
- :columns="columns"
- @confirm="onConfirm"
- @cancel="onCancel"
- />
- </van-popup>
- </div>
- </div>
- <div class="orderRow">
- <div class="rowTitle">发起部门</div>
- <div>{{ currentDetail.dept_name }}</div>
- </div>
- <div class="orderRow">
- <div class="rowTitle">发起任务时间</div>
- <div>{{ currentDetail.create_time }}</div>
- </div>
- <div class="orderRow">
- <span class="required-mark" v-if="isEditable">*</span>
- <div class="rowTitle">工单内容</div>
- <div v-if="!isEditable">{{ currentDetail.content }}</div>
- <van-field v-else v-model="currentDetail.content" name="remark" required placeholder="请输入工单内容" />
- </div>
- <div class="orderRow" v-if="isEditableProcess">
- <div class="guanlian">
- <span class="required-mark">*</span>
- <div class="rowTitle">
- 上传图片
- <span>(只能上传jpg、jpeg、png照片,且不超过5M)</span>
- </div>
- </div>
- <div>
- <span class="upload-link" @click="triggerUpload">上传图片</span>
-
- <!-- 隐藏的文件选择器 -->
- <input
- ref="fileInput"
- type="file"
- accept="image/png, image/jpeg, image/jpg"
- @change="handleFileChange"
- style="display: none"
- />
- </div>
- </div>
- <div class="orderRow" v-if="isEditableProcess">
- <span class="required-mark">*</span>
- <div class="rowTitle">事件处理详情</div>
- <van-field v-model="currentDetail.processingDetail" name="event_name" required />
- </div>
- </div>
- </div>
- <!-- 操作按钮 -->
- <div class="actionButton">
- <div class="leftBtn" @click="leftClick"><img src="/src/appDataSource/appwork/leftBtn.svg" alt="" /></div>
- <div class="btngroups" v-if="currentDetail.status === 2">
- <van-button type="danger" round text="不通过" @click="rejectTicket"></van-button>
- <van-button type="primary" round text="通过" @click="approveTicket"></van-button>
- </div>
- <div class="btngroups" v-else-if="currentDetail.status === 0">
- <van-button type="danger" round text="不受理" @click="rejectTicket"></van-button>
- <van-button type="primary" round text="受理" @click="approveAndDispatch"></van-button>
- </div>
- <div class="btngroups" v-else-if="currentDetail.status === 3">
- <van-button type="danger" round text="取消" @click="cancellation"></van-button>
- <van-button type="primary" round text="完成工单" @click="completeTicket"></van-button>
- </div>
- <div class="btngroups" v-else>
- <van-button type="danger" round text="取消" @click="cancellation"></van-button>
- </div>
- <div class="leftBtn" @click="rightClick"><img src="/src/appDataSource/appwork/rightBtn.svg" alt="" /></div>
- </div>
-
- <!--派发工单对话框-->
- <van-dialog
- v-model:show="isshowDispatch"
- title="派发工单"
- show-cancel-button
- @confirm="submitDispatch"
- @cancel="dispatchCancel"
- >
- <van-field
- v-model="dispatchForm.departmentName"
- is-link
- readonly
- label="选择部门"
- placeholder="请选择部门"
- @click="openPicker('department')"
- />
- <van-field
- v-model="dispatchForm.handlerName"
- is-link
- readonly
- label="选择处理人"
- placeholder="请选择处理人"
- @click="openPicker('processor')"
- :disabled="!dispatchForm.department"
- />
- </van-dialog>
-
- <teleport to="body">
- <van-popup v-model:show="showGlobalPicker" position="bottom">
- <!-- 部门选择器 -->
- <van-picker
- v-if="currentPickerType === 'department'"
- v-model="selectedDepartment"
- title="选择部门"
- :columns="departments"
- @confirm="onDepartmentConfirm"
- @cancel="onPickerCancel"
- />
-
- <!-- 处理人选择器 -->
- <van-picker
- v-if="currentPickerType === 'processor'"
- v-model="selectedProcessor"
- title="选择处理人"
- :columns="availableDispatchHandlers"
- @confirm="onProcessorConfirm"
- @cancel="onPickerCancel"
- />
- </van-popup>
- </teleport>
- </div>
-</template>
-
-<script setup>
-import { useRoute } from 'vue-router'
-import { getStepInfo, getList, flowEvent, getTicketInfo } from '/src/api/work/index.js'
-import { showToast, showNotify } from 'vant'
-import dayjs from 'dayjs'
-const showPicker = ref(false)
-const selectedValues = ref([])
-const columns = ref([])
-const allAlgorithms = ref([])
-const algorithms = ref([])
-const types = ref([]) //工单类型
-const eventNum = ref('')
-const currentStatus = ref('')
-const stepResponse = ref([])
-const currentStep = ref(0)
-const route = useRoute()
-const currentDetail = ref({})
-const currentIndex = ref(null) //当前显示数据索引
-const departments = ref([]) //部门
-const departmentUsers = ref({})
-// 处理人选择相关
-const processorColumns = ref([])
-// 可编辑状态
-const isEditable = computed(() => currentDetail.value.status === 0)
-const isEditableProcess = computed(() => currentDetail.value.status === 3)
-// 工单内容
-const workDetailData = ref({})
-const formatDate = dateString => {
- return dayjs(dateString).format('MM/DD HH:mm')
-}
-const allStepConfigs = ref([
- { title: '待审核', status: '2' },
- { title: '待处理', status: '0' },
- { title: '处理中', status: '3' },
- { title: '已完成', status: '4' },
-])
-
-const getStatusClass = index => {
- if (index <= currentStep.value) {
- const status = stepResponse.value[index]?.status
- const statusClasses = {
- '2': 'status-pending', // 待审核
- '0': 'status-waiting', // 待处理
- '3': 'status-processing', // 处理中
- '4': 'status-completed', // 已完成
- }
- return statusClasses[String(status)] || ''
- }
-
- return 'status-default'
-}
-// 关联算法
-const getTicketInfoData = async () => {
- const response = await getTicketInfo()
- const { dept_data, event_type, ai_type, info } = response.data.data
- allAlgorithms.value = info
-
- types.value = Object.entries(event_type).map(([key, value]) => ({
- label: value,
- value: key,
- }))
- departments.value = dept_data.map(item => ({
- text: item.dept_name,
- value: item.id,
- }))
- departmentUsers.value = dept_data.reduce((acc, dept) => {
- acc[dept.id] = dept.user_data || []
- return acc
- }, {})
-}
-// 处理人
-const availableDispatchHandlers = computed(() => {
- if (!dispatchForm.value.department) return []
- const users = departmentUsers.value[dispatchForm.value.department]
- if (!users) return []
- return users.map(user => ({
- text: user.name,
- value: user.id,
- }))
-})
-
-// 关联算法选择
-const handleTypeChange = typeValue => {
- const matchedCategory = allAlgorithms.value.find(category => category.dict_key === typeValue)
- if (!matchedCategory || !matchedCategory.algorithms || matchedCategory.algorithms.length === 0) {
- // 无匹配的算法时清空
- algorithms.value = []
- return
- }
- algorithms.value = matchedCategory.algorithms.map(algo => ({
- label: algo.dict_value,
- value: algo.dict_key,
- dict_key: algo.dict_key,
- dict_value: algo.dict_value,
- }))
- columns.value = algorithms.value.map(item => ({
- text: item.label,
- value: item.value,
- }))
-}
-const getDataList = async val => {
- const params = {
- current: 1,
- size: 9999,
- source: 1,
- event_name: val,
- }
- const res = await getList(params)
- const response = res.data.data.records
- currentDetail.value = {
- ...response[0],
- processingDetail: response[0].content,
- processing_details: response[0].processing_details,
- update_photo_url: response[0].update_photo_url,
- photos: [],
- aiType: response[0].ai_type_key_list?.join(',') || '',
- }
- currentStatus.value = currentDetail.value.status
- handleTypeChange(currentDetail.value.work_order_type_dict_key)
-}
-
-// 计算要显示的步骤
-const displayedSteps = computed(() => {
- return allStepConfigs.value.filter(stepConfig => {
- return stepResponse.value.some(stepData => String(stepData?.status) === stepConfig.status)
- })
-})
-// 计算工单类型显示名称
-const workOrderTypeName = computed(() => {
- const type = types.value.find(item => item.value === currentDetail.value.work_order_type_dict_key)
- return type ? type.label : currentDetail.value.work_order_type_dict_key
-})
-// 步骤条
-const calculateCurrentStep = status => {
- const stepIndex = displayedSteps.value.findIndex(step => step.status === String(status))
- return stepIndex !== -1 ? stepIndex : 0
-}
-
-const getStepInfoData = async val => {
- const res = await getStepInfo(val)
- stepResponse.value = res.data.data
-
- currentStep.value = calculateCurrentStep(currentStatus.value)
-}
-
-// 通过
-const approveTicket = async () => {
- const data = {
- id: currentDetail.value.id,
- status: currentDetail.value.status,
- isPass: 0, // 0 表示通过
- eventNum: currentDetail.value.event_num,
- }
- const file = currentDetail.value.file || null
- const response = await flowEvent(data, file)
- if (response.data.code === 0) {
- showNotify({ type: 'primary', message: '工单已通过' })
- }
-
- // const transmitData = { data: { type: 'workback', fun: 'add' } }
- // wx.miniProgram.switchTab({ url: `/pages/work/index?addLog=111` })
- // wx.miniProgram.postMessage(transmitData)
- // uni.postMessage(transmitData)
- getDataList()
-}
-// 不通过/不受理
-const rejectTicket = async () => {
- const data = {
- id: currentDetail.value.id,
- status: currentDetail.value.status,
- isPass: 1,
- }
- const response = await flowEvent(data)
- if (response.data.code === 0) {
- showNotify({ type: 'danger', message: '工单未通过' })
- }
- const transmitData = { data: { type: 'workback', fun: 'add' } }
- wx.miniProgram.switchTab({ url: `/pages/work/index?addLog=111` })
- wx.miniProgram.postMessage(transmitData)
- uni.postMessage(transmitData)
- getDataList()
-}
-const isshowDispatch = ref(false)
-// 受理
-const approveAndDispatch = () => {
- // 添加必填项检查
- if (!currentDetail.value.event_name) {
- showNotify({ type: 'danger', message: '请填写工单名称' })
- return
- }
- if (!currentDetail.value.ai_types) {
- showNotify({ type: 'danger', message: '请选择关联算法' })
- return
- }
- if (!currentDetail.value.content) {
- showNotify({ type: 'danger', message: '请填写工单内容' })
- return
- }
- isshowDispatch.value = true
-}
-const dispatchCancel = () => {
- // 重置表单
- dispatchForm.value = {
- department: '',
- departmentName: '',
- handler: '',
- handlerName: '',
- }
- isshowDispatch.value = false
-}
-const dispatchForm = ref({
- department: '', // 存储部门ID (value)
- departmentName: '', // 显示部门名称 (text)
- handler: '', // 存储处理人ID (value)
- handlerName: '', // 显示处理人名称 (text)
-})
-
-const selectedDepartment = ref([])
-const selectedProcessor = ref([])
-const showGlobalPicker = ref(false)
-const currentPickerType = ref('')
-
-const openPicker = type => {
- currentPickerType.value = type
- showGlobalPicker.value = true
-}
-// 部门选择确认
-const onDepartmentConfirm = value => {
- dispatchForm.value.department = value.selectedValues[0]
- dispatchForm.value.departmentName = value.selectedOptions[0].text
- showGlobalPicker.value = false
-}
-// 处理人选择确认
-const onProcessorConfirm = value => {
- // 确保已选择部门
- if (!dispatchForm.value.department) {
- showNotify({ type: 'warning', message: '请先选择部门' })
- return
- }
- dispatchForm.value.handler = value.selectedValues[0]
- dispatchForm.value.handlerName = value.selectedOptions[0].text
- showGlobalPicker.value = false
-}
-
-// 取消选择
-const onPickerCancel = () => {
- showGlobalPicker.value = false
-}
-// 派发工单
-const submitDispatch = async () => {
- // 验证必填项
- if (!dispatchForm.value.department) {
- showNotify({ type: 'danger', message: '请选择部门' })
- return
- }
-
- if (!dispatchForm.value.handler) {
- showNotify({ type: 'danger', message: '请选择处理人' })
- return
- }
-
- try {
- const data = {
- id: currentDetail.value.id,
- status: currentDetail.value.status,
- isPass: 0,
- eventName: currentDetail.value.event_name,
- eventNum: currentDetail.value.event_num,
- workOrderTypeDictKey: currentDetail.value.work_order_type_dict_key,
- content: currentDetail.value.content,
- createDept: dispatchForm.value.department,
- updateUser: dispatchForm.value.handler,
- aiType: currentDetail.value.aiType,
- }
- const file = currentDetail.value.file || null
- const response = await flowEvent(data, file)
- if (response.data.code === 0) {
- showNotify({ type: 'success', message: '工单派发成功' })
- isshowDispatch.value = false
- getDataList()
- }
- } catch (error) {
- showNotify({ type: 'danger', message: '工单派发失败' })
- }
-}
-
-// 完成工单
-const completeTicket = async () => {
- if (!currentDetail.value.processingDetail) {
- showNotify({ type: 'danger', message: '请先填写事件处理详情' })
- return
- }
- if (!currentDetail.value.photos || currentDetail.value.photos.length === 0) {
- showNotify({ type: 'danger', message: '请选择上传图片' })
- return
- }
- const data = {
- id: currentDetail.value.id,
- status: currentDetail.value.status,
- processingDetails: currentDetail.value.processingDetail,
- eventNum: currentDetail.value.event_num,
- }
- const file = currentDetail.value.photos?.[0]?.raw || null
- const response = await flowEvent(data, file)
- if (response.data.code === 0) {
- showNotify({ type: 'primary', message: '工单已完成' })
- }
- getDataList()
-}
-// 取消
-const cancellation = () => {
- const transmitData = { data: { type: 'workback', fun: 'add' } }
- wx.miniProgram.switchTab({ url: `/pages/work/index?addLog=111` })
- wx.miniProgram.postMessage(transmitData)
- uni.postMessage(transmitData)
-}
-// 上一页
-const leftClick = () => {}
-// 下一页
-const rightClick = () => {}
-
-// 下拉选择
-
-const openselect = () => {
- showPicker.value = true
-}
-// 选择器确认方法
-const onConfirm = val => {
- currentDetail.value.ai_types = val.selectedOptions.map(option => option.text).join(',')
- currentDetail.value.aiType = val.selectedValues.join(',')
- showPicker.value = false
-}
-// 选择器取消方法
-const onCancel = () => {
- showPicker.value = false
-}
-
-// 上传图片
-const fileInput = ref(null)
-// 触发文件选择对话框
-const triggerUpload = () => {
- fileInput.value?.click() // 调用原生input的click事件
-}
-// 处理文件选择后的逻辑
-const handleFileChange = e => {
- const file = e.target.files[0]
- if (!file) return
-
- // 验证文件格式
- const allowedTypes = ['image/png', 'image/jpeg', 'image/jpg']
- if (!allowedTypes.includes(file.type)) {
- showToast('只能上传png、jpeg、jpg格式的图片')
- resetFileInput() // 重置input
- return
- }
-
- // 验证文件大小(3MB = 3 * 1024 * 1024 bytes)
- if (file.size > 3 * 1024 * 1024) {
- showToast('图片大小不能超过3MB')
- resetFileInput() // 重置input
- return
- }
-
- // 创建文件预览(可选)
- const reader = new FileReader()
- reader.onload = event => {
- // 将文件对象和预览URL都保存到 currentDetail
- currentDetail.value.photos = [
- {
- raw: file, // 原始文件对象(用于上传)
- preview: event.target.result, // 预览URL(用于显示)
- name: file.name, // 文件名
- },
- ]
- }
- reader.readAsDataURL(file) // 读取文件为DataURL
-}
-
-// 重置文件输入
-const resetFileInput = () => {
- if (fileInput.value) {
- fileInput.value.value = ''
- }
-}
-
-onMounted(async () => {
- eventNum.value = route.query.eventNum || ''
- await getTicketInfoData()
- await getDataList(eventNum.value)
- await getStepInfoData(eventNum.value)
-})
-</script>
-
-<style lang="scss" scoped>
-.workDetailContainer {
- padding: 0 10px;
- .required-mark {
- color: #ff4d4f; // 红色
- margin-left: 4px;
- }
- .detailTop {
- .image-container {
- position: relative;
- width: 100%;
- height: 205px;
-
- .detailImage {
- width: 100%;
- height: 100%;
- display: block;
- object-fit: cover;
- }
-
- .detailTitle {
- position: absolute;
- left: 0;
- top: 0;
- width: 100%;
- padding: 5px;
- height: 30px;
- background: rgba(7, 7, 7, 0.4);
- }
-
- .titleText {
- display: flex;
- width: 100%;
- justify-content: space-between;
- align-items: center;
- font-family: Source Han Sans CN, Source Han Sans CN;
- font-weight: 400;
- font-size: 13px;
- color: #ffffff;
- .itemStatus {
- display: flex;
- align-items: center;
-
- span {
- display: inline-block;
- width: 10px;
- height: 10px;
- border-radius: 50%;
- margin-right: 7px;
- }
- }
- }
- .timeNavigation {
- display: flex;
- align-items: center;
- img {
- width: 11px;
- height: 13px;
- margin-left: 13px;
- }
- }
- }
- }
-
- .stepContainer {
- margin-top: 10px;
- display: flex;
-
- border-radius: 5px;
- padding: 10px;
-
- .horizontal-step {
- display: flex;
- align-items: center;
- gap: 12px;
-
- .step-title {
- min-width: 60px;
- background: #e8e8e8;
- padding: 5px;
- border-radius: 5px;
- text-align: center;
-
- &.status-pending {
- background-color: #ffebeb; // 待审核
- color: #ff1414;
- }
-
- &.status-waiting {
- background-color: #fff1e6; // 待处理
- color: #ff7411;
- }
-
- &.status-processing {
- background-color: #fff6d8; // 处理中
- color: #ffbb00;
- }
-
- &.status-completed {
- background-color: #e5fcff; // 已完成
- color: #0291a1;
- }
-
- &.status-default {
- background-color: #e8e8e8; // 默认背景色
- color: #191919;
- }
- }
-
- .step-desc {
- display: flex;
- justify-content: space-between;
- gap: 28px;
- color: #222324;
- font-size: 14px;
- }
- .step-desc span:first-child {
- min-width: 40px;
- white-space: nowrap;
- }
- }
- }
-
- :deep(.van-step__circle) {
- width: 8px;
- height: 8px;
- }
-
- .actionButton {
- display: flex;
- justify-content: space-between;
- margin-bottom: 10px;
- padding-bottom: 10px;
-
- .btngroups {
- display: flex;
- justify-content: space-between;
-
- .van-button {
- padding: 9px 20px;
- height: 32px;
-
- &:last-child {
- margin-left: 12px;
- margin-right: 12px;
- }
- }
- }
-
- .leftBtn {
- width: 27px;
- height: 27px;
- cursor: pointer;
- img {
- width: 27px;
- height: 27px;
- }
- }
-
- .disableds {
- background: #999 !important;
- cursor: not-allowed !important;
- pointer-events: none;
- opacity: 0.3 !important;
- }
- }
-
- .workOrderContent {
- margin-top: 15px;
-
- .workOrderTitle {
- font-family: Source Han Sans CN, Source Han Sans CN;
- font-weight: bold;
- font-size: 16px;
- color: #222324;
- margin-bottom: 16px;
- }
-
- .workOrderContainer {
- .orderRow {
- margin-bottom: 10px;
- display: flex;
- justify-content: space-between;
- align-items: center;
- height: 48px;
- border-bottom: 1px solid #f5f5f5;
- color: #7b7b7b;
- .guanlian {
- display: flex;
- }
- .rowTitle {
- font-family: Source Han Sans CN, Source Han Sans CN;
- font-weight: 400;
- font-size: 15px;
- color: #222324;
- white-space: nowrap;
-
- span {
- font-family: Source Han Sans CN, Source Han Sans CN;
- font-weight: 400;
- font-size: 10px;
- color: #3a3a3a;
- }
- }
- .rowAddress {
- font-size: 14px;
- color: #1d6fe9;
- white-space: nowrap; /* 禁止换行 */
- overflow: hidden;
- text-overflow: ellipsis;
- max-width: 75%;
- }
- .selectTrigger {
- font-family: Source Han Sans CN, Source Han Sans CN;
- font-weight: 400;
- font-size: 14px;
- color: #222324;
- }
- }
-
- .titketName {
- display: flex;
- align-items: center;
- }
- }
- }
-
- .upload-link {
- color: #1989fa; /* 右侧链接:Vant主题蓝色(与组件库统一) */
- cursor: pointer;
- text-decoration: underline; /* 下划线突出可点击性 */
- }
-}
-</style>
diff --git a/applications/mobile-web-view/src/page/work/workDetail/mapWork/index.vue b/applications/mobile-web-view/src/page/work/workDetail/mapWork/index.vue
deleted file mode 100644
index e82a780..0000000
--- a/applications/mobile-web-view/src/page/work/workDetail/mapWork/index.vue
+++ /dev/null
@@ -1,8 +0,0 @@
-<!-- 地图展示 -->
-<template>
- <view> 基础 </view>
-</template>
-
-<script setup></script>
-
-<style lang="scss" scoped></style>
diff --git a/applications/mobile-web-view/src/router/page/index.js b/applications/mobile-web-view/src/router/page/index.js
index 1f32678..8aedc96 100644
--- a/applications/mobile-web-view/src/router/page/index.js
+++ b/applications/mobile-web-view/src/router/page/index.js
@@ -1,15 +1,3 @@
-/*
- * @Author : yuan
- * @Date : 2025-06-06 09:53:47
- * @LastEditors : yuan
- * @LastEditTime : 2025-10-14 16:59:29
- * @FilePath : \src\router\page\index.js
- * @Description :
- * Copyright 2025 OBKoro1, All Rights Reserved.
- * 2025-06-06 09:53:47
- */
-import Store from '@/store/'
-
export default [
{
path: '/login',
--
Gitblit v1.9.3