异常日志处理 钉钉单点登录
|
@ -0,0 +1,43 @@
|
|||
<script>
|
||||
import config from "./config";
|
||||
import store from "@/store";
|
||||
import { getToken } from "@/utils/auth";
|
||||
import eruda from "eruda";
|
||||
export default {
|
||||
onLaunch: function () {
|
||||
// new VConsole();
|
||||
eruda.init();
|
||||
this.initApp();
|
||||
},
|
||||
methods: {
|
||||
// 初始化应用
|
||||
initApp() {
|
||||
// 初始化应用配置
|
||||
this.initConfig();
|
||||
},
|
||||
initConfig() {
|
||||
this.globalData.config = config;
|
||||
},
|
||||
checkLogin() {
|
||||
if (!getToken()) {
|
||||
this.$tab.reLaunch("/pages/login");
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "@/uni_modules/uview-ui/index.scss";
|
||||
@import "@/static/scss/index.scss";
|
||||
@import "@/static/font/iconfont.css";
|
||||
.overflowTextHidden{
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
page{
|
||||
height:100vh;
|
||||
}
|
||||
</style>
|
36
LICENSE
|
@ -1,23 +1,21 @@
|
|||
Attribution Assurance License
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2002 by AUTHOR PROFESSIONAL IDENTIFICATION * URL "PROMOTIONAL SLOGAN FOR AUTHOR'S PROFESSIONAL PRACTICE"
|
||||
Copyright (c) 2022 若依
|
||||
|
||||
All Rights Reserved
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
ATTRIBUTION ASSURANCE LICENSE (adapted from the original BSD license)
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the conditions below are met. These conditions require a modest attribution to <AUTHOR> (the "Author"), who hopes that its promotional value may help justify the thousands of dollars in otherwise billable time invested in writing this and other freely available, open-source software.
|
||||
|
||||
1. Redistributions of source code, in whole or part and with or without modification (the "Code"), must prominently display this GPG-signed text in verifiable form.
|
||||
|
||||
2. Redistributions of the Code in binary form must be accompanied by this GPG-signed text in any documentation and, each time the resulting executable program or a program dependent thereon is launched, a prominent display (e.g., splash screen or banner text) of the Author's attribution information, which includes:
|
||||
|
||||
(a) Name ("AUTHOR"),
|
||||
(b) Professional identification ("PROFESSIONAL IDENTIFICATION"), and
|
||||
(c) URL ("URL").
|
||||
|
||||
3. Neither the name nor any trademark of the Author may be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
4. Users are entirely responsible, to the exclusion of the Author and any other persons, for compliance with (1) regulations set by owners or administrators of employed equipment, (2) licensing terms of any other software, and (3) local regulations regarding use, including those regarding import, export, and use of encryption software.
|
||||
|
||||
THIS FREE SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR ANY CONTRIBUTOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, EFFECTS OF UNAUTHORIZED OR MALICIOUS NETWORK ACCESS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
|
72
README.md
|
@ -1,3 +1,71 @@
|
|||
# middleground_H5
|
||||
项目安装依赖报错时,切换node到16.20.2版本,使用npm安装依赖,不要使用yarn
|
||||
|
||||
中台移动端
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<p align="center">
|
||||
<img alt="logo" src="https://oscimg.oschina.net/oscnet/up-43e3941654fa3054c9684bf53d1b1d356a1.png">
|
||||
</p>
|
||||
<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">RuoYi v1.1.0</h1>
|
||||
<h4 align="center">基于UniApp开发的轻量级移动端框架</h4>
|
||||
<p align="center">
|
||||
<a href="https://gitee.com/y_project/RuoYi-App/stargazers"><img src="https://gitee.com/y_project/RuoYi-App/badge/star.svg?theme=dark"></a>
|
||||
<a href="https://gitee.com/y_project/RuoYi-App"><img src="https://img.shields.io/badge/RuoYi-v1.1.0-brightgreen.svg"></a>
|
||||
<a href="https://gitee.com/y_project/RuoYi-App/blob/master/LICENSE"><img src="https://img.shields.io/github/license/mashape/apistatus.svg"></a>
|
||||
</p>
|
||||
|
||||
## 平台简介
|
||||
|
||||
RuoYi App 移动解决方案,采用uniapp框架,一份代码多终端适配,同时支持APP、小程序、H5!实现了与[RuoYi-Vue](https://gitee.com/y_project/RuoYi-Vue)、[RuoYi-Cloud](https://gitee.com/y_project/RuoYi-Cloud)完美对接的移动解决方案!目前已经实现登录、我的、工作台、编辑资料、头像修改、密码修改、常见问题、关于我们等基础功能。
|
||||
|
||||
* 配套后端代码仓库地址[RuoYi-Vue](https://gitee.com/y_project/RuoYi-Vue) 或 [RuoYi-Cloud](https://github.com/yangzongzhuan/RuoYi-Cloud) 版本。
|
||||
* 应用框架基于[uniapp](https://uniapp.dcloud.net.cn/),支持小程序、H5、Android和IOS。
|
||||
* 前端组件采用[uni-ui](https://github.com/dcloudio/uni-ui),全端兼容的高性能UI框架。
|
||||
* 阿里云折扣场:[点我进入](http://aly.ruoyi.vip),腾讯云秒杀场:[点我进入](http://txy.ruoyi.vip)
|
||||
* 阿里云优惠券:[点我领取](https://www.aliyun.com/minisite/goods?userCode=brki8iof&share_source=copy_link),腾讯云优惠券:[点我领取](https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=198c8df2ed259157187173bc7f4f32fd&from=console)
|
||||
|
||||
|
||||
## 技术文档
|
||||
|
||||
- 官网网站:[http://ruoyi.vip](http://ruoyi.vip)
|
||||
- 文档地址:[http://doc.ruoyi.vip](http://doc.ruoyi.vip)
|
||||
- H5页体验:[http://h5.ruoyi.vip](http://h5.ruoyi.vip)
|
||||
- QQ交流群: ①133713780
|
||||
- 小程序体验
|
||||
|
||||
<img src="https://oscimg.oschina.net/oscnet/up-26c76dc90b92acdbd9ac8cd5252f07c8ad9.jpg" alt="小程序演示"/>
|
||||
|
||||
|
||||
## 演示图
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td><img src="https://oscimg.oschina.net/oscnet/up-3ea20e447ac621a161e395fb53ccc683d84.png"/></td>
|
||||
<td><img src="https://oscimg.oschina.net/oscnet/up-a6f23cf9a371a30165e135eff6d9ae89a9d.png"/></td>
|
||||
<td><img src="https://oscimg.oschina.net/oscnet/up-ff5f62016bf6624c1ff27eee57499dccd44.png"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://oscimg.oschina.net/oscnet/up-b9a582fdb26ec69d407fabd044d2c8494df.png"/></td>
|
||||
<td><img src="https://oscimg.oschina.net/oscnet/up-96427ee08fca29d77934cfc8d1b1a637cef.png"/></td>
|
||||
<td><img src="https://oscimg.oschina.net/oscnet/up-5fdadc582d24cccd7727030d397b63185a3.png"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://oscimg.oschina.net/oscnet/up-0a36797b6bcc50c36d40c3c782665b89efc.png"/></td>
|
||||
<td><img src="https://oscimg.oschina.net/oscnet/up-d77995cc00687cedd00d5ac7d68a07ea276.png"/></td>
|
||||
<td><img src="https://oscimg.oschina.net/oscnet/up-fa8f5ab20becf59b4b38c1b92a9989e7109.png"/></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 登录方法
|
||||
export function login(username, password) {
|
||||
const data = {
|
||||
loginCode: username,
|
||||
password: password,
|
||||
}
|
||||
return request({
|
||||
'url': 'kangarooDataCenterV3/entranceController/option',
|
||||
header: {
|
||||
isToken: false,
|
||||
tl: 'loginService',
|
||||
as: 'sysTestjdbc',
|
||||
dj: 'doLogin'
|
||||
},
|
||||
'method': 'post',
|
||||
'data': data
|
||||
})
|
||||
}
|
||||
export function authApi(tl, as, dj, url = '', data) {
|
||||
return request({
|
||||
url: 'kangarooDataCenterV3/entranceController/option' + url,
|
||||
header: {
|
||||
tl: tl,
|
||||
as: as,
|
||||
dj: dj,
|
||||
},
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
// 获取用户详细信息
|
||||
export function getInfo() {
|
||||
return request({
|
||||
'url': '/getInfo',
|
||||
'method': 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 退出方法
|
||||
export function logout() {
|
||||
return request({
|
||||
'url': '/logout',
|
||||
'method': 'post'
|
||||
})
|
||||
}
|
||||
|
||||
// 获取验证码
|
||||
export function getCodeImg() {
|
||||
return request({
|
||||
'url': '/captchaImage',
|
||||
header: {
|
||||
isToken: false
|
||||
},
|
||||
method: 'get',
|
||||
timeout: 20000
|
||||
})
|
||||
}
|
||||
|
||||
// 钉钉单点登录
|
||||
export function DDSSO(data) {
|
||||
return request({
|
||||
url: "Api/SSO/DDSSO",
|
||||
method: "post",
|
||||
data,
|
||||
});
|
||||
}
|
||||
// 钉钉认证
|
||||
export function DDAuthen(data) {
|
||||
return request({
|
||||
url: "Api/SSO/DDAuthen",
|
||||
method: "post",
|
||||
data,
|
||||
});
|
||||
}
|
||||
// wx认证
|
||||
export function WeChatSSO(data) {
|
||||
return request({
|
||||
url: "Api/SSO/WeChatSSO",
|
||||
method: "post",
|
||||
data,
|
||||
});
|
||||
}
|
||||
// wx认证
|
||||
export function WeChatAuthen(data) {
|
||||
return request({
|
||||
url: "Api/SSO/WeChatAuthen",
|
||||
method: "post",
|
||||
data,
|
||||
});
|
||||
}
|
||||
// wx认证
|
||||
export function GetAPPMenu(data) {
|
||||
return request({
|
||||
url: "/api/Menu/GetAPPMenu",
|
||||
method: "post",
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
// 用户所属公司列表
|
||||
export function OrganGetUserCompany(data) {
|
||||
return request({
|
||||
url: "/api/Organ/GetUserCompany",
|
||||
method: "post",
|
||||
data,
|
||||
});
|
||||
}
|
||||
//切换公司
|
||||
export function ChangeCompany(data) {
|
||||
return request({
|
||||
url: "/api/Organ/ChangeCompany",
|
||||
method: "post",
|
||||
data,
|
||||
});
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
export function GetOrganTree(data) {
|
||||
return request({
|
||||
url: '/Api/Organ/GetOrganTree',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
export function GetBillList(data) {
|
||||
return request({
|
||||
url: '/Api/Person/GetBillList',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
//审批流-提交审核
|
||||
export function submitAudit(data) {
|
||||
return request({
|
||||
url: "/Api/Workflow/SubmitAudit",
|
||||
method: "post",
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
//获取单据审批流程
|
||||
export function getAuditList(data) {
|
||||
return request({
|
||||
url: "/Api/Workflow/SowBillWork",
|
||||
method: "post",
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
//获取单据审批记录
|
||||
export function getAuditNote(data) {
|
||||
return request({
|
||||
url: "/Api/Workflow/GetAuditNoteList",
|
||||
method: "post",
|
||||
data,
|
||||
});
|
||||
}
|
||||
//催办
|
||||
export function auditUrging(data) {
|
||||
return request({
|
||||
url: "/Api/Workflow/Urging",
|
||||
method: "post",
|
||||
data,
|
||||
});
|
||||
}
|
||||
//审批流-审核
|
||||
export function audit(data) {
|
||||
return request({
|
||||
url: "/Api/Workflow/Audit",
|
||||
method: "post",
|
||||
data,
|
||||
});
|
||||
}
|
||||
//加签
|
||||
export function auditAddFlow(data) {
|
||||
return request({
|
||||
url: "/Api/Workflow/AddBillWorkFlowNote",
|
||||
method: "post",
|
||||
data,
|
||||
});
|
||||
}
|
||||
//获取单据审批按钮权限
|
||||
export function getAuditBtn(data) {
|
||||
return request({
|
||||
url: "/Api/Workflow/GetBillOperateBtn",
|
||||
method: "post",
|
||||
data,
|
||||
});
|
||||
}
|
||||
//审批流-已读
|
||||
export function read(data) {
|
||||
return request({
|
||||
url: "/Api/Workflow/Read",
|
||||
method: "post",
|
||||
data,
|
||||
});
|
||||
}
|
||||
//审批流-撤销审核
|
||||
export function removeAudit(data) {
|
||||
return request({
|
||||
url: "/Api/Workflow/Revocation",
|
||||
method: "post",
|
||||
data,
|
||||
});
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 人员列表接口
|
||||
export function PersonList(data) {
|
||||
return request({
|
||||
url: "/Api/Person/GetBillList",
|
||||
method: "post",
|
||||
data,
|
||||
});
|
||||
}
|
||||
// 部门树形数据
|
||||
export function GetOrganTree(data) {
|
||||
return request({
|
||||
url: "/Api/Organ/GetOrganTree",
|
||||
method: "post",
|
||||
data,
|
||||
});
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 获取消息列表
|
||||
export function GetMessageData(data) {
|
||||
return request({
|
||||
url: '/api/Message/GetMessageData',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 全部已读
|
||||
export function ReadMessage(data) {
|
||||
return request({
|
||||
url: '/api/Message/ReadMessage',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 全部已读
|
||||
export function GetAllWfToDo(data) {
|
||||
return request({
|
||||
url: '/Api/Workflow/GetWfToDo',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
import upload from '@/utils/upload'
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 用户密码重置
|
||||
export function updateUserPwd(oldPassword, newPassword) {
|
||||
const data = {
|
||||
oldPassword,
|
||||
newPassword
|
||||
}
|
||||
return request({
|
||||
url: '/system/user/profile/updatePwd',
|
||||
method: 'put',
|
||||
params: data
|
||||
})
|
||||
}
|
||||
|
||||
// 查询用户个人信息
|
||||
export function getUserProfile() {
|
||||
return request({
|
||||
url: '/system/user/profile',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 修改用户个人信息
|
||||
export function updateUserProfile(data) {
|
||||
return request({
|
||||
url: '/system/user/profile',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 用户头像上传
|
||||
export function uploadAvatar(data) {
|
||||
return upload({
|
||||
url: '/system/user/profile/avatar',
|
||||
name: data.name,
|
||||
filePath: data.filePath
|
||||
})
|
||||
}
|
|
@ -0,0 +1,106 @@
|
|||
/** * 单选人员 */
|
||||
<template>
|
||||
<u-picker
|
||||
:show="show"
|
||||
ref="uPicker"
|
||||
:columns="columns"
|
||||
:closeOnClickOverlay="true"
|
||||
keyName="label"
|
||||
@close="show = false"
|
||||
@cancel="show = false"
|
||||
@confirm="confirm"
|
||||
@change="changeHandler"
|
||||
></u-picker>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { GetOrganTree, GetBillList } from '@/api/system/assembly.js';
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
show: false,
|
||||
columns: [[], []],
|
||||
columnData: []
|
||||
};
|
||||
},
|
||||
|
||||
components: {},
|
||||
|
||||
computed: {},
|
||||
|
||||
mounted() {},
|
||||
|
||||
created() {
|
||||
this.init();
|
||||
},
|
||||
|
||||
methods: {
|
||||
changeHandler(e) {
|
||||
const {
|
||||
columnIndex,
|
||||
value,
|
||||
values, // values为当前变化列的数组内容
|
||||
index,
|
||||
// 微信小程序无法将picker实例传出来,只能通过ref操作
|
||||
picker = this.$refs.uPicker
|
||||
} = e;
|
||||
// 当第一列值发生变化时,变化第二列(后一列)对应的选项
|
||||
if (columnIndex === 0) {
|
||||
// picker为选择器this实例,变化第二列对应的选项
|
||||
picker.setColumnValues(1, this.columnData[index]);
|
||||
}
|
||||
},
|
||||
// 回调参数为包含columnIndex、value、values
|
||||
confirm(e) {
|
||||
this.$emit('confirm',e.value)
|
||||
this.show = false;
|
||||
},
|
||||
async init() {
|
||||
const res = await GetOrganTree({ companyID: 'null' });
|
||||
let item = await GetBillList({ departmentID: '', limit: '999', page: '1' });
|
||||
item.data[1].forEach(el => {
|
||||
el.label = el.p_PersonName
|
||||
})
|
||||
this.columns[0].push(...this.treeToArray(JSON.parse(res.data[0])));
|
||||
let keys = item.data[1].map((val) => {
|
||||
return val.o_OrganName;
|
||||
});
|
||||
keys = [...new Set(keys)];
|
||||
let data = {};
|
||||
keys.forEach((el) => {
|
||||
data[el] = [];
|
||||
});
|
||||
item.data[1].map((e) => {
|
||||
keys.some((value) => {
|
||||
if (e.o_OrganName == value) {
|
||||
data[value].push(e);
|
||||
return;
|
||||
}
|
||||
});
|
||||
});
|
||||
let treatment = this.sort(this.treeToArray(JSON.parse(res.data[0])),data)
|
||||
this.columns[1] = data[this.treeToArray(JSON.parse(res.data[0]))[0].label]
|
||||
this.columnData.push(...treatment)
|
||||
},
|
||||
// 数据扁平
|
||||
treeToArray(items) {
|
||||
let children = [];
|
||||
items.forEach((item) => {
|
||||
children.push(item);
|
||||
if (item.children) {
|
||||
children = children.concat(this.treeToArray(item.children));
|
||||
}
|
||||
});
|
||||
return children;
|
||||
},
|
||||
sort(item,data) {
|
||||
let list = []
|
||||
item.forEach(el => {
|
||||
list.push(data[el.label])
|
||||
})
|
||||
return list
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped lang="scss"></style>
|
|
@ -0,0 +1,139 @@
|
|||
<template>
|
||||
<view class="u-avatar" :class="[`u-avatar--${shape}`]" :style="[{
|
||||
backgroundColor: (text || icon) ? (randomBgColor ? colors[colorIndex !== '' ? colorIndex : $u.random(0, 19)] : bgColor) : 'transparent',
|
||||
width: $u.addUnit(size),
|
||||
height: $u.addUnit(size),
|
||||
}, $u.addStyle(customStyle)]" @tap="clickHandler">
|
||||
<slot>
|
||||
<image class="u-avatar__image" v-if="isSuccessSrc" :class="[`u-avatar__image--${shape}`]"
|
||||
:src="avatarUrl || defaultUrl" :mode="mode" @error="errorHandler" :style="[{
|
||||
width: $u.addUnit(size),
|
||||
height: $u.addUnit(size)
|
||||
}]"></image>
|
||||
<u--text v-else :text="text" :size="fontSize" :color="color" align="center"
|
||||
customStyle="justify-content: center"></u--text>
|
||||
</slot>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import props from './props.js';
|
||||
const base64Avatar =
|
||||
"data:image/jpg;base64,/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/sABFEdWNreQABAAQAAAA8AAD/4QMraHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/PiA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjMtYzAxMSA2Ni4xNDU2NjEsIDIwMTIvMDIvMDYtMTQ6NTY6MjcgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDUzYgKFdpbmRvd3MpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjREMEQwRkY0RjgwNDExRUE5OTY2RDgxODY3NkJFODMxIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjREMEQwRkY1RjgwNDExRUE5OTY2RDgxODY3NkJFODMxIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6NEQwRDBGRjJGODA0MTFFQTk5NjZEODE4Njc2QkU4MzEiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NEQwRDBGRjNGODA0MTFFQTk5NjZEODE4Njc2QkU4MzEiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7/7gAOQWRvYmUAZMAAAAAB/9sAhAAGBAQEBQQGBQUGCQYFBgkLCAYGCAsMCgoLCgoMEAwMDAwMDBAMDg8QDw4MExMUFBMTHBsbGxwfHx8fHx8fHx8fAQcHBw0MDRgQEBgaFREVGh8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx//wAARCADIAMgDAREAAhEBAxEB/8QAcQABAQEAAwEBAAAAAAAAAAAAAAUEAQMGAgcBAQAAAAAAAAAAAAAAAAAAAAAQAAIBAwICBgkDBQAAAAAAAAABAhEDBCEFMVFBYXGREiKBscHRMkJSEyOh4XLxYjNDFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8A/fAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHbHFyZ/Dam+yLA+Z2L0Pjtyj2poD4AAAAAAAAAAAAAAAAAAAAAAAAKWFs9y6lcvvwQeqj8z9wFaziY1n/HbUX9XF97A7QAGXI23EvJ1goyfzR0YEfN269jeZ+a03pNe0DIAAAAAAAAAAAAAAAAAAAACvtO3RcVkXlWutuL9YFYAAAAAOJRjKLjJVi9GmB5/csH/mu1h/in8PU+QGMAAAAAAAAAAAAAAAAAAaMDG/6MmMH8C80+xAelSSVFolwQAAAAAAAHVlWI37ErUulaPk+hgeYnCUJuElSUXRrrQHAAAAAAAAAAAAAAAAABa2Oz4bM7r4zdF2ICmAAAAAAAAAg7zZ8GX41wuJP0rRgYAAAAAAAAAAAAAAAAAD0m2R8ODaXU33tsDSAAAAAAAAAlb9HyWZcnJd9PcBHAAAAAAAAAAAAAAAAAPS7e64Vn+KA0AAAAAAAAAJm+v8Ftf3ewCKAAAAAAAAAAAAAAAAAX9muqeGo9NttP06+0DcAAAAAAAAAjb7dTu2ra+VOT9P8AQCWAAAAAAAAAAAAAAAAAUNmyPt5Ltv4bui/kuAF0AAAAAAADiUlGLlJ0SVW+oDzOXfd/Ind6JPRdS0QHSAAAAAAAAAAAAAAAAAE2nVaNcGB6Lbs6OTao9LsF51z60BrAAAAAABJ3jOVHjW3r/sa9QEgAAAAAAAAAAAAAAAAAAAPu1duWriuW34ZR4MC9hbnZyEoy8l36XwfYBsAAADaSq9EuLAlZ+7xSdrGdW9Hc5dgEdtt1erfFgAAAAAAAAAAAAAAAAADVjbblX6NR8MH80tEBRs7HYivyzlN8lovaBPzduvY0m6eK10TXtAyAarO55lpJK54orolr+4GqO/Xaea1FvqbXvA+Z77kNeW3GPbV+4DJfzcm/pcm3H6Vou5AdAFLC2ed2Pjv1txa8sV8T6wOL+yZEKu1JXFy4MDBOE4ScZxcZLinoB8gAAAAAAAAAAAB242LeyJ+C3GvN9C7QLmJtePYpKS+5c+p8F2IDYAANJqj1T4oCfk7Nj3G5Wn9qXJax7gJ93Z82D8sVNc4v30A6Xg5i42Z+iLfqARwcyT0sz9MWvWBps7LlTf5Grce9/oBTxdtxseklHxT+uWr9AGoAB138ezfj4bsFJdD6V2MCPm7RdtJzs1uW1xXzL3gTgAAAAAAAAADRhYc8q74I6RWs5ckB6GxYtWLat21SK731sDsAAAAAAAAAAAAAAAASt021NO/YjrxuQXT1oCOAAAAAAABzGLlJRSq26JAelwsWONYjbXxcZvmwO8AAAAAAAAAAAAAAAAAAef3TEWPkVivx3NY9T6UBiAAAAAABo2+VmGXblddIJ8eivRUD0oAAAAAAAAAAAAAAAAAAAYt4tKeFKVNYNSXfRgefAAAAAAAAr7VuSSWPedKaW5v1MCsAAAAAAAAAAAAAAAAAAIe6bj96Ts2n+JPzSXzP3ATgAAAAAAAAFbbt1UUrOQ9FpC4/UwK6aaqtU+DAAAAAAAAAAAAAAA4lKMIuUmoxWrb4ARNx3R3q2rLpa4Sl0y/YCcAAAAAAAAAAANmFud7G8r89r6X0dgFvGzLGRGtuWvTF6NAdwAAAAAAAAAAAy5W442PVN+K59EePp5ARMvOv5MvO6QXCC4AZwAAAAAAAAAAAAAcxlKLUotprg1owN+PvORborq+7Hnwl3gUbO74VzRydt8pKn68ANcJwmqwkpLmnUDkAAAAfNy9atqtyagut0AxXt5xIV8Fbj6lRd7Am5G65V6qUvtwfyx94GMAAAAAAAAAAAAAAAAAAAOU2nVOj5gdsc3LiqRvTpyqwOxbnnrhdfpSfrQB7pnv/AGvuS9gHXPMy5/Fem1yq0v0A6W29XqwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf//Z";
|
||||
/**
|
||||
* Avatar 头像
|
||||
* @description 本组件一般用于展示头像的地方,如个人中心,或者评论列表页的用户头像展示等场所。
|
||||
* @tutorial https://www.uviewui.com/components/avatar.html
|
||||
*
|
||||
* @property {String} src 头像路径,如加载失败,将会显示默认头像(不能为相对路径)
|
||||
* @property {String} shape 头像形状 ( circle (默认) | square)
|
||||
* @property {String | Number} size 头像尺寸,可以为指定字符串(large, default, mini),或者数值 (默认 40 )
|
||||
* @property {String} mode 头像图片的裁剪类型,与uni的image组件的mode参数一致,如效果达不到需求,可尝试传widthFix值 (默认 'scaleToFill' )
|
||||
* @property {String} text 用文字替代图片,级别优先于src
|
||||
* @property {String} bgColor 背景颜色,一般显示文字时用 (默认 '#c0c4cc' )
|
||||
* @property {String} color 文字颜色 (默认 '#ffffff' )
|
||||
* @property {String | Number} fontSize 文字大小 (默认 18 )
|
||||
* @property {String} icon 显示的图标
|
||||
* @property {Boolean} mpAvatar 显示小程序头像,只对百度,微信,QQ小程序有效 (默认 false )
|
||||
* @property {Boolean} randomBgColor 是否使用随机背景色 (默认 false )
|
||||
* @property {String} defaultUrl 加载失败的默认头像(组件有内置默认图片)
|
||||
* @property {String | Number} colorIndex 如果配置了randomBgColor为true,且配置了此值,则从默认的背景色数组中取出对应索引的颜色值,取值0-19之间
|
||||
* @property {String} name 组件标识符 (默认 'level' )
|
||||
* @property {Object} customStyle 定义需要用到的外部样式
|
||||
*
|
||||
* @event {Function} click 点击组件时触发 index: 用户传递的标识符
|
||||
* @example <u-avatar :src="src" mode="square"></u-avatar>
|
||||
*/
|
||||
export default {
|
||||
name: 'u-avatar',
|
||||
mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
|
||||
data() {
|
||||
return {
|
||||
// 如果配置randomBgColor参数为true,在图标或者文字的模式下,会随机从中取出一个颜色值当做背景色
|
||||
colors: ['#ffb34b', '#f2bba9', '#f7a196', '#f18080', '#88a867', '#bfbf39', '#89c152', '#94d554', '#f19ec2',
|
||||
'#afaae4', '#e1b0df', '#c38cc1', '#72dcdc', '#9acdcb', '#77b1cc', '#448aca', '#86cefa', '#98d1ee',
|
||||
'#73d1f1',
|
||||
'#80a7dc'
|
||||
],
|
||||
avatarUrl: this.src,
|
||||
allowMp: false,
|
||||
isSuccessSrc:false,
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
// 监听头像src的变化,赋值给内部的avatarUrl变量,因为图片加载失败时,需要修改图片的src为默认值
|
||||
// 而组件内部不能直接修改props的值,所以需要一个中间变量
|
||||
src: {
|
||||
immediate: true,
|
||||
handler(newVal) {
|
||||
this.isSuccessSrc = true
|
||||
this.avatarUrl = newVal
|
||||
// 如果没有传src,则主动触发error事件,用于显示默认的头像,否则src为''空字符等的时候,会无内容展示
|
||||
if (!newVal) {
|
||||
this.isSuccessSrc = false
|
||||
this.errorHandler()
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
imageStyle() {
|
||||
const style = {}
|
||||
return style
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.init()
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
// 目前只有这几个小程序平台具有open-data标签
|
||||
// 其他平台可以通过uni.getUserInfo类似接口获取信息,但是需要弹窗授权(首次),不合符组件逻辑
|
||||
// 故目前自动获取小程序头像只支持这几个平台
|
||||
// #ifdef MP-WEIXIN || MP-QQ || MP-BAIDU
|
||||
this.allowMp = true
|
||||
// #endif
|
||||
},
|
||||
// 判断传入的name属性,是否图片路径,只要带有"/"均认为是图片形式
|
||||
isImg() {
|
||||
return this.src.indexOf('/') !== -1
|
||||
},
|
||||
// 图片加载时失败时触发
|
||||
errorHandler() {
|
||||
this.isSuccessSrc = false
|
||||
// this.avatarUrl = this.defaultUrl || base64Avatar
|
||||
},
|
||||
clickHandler() {
|
||||
this.$emit('click', this.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// @import "../../libs/css/components.scss";
|
||||
|
||||
.u-avatar {
|
||||
@include flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
&--circle {
|
||||
border-radius: 100px;
|
||||
}
|
||||
|
||||
&--square {
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
&__image {
|
||||
&--circle {
|
||||
border-radius: 100px;
|
||||
}
|
||||
|
||||
&--square {
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,78 @@
|
|||
export default {
|
||||
props: {
|
||||
// 头像图片路径(不能为相对路径)
|
||||
src: {
|
||||
type: String,
|
||||
default: uni.$u.props.avatar.src
|
||||
},
|
||||
// 头像形状,circle-圆形,square-方形
|
||||
shape: {
|
||||
type: String,
|
||||
default: uni.$u.props.avatar.shape
|
||||
},
|
||||
// 头像尺寸
|
||||
size: {
|
||||
type: [String, Number],
|
||||
default: uni.$u.props.avatar.size
|
||||
},
|
||||
// 裁剪模式
|
||||
mode: {
|
||||
type: String,
|
||||
default: uni.$u.props.avatar.mode
|
||||
},
|
||||
// 显示的文字
|
||||
text: {
|
||||
type: String,
|
||||
default: uni.$u.props.avatar.text
|
||||
},
|
||||
// 背景色
|
||||
bgColor: {
|
||||
type: String,
|
||||
default: uni.$u.props.avatar.bgColor
|
||||
},
|
||||
// 文字颜色
|
||||
color: {
|
||||
type: String,
|
||||
default: uni.$u.props.avatar.color
|
||||
},
|
||||
// 文字大小
|
||||
fontSize: {
|
||||
type: [String, Number],
|
||||
default: uni.$u.props.avatar.fontSize
|
||||
},
|
||||
// 显示的图标
|
||||
icon: {
|
||||
type: String,
|
||||
default: uni.$u.props.avatar.icon
|
||||
},
|
||||
// 显示小程序头像,只对百度,微信,QQ小程序有效
|
||||
mpAvatar: {
|
||||
type: Boolean,
|
||||
default: uni.$u.props.avatar.mpAvatar
|
||||
},
|
||||
// 是否使用随机背景色
|
||||
randomBgColor: {
|
||||
type: Boolean,
|
||||
default: uni.$u.props.avatar.randomBgColor
|
||||
},
|
||||
// 加载失败的默认头像(组件有内置默认图片)
|
||||
defaultUrl: {
|
||||
type: String,
|
||||
default: uni.$u.props.avatar.defaultUrl
|
||||
},
|
||||
// 如果配置了randomBgColor为true,且配置了此值,则从默认的背景色数组中取出对应索引的颜色值,取值0-19之间
|
||||
colorIndex: {
|
||||
type: [String, Number],
|
||||
// 校验参数规则,索引在0-19之间
|
||||
validator(n) {
|
||||
return uni.$u.test.range(n, [0, 19]) || n === ''
|
||||
},
|
||||
default: uni.$u.props.avatar.colorIndex
|
||||
},
|
||||
// 组件标识符
|
||||
name: {
|
||||
type: String,
|
||||
default: uni.$u.props.avatar.name
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,297 @@
|
|||
<template>
|
||||
<view>
|
||||
<base-popup
|
||||
:title="'关联客户'"
|
||||
ref="basePopup"
|
||||
@handleConfirmClick="handlerCustomerConfirm"
|
||||
@handleCloseClick="resetDialog"
|
||||
>
|
||||
<view style="padding: 20rpx 30rpx 0 30rpx">
|
||||
<u-search
|
||||
v-if="showSearch"
|
||||
:placeholder="placeholder"
|
||||
v-model="CodeOrName"
|
||||
shape="square"
|
||||
clearabled
|
||||
:showAction="false"
|
||||
@change="contractSearch"
|
||||
></u-search>
|
||||
<scroll-view
|
||||
:scroll-top="scrollTop"
|
||||
scroll-y="true"
|
||||
class="scroll-Y"
|
||||
@scrolltolower="scrolltolower"
|
||||
:lower-threshold="0"
|
||||
style="margin-top: 20rpx"
|
||||
v-if="!isLoading"
|
||||
>
|
||||
<!--单选-->
|
||||
<u-radio-group
|
||||
v-if="type == 'radio'"
|
||||
:borderBottom="true"
|
||||
iconPlacement="right"
|
||||
placement="column"
|
||||
@change="groupChange"
|
||||
v-model="radioValue"
|
||||
>
|
||||
<u-radio
|
||||
:customStyle="{ marginBottom: '12px' }"
|
||||
v-for="(item, index) in dataLists"
|
||||
:key="index"
|
||||
:name="item.cusCode"
|
||||
>
|
||||
<view class="listData">
|
||||
<view class="content">
|
||||
<text>客户编码:</text>
|
||||
{{ item.cusCode }}
|
||||
</view>
|
||||
<view class="content">
|
||||
<text>客户名称:</text>
|
||||
{{ item.cusName }}
|
||||
</view>
|
||||
<view class="flex time">
|
||||
<view class="overflowTextHidden">
|
||||
<text>客户简称:</text>
|
||||
{{ item.cusShortName }}
|
||||
</view>
|
||||
<view class="overflowTextHidden">
|
||||
<text>客户分类:</text>
|
||||
{{ item.cusClassifyName }}
|
||||
</view>
|
||||
<view class="overflowTextHidden">
|
||||
<text>分管部门:</text>
|
||||
{{ item.orgainName }}
|
||||
</view>
|
||||
<view class="overflowTextHidden">
|
||||
<text>法人:</text>
|
||||
{{ item.legalPerson }}
|
||||
</view>
|
||||
<view class="overflowTextHidden">
|
||||
<text>税号:</text>
|
||||
{{ item.taxNumber }}
|
||||
</view>
|
||||
<view class="overflowTextHidden">
|
||||
<text>电话:</text>
|
||||
{{ item.telphone }}
|
||||
</view>
|
||||
<view>
|
||||
<text>地址:</text>
|
||||
{{ item.address }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</u-radio>
|
||||
</u-radio-group>
|
||||
|
||||
<!--多选-->
|
||||
<u-checkbox-group
|
||||
v-if="type == 'checkbox'"
|
||||
:borderBottom="true"
|
||||
placement="column"
|
||||
iconPlacement="right"
|
||||
@change="checkboxChange"
|
||||
v-model="checkboxValue"
|
||||
>
|
||||
<u-checkbox
|
||||
:customStyle="{ marginBottom: '12px', paddingBottom: '12px' }"
|
||||
v-for="(item, index) in dataLists"
|
||||
:key="index"
|
||||
:name="item.cusCode"
|
||||
:label="item.cusName + ' ' + item.cusCode"
|
||||
>
|
||||
</u-checkbox>
|
||||
</u-checkbox-group>
|
||||
<view class="contractNoData" v-show="noData">
|
||||
<u-divider text="我是有底线哒!" :hairline="true"></u-divider>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<u-loadmore
|
||||
v-else
|
||||
status="loading"
|
||||
:loadingText="'数据加载中'"
|
||||
:marginTop="150"
|
||||
></u-loadmore>
|
||||
</view>
|
||||
</base-popup>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { OrganGetCustomer } from "@/api/system/projectAdd.js";
|
||||
import basePopup from "@/components/basePopup/index.vue";
|
||||
export default {
|
||||
components: {
|
||||
basePopup,
|
||||
},
|
||||
props: {
|
||||
// 是否显示搜索
|
||||
showSearch: {
|
||||
default: true,
|
||||
type: Boolean,
|
||||
},
|
||||
placeholder: {
|
||||
default: "请输入客户名称、客户编码",
|
||||
type: String,
|
||||
},
|
||||
type: {
|
||||
default: "checkbox",
|
||||
type: String,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
noData: false,
|
||||
CodeOrName: "",
|
||||
scrollTop: 0,
|
||||
pages: {
|
||||
page: 1, //当前页码
|
||||
limit: 20, //每页显示多少
|
||||
cusClassify: "", //树形分类id
|
||||
Sequence: "", //排列方式
|
||||
SequenceName: "", //需要排列的字段名
|
||||
CodeOrName: "",
|
||||
},
|
||||
dataLists: [],
|
||||
checkboxData: [],
|
||||
checkboxValue: [],
|
||||
radioData: "",
|
||||
radioValue: "",
|
||||
timer: null,
|
||||
isLoading: false,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
openDialog() {
|
||||
this.OrganGetCustomer();
|
||||
this.$refs.basePopup.isShowPopup = true;
|
||||
},
|
||||
// 搜索
|
||||
contractSearch(value) {
|
||||
if (this.timer !== null) clearTimeout(this.timer);
|
||||
this.timer = setTimeout(() => {
|
||||
this.pages.CodeOrName = value;
|
||||
this.OrganGetCustomer();
|
||||
this.radioValue = "";
|
||||
this.checkboxValue = Object.assign([], []);
|
||||
}, 800);
|
||||
},
|
||||
resetDialog() {
|
||||
this.CodeOrName = "";
|
||||
this.pages.page = 1;
|
||||
this.pages.CodeOrName = "";
|
||||
this.radioValue = "";
|
||||
this.checkboxValue = Object.assign([], []);
|
||||
},
|
||||
checkboxChange(n) {
|
||||
this.checkboxData = [];
|
||||
n.forEach((key) => {
|
||||
this.dataLists.forEach((item) => {
|
||||
if (item.cusCode == key) {
|
||||
this.checkboxData.push(item);
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
//选择列表项触发
|
||||
groupChange(n) {
|
||||
this.radioData = this.dataLists.filter((item) => item.cusCode === n);
|
||||
},
|
||||
// 滑动到底部触发,用于下拉加载新数据
|
||||
scrolltolower() {
|
||||
if (this.noData != true) {
|
||||
this.pages.page++;
|
||||
this.OrganGetCustomer();
|
||||
}
|
||||
},
|
||||
// 获取客户弹窗--列表
|
||||
async OrganGetCustomer() {
|
||||
this.isLoading = true;
|
||||
this.noData = false;
|
||||
let params = {
|
||||
...this.pages,
|
||||
};
|
||||
const res = await OrganGetCustomer(params);
|
||||
this.isLoading = false;
|
||||
if (this.pages.page > 1) {
|
||||
this.dataLists.push(...res.data[1]);
|
||||
} else {
|
||||
this.dataLists = res.data[1];
|
||||
}
|
||||
if (res.data[1].length < 20) {
|
||||
this.noData = true;
|
||||
}
|
||||
},
|
||||
// 确认按钮点击事件
|
||||
handlerCustomerConfirm() {
|
||||
if (this.type == "radio") {
|
||||
if (
|
||||
this.radioData == "" ||
|
||||
this.radioData == undefined ||
|
||||
this.radioData == null
|
||||
) {
|
||||
uni.$u.toast("请选择数据");
|
||||
return;
|
||||
}
|
||||
this.$emit("handlerCustomerConfirm", this.radioData);
|
||||
this.$refs.basePopup.isShowPopup = false;
|
||||
this.resetDialog();
|
||||
} else if (this.type == "checkbox") {
|
||||
if (this.checkboxData.length == 0) {
|
||||
uni.$u.toast("请选择数据");
|
||||
return;
|
||||
}
|
||||
this.$emit("handlerCustomerConfirm", this.checkboxData);
|
||||
this.$refs.basePopup.isShowPopup = false;
|
||||
this.resetDialog();
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.scroll-Y {
|
||||
height: 680rpx;
|
||||
}
|
||||
.contractNoData .u-divider {
|
||||
margin: 0;
|
||||
}
|
||||
.content {
|
||||
line-height: 1.5;
|
||||
font-size: 28rpx;
|
||||
margin-bottom: 20rpx;
|
||||
|
||||
text {
|
||||
font-size: 28rpx;
|
||||
color: #979797;
|
||||
}
|
||||
}
|
||||
.time {
|
||||
font-size: 28rpx;
|
||||
flex-wrap: wrap;
|
||||
line-height: 1.5;
|
||||
|
||||
text {
|
||||
display: inline-block;
|
||||
font-size: 26rpx;
|
||||
color: #979797;
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
view {
|
||||
height: 48rpx;
|
||||
}
|
||||
view:nth-child(2n + 1) {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
view:nth-child(2n) {
|
||||
width: 50%;
|
||||
}
|
||||
view:nth-child(4) {
|
||||
text:nth-child(2) {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,297 @@
|
|||
<!--
|
||||
@desc 自定义表单组件
|
||||
@date 20230720
|
||||
--------对于整个表单-----------
|
||||
labelFormPosition: 表单域提示文字的位置,left-左侧,top-上方
|
||||
borderFormBottom: 是否显示表单域的下划线边框
|
||||
labelFormWidth: 提示文字的宽度,单位px
|
||||
labelFormAlign:lable字体的对齐方式 默认left 可选 center/right
|
||||
-->
|
||||
|
||||
<template>
|
||||
<view>
|
||||
<u--form :labelPosition="labelFormPosition" :borderBottom="borderFormBottom" :labelWidth="labelFormWidth"
|
||||
class="baseform" :labelAlign="labelFormAlign" :labelStyle="labelStyle" :model="formModel" :rules="formRules"
|
||||
ref="baseForm">
|
||||
<view style="padding-bottom: 40rpx;">
|
||||
<u-row v-for="(item,index) in formRow" :key="index">
|
||||
<u-col v-for="(row,rowIndex) in item.uCol" :span="row.span ? row.span : spanNumber" :key="rowIndex">
|
||||
<u-form-item v-if="row.tag == 'input'" :label="row.label" :prop="row.prop" ref="item1"
|
||||
:borderBottom="row.borderBottom" @click="handlerRowInputClickEvent(row,rowIndex)"
|
||||
:labelWidth="row.labelWidth" :labelPosition="row.labelPosition" :rightIcon="row.rightIcon"
|
||||
:leftIcon="row.leftIcon" :required="row.required"
|
||||
:class="(getRule(row.prop)?'ruleFormClass ':'')">
|
||||
<u--input v-if="row.type == 'uInput'" :placeholder="row.placeholder" clearable
|
||||
v-model="formModel.formData[row.prop]" :suffixIcon="row.suffixIcon"
|
||||
:disabled="row.disabled" :border="row.border"
|
||||
:disabledColor="row.disabledColor"></u--input>
|
||||
|
||||
<u--textarea v-if="row.type == 'uTextarea'" v-model="formModel.formData[row.prop]"
|
||||
:height="row.height?row.height: 100" :maxlength="row.maxlength ? row.maxlength: '-1'"
|
||||
:placeholder="row.placeholder" :suffixIcon="row.suffixIcon" :disabled="row.disabled"
|
||||
:border="row.border" :disabledColor="row.disabledColor"></u--textarea>
|
||||
<u-radio-group v-if="row.type == 'uRadio'" v-model="formModel.formData[row.prop]"
|
||||
@change="handlerRadioChange($event,row,rowIndex)">
|
||||
<u-radio :customStyle="{marginRight: '16px'}" v-for="(item, index) in row.options"
|
||||
:key="index" :label="item.label" :name="item.value">
|
||||
</u-radio>
|
||||
</u-radio-group>
|
||||
<u-checkbox-group v-if="row.type == 'uCheckbox'" v-model="formModel.formData[row.prop]"
|
||||
shape="square" placement="column" @change="handlerCheckboxChange($event,row,rowIndex)">
|
||||
<u-checkbox :customStyle="{marginBottom: '8px'}" v-for="(item, index) in row.options"
|
||||
:key="index" :label="item.label" :name="item.value"
|
||||
:disabled="item.disabled ? true:false">
|
||||
</u-checkbox>
|
||||
</u-checkbox-group>
|
||||
</u-form-item>
|
||||
<!-- 简单下拉框 -->
|
||||
<u-form-item v-if="row.tag == 'select'" :label="row.label" :prop="row.prop" ref="item2"
|
||||
:class="(getRule(row.prop)?'ruleFormClass ':'')" :borderBottom="row.borderBottom"
|
||||
@click="row.show = true" :labelWidth="row.labelWidth" :labelPosition="row.labelPosition"
|
||||
:rightIcon="row.rightIcon" :leftIcon="row.leftIcon" :required="row.required">
|
||||
<!-- keyName,自定义需要展示的text属性键名 -->
|
||||
<u-picker :show="row.show" :columns="[row.options]"
|
||||
:closeOnClickOverlay="row.closeOnClickOverlay ? true:false"
|
||||
@close="handlerSelectClose(row,rowIndex)" @cancel="handlerSelectClose(row,rowIndex)"
|
||||
@confirm="selectConfirm($event,row,rowIndex)" :keyName="row.keyName"></u-picker>
|
||||
<u--input :placeholder="row.placeholder" v-model="formModel.formData[row.prop]" clearable
|
||||
:suffixIcon="row.suffixIcon ? row.suffixIcon:''" :disabled="row.disabled"
|
||||
:border="row.border" :disabledColor="row.disabledColor"></u--input>
|
||||
</u-form-item>
|
||||
<!-- 此组件用于单个选择日期,范围选择日期等
|
||||
mode
|
||||
为single只能选择单个日期
|
||||
为multiple可以选择多个日期
|
||||
为range可以选择日期范围
|
||||
-->
|
||||
<u-form-item v-if="row.tag == 'calendar'" :label="row.label" :prop="row.prop" ref="item2"
|
||||
:class="(getRule(row.prop)?'ruleFormClass ':'')" :borderBottom="row.borderBottom"
|
||||
@click="row.show = true" :labelWidth="row.labelWidth" :labelPosition="row.labelPosition"
|
||||
:rightIcon="row.rightIcon" :leftIcon="row.leftIcon" :required="row.required">
|
||||
<!-- keyName,自定义需要展示的text属性键名 -->
|
||||
<u-calendar :show="row.show" :mode="row.mode" :showTitle="row.title" round="10"
|
||||
:closeOnClickOverlay="row.closeOnClickOverlay ? true:false"
|
||||
@close="handlerCalendarClose(row,rowIndex)"
|
||||
@confirm="calendarConfirm($event,row,rowIndex)" :maxDate="row.maxDate"
|
||||
:minDate="row.minDate" :monthNum="row.monthNum"></u-calendar>
|
||||
<u--input :placeholder="row.placeholder" v-model="formModel.formData[row.prop]"
|
||||
suffixIcon="calendar" clearable :disabled="row.disabled" :border="row.border"
|
||||
:disabledColor="row.disabledColor"></u--input>
|
||||
</u-form-item>
|
||||
<!-- 此选择器用于时间日期
|
||||
mode 配置选择何种日期格式。datetime年月日时分 date为日期选择,time为时间选择,year-month为年月选择
|
||||
参数minDate和maxDate可以设置最大值和最小值(传入时间戳)。
|
||||
-->
|
||||
<u-form-item v-if="row.tag == 'datetime'" :label="row.label" :prop="row.prop" ref="item2"
|
||||
:class="(getRule(row.prop)?'ruleFormClass ':'')" :borderBottom="row.borderBottom"
|
||||
@click="row.show = true" :labelWidth="row.labelWidth" :labelPosition="row.labelPosition"
|
||||
:rightIcon="row.rightIcon" :leftIcon="row.leftIcon" :required="row.required">
|
||||
<!-- keyName,自定义需要展示的text属性键名 -->
|
||||
<u-datetime-picker :show="row.show" :mode="row.mode" :value="defaultTime(row)"
|
||||
:closeOnClickOverlay="row.closeOnClickOverlay ? true:false" :maxDate="row.maxDate"
|
||||
:minDate="row.minDate" @confirm="dateTimeConfirm($event,row,rowIndex)"
|
||||
@cancel="handlerDateTimeClose(row,rowIndex)"
|
||||
@close="handlerDateTimeClose(row,rowIndex)"></u-datetime-picker>
|
||||
<u--input :placeholder="row.placeholder" v-model="formModel.formData[row.prop]" clearable
|
||||
suffixIcon="arrow-right" :disabled="row.disabled" :border="row.border"
|
||||
:disabledColor="row.disabledColor"></u--input>
|
||||
</u-form-item>
|
||||
</u-col>
|
||||
</u-row>
|
||||
</view>
|
||||
</u--form>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
labelFormPosition: {
|
||||
type: String,
|
||||
default: "left"
|
||||
},
|
||||
borderFormBottom: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
labelFormWidth: {
|
||||
type: [Number, String],
|
||||
default: 100
|
||||
},
|
||||
labelFormAlign: {
|
||||
type: String,
|
||||
default: "left"
|
||||
},
|
||||
labelStyle: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {
|
||||
padding: '10px 0 10px 10px'
|
||||
};
|
||||
},
|
||||
},
|
||||
// 表单验证规则
|
||||
formRules: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {};
|
||||
},
|
||||
},
|
||||
// 表单页面结构数据
|
||||
formRow: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
return [];
|
||||
},
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
spanNumber: 12,
|
||||
formModel: {
|
||||
formData: {
|
||||
hour: ''
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
mounted() {},
|
||||
methods: {
|
||||
bbb(a, b) {
|
||||
console.log(a, "测试", b)
|
||||
},
|
||||
defaultTime(row) {
|
||||
if (row.mode == 'datetime' || row.mode == 'date' || row.mode == 'year-month') {
|
||||
return Number(new Date())
|
||||
} else if (row.mode == 'time') {
|
||||
return new Date().toLocaleTimeString().slice(0, 5)
|
||||
} else {
|
||||
return
|
||||
}
|
||||
},
|
||||
handlerRowInputClickEvent(row, index) {
|
||||
this.$emit("handlerRowInputClickEvent", row, index)
|
||||
},
|
||||
// 下拉框确认事件
|
||||
selectConfirm(value, row, index) {
|
||||
this.$emit("selectConfirm", value, row, index)
|
||||
row.show = false
|
||||
},
|
||||
// 下拉框关闭事件
|
||||
handlerSelectClose(row, index) {
|
||||
row.show = false
|
||||
},
|
||||
// 日期关闭事件
|
||||
handlerCalendarClose(row, index) {
|
||||
row.show = false
|
||||
},
|
||||
// 日期时间关闭事件
|
||||
handlerDateTimeClose(row, index) {
|
||||
row.show = false
|
||||
},
|
||||
// 日期确认事件
|
||||
calendarConfirm(value, row, index) {
|
||||
this.$emit("calendarConfirm", value, row, index)
|
||||
row.show = false
|
||||
},
|
||||
// 日期时间确认事件
|
||||
dateTimeConfirm(e, row, index) {
|
||||
const timeFormat = uni.$u.timeFormat
|
||||
let time = ''
|
||||
if (row.mode == 'datetime') {
|
||||
time = timeFormat(e.value, 'yyyy-mm-dd hh:MM')
|
||||
} else if (row.mode == 'date') {
|
||||
time = timeFormat(e.value, 'yyyy-mm-dd')
|
||||
} else if (row.mode == 'year-month') {
|
||||
time = timeFormat(e.value, 'yyyy-mm')
|
||||
} else if (row.mode == 'time') {
|
||||
// time = timeFormat(e.value, 'hh:MM')
|
||||
time = e.value
|
||||
} else {
|
||||
time = ''
|
||||
}
|
||||
this.$emit("dateTimeConfirm", time, row, index)
|
||||
row.show = false
|
||||
},
|
||||
// 复选框change事件
|
||||
handlerCheckboxChange(e, row, rowIndex) {
|
||||
this.$emit("handlerCheckboxChange", e, row, rowIndex)
|
||||
},
|
||||
// 单选框change事件
|
||||
handlerRadioChange(e, row, rowIndex) {
|
||||
this.$emit("handlerRadioChange", e, row, rowIndex)
|
||||
},
|
||||
setField(propLabel, value) {
|
||||
this.$set(this.formModel.formData, propLabel, value);
|
||||
},
|
||||
incomingParameters(vale) {
|
||||
for (let i in vale) {
|
||||
this.setField(i, vale[i]);
|
||||
}
|
||||
},
|
||||
// 表单提交
|
||||
submitForm(formName) {
|
||||
let formRules = {
|
||||
formData: {
|
||||
...this.formRules
|
||||
}
|
||||
}
|
||||
// this.formRules = formRules
|
||||
console.log(this.$refs[formName].validate(), "formRules")
|
||||
this.$refs[formName].validate((valid) => {
|
||||
if (valid) {
|
||||
console.log(valid)
|
||||
// this.$emit('onSubmit', this.formModel.formData)
|
||||
} else {
|
||||
console.log('error submit!!');
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
// 表单重置
|
||||
resetForm(formName) {
|
||||
this.choiceAssignment({})
|
||||
},
|
||||
//弹窗赋值
|
||||
choiceAssignment(value) {
|
||||
this.formModel.formData = Object.assign({}, value)
|
||||
},
|
||||
getRule(rowList) {
|
||||
let requiredType = false
|
||||
if (this.formRules[rowList] && this.formRules[rowList].length > 0) {
|
||||
this.formRules[rowList].forEach(el => {
|
||||
if (el.required) {
|
||||
requiredType = true
|
||||
}
|
||||
})
|
||||
}
|
||||
return requiredType
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.baseform {
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.u-form-item {
|
||||
padding: 0 30rpx;
|
||||
}
|
||||
|
||||
.u-popup {
|
||||
flex: none;
|
||||
}
|
||||
|
||||
::v-deep .u-form-item__body__right__message {
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
::v-deep .ruleFormClass {
|
||||
.u-line {
|
||||
border-bottom: 2rpx solid #E6A23C !important;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,325 @@
|
|||
<!-- 选择人员组件 非弹窗
|
||||
@desc 多选
|
||||
-->
|
||||
<template>
|
||||
<view :style="{ marginTop: tarbarHeight }">
|
||||
<view style="padding-bottom: 160rpx">
|
||||
<u-collapse>
|
||||
<!-- 手风琴headImageUr1 -->
|
||||
<u-collapse-item
|
||||
v-for="(item, index) in dataList"
|
||||
:key="index"
|
||||
:title="item.o_OrganName"
|
||||
class="department"
|
||||
:name="index"
|
||||
>
|
||||
<u-icon
|
||||
name="star-fill"
|
||||
size="20"
|
||||
slot="icon"
|
||||
:color="color"
|
||||
class="el-icon-star-on star"
|
||||
@click.native="selectAll(item, index)"
|
||||
:class="{ active: item.active }"
|
||||
></u-icon>
|
||||
<u-list :height="'auto'">
|
||||
<u-list-item
|
||||
v-for="(elItem, elIndex) in item.personList"
|
||||
:key="elIndex"
|
||||
>
|
||||
<u-cell
|
||||
:title="elItem.p_PersonName + ' ' + elItem.p_Telphone"
|
||||
@click="selectPerson(elItem)"
|
||||
>
|
||||
<base-avatar
|
||||
slot="icon"
|
||||
shape="square"
|
||||
size="35"
|
||||
:text="
|
||||
elItem.p_PersonName ? elItem.p_PersonName.slice(-2) : ''
|
||||
"
|
||||
bg-color="#3c9cff"
|
||||
color="#ffffff"
|
||||
font-size="10"
|
||||
:src="elItem.headImageUrl"
|
||||
customStyle="margin: -3px 5px -3px 0"
|
||||
></base-avatar>
|
||||
<u-icon
|
||||
name="checkbox-mark"
|
||||
slot="right-icon"
|
||||
size="20"
|
||||
:color="color"
|
||||
class="el-icon-star-on star"
|
||||
:class="{ active: elItem.active }"
|
||||
></u-icon>
|
||||
</u-cell>
|
||||
</u-list-item>
|
||||
</u-list>
|
||||
</u-collapse-item>
|
||||
</u-collapse>
|
||||
</view>
|
||||
<view class="bottomPage">
|
||||
<view style="width: 58%; font-weight: 600"
|
||||
>已选 {{ selectedDataList.length }} 人</view
|
||||
>
|
||||
<u-button
|
||||
text="确认"
|
||||
type="primary"
|
||||
size="normal"
|
||||
style="width: 35%"
|
||||
@click="personConfirmClick"
|
||||
></u-button>
|
||||
</view>
|
||||
<base-tarbar ref="baseTarbar" :pageTitle="'选择人员'"></base-tarbar>
|
||||
<u-loading-page :loading="personLoading"></u-loading-page>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import baseAvatar from "@/components/baseAvatar/index.vue";
|
||||
import { PersonList, GetOrganTree } from "@/api/system/basePerson";
|
||||
import baseTarbar from "@/components/baseTarbar/index.vue";
|
||||
import config from "@/config";
|
||||
import { getUserInfo } from "@/utils/auth";
|
||||
export default {
|
||||
components: {
|
||||
baseAvatar,
|
||||
baseTarbar,
|
||||
},
|
||||
onReady() {
|
||||
this.$refs.baseTarbar.currentEnvironment();
|
||||
if (this.$refs.baseTarbar.isOther) {
|
||||
this.tarbarHeight = "88rpx";
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
selectedDataList: {
|
||||
deep: true, //深度监听设置为 true
|
||||
handler: function (newV, oldV) {
|
||||
this.dataList.forEach((el) => {
|
||||
let personNum = 0;
|
||||
el.personList.forEach((personEl) => {
|
||||
if (personEl.active) {
|
||||
personNum = personNum + 1;
|
||||
}
|
||||
});
|
||||
if (personNum == 0) {
|
||||
el.active = false;
|
||||
} else {
|
||||
el.active = true;
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
dataList: {
|
||||
deep: true, //深度监听设置为 true
|
||||
handler: function (newV, oldV) {
|
||||
let selectedDataList = [];
|
||||
newV.forEach((el) => {
|
||||
el.personList.forEach((item) => {
|
||||
if (item.active) {
|
||||
selectedDataList.push(item);
|
||||
}
|
||||
});
|
||||
});
|
||||
this.selectedDataList = selectedDataList;
|
||||
},
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dataList: [],
|
||||
selectedDataList: [],
|
||||
personLoading: false,
|
||||
color: "f0f0f0",
|
||||
configData: {},
|
||||
tarbarHeight:"",
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.openDialog();
|
||||
},
|
||||
methods: {
|
||||
// 打开弹窗
|
||||
openDialog(selectedDataList = [], type) {
|
||||
this.configData = config;
|
||||
this.selectedDataList = [];
|
||||
this.getMenuData(selectedDataList);
|
||||
},
|
||||
// 人员确定
|
||||
personConfirmClick() {
|
||||
this.$store.commit("SET_SELECTSDATA", this.selectedDataList);
|
||||
uni.navigateBack({
|
||||
delta: 1, //* 返回上一页
|
||||
});
|
||||
},
|
||||
closePersonClick() {
|
||||
uni.navigateBack({
|
||||
delta: 1, //* 返回上一页
|
||||
});
|
||||
},
|
||||
// 获得组织图
|
||||
async getMenuData(selectedDataList) {
|
||||
this.personLoading = true;
|
||||
setTimeout(() => {
|
||||
this.personLoading = false;
|
||||
}, 5000);
|
||||
let params = {
|
||||
CompanyID: getUserInfo().companyID,
|
||||
};
|
||||
|
||||
let res = await GetOrganTree(params);
|
||||
let dataList = JSON.parse(res.data[0]);
|
||||
|
||||
let departmentList = [];
|
||||
|
||||
function setDepartmentList(data) {
|
||||
data.forEach((item) => {
|
||||
let arr = {
|
||||
o_OrganName: item.label,
|
||||
personList: [],
|
||||
active: false,
|
||||
};
|
||||
departmentList.push(arr);
|
||||
if (item.children && item.children.length > 0) {
|
||||
setDepartmentList(item.children);
|
||||
}
|
||||
});
|
||||
}
|
||||
setDepartmentList(dataList);
|
||||
this.getPersonList(departmentList, selectedDataList);
|
||||
this.personLoading = false
|
||||
},
|
||||
// 获得人员列表
|
||||
async getPersonList(departmentList, selectedDataList) {
|
||||
let params = {
|
||||
page: "1",
|
||||
limit: "999",
|
||||
departmentID: "",
|
||||
};
|
||||
let res = await PersonList(params);
|
||||
if (res.code === 1) {
|
||||
departmentList.forEach((el) => {
|
||||
res.data[1].forEach((item) => {
|
||||
if (el.o_OrganName == item.o_OrganName) {
|
||||
let personArr = {
|
||||
o_OrganName: item.o_OrganName,
|
||||
p_PersonName: item.p_PersonName,
|
||||
p_PersonID: item.p_PersonID,
|
||||
p_Telphone: item.p_Telphone,
|
||||
headImageUrl: item.headImageUrl
|
||||
? this.configData.baseUrl +
|
||||
String(item.headImageUrl).split("/wwwroot")[1]
|
||||
: "",
|
||||
active: false,
|
||||
};
|
||||
el.personList.push(personArr);
|
||||
}
|
||||
});
|
||||
});
|
||||
this.dataList = departmentList;
|
||||
this.dataList.forEach((el) => {
|
||||
el.personList.forEach((elItem) => {
|
||||
selectedDataList.forEach((item) => {
|
||||
if (item.p_PersonID == elItem.p_PersonID) {
|
||||
elItem.active = true;
|
||||
this.selectedDataList.push(elItem);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
this.personLoading = false;
|
||||
}
|
||||
},
|
||||
selectPerson(val) {
|
||||
let personActive = false;
|
||||
val.active = !val.active;
|
||||
},
|
||||
// 全选
|
||||
selectAll(item) {
|
||||
item.active = !item.active;
|
||||
item.personList.forEach((el) => {
|
||||
el.active = item.active;
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
$activeColor: var(--bg-color, "#00aaff");
|
||||
|
||||
::v-deep .u-collapse-item__content__text {
|
||||
padding: 0;
|
||||
}
|
||||
::v-deep .u-list-item.u-list-item- .u-cell .u-line {
|
||||
border-bottom: 0 solid rgb(214, 215, 217) !important;
|
||||
}
|
||||
.bottomPage {
|
||||
width: 100%;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
padding: 20rpx 30rpx 30rpx 30rpx;
|
||||
background-color: #fff;
|
||||
margin-top: 15rpx;
|
||||
display: flex;
|
||||
border-top: 8rpx solid #f1f1f1;
|
||||
align-items: center;
|
||||
}
|
||||
.dataBox {
|
||||
padding: 10rpx 0;
|
||||
border-bottom: 2rpx solid #ccc;
|
||||
min-height: 100rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.personBox {
|
||||
border-radius: 6rpx;
|
||||
text-align: center;
|
||||
background-color: #f0f0f0;
|
||||
color: #817582;
|
||||
padding: 20rpx 0;
|
||||
cursor: pointer;
|
||||
min-width: 200rpx;
|
||||
|
||||
.name {
|
||||
}
|
||||
|
||||
.phone {
|
||||
font-size: 24rpx;
|
||||
margin-top: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.personBox {
|
||||
margin-right: 20rpx;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.personBox.active {
|
||||
color: #fff;
|
||||
background-color: #3c9cff;
|
||||
}
|
||||
|
||||
.department {
|
||||
.el-icon-star-on {
|
||||
color: #f0f0f0;
|
||||
}
|
||||
}
|
||||
|
||||
.el-icon-star-on.active {
|
||||
color: #3c9cff;
|
||||
}
|
||||
|
||||
.personItem {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
</style>
|
||||
<style scoped>
|
||||
page {
|
||||
background: #fff;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,291 @@
|
|||
<!-- 选择人员组件
|
||||
@desc 多选 弹窗
|
||||
-->
|
||||
<template>
|
||||
<view>
|
||||
<base-popup
|
||||
ref="basePopup"
|
||||
@handleConfirmClick="personConfirmClick"
|
||||
:title="'选择人员'"
|
||||
>
|
||||
<view>
|
||||
<u-collapse>
|
||||
<!-- 手风琴headImageUr1 -->
|
||||
<u-collapse-item
|
||||
v-for="(item, index) in dataList"
|
||||
:key="index"
|
||||
:title="item.o_OrganName"
|
||||
class="department"
|
||||
:name="index"
|
||||
>
|
||||
<u-icon
|
||||
name="star-fill"
|
||||
size="20"
|
||||
slot="icon"
|
||||
:color="color"
|
||||
class="el-icon-star-on star"
|
||||
@click.native.stop="selectAll(item, index)"
|
||||
:class="{ active: item.active }"
|
||||
></u-icon>
|
||||
<u-list :height="'auto'" v-if="item.personList && item.personList.length > 0">
|
||||
<u-list-item
|
||||
v-for="(elItem, elIndex) in item.personList"
|
||||
:key="elIndex"
|
||||
|
||||
>
|
||||
<u-cell
|
||||
:title="elItem.p_PersonName + ' ' + elItem.p_Telphone"
|
||||
@click="selectPerson(elItem)"
|
||||
>
|
||||
<base-avatar
|
||||
slot="icon"
|
||||
shape="square"
|
||||
size="35"
|
||||
:text="
|
||||
elItem.p_PersonName ? elItem.p_PersonName.slice(-2) : ''
|
||||
"
|
||||
bg-color="#3c9cff"
|
||||
color="#ffffff"
|
||||
font-size="10"
|
||||
:src="elItem.headImageUrl"
|
||||
customStyle="margin: -3px 5px -3px 0"
|
||||
></base-avatar>
|
||||
<u-icon
|
||||
name="checkbox-mark"
|
||||
slot="right-icon"
|
||||
size="20"
|
||||
:color="color"
|
||||
class="el-icon-star-on star"
|
||||
:class="{ active: elItem.active }"
|
||||
></u-icon>
|
||||
</u-cell>
|
||||
</u-list-item>
|
||||
</u-list>
|
||||
<view v-else class="empty">暂无数据</view>
|
||||
</u-collapse-item>
|
||||
</u-collapse>
|
||||
</view>
|
||||
</base-popup>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import baseAvatar from "@/components/baseAvatar/index.vue";
|
||||
import basePopup from "@/components/basePopup/index.vue";
|
||||
import { PersonList, GetOrganTree } from "@/api/system/basePerson";
|
||||
import config from "@/config";
|
||||
import { getUserInfo } from "@/utils/auth";
|
||||
export default {
|
||||
components: {
|
||||
basePopup,
|
||||
baseAvatar,
|
||||
},
|
||||
watch: {
|
||||
selectedDataList: {
|
||||
deep: true, //深度监听设置为 true
|
||||
handler: function (newV, oldV) {
|
||||
this.dataList.forEach((el) => {
|
||||
let personNum = 0;
|
||||
el.personList.forEach((personEl) => {
|
||||
if (personEl.active) {
|
||||
personNum = personNum + 1;
|
||||
}
|
||||
});
|
||||
if (personNum == 0) {
|
||||
el.active = false;
|
||||
} else {
|
||||
el.active = true;
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
dataList: {
|
||||
deep: true, //深度监听设置为 true
|
||||
handler: function (newV, oldV) {
|
||||
let selectedDataList = [];
|
||||
newV.forEach((el) => {
|
||||
el.personList.forEach((item) => {
|
||||
if (item.active) {
|
||||
selectedDataList.push(item);
|
||||
}
|
||||
});
|
||||
});
|
||||
this.selectedDataList = selectedDataList;
|
||||
},
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dataList: [],
|
||||
selectedDataList: [],
|
||||
personLoading: false,
|
||||
color: "f0f0f0",
|
||||
configData: {},
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 打开弹窗
|
||||
openDialog(selectedDataList = [], type) {
|
||||
this.configData = config;
|
||||
this.$refs.basePopup.isShowPopup = true;
|
||||
this.selectedDataList = [];
|
||||
this.getMenuData(selectedDataList);
|
||||
},
|
||||
// 人员确定
|
||||
personConfirmClick() {
|
||||
this.$emit("personConfirmClick", this.selectedDataList);
|
||||
this.$refs.basePopup.isShowPopup = false;
|
||||
},
|
||||
// 获得组织图
|
||||
async getMenuData(selectedDataList) {
|
||||
this.personLoading = true;
|
||||
setTimeout(() => {
|
||||
this.personLoading = false;
|
||||
}, 5000);
|
||||
let params = {
|
||||
CompanyID: getUserInfo().companyID,
|
||||
};
|
||||
|
||||
let res = await GetOrganTree(params);
|
||||
let dataList = JSON.parse(res.data[0]);
|
||||
|
||||
let departmentList = [];
|
||||
|
||||
function setDepartmentList(data) {
|
||||
data.forEach((item) => {
|
||||
let arr = {
|
||||
o_OrganName: item.label,
|
||||
personList: [],
|
||||
active: false,
|
||||
};
|
||||
departmentList.push(arr);
|
||||
if (item.children && item.children.length > 0) {
|
||||
setDepartmentList(item.children);
|
||||
}
|
||||
});
|
||||
}
|
||||
setDepartmentList(dataList);
|
||||
this.getPersonList(departmentList, selectedDataList);
|
||||
},
|
||||
// 获得人员列表
|
||||
async getPersonList(departmentList, selectedDataList) {
|
||||
let params = {
|
||||
page: "1",
|
||||
limit: "999",
|
||||
departmentID: "",
|
||||
};
|
||||
let res = await PersonList(params);
|
||||
if (res.code === 1) {
|
||||
departmentList.forEach((el) => {
|
||||
res.data[1].forEach((item) => {
|
||||
if (el.o_OrganName == item.o_OrganName) {
|
||||
let personArr = {
|
||||
o_OrganName: item.o_OrganName,
|
||||
p_PersonName: item.p_PersonName,
|
||||
p_PersonID: item.p_PersonID,
|
||||
p_Telphone: item.p_Telphone,
|
||||
headImageUrl: item.headImageUrl ? this.configData.baseUrl + String(item.headImageUrl).split('/wwwroot')[1]:'',
|
||||
active: false,
|
||||
};
|
||||
el.personList.push(personArr);
|
||||
}
|
||||
});
|
||||
});
|
||||
this.dataList = departmentList;
|
||||
this.dataList.forEach((el) => {
|
||||
el.personList.forEach((elItem) => {
|
||||
selectedDataList.forEach((item) => {
|
||||
if (item.p_PersonID == elItem.p_PersonID) {
|
||||
elItem.active = true;
|
||||
this.selectedDataList.push(elItem);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
this.personLoading = false;
|
||||
}
|
||||
},
|
||||
selectPerson(val) {
|
||||
let personActive = false;
|
||||
val.active = !val.active;
|
||||
},
|
||||
// 全选
|
||||
selectAll(item) {
|
||||
item.active = !item.active;
|
||||
item.personList.forEach((el) => {
|
||||
el.active = item.active;
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
$activeColor: var(--bg-color, "#00aaff");
|
||||
|
||||
::v-deep .u-collapse-item__content__text {
|
||||
padding: 0;
|
||||
}
|
||||
.empty {
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
color: #919398;
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
||||
::v-deep .u-list-item.u-list-item- .u-cell .u-line {
|
||||
border-bottom: 0 solid rgb(214, 215, 217) !important;
|
||||
}
|
||||
|
||||
.dataBox {
|
||||
padding: 10rpx 0;
|
||||
border-bottom: 2rpx solid #ccc;
|
||||
min-height: 100rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.personBox {
|
||||
border-radius: 6rpx;
|
||||
text-align: center;
|
||||
background-color: #f0f0f0;
|
||||
color: #817582;
|
||||
padding: 20rpx 0;
|
||||
cursor: pointer;
|
||||
min-width: 200rpx;
|
||||
|
||||
.name {
|
||||
}
|
||||
|
||||
.phone {
|
||||
font-size: 24rpx;
|
||||
margin-top: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.personBox {
|
||||
margin-right: 20rpx;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.personBox.active {
|
||||
color: #fff;
|
||||
background-color: #3c9cff;
|
||||
}
|
||||
|
||||
.department {
|
||||
.el-icon-star-on {
|
||||
color: #f0f0f0;
|
||||
}
|
||||
}
|
||||
|
||||
.el-icon-star-on.active {
|
||||
color: #3c9cff;
|
||||
}
|
||||
|
||||
.personItem {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,174 @@
|
|||
<!--
|
||||
desc: 弹窗组件
|
||||
date: 20230719
|
||||
参数说明:
|
||||
isShowPopup:是否打开弹窗,布尔类型
|
||||
isOverlay: 是否显示遮罩
|
||||
mode: 弹出方向 String类型 默认:bottom 可选值 top / right / bottom / center
|
||||
duration: 遮罩打开或收起的动画过渡时间,单位ms
|
||||
closeable: 是否显示关闭图标
|
||||
overlayOpacity:遮罩透明度,0-1之间,勿与overlayStyle共用
|
||||
closeOnClickOverlay: 点击遮罩是否关闭
|
||||
safeAreaInsetTop:是否留出顶部安全距离(状态栏高度)默认false
|
||||
closeIconPos:自定义关闭图标位置,top-left为左上角,top-right为右上角,bottom-left为左下角,bottom-right为右下角
|
||||
round: 设置圆角值,仅对mode = top | bottom | center有效
|
||||
bgColor:背景色,一般用于特殊弹窗内容场景,设置为transparent可去除默认的白色背景
|
||||
zoom:当mode=center时 是否开启缩放
|
||||
-->
|
||||
<template>
|
||||
<view>
|
||||
<u-popup
|
||||
:show="isShowPopup"
|
||||
:overlay="isOverlay"
|
||||
:mode="mode"
|
||||
:duration="duration"
|
||||
:closeable="closeable"
|
||||
:overlayOpacity="overlayOpacity"
|
||||
:closeOnClickOverlay="closeOnClickOverlay"
|
||||
:overlayStyle="{ 'touch-action': 'none' }"
|
||||
:safeAreaInsetTop="safeAreaInsetTop"
|
||||
:closeIconPos="closeIconPos"
|
||||
:round="round"
|
||||
bgColor="bgColor"
|
||||
:zoom="zoom"
|
||||
@close="handleCloseClick"
|
||||
@open="handlerPopupOpen"
|
||||
>
|
||||
<view class="buttom" v-if="buttomBtn">
|
||||
<text @click="handleCloseClick" v-if="showCancle">取消</text>
|
||||
<text class="title" v-if="showtitle">{{ title }}</text>
|
||||
<text @click="handleConfirmClick" v-if="showSubmitBtn">确定</text>
|
||||
<slot name="btn" style="width:100%;"></slot>
|
||||
</view>
|
||||
<view class="scrool" :style="{ height: popuoHeight }">
|
||||
<slot></slot>
|
||||
</view>
|
||||
</u-popup>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
isOverlay: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
mode: {
|
||||
type: String,
|
||||
default: "bottom",
|
||||
},
|
||||
popuoHeight: {
|
||||
type: String,
|
||||
default: "800rpx",
|
||||
},
|
||||
duration: {
|
||||
type: [Number, String],
|
||||
default: 300,
|
||||
},
|
||||
closeable: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
overlayOpacity: {
|
||||
type: [Number, String],
|
||||
default: 0.5,
|
||||
},
|
||||
closeOnClickOverlay: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
showSubmitBtn: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
showCancle: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
showtitle: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
buttomBtn: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
safeAreaInsetTop: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
closeIconPos: {
|
||||
type: String,
|
||||
default: "top-right",
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
round: {
|
||||
type: [Number, String],
|
||||
default: 0,
|
||||
},
|
||||
bgColor: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
zoom: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isShowPopup: false,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 弹窗关闭时触发的方法
|
||||
handlerPopupClose() {
|
||||
this.isShowPopup = false;
|
||||
},
|
||||
// 弹窗打卡触发的方法
|
||||
handlerPopupOpen() {
|
||||
// this.isShowPopup = true
|
||||
},
|
||||
handleConfirmClick() {
|
||||
this.$emit("handleConfirmClick");
|
||||
},
|
||||
handleCloseClick() {
|
||||
this.isShowPopup = false;
|
||||
this.$emit("handleCloseClick");
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.buttom {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
border-bottom: 1px solid #f2f3f4;
|
||||
width: 100%;
|
||||
view{
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
text {
|
||||
padding: 20rpx 40rpx;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
text:last-child {
|
||||
color: #3c9cff;
|
||||
}
|
||||
}
|
||||
|
||||
.scrool {
|
||||
overflow-y: scroll; // 超出滚动
|
||||
overscroll-behavior: none; // 禁止滚动溢出
|
||||
}
|
||||
.title {
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,287 @@
|
|||
<template>
|
||||
<view>
|
||||
<base-popup
|
||||
:title="'关联项目'"
|
||||
ref="basePopup"
|
||||
@handleConfirmClick="handlerProjectConfirm"
|
||||
@handleCloseClick="resetDialog"
|
||||
>
|
||||
<view style="padding: 20rpx 30rpx 0 30rpx">
|
||||
<u-search
|
||||
v-if="showSearch"
|
||||
:placeholder="placeholder"
|
||||
v-model="CodeOrName"
|
||||
shape="square"
|
||||
clearabled
|
||||
:showAction="false"
|
||||
@change="contractSearch"
|
||||
></u-search>
|
||||
<scroll-view
|
||||
:scroll-top="scrollTop"
|
||||
scroll-y="true"
|
||||
class="scroll-Y"
|
||||
@scrolltolower="scrolltolower"
|
||||
:lower-threshold="0"
|
||||
style="margin-top: 20rpx"
|
||||
v-if="!isLoading"
|
||||
>
|
||||
<!--单选-->
|
||||
<u-radio-group
|
||||
v-if="type == 'radio'"
|
||||
:borderBottom="true"
|
||||
iconPlacement="right"
|
||||
placement="column"
|
||||
@change="groupChange"
|
||||
v-model="radioValue"
|
||||
>
|
||||
<u-radio
|
||||
:customStyle="{ marginBottom: '12px' }"
|
||||
v-for="(item, index) in dataLists"
|
||||
:key="index"
|
||||
:name="item.projectID"
|
||||
>
|
||||
<view class="listData">
|
||||
<view class="content">
|
||||
<text>项目名称:</text>
|
||||
{{ item.projectName }}
|
||||
</view>
|
||||
<view class="flex time">
|
||||
<view>
|
||||
<text>项目任务:</text>
|
||||
{{ item.projectTotalCount }}
|
||||
</view>
|
||||
<view>
|
||||
<text>当前BUG:</text>
|
||||
{{ item.bugTotalCount || 0 }}
|
||||
</view>
|
||||
<view>
|
||||
<text>项目经理:</text>
|
||||
{{ item.pmPersonName }}
|
||||
</view>
|
||||
<view>
|
||||
<text>业务员:</text>
|
||||
{{ item.salesName }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</u-radio>
|
||||
</u-radio-group>
|
||||
|
||||
<!--多选-->
|
||||
<u-checkbox-group
|
||||
v-if="type == 'checkbox'"
|
||||
:borderBottom="true"
|
||||
placement="column"
|
||||
iconPlacement="right"
|
||||
@change="checkboxChange"
|
||||
v-model="checkboxValue"
|
||||
>
|
||||
<u-checkbox
|
||||
:customStyle="{ marginBottom: '12px', paddingBottom: '12px' }"
|
||||
v-for="(item, index) in dataLists"
|
||||
:key="index"
|
||||
:name="item.projectID"
|
||||
:label="item.cusName + ' ' + item.projectID"
|
||||
>
|
||||
</u-checkbox>
|
||||
</u-checkbox-group>
|
||||
<view class="contractNoData" v-show="noData">
|
||||
<u-divider text="我是有底线哒!" :hairline="true"></u-divider>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<u-loadmore
|
||||
v-else
|
||||
status="loading"
|
||||
:loadingText="'数据加载中'"
|
||||
:marginTop="150"
|
||||
></u-loadmore>
|
||||
</view>
|
||||
</base-popup>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { GetProjectListData } from "@/api/system/projectAdd.js";
|
||||
import basePopup from "@/components/basePopup/index.vue";
|
||||
export default {
|
||||
components: {
|
||||
basePopup,
|
||||
},
|
||||
props: {
|
||||
// 是否显示搜索
|
||||
showSearch: {
|
||||
default: true,
|
||||
type: Boolean,
|
||||
},
|
||||
placeholder: {
|
||||
default: "请输入项目名称",
|
||||
type: String,
|
||||
},
|
||||
type: {
|
||||
default: "checkbox",
|
||||
type: String,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
noData: false,
|
||||
CodeOrName: "",
|
||||
scrollTop: 0,
|
||||
pages: {
|
||||
page: 1, //当前页码
|
||||
limit: 20, //每页显示多少
|
||||
CodeOrName: "",
|
||||
},
|
||||
dataLists: [],
|
||||
checkboxData: [],
|
||||
checkboxValue: [],
|
||||
radioData: "",
|
||||
radioValue: "",
|
||||
timer: null,
|
||||
isLoading: false,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
openDialog(radioValue = "") {
|
||||
this.GetProjectListData();
|
||||
setTimeout(() => {
|
||||
this.$nextTick(() => {
|
||||
this.radioValue = radioValue;
|
||||
if (radioValue) {
|
||||
this.groupChange(radioValue);
|
||||
}
|
||||
this.$refs.basePopup.isShowPopup = true;
|
||||
});
|
||||
}, 100);
|
||||
},
|
||||
// 搜索
|
||||
contractSearch(value) {
|
||||
if (this.timer !== null) clearTimeout(this.timer);
|
||||
this.timer = setTimeout(() => {
|
||||
this.pages.CodeOrName = value;
|
||||
this.GetProjectListData();
|
||||
this.radioValue = "";
|
||||
this.checkboxValue = Object.assign([], []);
|
||||
}, 800);
|
||||
},
|
||||
resetDialog() {
|
||||
this.CodeOrName = "";
|
||||
this.pages.page = 1;
|
||||
this.pages.CodeOrName = "";
|
||||
this.radioValue = "";
|
||||
this.radioData = "";
|
||||
this.checkboxValue = Object.assign([], []);
|
||||
},
|
||||
checkboxChange(n) {
|
||||
this.checkboxData = [];
|
||||
n.forEach((key) => {
|
||||
this.dataLists.forEach((item) => {
|
||||
if (item.projectID == key) {
|
||||
this.checkboxData.push(item);
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
//选择列表项触发
|
||||
groupChange(n) {
|
||||
this.radioData = this.dataLists.filter((item) => item.projectID === n);
|
||||
},
|
||||
// 滑动到底部触发,用于下拉加载新数据
|
||||
scrolltolower() {
|
||||
if (this.noData != true) {
|
||||
this.pages.page++;
|
||||
this.GetProjectListData();
|
||||
}
|
||||
},
|
||||
// 获取客户弹窗--列表
|
||||
async GetProjectListData() {
|
||||
this.isLoading = true;
|
||||
this.noData = false;
|
||||
let params = {
|
||||
...this.pages,
|
||||
};
|
||||
const res = await GetProjectListData(params);
|
||||
this.isLoading = false;
|
||||
if (this.pages.page > 1) {
|
||||
this.dataLists.push(...res.data[1]);
|
||||
} else {
|
||||
this.dataLists = res.data[1];
|
||||
}
|
||||
if (res.data[1].length < 20) {
|
||||
this.noData = true;
|
||||
}
|
||||
},
|
||||
// 确认按钮点击事件
|
||||
handlerProjectConfirm() {
|
||||
if (this.type == "radio") {
|
||||
if (
|
||||
this.radioData == "" ||
|
||||
this.radioData == undefined ||
|
||||
this.radioData == null
|
||||
) {
|
||||
uni.$u.toast("请选择数据");
|
||||
return;
|
||||
}
|
||||
this.$emit("handlerProjectConfirm", this.radioData);
|
||||
this.$refs.basePopup.isShowPopup = false;
|
||||
this.resetDialog();
|
||||
} else if (this.type == "checkbox") {
|
||||
if (this.checkboxData.length == 0) {
|
||||
uni.$u.toast("请选择数据");
|
||||
return;
|
||||
}
|
||||
this.$emit("handlerProjectConfirm", this.checkboxData);
|
||||
this.$refs.basePopup.isShowPopup = false;
|
||||
this.resetDialog();
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.scroll-Y {
|
||||
height: 680rpx;
|
||||
}
|
||||
.contractNoData .u-divider {
|
||||
margin: 0;
|
||||
}
|
||||
.content {
|
||||
line-height: 1.5;
|
||||
font-size: 28rpx;
|
||||
margin-bottom: 10rpx;
|
||||
|
||||
text {
|
||||
font-size: 28rpx;
|
||||
color: #979797;
|
||||
}
|
||||
}
|
||||
.time {
|
||||
font-size: 28rpx;
|
||||
flex-wrap: wrap;
|
||||
line-height: 1.5;
|
||||
|
||||
text {
|
||||
display: inline-block;
|
||||
font-size: 26rpx;
|
||||
color: #979797;
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
view {
|
||||
height: 48rpx;
|
||||
}
|
||||
view:nth-child(2n + 1) {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
view:nth-child(2n) {
|
||||
width: 50%;
|
||||
}
|
||||
view:nth-child(4) {
|
||||
text:nth-child(2) {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,258 @@
|
|||
<!-- 选择人员组件
|
||||
@desc 单选 弹窗
|
||||
-->
|
||||
<template>
|
||||
<view>
|
||||
<base-popup
|
||||
ref="basePopup"
|
||||
@handleConfirmClick="personConfirmClick"
|
||||
:title="'选择人员'"
|
||||
>
|
||||
<view>
|
||||
<u-collapse>
|
||||
<!-- 手风琴headImageUr1 -->
|
||||
<u-collapse-item
|
||||
v-for="(item, index) in dataList"
|
||||
:key="index"
|
||||
:title="item.o_OrganName"
|
||||
class="department"
|
||||
:name="index"
|
||||
>
|
||||
<u-icon
|
||||
name="star-fill"
|
||||
size="20"
|
||||
slot="icon"
|
||||
:color="color"
|
||||
class="el-icon-star-on star"
|
||||
:class="{ active: item.active }"
|
||||
></u-icon>
|
||||
<u-list :height="'auto'" v-if="item.personList && item.personList.length > 0">
|
||||
<u-list-item
|
||||
v-for="(elItem, elIndex) in item.personList"
|
||||
:key="elIndex"
|
||||
>
|
||||
<u-cell
|
||||
:title="elItem.p_PersonName + ' ' + elItem.p_Telphone"
|
||||
@click="selectPerson(elItem)"
|
||||
>
|
||||
<base-avatar
|
||||
slot="icon"
|
||||
shape="square"
|
||||
size="35"
|
||||
:text="
|
||||
elItem.p_PersonName ? elItem.p_PersonName.slice(-2) : ''
|
||||
"
|
||||
bg-color="#3c9cff"
|
||||
color="#ffffff"
|
||||
font-size="10"
|
||||
:src="elItem.headImageUrl"
|
||||
customStyle="margin: -3px 5px -3px 0"
|
||||
></base-avatar>
|
||||
<u-icon
|
||||
name="checkbox-mark"
|
||||
slot="right-icon"
|
||||
size="20"
|
||||
:color="color"
|
||||
class="el-icon-star-on star"
|
||||
:class="{ active: elItem.p_PersonID == chooseData.p_PersonID }"
|
||||
></u-icon>
|
||||
</u-cell>
|
||||
</u-list-item>
|
||||
</u-list>
|
||||
<view v-else class="empty">暂无数据</view>
|
||||
</u-collapse-item>
|
||||
</u-collapse>
|
||||
<u-toast ref="uToast"></u-toast>
|
||||
</view>
|
||||
</base-popup>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import baseAvatar from "@/components/baseAvatar/index.vue";
|
||||
import basePopup from "@/components/basePopup/index.vue";
|
||||
import { PersonList, GetOrganTree } from "@/api/system/basePerson";
|
||||
import config from "@/config";
|
||||
import { getUserInfo } from "@/utils/auth";
|
||||
export default {
|
||||
components: {
|
||||
basePopup,
|
||||
baseAvatar,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dataList: [],
|
||||
selectedDataList: [],
|
||||
personLoading: false,
|
||||
color: "f0f0f0",
|
||||
configData: {},
|
||||
chooseData: {},
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 打开弹窗
|
||||
openDialog(selectedDataList = [], type) {
|
||||
this.configData = config;
|
||||
this.$refs.basePopup.isShowPopup = true;
|
||||
this.selectedDataList = [];
|
||||
this.getMenuData(selectedDataList);
|
||||
},
|
||||
// 人员确定
|
||||
personConfirmClick() {
|
||||
if (JSON.stringify(this.chooseData) == "{}") {
|
||||
this.$refs.uToast.show({
|
||||
type: "warning",
|
||||
message: "请选择人员!",
|
||||
});
|
||||
return;
|
||||
}
|
||||
this.$emit("personConfirmClick", this.chooseData);
|
||||
this.$refs.basePopup.isShowPopup = false;
|
||||
},
|
||||
// 获得组织图
|
||||
async getMenuData(selectedDataList) {
|
||||
this.personLoading = true;
|
||||
setTimeout(() => {
|
||||
this.personLoading = false;
|
||||
}, 5000);
|
||||
let params = {
|
||||
CompanyID: getUserInfo().companyID,
|
||||
};
|
||||
|
||||
let res = await GetOrganTree(params);
|
||||
let dataList = JSON.parse(res.data[0]);
|
||||
|
||||
let departmentList = [];
|
||||
|
||||
function setDepartmentList(data) {
|
||||
data.forEach((item) => {
|
||||
let arr = {
|
||||
o_OrganName: item.label,
|
||||
personList: [],
|
||||
active: false,
|
||||
};
|
||||
departmentList.push(arr);
|
||||
if (item.children && item.children.length > 0) {
|
||||
setDepartmentList(item.children);
|
||||
}
|
||||
});
|
||||
}
|
||||
setDepartmentList(dataList);
|
||||
this.getPersonList(departmentList, selectedDataList);
|
||||
},
|
||||
// 获得人员列表
|
||||
async getPersonList(departmentList, selectedDataList) {
|
||||
let params = {
|
||||
page: "1",
|
||||
limit: "999",
|
||||
departmentID: "",
|
||||
};
|
||||
let res = await PersonList(params);
|
||||
if (res.code === 1) {
|
||||
departmentList.forEach((el) => {
|
||||
res.data[1].forEach((item) => {
|
||||
if (el.o_OrganName == item.o_OrganName) {
|
||||
let personArr = {
|
||||
o_OrganName: item.o_OrganName,
|
||||
p_PersonName: item.p_PersonName,
|
||||
p_PersonID: item.p_PersonID,
|
||||
p_Telphone: item.p_Telphone,
|
||||
headImageUrl: item.headImageUrl
|
||||
? this.configData.baseUrl +
|
||||
String(item.headImageUrl).split("/wwwroot")[1]
|
||||
: "",
|
||||
active: false,
|
||||
};
|
||||
el.personList.push(personArr);
|
||||
}
|
||||
});
|
||||
});
|
||||
this.dataList = departmentList;
|
||||
this.dataList.forEach((el) => {
|
||||
el.personList.forEach((elItem) => {
|
||||
selectedDataList.forEach((item) => {
|
||||
if (item.p_PersonID == elItem.p_PersonID) {
|
||||
elItem.active = true;
|
||||
this.selectedDataList.push(elItem);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
this.personLoading = false;
|
||||
}
|
||||
},
|
||||
selectPerson(val) {
|
||||
this.chooseData = val;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
$activeColor: var(--bg-color, "#00aaff");
|
||||
|
||||
::v-deep .u-collapse-item__content__text {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
::v-deep .u-list-item.u-list-item- .u-cell .u-line {
|
||||
border-bottom: 0 solid rgb(214, 215, 217) !important;
|
||||
}
|
||||
.empty {
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
color: #919398;
|
||||
padding: 10px 0;
|
||||
}
|
||||
.dataBox {
|
||||
padding: 10rpx 0;
|
||||
border-bottom: 2rpx solid #ccc;
|
||||
min-height: 100rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.personBox {
|
||||
border-radius: 6rpx;
|
||||
text-align: center;
|
||||
background-color: #f0f0f0;
|
||||
color: #817582;
|
||||
padding: 20rpx 0;
|
||||
cursor: pointer;
|
||||
min-width: 200rpx;
|
||||
|
||||
.name {
|
||||
}
|
||||
|
||||
.phone {
|
||||
font-size: 24rpx;
|
||||
margin-top: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.personBox {
|
||||
margin-right: 20rpx;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.personBox.active {
|
||||
color: #fff;
|
||||
background-color: #3c9cff;
|
||||
}
|
||||
|
||||
.department {
|
||||
.el-icon-star-on {
|
||||
color: #f0f0f0;
|
||||
}
|
||||
}
|
||||
|
||||
.el-icon-star-on.active {
|
||||
color: #3c9cff;
|
||||
}
|
||||
|
||||
.personItem {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,62 @@
|
|||
<template>
|
||||
<!-- h5显示导航栏 -->
|
||||
<view>
|
||||
<u-navbar
|
||||
:autoBack="true"
|
||||
:title="pageTitle"
|
||||
:titleStyle="{ fontSize: '16px', fontWeight: '700' }"
|
||||
:leftIcon="leftIcon"
|
||||
v-if="isOther"
|
||||
>
|
||||
</u-navbar>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
pageTitle: {
|
||||
type: String,
|
||||
required: "",
|
||||
},
|
||||
isAuditTitle: {
|
||||
type: String,
|
||||
required: "",
|
||||
},
|
||||
leftIcon: {
|
||||
type: String,
|
||||
required: "arrow-left",
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isOther: false, //H5
|
||||
// 判断当前环境是微信、钉钉
|
||||
isWeChatOrDingTalk: "",
|
||||
// 页面标题
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
currentEnvironment() {
|
||||
// 检测是否在微信或钉钉环境中打开
|
||||
const userAgent = navigator.userAgent.toLowerCase();
|
||||
if (userAgent.indexOf("dingtalk") !== -1) {
|
||||
//钉钉
|
||||
this.$ddFunction.setTitle(this.pageTitle);
|
||||
if (this.isAuditTitle == "external") {
|
||||
this.$ddFunction.setRight();
|
||||
}
|
||||
this.isOther = false;
|
||||
} else if (userAgent.indexOf("micromessenger") !== -1) {
|
||||
//微信
|
||||
this.isOther = true
|
||||
} else {
|
||||
this.isOther = true;
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
|
@ -0,0 +1,208 @@
|
|||
<template>
|
||||
<view>
|
||||
<u-popup :show="show" @close="cancel">
|
||||
<view class="title">{{ popupTitle }}</view>
|
||||
<view style="padding: 20rpx">
|
||||
<u-search
|
||||
v-if="showSearch"
|
||||
@custom="search"
|
||||
@search="search"
|
||||
:placeholder="placeholder"
|
||||
v-model="keyword"
|
||||
></u-search>
|
||||
<u-gap v-if="showSearch" height="15"></u-gap>
|
||||
<scroll-view
|
||||
:scroll-top="scrollTop"
|
||||
scroll-y="true"
|
||||
class="scroll-Y"
|
||||
@scrolltolower="$emit('lower')"
|
||||
>
|
||||
<!--单选-->
|
||||
<u-radio-group
|
||||
v-if="type == 'radio'"
|
||||
:borderBottom="true"
|
||||
iconPlacement="right"
|
||||
placement="column"
|
||||
@change="groupChange"
|
||||
v-model="radioValue"
|
||||
>
|
||||
<u-radio
|
||||
:customStyle="{ marginBottom: '12px' }"
|
||||
v-for="(item, index) in dataLists"
|
||||
:key="index"
|
||||
:label="item[name]"
|
||||
:name="index"
|
||||
>
|
||||
</u-radio>
|
||||
</u-radio-group>
|
||||
|
||||
<!--多选-->
|
||||
<u-checkbox-group
|
||||
v-if="type == 'checkbox'"
|
||||
:borderBottom="true"
|
||||
placement="column"
|
||||
iconPlacement="right"
|
||||
@change="checkboxChange"
|
||||
v-model="checkboxValue"
|
||||
>
|
||||
<u-checkbox
|
||||
:customStyle="{ marginBottom: '12px', paddingBottom: '12px' }"
|
||||
v-for="(item, index) in dataLists"
|
||||
:key="index"
|
||||
:label="item[name]"
|
||||
:name="index"
|
||||
>
|
||||
</u-checkbox>
|
||||
</u-checkbox-group>
|
||||
</scroll-view>
|
||||
<u-gap height="45"></u-gap>
|
||||
<view class="bottons">
|
||||
<u-row>
|
||||
<u-col customStyle="padding:0 10rpx 20rpx 20rpx" span="6">
|
||||
<u-button @click="cancel">取消</u-button>
|
||||
</u-col>
|
||||
<u-col customStyle="padding:0 20rpx 20rpx 10rpx" span="6">
|
||||
<u-button
|
||||
@click="submit"
|
||||
type="primary"
|
||||
throttleTime="1000"
|
||||
:disabled="
|
||||
JSON.stringify(radioData) === '{}' &&
|
||||
checkboxData.length === 0
|
||||
"
|
||||
>确认</u-button
|
||||
>
|
||||
</u-col>
|
||||
</u-row>
|
||||
</view>
|
||||
</view>
|
||||
</u-popup>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/**
|
||||
* 公共选择下拉框,基于uview。支持下拉加载、列表搜索、单选|多选
|
||||
* @author qianziyu
|
||||
* @description 弹出层选择器,基于uview中u-popup实现
|
||||
* @property {Array} dataLists 数据列表
|
||||
* @property {String} name 列表显示的字段名
|
||||
* @property {Boolean} show 是否展示弹窗 (默认 false )
|
||||
* @property {String} type 选择类型 单选|多选 (默认 单选 )
|
||||
* @property {Boolean} showSearch 是否显示搜索框 (默认 true )
|
||||
* @property {String} popupTitle 列表标题
|
||||
* @property {String} placeholder 搜索框placeholder
|
||||
* @event {Function} search 搜索事件,返回keyword
|
||||
* @event {Function} lower 滑动到底部触发,用于下拉加载新数据
|
||||
* @event {Function} cancel 组件关闭事件
|
||||
* @event {Function} submit 提交按钮,返回选中的列表数据
|
||||
* @example <common-select :show="show" :popupTitle="popupTitle" @cancel="show=false" @search="selectSearch" name="cworkStationName" @submit="onsubmit"
|
||||
:dataLists="dataLists" placeholder="输入工站名称搜索"></common-select>
|
||||
*/
|
||||
export default {
|
||||
name: "qianziyu-select",
|
||||
props: {
|
||||
dataLists: {
|
||||
default: {},
|
||||
type: Array,
|
||||
},
|
||||
name: {
|
||||
default: "name",
|
||||
},
|
||||
show: {
|
||||
default: false,
|
||||
type: Boolean,
|
||||
},
|
||||
type: {
|
||||
default: "radio",
|
||||
type: String,
|
||||
},
|
||||
showSearch: {
|
||||
default: true,
|
||||
type: Boolean,
|
||||
},
|
||||
popupTitle: {
|
||||
default: "列表选择",
|
||||
type: String,
|
||||
},
|
||||
placeholder: {
|
||||
default: "请输入搜索内容",
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
keyword: "",
|
||||
scrollTop: 0,
|
||||
checkboxData: [],
|
||||
checkboxValue: [],
|
||||
radioData: {},
|
||||
radioValue: "",
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
checkboxChange(n) {
|
||||
this.checkboxData = [];
|
||||
n.forEach((key) => {
|
||||
this.checkboxData.push(this.dataLists[key]);
|
||||
});
|
||||
},
|
||||
//选择列表项触发
|
||||
groupChange(n) {
|
||||
this.radioData = this.dataLists[n];
|
||||
},
|
||||
//点击搜索触发
|
||||
search() {
|
||||
this.$emit("search", this.keyword);
|
||||
},
|
||||
// 触底刷新事件
|
||||
onReachBottom() {
|
||||
this.$emit("onReachBottom")
|
||||
},
|
||||
//点击取消按钮触发
|
||||
cancel() {
|
||||
this.$emit("cancel");
|
||||
},
|
||||
//提交触发
|
||||
submit() {
|
||||
if (this.type == "radio") {
|
||||
if (JSON.stringify(this.radioData) == "{}") {
|
||||
uni.$u.toast("请选择数据");
|
||||
return;
|
||||
}
|
||||
this.$emit("submit", this.radioData);
|
||||
} else if (this.type == "checkbox") {
|
||||
if (this.checkboxData.length == 0) {
|
||||
uni.$u.toast("请选择数据");
|
||||
return;
|
||||
}
|
||||
this.$emit("submit", this.checkboxData);
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.u-popup {
|
||||
.title {
|
||||
border-bottom: 1px solid #f7f7f7;
|
||||
padding: 20rpx;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.scroll-Y {
|
||||
height: 650rpx;
|
||||
}
|
||||
|
||||
.bottons {
|
||||
background-color: white;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
bottom: constant(safe-area-inset-bottom);
|
||||
bottom: env(safe-area-inset-bottom);
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,167 @@
|
|||
<template>
|
||||
<view class="uni-section">
|
||||
<view class="uni-section-header" @click="onClick">
|
||||
<view class="uni-section-header__decoration" v-if="type" :class="type" />
|
||||
<slot v-else name="decoration"></slot>
|
||||
|
||||
<view class="uni-section-header__content">
|
||||
<text :style="{'font-size':titleFontSize,'color':titleColor}" class="uni-section__content-title" :class="{'distraction':!subTitle}">{{ title }}</text>
|
||||
<text v-if="subTitle" :style="{'font-size':subTitleFontSize,'color':subTitleColor}" class="uni-section-header__content-sub">{{ subTitle }}</text>
|
||||
</view>
|
||||
|
||||
<view class="uni-section-header__slot-right">
|
||||
<slot name="right"></slot>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="uni-section-content" :style="{padding: _padding}">
|
||||
<slot />
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
/**
|
||||
* Section 标题栏
|
||||
* @description 标题栏
|
||||
* @property {String} type = [line|circle|square] 标题装饰类型
|
||||
* @value line 竖线
|
||||
* @value circle 圆形
|
||||
* @value square 正方形
|
||||
* @property {String} title 主标题
|
||||
* @property {String} titleFontSize 主标题字体大小
|
||||
* @property {String} titleColor 主标题字体颜色
|
||||
* @property {String} subTitle 副标题
|
||||
* @property {String} subTitleFontSize 副标题字体大小
|
||||
* @property {String} subTitleColor 副标题字体颜色
|
||||
* @property {String} padding 默认插槽 padding
|
||||
*/
|
||||
|
||||
export default {
|
||||
name: 'UniSection',
|
||||
emits:['click'],
|
||||
props: {
|
||||
type: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
required: true,
|
||||
default: ''
|
||||
},
|
||||
titleFontSize: {
|
||||
type: String,
|
||||
default: '14px'
|
||||
},
|
||||
titleColor:{
|
||||
type: String,
|
||||
default: '#333'
|
||||
},
|
||||
subTitle: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
subTitleFontSize: {
|
||||
type: String,
|
||||
default: '12px'
|
||||
},
|
||||
subTitleColor: {
|
||||
type: String,
|
||||
default: '#999'
|
||||
},
|
||||
padding: {
|
||||
type: [Boolean, String],
|
||||
default: false
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
_padding(){
|
||||
if(typeof this.padding === 'string'){
|
||||
return this.padding
|
||||
}
|
||||
|
||||
return this.padding?'10px':''
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
title(newVal) {
|
||||
if (uni.report && newVal !== '') {
|
||||
uni.report('title', newVal)
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onClick() {
|
||||
this.$emit('click')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" >
|
||||
$uni-primary: #2979ff !default;
|
||||
|
||||
.uni-section {
|
||||
background-color: #fff;
|
||||
.uni-section-header {
|
||||
position: relative;
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
padding: 12px 10px;
|
||||
font-weight: normal;
|
||||
|
||||
&__decoration{
|
||||
margin-right: 6px;
|
||||
background-color: $uni-primary;
|
||||
&.line {
|
||||
width: 4px;
|
||||
height: 12px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
&.circle {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-top-right-radius: 50px;
|
||||
border-top-left-radius: 50px;
|
||||
border-bottom-left-radius: 50px;
|
||||
border-bottom-right-radius: 50px;
|
||||
}
|
||||
|
||||
&.square {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
&__content {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
color: #333;
|
||||
|
||||
.distraction {
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
&-sub {
|
||||
margin-top: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
&__slot-right{
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.uni-section-content{
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,26 @@
|
|||
// 应用全局配置
|
||||
module.exports = {
|
||||
baseUrl: `http://ufidahz.com.cn:9067/`,//正式环境
|
||||
// baseUrl: `http://192.168.2.78:10086/`,//刚子
|
||||
// 应用信息
|
||||
appInfo: {
|
||||
// 应用名称
|
||||
name: "用安数智中台",
|
||||
// 应用版本
|
||||
version: "1.1.0",
|
||||
// 应用logo
|
||||
logo: "/static/logo1.png",
|
||||
// 官方网站
|
||||
site_url: "http://ruoyi.vip",
|
||||
// 政策协议
|
||||
agreements: [{
|
||||
title: "隐私政策",
|
||||
url: "https://ruoyi.vip/protocol.html"
|
||||
},
|
||||
{
|
||||
title: "用户服务协议",
|
||||
url: "https://ruoyi.vip/protocol.html"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
import Vue from 'vue'
|
||||
import App from './App'
|
||||
import store from './store' // store
|
||||
import plugins from './plugins' // plugins
|
||||
import './permission' // permission
|
||||
Vue.use(plugins)
|
||||
|
||||
import uView from '@/uni_modules/uview-ui'
|
||||
Vue.use(uView)
|
||||
|
||||
import * as whole from '@/utils/common.js'
|
||||
Vue.prototype.$whole = whole
|
||||
|
||||
import * as utilDD from '@/utils/dd.js'
|
||||
Vue.prototype.$ddFunction = utilDD
|
||||
|
||||
Vue.config.productionTip = false
|
||||
Vue.prototype.$store = store
|
||||
|
||||
App.mpType = 'app'
|
||||
|
||||
const app = new Vue({
|
||||
...App
|
||||
})
|
||||
|
||||
app.$mount()
|
|
@ -0,0 +1,78 @@
|
|||
{
|
||||
"name" : "用安数智中台移动端",
|
||||
"appid" : "__UNI__A6D00FF",
|
||||
"description" : "",
|
||||
"versionName" : "1.1.0",
|
||||
"versionCode" : "100",
|
||||
"transformPx" : false,
|
||||
"app-plus" : {
|
||||
"usingComponents" : true,
|
||||
"nvueCompiler" : "uni-app",
|
||||
"splashscreen" : {
|
||||
"alwaysShowBeforeRender" : true,
|
||||
"waiting" : true,
|
||||
"autoclose" : true,
|
||||
"delay" : 0
|
||||
},
|
||||
"modules" : {
|
||||
"OAuth" : {}
|
||||
},
|
||||
"distribute" : {
|
||||
"android" : {
|
||||
"permissions" : [
|
||||
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
|
||||
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
|
||||
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
|
||||
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
|
||||
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
|
||||
"<uses-feature android:name=\"android.hardware.camera\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
|
||||
]
|
||||
},
|
||||
"ios" : {},
|
||||
"sdkConfigs" : {
|
||||
"oauth" : {
|
||||
"weixin" : {
|
||||
"appid" : "wwb46c3f5e6ffe3e2b",
|
||||
"UniversalLinks" : ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"quickapp" : {},
|
||||
"mp-weixin" : {
|
||||
"appid" : "wx7dff96a8822ea082",
|
||||
"setting" : {
|
||||
"urlCheck" : false,
|
||||
"es6" : false,
|
||||
"minified" : true,
|
||||
"postcss" : true
|
||||
},
|
||||
"optimization" : {
|
||||
"subPackages" : true
|
||||
},
|
||||
"usingComponents" : true
|
||||
},
|
||||
"vueVersion" : "2",
|
||||
"h5" : {
|
||||
"template" : "static/index.html",
|
||||
"devServer" : {
|
||||
"port" : 9090,
|
||||
"https" : false
|
||||
},
|
||||
"title" : "用安数智中台",
|
||||
"router" : {
|
||||
"mode" : "hash",
|
||||
"base" : "./"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,319 @@
|
|||
{
|
||||
"name": "middleground_H5",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"dependencies": {
|
||||
"@fullcalendar/daygrid": "^6.1.8",
|
||||
"@fullcalendar/interaction": "^6.1.8",
|
||||
"@fullcalendar/list": "^6.1.8",
|
||||
"@fullcalendar/timegrid": "^6.1.8",
|
||||
"@fullcalendar/vue": "^6.1.8",
|
||||
"dingtalk-jsapi": "^3.0.25",
|
||||
"eruda": "^3.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/parser": {
|
||||
"version": "7.22.16",
|
||||
"resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.22.16.tgz",
|
||||
"integrity": "sha512-+gPfKv8UWeKKeJTUxe59+OobVcrYHETCsORl61EmSkmgymguYk/X5bp7GuUIXaFsc6y++v8ZxPsLSSuujqDphA==",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"parser": "bin/babel-parser.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@fullcalendar/core": {
|
||||
"version": "6.1.8",
|
||||
"resolved": "https://registry.npmmirror.com/@fullcalendar/core/-/core-6.1.8.tgz",
|
||||
"integrity": "sha512-i8JBIvZCWGO9dsMEDcx9bnsQZ9PtGSJdOXGgWbhLaGq2iq41OBdp9g9gM4b/Otv2oK8bL5Gl6CsMmb/HkDtA6Q==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"preact": "~10.12.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@fullcalendar/daygrid": {
|
||||
"version": "6.1.8",
|
||||
"resolved": "https://registry.npmmirror.com/@fullcalendar/daygrid/-/daygrid-6.1.8.tgz",
|
||||
"integrity": "sha512-kCZxQFKb9Vqa3CZRX0v7rMSJ2mlTt4gDpyLfiNJKxUAq7W51uKurPaFZWicaXy1ESHVBxKNlbx5uNjBpyu50JQ==",
|
||||
"peerDependencies": {
|
||||
"@fullcalendar/core": "~6.1.8"
|
||||
}
|
||||
},
|
||||
"node_modules/@fullcalendar/interaction": {
|
||||
"version": "6.1.8",
|
||||
"resolved": "https://registry.npmmirror.com/@fullcalendar/interaction/-/interaction-6.1.8.tgz",
|
||||
"integrity": "sha512-r6W4E9ohaA87M2uPSlmpE2WT7Fzu7LN0u2pE6D/tThruCEaAPbN8Pw5+sqclsuyTIL09mg0eSJm/ggJekTabSA==",
|
||||
"peerDependencies": {
|
||||
"@fullcalendar/core": "~6.1.8"
|
||||
}
|
||||
},
|
||||
"node_modules/@fullcalendar/list": {
|
||||
"version": "6.1.8",
|
||||
"resolved": "https://registry.npmmirror.com/@fullcalendar/list/-/list-6.1.8.tgz",
|
||||
"integrity": "sha512-10N0T/vCtId1cE3JGLpnbAivWVnaWCCkVO7wmbsyr5Y+I939kr/zq4BUNwBoP/xSFVVxx59FETh3iyA+MkV8Fw==",
|
||||
"peerDependencies": {
|
||||
"@fullcalendar/core": "~6.1.8"
|
||||
}
|
||||
},
|
||||
"node_modules/@fullcalendar/timegrid": {
|
||||
"version": "6.1.8",
|
||||
"resolved": "https://registry.npmmirror.com/@fullcalendar/timegrid/-/timegrid-6.1.8.tgz",
|
||||
"integrity": "sha512-3+3KHHCoNcaLs/gQt004hAqICbY5+WAffrZ0ePv+80HFB1OVh8BQ5XXLHSOUbTvXdgtUTcfBHuw9fhO31kt5gA==",
|
||||
"dependencies": {
|
||||
"@fullcalendar/daygrid": "~6.1.8"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@fullcalendar/core": "~6.1.8"
|
||||
}
|
||||
},
|
||||
"node_modules/@fullcalendar/vue": {
|
||||
"version": "6.1.8",
|
||||
"resolved": "https://registry.npmmirror.com/@fullcalendar/vue/-/vue-6.1.8.tgz",
|
||||
"integrity": "sha512-rCfmpwsNkMQhhNiSGt2ZVW0yNmFyXC6O5dto+Rsj3MsJDVXAjI9pR2KRtg1vBh/6hgp8vHcMFcSCJZxIqfui+A==",
|
||||
"peerDependencies": {
|
||||
"@fullcalendar/core": "~6.1.8",
|
||||
"vue": "^2.6.12"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/compiler-sfc": {
|
||||
"version": "2.7.14",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-2.7.14.tgz",
|
||||
"integrity": "sha512-aNmNHyLPsw+sVvlQFQ2/8sjNuLtK54TC6cuKnVzAY93ks4ZBrvwQSnkkIh7bsbNhum5hJBS00wSDipQ937f5DA==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/parser": "^7.18.4",
|
||||
"postcss": "^8.4.14",
|
||||
"source-map": "^0.6.1"
|
||||
}
|
||||
},
|
||||
"node_modules/csstype": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.1.2.tgz",
|
||||
"integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/dingtalk-jsapi": {
|
||||
"version": "3.0.25",
|
||||
"resolved": "https://registry.npmmirror.com/dingtalk-jsapi/-/dingtalk-jsapi-3.0.25.tgz",
|
||||
"integrity": "sha512-l+q2lRzTCH/00DM2EZ+GKFiP/3TZHOupCM7rpG/hgrNpYkexGvF/O6yDI0XNqSMs8iFqWv9haCLOPf1nvCqB/w==",
|
||||
"dependencies": {
|
||||
"promise-polyfill": "^7.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/eruda": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/eruda/-/eruda-3.0.1.tgz",
|
||||
"integrity": "sha512-6q1Xdwga4JTr1mKSW4mzuWSSbmXgqpm/8Wa1QGFGfCWRjC0bCQjbS4u06M1te1moucIS3hBLlbSTPWYH2W0qbQ=="
|
||||
},
|
||||
"node_modules/nanoid": {
|
||||
"version": "3.3.6",
|
||||
"resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.6.tgz",
|
||||
"integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"nanoid": "bin/nanoid.cjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/picocolors": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.0.0.tgz",
|
||||
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/postcss": {
|
||||
"version": "8.4.30",
|
||||
"resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.4.30.tgz",
|
||||
"integrity": "sha512-7ZEao1g4kd68l97aWG/etQKPKq07us0ieSZ2TnFDk11i0ZfDW2AwKHYU8qv4MZKqN2fdBfg+7q0ES06UA73C1g==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"nanoid": "^3.3.6",
|
||||
"picocolors": "^1.0.0",
|
||||
"source-map-js": "^1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^10 || ^12 || >=14"
|
||||
}
|
||||
},
|
||||
"node_modules/preact": {
|
||||
"version": "10.12.1",
|
||||
"resolved": "https://registry.npmmirror.com/preact/-/preact-10.12.1.tgz",
|
||||
"integrity": "sha512-l8386ixSsBdbreOAkqtrwqHwdvR35ID8c3rKPa8lCWuO86dBi32QWHV4vfsZK1utLLFMvw+Z5Ad4XLkZzchscg==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/promise-polyfill": {
|
||||
"version": "7.1.2",
|
||||
"resolved": "https://registry.npmmirror.com/promise-polyfill/-/promise-polyfill-7.1.2.tgz",
|
||||
"integrity": "sha512-FuEc12/eKqqoRYIGBrUptCBRhobL19PS2U31vMNTfyck1FxPyMfgsXyW4Mav85y/ZN1hop3hOwRlUDok23oYfQ=="
|
||||
},
|
||||
"node_modules/source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/source-map-js": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.0.2.tgz",
|
||||
"integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vue": {
|
||||
"version": "2.7.14",
|
||||
"resolved": "https://registry.npmmirror.com/vue/-/vue-2.7.14.tgz",
|
||||
"integrity": "sha512-b2qkFyOM0kwqWFuQmgd4o+uHGU7T+2z3T+WQp8UBjADfEv2n4FEMffzBmCKNP0IGzOEEfYjvtcC62xaSKeQDrQ==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@vue/compiler-sfc": "2.7.14",
|
||||
"csstype": "^3.1.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/parser": {
|
||||
"version": "7.22.16",
|
||||
"resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.22.16.tgz",
|
||||
"integrity": "sha512-+gPfKv8UWeKKeJTUxe59+OobVcrYHETCsORl61EmSkmgymguYk/X5bp7GuUIXaFsc6y++v8ZxPsLSSuujqDphA==",
|
||||
"peer": true
|
||||
},
|
||||
"@fullcalendar/core": {
|
||||
"version": "6.1.8",
|
||||
"resolved": "https://registry.npmmirror.com/@fullcalendar/core/-/core-6.1.8.tgz",
|
||||
"integrity": "sha512-i8JBIvZCWGO9dsMEDcx9bnsQZ9PtGSJdOXGgWbhLaGq2iq41OBdp9g9gM4b/Otv2oK8bL5Gl6CsMmb/HkDtA6Q==",
|
||||
"peer": true,
|
||||
"requires": {
|
||||
"preact": "~10.12.1"
|
||||
}
|
||||
},
|
||||
"@fullcalendar/daygrid": {
|
||||
"version": "6.1.8",
|
||||
"resolved": "https://registry.npmmirror.com/@fullcalendar/daygrid/-/daygrid-6.1.8.tgz",
|
||||
"integrity": "sha512-kCZxQFKb9Vqa3CZRX0v7rMSJ2mlTt4gDpyLfiNJKxUAq7W51uKurPaFZWicaXy1ESHVBxKNlbx5uNjBpyu50JQ==",
|
||||
"requires": {}
|
||||
},
|
||||
"@fullcalendar/interaction": {
|
||||
"version": "6.1.8",
|
||||
"resolved": "https://registry.npmmirror.com/@fullcalendar/interaction/-/interaction-6.1.8.tgz",
|
||||
"integrity": "sha512-r6W4E9ohaA87M2uPSlmpE2WT7Fzu7LN0u2pE6D/tThruCEaAPbN8Pw5+sqclsuyTIL09mg0eSJm/ggJekTabSA==",
|
||||
"requires": {}
|
||||
},
|
||||
"@fullcalendar/list": {
|
||||
"version": "6.1.8",
|
||||
"resolved": "https://registry.npmmirror.com/@fullcalendar/list/-/list-6.1.8.tgz",
|
||||
"integrity": "sha512-10N0T/vCtId1cE3JGLpnbAivWVnaWCCkVO7wmbsyr5Y+I939kr/zq4BUNwBoP/xSFVVxx59FETh3iyA+MkV8Fw==",
|
||||
"requires": {}
|
||||
},
|
||||
"@fullcalendar/timegrid": {
|
||||
"version": "6.1.8",
|
||||
"resolved": "https://registry.npmmirror.com/@fullcalendar/timegrid/-/timegrid-6.1.8.tgz",
|
||||
"integrity": "sha512-3+3KHHCoNcaLs/gQt004hAqICbY5+WAffrZ0ePv+80HFB1OVh8BQ5XXLHSOUbTvXdgtUTcfBHuw9fhO31kt5gA==",
|
||||
"requires": {
|
||||
"@fullcalendar/daygrid": "~6.1.8"
|
||||
}
|
||||
},
|
||||
"@fullcalendar/vue": {
|
||||
"version": "6.1.8",
|
||||
"resolved": "https://registry.npmmirror.com/@fullcalendar/vue/-/vue-6.1.8.tgz",
|
||||
"integrity": "sha512-rCfmpwsNkMQhhNiSGt2ZVW0yNmFyXC6O5dto+Rsj3MsJDVXAjI9pR2KRtg1vBh/6hgp8vHcMFcSCJZxIqfui+A==",
|
||||
"requires": {}
|
||||
},
|
||||
"@vue/compiler-sfc": {
|
||||
"version": "2.7.14",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-2.7.14.tgz",
|
||||
"integrity": "sha512-aNmNHyLPsw+sVvlQFQ2/8sjNuLtK54TC6cuKnVzAY93ks4ZBrvwQSnkkIh7bsbNhum5hJBS00wSDipQ937f5DA==",
|
||||
"peer": true,
|
||||
"requires": {
|
||||
"@babel/parser": "^7.18.4",
|
||||
"postcss": "^8.4.14",
|
||||
"source-map": "^0.6.1"
|
||||
}
|
||||
},
|
||||
"csstype": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.1.2.tgz",
|
||||
"integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==",
|
||||
"peer": true
|
||||
},
|
||||
"dingtalk-jsapi": {
|
||||
"version": "3.0.25",
|
||||
"resolved": "https://registry.npmmirror.com/dingtalk-jsapi/-/dingtalk-jsapi-3.0.25.tgz",
|
||||
"integrity": "sha512-l+q2lRzTCH/00DM2EZ+GKFiP/3TZHOupCM7rpG/hgrNpYkexGvF/O6yDI0XNqSMs8iFqWv9haCLOPf1nvCqB/w==",
|
||||
"requires": {
|
||||
"promise-polyfill": "^7.1.0"
|
||||
}
|
||||
},
|
||||
"eruda": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/eruda/-/eruda-3.0.1.tgz",
|
||||
"integrity": "sha512-6q1Xdwga4JTr1mKSW4mzuWSSbmXgqpm/8Wa1QGFGfCWRjC0bCQjbS4u06M1te1moucIS3hBLlbSTPWYH2W0qbQ=="
|
||||
},
|
||||
"nanoid": {
|
||||
"version": "3.3.6",
|
||||
"resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.6.tgz",
|
||||
"integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
|
||||
"peer": true
|
||||
},
|
||||
"picocolors": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.0.0.tgz",
|
||||
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
|
||||
"peer": true
|
||||
},
|
||||
"postcss": {
|
||||
"version": "8.4.30",
|
||||
"resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.4.30.tgz",
|
||||
"integrity": "sha512-7ZEao1g4kd68l97aWG/etQKPKq07us0ieSZ2TnFDk11i0ZfDW2AwKHYU8qv4MZKqN2fdBfg+7q0ES06UA73C1g==",
|
||||
"peer": true,
|
||||
"requires": {
|
||||
"nanoid": "^3.3.6",
|
||||
"picocolors": "^1.0.0",
|
||||
"source-map-js": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"preact": {
|
||||
"version": "10.12.1",
|
||||
"resolved": "https://registry.npmmirror.com/preact/-/preact-10.12.1.tgz",
|
||||
"integrity": "sha512-l8386ixSsBdbreOAkqtrwqHwdvR35ID8c3rKPa8lCWuO86dBi32QWHV4vfsZK1utLLFMvw+Z5Ad4XLkZzchscg==",
|
||||
"peer": true
|
||||
},
|
||||
"promise-polyfill": {
|
||||
"version": "7.1.2",
|
||||
"resolved": "https://registry.npmmirror.com/promise-polyfill/-/promise-polyfill-7.1.2.tgz",
|
||||
"integrity": "sha512-FuEc12/eKqqoRYIGBrUptCBRhobL19PS2U31vMNTfyck1FxPyMfgsXyW4Mav85y/ZN1hop3hOwRlUDok23oYfQ=="
|
||||
},
|
||||
"source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
||||
"peer": true
|
||||
},
|
||||
"source-map-js": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.0.2.tgz",
|
||||
"integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
|
||||
"peer": true
|
||||
},
|
||||
"vue": {
|
||||
"version": "2.7.14",
|
||||
"resolved": "https://registry.npmmirror.com/vue/-/vue-2.7.14.tgz",
|
||||
"integrity": "sha512-b2qkFyOM0kwqWFuQmgd4o+uHGU7T+2z3T+WQp8UBjADfEv2n4FEMffzBmCKNP0IGzOEEfYjvtcC62xaSKeQDrQ==",
|
||||
"peer": true,
|
||||
"requires": {
|
||||
"@vue/compiler-sfc": "2.7.14",
|
||||
"csstype": "^3.1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"dependencies": {
|
||||
"@fullcalendar/daygrid": "^6.1.8",
|
||||
"@fullcalendar/interaction": "^6.1.8",
|
||||
"@fullcalendar/list": "^6.1.8",
|
||||
"@fullcalendar/timegrid": "^6.1.8",
|
||||
"@fullcalendar/vue": "^6.1.8",
|
||||
"dingtalk-jsapi": "^3.0.25",
|
||||
"eruda": "^3.0.1"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,148 @@
|
|||
{
|
||||
"pages": [
|
||||
{
|
||||
"path": "pages/login",
|
||||
"style": {
|
||||
"navigationBarTitleText": "登录",
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/homePage/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "工作台",
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "components/basePeople/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "选择人员",
|
||||
"onReachBottomDistance": 50,
|
||||
// "enablePullDownRefresh": true,
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/logsError/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "异常日志",
|
||||
"onReachBottomDistance": 50,
|
||||
"enablePullDownRefresh": true,
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/logsError/details",
|
||||
"style": {
|
||||
"navigationBarTitleText": "处理异常日志",
|
||||
"onReachBottomDistance": 50,
|
||||
// "enablePullDownRefresh": true,
|
||||
"navigationStyle": "custom",
|
||||
"app-plus":{
|
||||
"bounce":"none"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/logsError/show",
|
||||
"style": {
|
||||
"navigationBarTitleText": "查看异常日志",
|
||||
"onReachBottomDistance": 50,
|
||||
// "enablePullDownRefresh": true,
|
||||
"navigationStyle": "custom",
|
||||
"app-plus":{
|
||||
"bounce":"none"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/loginAuthen/authenDingDing",
|
||||
"style": {
|
||||
"navigationBarTitleText": "钉钉免登录认证",
|
||||
"onReachBottomDistance": 50,
|
||||
"enablePullDownRefresh": true,
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/loginAuthen/loginDingDing",
|
||||
"style": {
|
||||
"navigationBarTitleText": "钉钉免登录认证",
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/loginAuthen/selectCompany",
|
||||
"style": {
|
||||
"navigationBarTitleText": "钉钉免登录认证",
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/loginAuthen/authenWeChat",
|
||||
"style": {
|
||||
"navigationBarTitleText": "微信免登录认证",
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/loginAuthen/authenDingDingAudit",
|
||||
"style": {
|
||||
"navigationBarTitleText": "钉钉免登录认证",
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/loginAuthen/loginWeChat",
|
||||
"style": {
|
||||
"navigationBarTitleText": "微信免登录认证",
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tabBar": {
|
||||
"color": "#000000",
|
||||
"selectedColor": "#000000",
|
||||
"borderStyle": "white",
|
||||
"backgroundColor": "#ffffff",
|
||||
"list": [
|
||||
{
|
||||
"pagePath": "pages/homePage/index",
|
||||
"iconPath": "static/images/tabbar/staging.png",
|
||||
"selectedIconPath": "static/images/tabbar/staging_.png",
|
||||
"text": "工作台"
|
||||
}
|
||||
]
|
||||
},
|
||||
"globalStyle": {
|
||||
"navigationBarTextStyle": "black",
|
||||
"navigationBarTitleText": "RuoYi",
|
||||
"navigationBarBackgroundColor": "#FFFFFF",
|
||||
"usingComponents": {
|
||||
// "van-button": "/wxcomponents/vant/button/index",
|
||||
// "van-checkbox": "/wxcomponents/vant/checkbox/index",
|
||||
// "van-checkbox-group": "/wxcomponents/vant/checkbox-group/index",
|
||||
// "van-nav-bar": "/wxcomponents/vant/nav-bar/index"
|
||||
// "van-action-sheet": "/wxcomponents/vant/action-sheet/index",
|
||||
// "van-overlay": "/wxcomponents/vant/overlay/index",
|
||||
// "van-popup": "/wxcomponents/vant/popup/index"
|
||||
}
|
||||
},
|
||||
"easycom": {
|
||||
"autoscan": true,
|
||||
"custom": {
|
||||
"^u-(.*)": "@/uni_modules/uview-ui/components/u-$1/u-$1.vue"
|
||||
}
|
||||
},
|
||||
"condition" : { //模式配置,仅开发期间生效
|
||||
"current": 0, //当前激活的模式(list 的索引项)
|
||||
"list": [
|
||||
{
|
||||
"name": "", //模式名称
|
||||
"path": "", //启动页面,必选
|
||||
"query": "" //启动参数,在页面的onLoad函数里面得到
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,154 @@
|
|||
<template>
|
||||
<view
|
||||
class="container"
|
||||
:style="{ marginTop: tarbarHeight }"
|
||||
style="padding-bottom: 200rpx"
|
||||
>
|
||||
<view v-for="(item, index) in errList" :key="index" class="planBox">
|
||||
<div class="errItem" @click="logDetails(item)">
|
||||
<div class="img">
|
||||
<img
|
||||
:src="require('@/static/images/defaultIcon.png')"
|
||||
alt=""
|
||||
@error="handleImageError(item)"
|
||||
/>
|
||||
</div>
|
||||
<div class="title">
|
||||
<u--text
|
||||
:lines="1"
|
||||
:text="item.name"
|
||||
:size="14"
|
||||
:align="'right'"
|
||||
></u--text>
|
||||
<u--text
|
||||
:lines="1"
|
||||
:text="item.num"
|
||||
:bold="true"
|
||||
:align="'right'"
|
||||
:margin="'5px 0'"
|
||||
:size="16"
|
||||
></u--text>
|
||||
</div>
|
||||
</div>
|
||||
</view>
|
||||
<base-tarbar ref="baseTarbar" :pageTitle="'工作台'" :leftIcon="' '"></base-tarbar>
|
||||
<u-empty
|
||||
v-show="noData"
|
||||
mode="data"
|
||||
:icon="require('@/static/images/empty.png')"
|
||||
>
|
||||
</u-empty>
|
||||
<u-toast ref="uToast"></u-toast>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import baseTarbar from "@/components/baseTarbar/index.vue";
|
||||
import { authApi } from "@/api/login";
|
||||
import request from "@/utils/request";
|
||||
export default {
|
||||
components: {
|
||||
baseTarbar,
|
||||
},
|
||||
onReady() {
|
||||
this.$refs.baseTarbar.currentEnvironment();
|
||||
if (this.$refs.baseTarbar.isOther) {
|
||||
this.tarbarHeight = "88rpx";
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tarbarHeight: "0",
|
||||
errList: [],
|
||||
noData: false,
|
||||
msgType: "warn",
|
||||
};
|
||||
},
|
||||
onShow() {},
|
||||
mounted() {
|
||||
this.getErrorLogs();
|
||||
},
|
||||
methods: {
|
||||
logDetails(row) {
|
||||
this.$tab.navigateTo("/pages/logsError/index?appId=" + row.appId);
|
||||
},
|
||||
// 异常日志
|
||||
async getErrorLogs() {
|
||||
const res = await authApi("homeService", "app", "appErrorNum", "", {});
|
||||
if (res.status === "200") {
|
||||
this.errList = [];
|
||||
//图片处理
|
||||
this.imgHandle(res.attribute);
|
||||
this.errList = res.attribute;
|
||||
console.log(this.errList, "异常日志");
|
||||
}
|
||||
},
|
||||
//图片处理
|
||||
imgHandle(arr = []) {
|
||||
arr.map((el) => {
|
||||
return request({
|
||||
url:
|
||||
"kangarooDataCenterV3/entranceController/fileDownloadNew?id=" +
|
||||
el.path,
|
||||
method: "get",
|
||||
responseType: "arraybuffer",
|
||||
}).then((res) => {
|
||||
let tempImgUrl =
|
||||
"data:image/png/jpg;base64," +
|
||||
btoa(
|
||||
new Uint8Array(res).reduce(
|
||||
(data, byte) => data + String.fromCharCode(byte),
|
||||
""
|
||||
)
|
||||
);
|
||||
if (el.path) {
|
||||
this.$set(el, "imgUrl", tempImgUrl);
|
||||
} else {
|
||||
this.$set(el, "imgUrl", null);
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
//图片发生错误时 使用默认图片
|
||||
handleImageError(row = {}) {
|
||||
console.log("ksksksk");
|
||||
row.imgUrl = require("@/static/images/defaultIcon.png");
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.container {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr); /* 创建两列,每列占 1fr */
|
||||
gap: 10px; /* 可以设置列与列之间的间距 */
|
||||
padding: 15px 10px;
|
||||
}
|
||||
.planBox {
|
||||
background: #fff;
|
||||
border-radius: 12px;
|
||||
}
|
||||
.title {
|
||||
margin-left: 10px;
|
||||
width: calc(100% - 58px);
|
||||
}
|
||||
.errItem {
|
||||
padding: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.img {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style scoped>
|
||||
page {
|
||||
height: 100vh;
|
||||
background: #f3f4f6;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,234 @@
|
|||
<template>
|
||||
<view class="normal-login-container">
|
||||
<view class="logo-content">
|
||||
<image
|
||||
style="
|
||||
width: 330rpx;
|
||||
background: #c73b26;
|
||||
border-radius: 10px;
|
||||
padding: 15px;
|
||||
"
|
||||
:src="globalConfig.appInfo.logo"
|
||||
mode="widthFix"
|
||||
></image>
|
||||
</view>
|
||||
<view class="login-form-content">
|
||||
<view class="input-item flex align-center">
|
||||
<u-icon name="account" class="icon" size="20"></u-icon>
|
||||
<input
|
||||
v-model="loginForm.username"
|
||||
class="input"
|
||||
type="text"
|
||||
placeholder="请输入账号"
|
||||
maxlength="30"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<view class="input-item flex align-center">
|
||||
<u-icon name="lock" class="icon" size="20"></u-icon>
|
||||
<input
|
||||
v-model="loginForm.password"
|
||||
type="password"
|
||||
class="input"
|
||||
placeholder="请输入密码"
|
||||
maxlength="30"
|
||||
@confirm="handleLogin"
|
||||
/>
|
||||
</view>
|
||||
<view class="flex">
|
||||
<u-checkbox-group v-model="checkboxValue1">
|
||||
<u-checkbox
|
||||
v-for="(item, index) in checkboxList1"
|
||||
:key="index"
|
||||
:label="item.name"
|
||||
:name="item.key"
|
||||
></u-checkbox>
|
||||
</u-checkbox-group>
|
||||
</view>
|
||||
<view class="action-btn">
|
||||
<button
|
||||
@click="handleLogin"
|
||||
class="login-btn cu-btn block bg-blue lg round"
|
||||
>
|
||||
登录
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getCodeImg } from "@/api/login";
|
||||
import localStorage from "@/utils/localStorage";
|
||||
import { getUserInfo, setUserInfo } from "@/utils/auth";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
codeUrl: "",
|
||||
captchaEnabled: true,
|
||||
globalConfig: getApp().globalData.config,
|
||||
loginForm: {
|
||||
username: "",
|
||||
password: "",
|
||||
},
|
||||
checkboxList1: [
|
||||
{
|
||||
name: "记住密码",
|
||||
key: 1,
|
||||
},
|
||||
],
|
||||
checkboxValue1: [],
|
||||
selectCompany: false,
|
||||
companyList: [], //公司账套
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getData();
|
||||
},
|
||||
methods: {
|
||||
getData() {
|
||||
let data = localStorage.get("middleGroundNumber");
|
||||
if (data != "") {
|
||||
this.checkboxValue1 = [1];
|
||||
this.loginForm.username = data.username;
|
||||
this.loginForm.password = data.password;
|
||||
}
|
||||
let item = localStorage.get("automaticLogon");
|
||||
if (item != "") {
|
||||
this.checkboxValue1 = [1];
|
||||
this.handleLogin();
|
||||
}
|
||||
},
|
||||
// 登录方法
|
||||
async handleLogin() {
|
||||
if (this.loginForm.username === "") {
|
||||
this.$modal.msgError("请输入您的账号");
|
||||
} else if (this.loginForm.password === "") {
|
||||
this.$modal.msgError("请输入您的密码");
|
||||
} else {
|
||||
this.$modal.loading("登录中,请耐心等待...");
|
||||
if (this.checkboxValue1.includes(1)) {
|
||||
localStorage.set("middleGroundNumber", this.loginForm);
|
||||
} else {
|
||||
localStorage.remove("middleGroundNumber");
|
||||
}
|
||||
this.pwdLogin();
|
||||
}
|
||||
},
|
||||
// 密码登录
|
||||
async pwdLogin() {
|
||||
this.$store
|
||||
.dispatch("Login", this.loginForm)
|
||||
.then(() => {
|
||||
this.$modal.closeLoading();
|
||||
uni.switchTab({
|
||||
url: "/pages/homePage/index",
|
||||
});
|
||||
})
|
||||
.catch(() => {});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
page {
|
||||
background-color: #ffffff;
|
||||
}
|
||||
.comBtnBox {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
.comBtn {
|
||||
border: 2rpx solid #f1f1f1;
|
||||
padding: 20rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: 80%;
|
||||
border-radius: 6rpx;
|
||||
margin: 16rpx 0;
|
||||
color: #606266;
|
||||
}
|
||||
.comBtnTitle {
|
||||
width: 100%;
|
||||
font-size: 32rpx;
|
||||
color: #666;
|
||||
text-align: center;
|
||||
margin: 20rpx 0 20rpx 0;
|
||||
}
|
||||
.comBtnText {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
margin: 0 20rpx 0 0;
|
||||
}
|
||||
.normal-login-container {
|
||||
width: 100%;
|
||||
|
||||
.logo-content {
|
||||
width: 100%;
|
||||
font-size: 25px;
|
||||
text-align: center;
|
||||
padding-top: 15%;
|
||||
|
||||
image {
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-left: 10px;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.login-form-content {
|
||||
text-align: center;
|
||||
margin: 20px auto;
|
||||
margin-top: 15%;
|
||||
width: 80%;
|
||||
|
||||
.input-item {
|
||||
margin: 20px auto;
|
||||
background-color: #f5f6f7;
|
||||
height: 45px;
|
||||
border-radius: 20px;
|
||||
padding-left: 20rpx;
|
||||
|
||||
.input {
|
||||
width: 100%;
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
text-align: left;
|
||||
padding-left: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
.login-btn {
|
||||
margin-top: 40px;
|
||||
height: 45px;
|
||||
}
|
||||
|
||||
.xieyi {
|
||||
color: #333;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.login-code {
|
||||
height: 38px;
|
||||
float: right;
|
||||
|
||||
.login-code-img {
|
||||
height: 38px;
|
||||
position: absolute;
|
||||
margin-left: 10px;
|
||||
width: 200rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
::v-deep .u-checkbox-label--left {
|
||||
margin-right: 40rpx;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,132 @@
|
|||
<template>
|
||||
<view class="login">
|
||||
<div class="title">
|
||||
<view class="logo-content">
|
||||
<img :src="globalConfig" alt="" class="logo" style="width: 250rpx" />
|
||||
</view>
|
||||
<span class="text">钉钉登录认证中...</span>
|
||||
</div>
|
||||
<u-toast ref="uToast"></u-toast>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as dd from "dingtalk-jsapi";
|
||||
import { authApi } from "@/api/login";
|
||||
import logo from "@/static/logo1.png";
|
||||
import localStorage from "@/utils/localStorage";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
globalConfig: logo,
|
||||
};
|
||||
},
|
||||
onReady() {
|
||||
this.$ddFunction.setTitle("钉钉免登录认证");
|
||||
},
|
||||
onShow() {
|
||||
const currentUrl = document.location.toString();
|
||||
//解析url中包含的corpId
|
||||
const corpId = currentUrl.split("corpid=")[1];
|
||||
if (corpId == "" || corpId == null || corpId == undefined) {
|
||||
this.$modal.showToast("企业id获取失败, 请使用钉钉手机端登录或重新加载");
|
||||
} else {
|
||||
this.$store.commit("SET_DINGCROPID", corpId);
|
||||
this.dingtalkLogin(corpId);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
dingtalkLogin(corpId) {
|
||||
let that = this;
|
||||
if (dd.env.platform !== "notInDingTalk") {
|
||||
dd.ready(() => {
|
||||
//使用SDK 获取免登授权码
|
||||
dd.runtime.permission.requestAuthCode({
|
||||
corpId: corpId,
|
||||
onSuccess: function (result) {
|
||||
let code = result.code;
|
||||
that.loginDDSSO(code);
|
||||
},
|
||||
onFail: (err) => {
|
||||
console.info("获取个人信息异常,请稍后重试!", err);
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
async loginDDSSO(code) {
|
||||
let params = {
|
||||
code: code,
|
||||
appType: "DD", //移动端类型
|
||||
appId: "800043", //请求的APIID 默认
|
||||
apiCode: "8000430000", //请求的API编码 默认
|
||||
userApiCode: "8000430004", //请求认证的API编码 默认
|
||||
};
|
||||
let res = await authApi("loginService", "", "appDoLogin", "", params);
|
||||
if (res.status === "200") {
|
||||
localStorage.set("MIDDLEGROUND-TOKEN", res.attribute.token);
|
||||
localStorage.set("MIDDLEGROUND-USERINFO", res.attribute.userInfo);
|
||||
uni.switchTab({
|
||||
url: "/pages/homePage/index",
|
||||
});
|
||||
} else if (res.status == "1005") {
|
||||
if (
|
||||
res.attribute.userid == "" ||
|
||||
res.attribute.userid == null ||
|
||||
res.attribute.userid == undefined
|
||||
) {
|
||||
this.$refs.uToast.show({
|
||||
type: "warning",
|
||||
message: "登录时获取的 code 为空, 请联系管理员处理!",
|
||||
});
|
||||
} else {
|
||||
this.$refs.uToast.show({
|
||||
type: "warning",
|
||||
message: "您尚未进行登录认证,请先认证!",
|
||||
});
|
||||
setTimeout(() => {
|
||||
localStorage.set("MIDDLEGROUND-USERID", res.attribute.userid);
|
||||
uni.reLaunch({
|
||||
url: "/pages/loginAuthen/loginDingDing",
|
||||
});
|
||||
}, 1000);
|
||||
}
|
||||
} else {
|
||||
// do something
|
||||
localStorage.remove("MIDDLEGROUND-TOKEN");
|
||||
localStorage.remove("MIDDLEGROUND-USERINFO");
|
||||
localStorage.remove("MIDDLEGROUND-USERID");
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.title {
|
||||
padding-top: 80rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
.logo-content {
|
||||
background: #c73b26;
|
||||
border-radius: 10px;
|
||||
padding: 15px;
|
||||
}
|
||||
.title .logo {
|
||||
vertical-align: middle;
|
||||
}
|
||||
.title .text {
|
||||
font-size: 17px;
|
||||
font-weight: 700;
|
||||
vertical-align: middle;
|
||||
padding: 24px;
|
||||
color: var(--text-color-light);
|
||||
}
|
||||
</style>
|
||||
<style scoped>
|
||||
page {
|
||||
background: #fff;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,174 @@
|
|||
<template>
|
||||
<view class="login">
|
||||
<div class="title">
|
||||
<img :src="globalConfig" alt="" class="logo" style="width: 250rpx" />
|
||||
<span class="text">钉钉登录认证中...</span>
|
||||
</div>
|
||||
<u-toast ref="uToast"></u-toast>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as dd from "dingtalk-jsapi";
|
||||
import { DDSSO } from "@/api/login.js";
|
||||
import logo from "@/static/logo.png";
|
||||
import localStorage from "@/utils/localStorage";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
globalConfig: logo,
|
||||
billID: "",
|
||||
billKindID: "",
|
||||
};
|
||||
},
|
||||
onReady() {
|
||||
this.$ddFunction.setTitle("钉钉免登录认证");
|
||||
},
|
||||
onShow() {
|
||||
const currentUrl = document.location.toString();
|
||||
//解析url中包含的corpId
|
||||
const obj = this.parseURLParams(currentUrl);
|
||||
const corpId = obj.corpid;
|
||||
this.billID = obj.billid;
|
||||
this.billKindID = obj.billKindID;
|
||||
if (corpId == "" || corpId == null || corpId == undefined) {
|
||||
this.$modal.showToast("企业id获取失败, 请使用钉钉手机端登录或重新加载");
|
||||
} else {
|
||||
this.$store.commit("SET_DINGCROPID", corpId);
|
||||
this.dingtalkLogin(corpId);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 解析URL字符串
|
||||
parseURLParams(url) {
|
||||
const params = {};
|
||||
const paramStr = url.split("?")[1];
|
||||
if (paramStr) {
|
||||
const paramPairs = paramStr.split("&");
|
||||
paramPairs.forEach((pair) => {
|
||||
const [key, value] = pair.split("=");
|
||||
params[key] = decodeURIComponent(value);
|
||||
});
|
||||
}
|
||||
return params;
|
||||
},
|
||||
dingtalkLogin(corpId) {
|
||||
let that = this;
|
||||
if (dd.env.platform !== "notInDingTalk") {
|
||||
dd.ready(() => {
|
||||
//使用SDK 获取免登授权码
|
||||
dd.runtime.permission.requestAuthCode({
|
||||
corpId: corpId,
|
||||
onSuccess: function (result) {
|
||||
let code = result.code;
|
||||
that.loginDDSSO(code);
|
||||
},
|
||||
onFail: (err) => {
|
||||
console.info("获取个人信息异常,请稍后重试!", err);
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
async loginDDSSO(code) {
|
||||
let params = {
|
||||
code: code,
|
||||
};
|
||||
let res = await DDSSO(params);
|
||||
if (res.code == 1) {
|
||||
localStorage.set("MIDDLEGROUND-TOKEN", res.data[0]);
|
||||
localStorage.set("MIDDLEGROUND-USERINFO", res.data[1]);
|
||||
// 合同
|
||||
if (this.billKindID == "45") {
|
||||
let url =
|
||||
"/pages/contractManagement/contractList/contractAssistant?billid=" +
|
||||
this.billID +
|
||||
"&billKindID=" +
|
||||
this.billKindID +
|
||||
"&type=audit&external=external";
|
||||
uni.reLaunch({
|
||||
url: url,
|
||||
});
|
||||
} else if (this.billKindID == "187") {
|
||||
//合同交接
|
||||
let url =
|
||||
"/pages/contractManagement/contractHandover/handoverAssistant?billid=" +
|
||||
this.billID +
|
||||
"&billKindID=" +
|
||||
this.billKindID +
|
||||
"&type=audit&external=external";
|
||||
uni.reLaunch({
|
||||
url: url,
|
||||
});
|
||||
} else if (this.billKindID == "171") {
|
||||
//商机
|
||||
let url =
|
||||
"/pages/opportunityManagement/opportunityAssistant?billid=" +
|
||||
this.billID +
|
||||
"&billKindID=" +
|
||||
this.billKindID +
|
||||
"&type=audit&external=external";
|
||||
uni.reLaunch({
|
||||
url: url,
|
||||
});
|
||||
} else {
|
||||
uni.switchTab({
|
||||
url: "/pages/staging/index",
|
||||
});
|
||||
}
|
||||
} else if (res.code == "1005") {
|
||||
if (
|
||||
res.data[0] == "" ||
|
||||
res.data[0] == null ||
|
||||
res.data[0] == undefined
|
||||
) {
|
||||
this.$refs.uToast.show({
|
||||
type: "warning",
|
||||
message: "登录时获取的 code 为空, 请联系管理员处理!",
|
||||
});
|
||||
} else {
|
||||
this.$refs.uToast.show({
|
||||
type: "warning",
|
||||
message: "您尚未进行登录认证,请先认证!",
|
||||
});
|
||||
setTimeout(() => {
|
||||
localStorage.set("MIDDLEGROUND-USERID", res.data[0]);
|
||||
uni.reLaunch({
|
||||
url: "/pages/loginAuthen/loginDingDing",
|
||||
});
|
||||
}, 1000);
|
||||
}
|
||||
} else {
|
||||
// do something
|
||||
localStorage.remove("MIDDLEGROUND-TOKEN");
|
||||
localStorage.remove("MIDDLEGROUND-USERINFO");
|
||||
localStorage.remove("MIDDLEGROUND-USERID");
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.title {
|
||||
padding-top: 80rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
.title .logo {
|
||||
vertical-align: middle;
|
||||
}
|
||||
.title .text {
|
||||
font-size: 17px;
|
||||
font-weight: 700;
|
||||
vertical-align: middle;
|
||||
padding: 24px;
|
||||
color: var(--text-color-light);
|
||||
}
|
||||
</style>
|
||||
<style scoped>
|
||||
page {
|
||||
background: #fff;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,113 @@
|
|||
<template>
|
||||
<view class="login">
|
||||
<div class="title">
|
||||
<img :src="globalConfig" alt="" class="logo" style="width: 250rpx" />
|
||||
<span class="text">微信登录认证中...</span>
|
||||
</div>
|
||||
<u-toast ref="uToast"></u-toast>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { WeChatSSO } from "@/api/login.js";
|
||||
import logo from "@/static/logo.png";
|
||||
import localStorage from "@/utils/localStorage";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
globalConfig: logo,
|
||||
};
|
||||
},
|
||||
onShow() {
|
||||
//页面通过微信服务器回调回来时会带上code,页面获取code后再去进行身份认证
|
||||
const currentUrl = document.location.toString();
|
||||
const obj = this.parseURLParams(currentUrl);
|
||||
//解析url中包含的code
|
||||
const code = obj.code;
|
||||
if (code == "" || code == null || code == undefined) {
|
||||
//重定向回当前页面
|
||||
var redirect = encodeURIComponent(
|
||||
"http://ufidahz.com.cn:9085/app/index.html#/pages/loginAuthen/authenWeChat"
|
||||
);
|
||||
var url =
|
||||
"https://open.weixin.qq.com/connect/oauth2/authorize" +
|
||||
"?appid=wwb46c3f5e6ffe3e2b" +
|
||||
"&redirect_uri=" +
|
||||
redirect +
|
||||
"&response_type=code&scope=SCOPE&state=STATE#wechat_redirect";
|
||||
window.location.href = url;
|
||||
} else {
|
||||
this.WXLogin(code);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 解析URL字符串
|
||||
parseURLParams(url) {
|
||||
const params = {};
|
||||
const paramStr = url.split("?")[1];
|
||||
if (paramStr) {
|
||||
const paramPairs = paramStr.split("&");
|
||||
paramPairs.forEach((pair) => {
|
||||
const [key, value] = pair.split("=");
|
||||
params[key] = decodeURIComponent(value);
|
||||
});
|
||||
}
|
||||
return params;
|
||||
},
|
||||
async WXLogin(code) {
|
||||
let params = {
|
||||
code: code,
|
||||
};
|
||||
let res = await WeChatSSO(params);
|
||||
if (res.code == 1) {
|
||||
localStorage.set("MIDDLEGROUND-TOKEN", res.data[0]);
|
||||
localStorage.set("MIDDLEGROUND-USERINFO", res.data[1]);
|
||||
this.$nextTick(()=>{
|
||||
uni.reLaunch({
|
||||
url: "/pages/loginAuthen/selectCompany",
|
||||
});
|
||||
})
|
||||
} else if (res.code == "1005") {
|
||||
this.$refs.uToast.show({
|
||||
type: "warning",
|
||||
message: "您尚未进行登录认证,请先认证!",
|
||||
});
|
||||
setTimeout(() => {
|
||||
localStorage.set("MIDDLEGROUND-USERID", res.data[0]);
|
||||
uni.reLaunch({
|
||||
url: "/pages/loginAuthen/loginWeChat",
|
||||
});
|
||||
}, 1000);
|
||||
} else {
|
||||
localStorage.remove("MIDDLEGROUND-TOKEN");
|
||||
localStorage.remove("MIDDLEGROUND-USERINFO");
|
||||
localStorage.remove("MIDDLEGROUND-USERID");
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.title {
|
||||
padding-top: 80rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
.title .logo {
|
||||
vertical-align: middle;
|
||||
}
|
||||
.title .text {
|
||||
font-size: 17px;
|
||||
font-weight: 700;
|
||||
vertical-align: middle;
|
||||
padding: 24px;
|
||||
color: var(--text-color-light);
|
||||
}
|
||||
</style>
|
||||
<style scoped>
|
||||
page {
|
||||
background: #fff;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,145 @@
|
|||
<template>
|
||||
<view class="loginBox">
|
||||
<view class="logo-content">
|
||||
<img :src="globalConfig" alt="" class="logo" style="width: 250rpx" />
|
||||
</view>
|
||||
<u-form
|
||||
:model="userform"
|
||||
:rules="userRules"
|
||||
class="loginForm"
|
||||
ref="loginForm"
|
||||
>
|
||||
<u-form-item prop="loginCode" ref="item1" :borderBottom="true">
|
||||
<u--input
|
||||
v-model="userform.loginCode"
|
||||
:border="'none'"
|
||||
:placeholder="'请输入账号'"
|
||||
prefixIcon="account"
|
||||
prefixIconStyle="font-size: 22px;color: #909399"
|
||||
></u--input>
|
||||
</u-form-item>
|
||||
<u-form-item prop="loginPwd" ref="item1" :borderBottom="true">
|
||||
<u--input
|
||||
v-model="userform.loginPwd"
|
||||
:border="'none'"
|
||||
prefixIcon="lock"
|
||||
:placeholder="'请输入密码'"
|
||||
password
|
||||
prefixIconStyle="font-size: 22px;color: #909399"
|
||||
></u--input>
|
||||
</u-form-item>
|
||||
</u-form>
|
||||
<view class="btn">
|
||||
<u-button
|
||||
text="认证"
|
||||
size="normal"
|
||||
type="primary"
|
||||
@click="handlerSubmit"
|
||||
></u-button>
|
||||
</view>
|
||||
<u-toast ref="uToast"></u-toast>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { authApi } from "@/api/login";
|
||||
import logo from "@/static/logo1.png";
|
||||
import localStorage from "@/utils/localStorage";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
globalConfig: logo,
|
||||
userform: {
|
||||
loginCode: "",
|
||||
loginPwd: "",
|
||||
},
|
||||
userRules: {
|
||||
loginCode: [
|
||||
{
|
||||
required: true,
|
||||
message: "请输入账号",
|
||||
trigger: ["change", "blur"],
|
||||
},
|
||||
],
|
||||
loginPwd: [
|
||||
{
|
||||
required: true,
|
||||
message: "请输入密码",
|
||||
trigger: ["change", "blur"],
|
||||
},
|
||||
],
|
||||
},
|
||||
userid: "",
|
||||
};
|
||||
},
|
||||
onReady() {
|
||||
this.$ddFunction.setTitle("钉钉免登录认证");
|
||||
},
|
||||
methods: {
|
||||
handlerSubmit() {
|
||||
this.$refs.loginForm
|
||||
.validate()
|
||||
.then((res) => {
|
||||
let params = {
|
||||
loginCode: this.userform.loginCode,
|
||||
password: this.userform.loginPwd,
|
||||
ddUserId: localStorage.get("MIDDLEGROUND-USERID"),
|
||||
};
|
||||
this.submit(params);
|
||||
})
|
||||
.catch((errors) => {});
|
||||
},
|
||||
async submit(params) {
|
||||
let res = await authApi(
|
||||
"loginService",
|
||||
"sysTestjdbc",
|
||||
"doLogin",
|
||||
"",
|
||||
params
|
||||
);
|
||||
if (res.status === "200") {
|
||||
this.$refs.uToast.show({
|
||||
type: "success",
|
||||
message: "认证成功!",
|
||||
});
|
||||
setTimeout(() => {
|
||||
localStorage.set("MIDDLEGROUND-TOKEN", res.attribute.token);
|
||||
localStorage.set("MIDDLEGROUND-USERINFO", res.attribute.userInfo);
|
||||
uni.switchTab({
|
||||
url: "/pages/homePage/index",
|
||||
});
|
||||
}, 1000);
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.logo-content {
|
||||
background: #c73b26;
|
||||
border-radius: 10px;
|
||||
padding: 15px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 310rpx;
|
||||
text-align: center;
|
||||
margin: auto;
|
||||
|
||||
}
|
||||
.loginBox {
|
||||
background: #ffffff;
|
||||
padding-top: 20%;
|
||||
.loginForm {
|
||||
padding: 70rpx 80rpx;
|
||||
}
|
||||
.btn {
|
||||
padding: 30rpx 80rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style scoped>
|
||||
page {
|
||||
background: #fff;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,138 @@
|
|||
<template>
|
||||
<view class="loginBox">
|
||||
<view class="logo-content">
|
||||
<image style="width: 250rpx" :src="globalConfig" mode="widthFix"></image>
|
||||
</view>
|
||||
<u-form
|
||||
:model="userform"
|
||||
:rules="userRules"
|
||||
class="loginForm"
|
||||
ref="loginForm"
|
||||
>
|
||||
<u-form-item prop="loginCode" ref="item1" :borderBottom="true">
|
||||
<u--input
|
||||
v-model="userform.loginCode"
|
||||
:border="'none'"
|
||||
:placeholder="'请输入账号'"
|
||||
prefixIcon="MIDDLEGROUND"
|
||||
prefixIconStyle="font-size: 22px;color: #909399"
|
||||
></u--input>
|
||||
</u-form-item>
|
||||
<u-form-item prop="loginPwd" ref="item1" :borderBottom="true">
|
||||
<u--input
|
||||
v-model="userform.loginPwd"
|
||||
:border="'none'"
|
||||
prefixIcon="lock"
|
||||
:placeholder="'请输入密码'"
|
||||
password
|
||||
prefixIconStyle="font-size: 22px;color: #909399"
|
||||
></u--input>
|
||||
</u-form-item>
|
||||
</u-form>
|
||||
<view class="btn">
|
||||
<u-button
|
||||
text="认证"
|
||||
size="normal"
|
||||
type="primary"
|
||||
@click="handlerSubmit"
|
||||
></u-button>
|
||||
</view>
|
||||
<u-toast ref="uToast"></u-toast>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { WeChatAuthen } from "@/api/login.js";
|
||||
import logo from "@/static/logo.png";
|
||||
import localStorage from "@/utils/localStorage";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
globalConfig: logo,
|
||||
userform: {
|
||||
loginCode: "",
|
||||
loginPwd: "",
|
||||
},
|
||||
userRules: {
|
||||
loginCode: [
|
||||
{
|
||||
required: true,
|
||||
message: "请输入账号",
|
||||
trigger: ["change", "blur"],
|
||||
},
|
||||
],
|
||||
loginPwd: [
|
||||
{
|
||||
required: true,
|
||||
message: "请输入密码",
|
||||
trigger: ["change", "blur"],
|
||||
},
|
||||
],
|
||||
},
|
||||
userid: "",
|
||||
};
|
||||
},
|
||||
onReady() {
|
||||
this.$ddFunction.setTitle("钉钉免登录认证");
|
||||
},
|
||||
methods: {
|
||||
handlerSubmit() {
|
||||
this.$refs.loginForm
|
||||
.validate()
|
||||
.then((res) => {
|
||||
let params = {
|
||||
...this.userform,
|
||||
userID: localStorage.get("MIDDLEGROUND-USERID"),
|
||||
};
|
||||
this.submit(params);
|
||||
})
|
||||
.catch((errors) => {});
|
||||
},
|
||||
async submit(params) {
|
||||
let res = await WeChatAuthen(params);
|
||||
if (res.code == 1) {
|
||||
this.$refs.uToast.show({
|
||||
type: "success",
|
||||
message: "认证成功!",
|
||||
});
|
||||
setTimeout(() => {
|
||||
window.location.href = "http://ufidahz.com.cn:9085/app/index.html#/pages/loginAuthen/authenWeChat"
|
||||
}, 1000);
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.loginBox {
|
||||
background: #ffffff;
|
||||
|
||||
.logo-content {
|
||||
width: 100%;
|
||||
font-size: 25px;
|
||||
text-align: center;
|
||||
padding-top: 20%;
|
||||
|
||||
image {
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-left: 10px;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
.loginForm {
|
||||
padding: 70rpx 80rpx;
|
||||
}
|
||||
.btn {
|
||||
padding: 30rpx 80rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style scoped>
|
||||
page {
|
||||
background: #fff;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,150 @@
|
|||
<template>
|
||||
<view class="loginBox">
|
||||
<view class="logo-content">
|
||||
<image style="width: 250rpx" :src="globalConfig" mode="widthFix"></image>
|
||||
</view>
|
||||
<p class="comBtnTitle">请选择您本次登录的组织</p>
|
||||
<view class="comBtnBox">
|
||||
<view
|
||||
v-for="item in companyList"
|
||||
:key="item.companyID"
|
||||
class="comBtn"
|
||||
@click.native.prevent="handleSelectCompany(item)"
|
||||
>
|
||||
<text class="comBtnText" :title="item.companyName">
|
||||
{{ item.companyName }}
|
||||
</text>
|
||||
<u-icon name="arrow-right" color="#606266" size="14"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
<u-toast ref="uToast"></u-toast>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { OrganGetUserCompany, ChangeCompany } from "@/api/login.js";
|
||||
import logo from "@/static/logo.png";
|
||||
import localStorage from "@/utils/localStorage";
|
||||
import { getUserInfo, setUserInfo } from "@/utils/auth";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
globalConfig: logo,
|
||||
selectCompany: false,
|
||||
companyList: [], //公司账套
|
||||
};
|
||||
},
|
||||
onReady() {
|
||||
this.$ddFunction.setTitle("钉钉免登录认证");
|
||||
},
|
||||
mounted() {
|
||||
this.getCompanyList()
|
||||
},
|
||||
methods: {
|
||||
// 获取公司列表数据
|
||||
async getCompanyList() {
|
||||
let params = {};
|
||||
let res = await OrganGetUserCompany(params);
|
||||
if (res.code == 1) {
|
||||
// 如果只存在一个公司 直接跳转到首页
|
||||
if (res.data[0].length == 1) {
|
||||
if (
|
||||
res.data[0][0].companyID == null ||
|
||||
res.data[0][0].companyID == "" ||
|
||||
res.data[0][0].companyID == undefined
|
||||
) {
|
||||
this.$refs.uToast.show({
|
||||
type: "warning",
|
||||
message: "当前登录人公司信息为空,请联系管理员处理!",
|
||||
});
|
||||
} else {
|
||||
this.handleSelectCompany(res.data[0][0]);
|
||||
}
|
||||
} else {
|
||||
this.companyList = res.data[0];
|
||||
this.selectCompany = true;
|
||||
}
|
||||
}
|
||||
},
|
||||
// 当前选择的组织
|
||||
handleSelectCompany(item) {
|
||||
let obj = getUserInfo();
|
||||
obj.companyID = item.companyID;
|
||||
obj.companyName = item.companyName;
|
||||
setUserInfo(obj);
|
||||
this.ChangeCompany(item.companyID);
|
||||
uni.switchTab({
|
||||
url: "/pages/staging/index",
|
||||
});
|
||||
},
|
||||
async ChangeCompany(CompanyID) {
|
||||
let params = {
|
||||
CompanyID: CompanyID,
|
||||
};
|
||||
let res = await ChangeCompany(params);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.comBtnBox {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
.comBtn {
|
||||
border: 2rpx solid #f1f1f1;
|
||||
padding: 20rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: 80%;
|
||||
border-radius: 6rpx;
|
||||
margin: 16rpx 0;
|
||||
color: #606266;
|
||||
}
|
||||
.comBtnTitle {
|
||||
width: 100%;
|
||||
font-size: 32rpx;
|
||||
color: #666;
|
||||
text-align: center;
|
||||
margin: 20rpx 0 20rpx 0;
|
||||
}
|
||||
.comBtnText {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
margin: 0 20rpx 0 0;
|
||||
}
|
||||
.loginBox {
|
||||
background: #ffffff;
|
||||
|
||||
.logo-content {
|
||||
width: 100%;
|
||||
font-size: 25px;
|
||||
text-align: center;
|
||||
padding-top: 20%;
|
||||
|
||||
image {
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-left: 10px;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
.loginForm {
|
||||
padding: 70rpx 80rpx;
|
||||
}
|
||||
.btn {
|
||||
padding: 30rpx 80rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style scoped>
|
||||
page {
|
||||
background: #fff;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,323 @@
|
|||
<template>
|
||||
<view class="taskContent">
|
||||
<u--form
|
||||
:model="model"
|
||||
ref="uForm"
|
||||
:labelAlign="'left'"
|
||||
:labelStyle="{ fontSize: '28rpx' }"
|
||||
labelPosition="top"
|
||||
:style="{ marginTop: tarbarHeight }"
|
||||
class="formBox"
|
||||
>
|
||||
<u-form-item
|
||||
label="发送者应用"
|
||||
prop="sendAppName"
|
||||
ref="item1"
|
||||
required
|
||||
:borderBottom="true"
|
||||
:labelWidth="'180rpx'"
|
||||
>
|
||||
<uni-easyinput
|
||||
v-model="model.sendAppName"
|
||||
:disabled="true"
|
||||
:inputBorder="false"
|
||||
:styles="{ disableColor: '#ffffff', color: '#999999' }"
|
||||
></uni-easyinput>
|
||||
</u-form-item>
|
||||
<u-form-item
|
||||
label="接口名称"
|
||||
prop="apiName"
|
||||
ref="item1"
|
||||
required
|
||||
:borderBottom="true"
|
||||
:labelWidth="'180rpx'"
|
||||
>
|
||||
<uni-easyinput
|
||||
v-model="model.apiName"
|
||||
:inputBorder="false"
|
||||
:disabled="true"
|
||||
:styles="{ disableColor: '#ffffff', color: '#999999' }"
|
||||
></uni-easyinput>
|
||||
</u-form-item>
|
||||
<u-form-item
|
||||
label="源数据"
|
||||
prop="sourceData"
|
||||
ref="item1"
|
||||
required
|
||||
:borderBottom="true"
|
||||
:labelWidth="'180rpx'"
|
||||
>
|
||||
<uni-easyinput
|
||||
v-model="model.sourceData"
|
||||
type="textarea"
|
||||
autoHeight
|
||||
:inputBorder="false"
|
||||
:maxlength="-1"
|
||||
:styles="{
|
||||
paddingLeft: '10px',
|
||||
}"
|
||||
></uni-easyinput>
|
||||
</u-form-item>
|
||||
<u-form-item
|
||||
label="目标数据"
|
||||
prop="targetData"
|
||||
ref="item1"
|
||||
required
|
||||
:borderBottom="true"
|
||||
:labelWidth="'180rpx'"
|
||||
>
|
||||
<uni-easyinput
|
||||
v-model="model.targetData"
|
||||
type="textarea"
|
||||
autoHeight
|
||||
:inputBorder="false"
|
||||
:maxlength="-1"
|
||||
:styles="{
|
||||
paddingLeft: '10px',
|
||||
}"
|
||||
></uni-easyinput>
|
||||
</u-form-item>
|
||||
<u-form-item
|
||||
label="状态"
|
||||
prop="status"
|
||||
ref="item1"
|
||||
:borderBottom="true"
|
||||
:labelWidth="'180rpx'"
|
||||
>
|
||||
<u-radio-group
|
||||
v-model="model.status"
|
||||
iconPlacement="left"
|
||||
style="margin-left: 10rpx"
|
||||
:disabled="true"
|
||||
>
|
||||
<u-radio
|
||||
:customStyle="{ marginRight: '15px' }"
|
||||
v-for="(item, index) in radiolist"
|
||||
:key="index"
|
||||
:label="item.name"
|
||||
:name="item.id"
|
||||
:labelSize="13"
|
||||
:iconSize="13"
|
||||
></u-radio>
|
||||
</u-radio-group>
|
||||
</u-form-item>
|
||||
<u-form-item
|
||||
label="错误状态"
|
||||
prop="errorStatus"
|
||||
ref="item1"
|
||||
:borderBottom="true"
|
||||
:labelWidth="'180rpx'"
|
||||
:disabled="true"
|
||||
>
|
||||
<u-radio-group
|
||||
v-model="model.errorStatus"
|
||||
iconPlacement="left"
|
||||
style="margin-left: 10rpx"
|
||||
:disabled="true"
|
||||
>
|
||||
<u-radio
|
||||
:customStyle="{ marginRight: '15px' }"
|
||||
v-for="(item, index) in errorRadiolist"
|
||||
:key="index"
|
||||
:label="item.name"
|
||||
:name="item.id"
|
||||
:labelSize="13"
|
||||
:iconSize="13"
|
||||
></u-radio>
|
||||
</u-radio-group>
|
||||
</u-form-item>
|
||||
<u-form-item
|
||||
label="返回信息"
|
||||
prop="returnData"
|
||||
ref="item1"
|
||||
required
|
||||
:borderBottom="true"
|
||||
:labelWidth="'180rpx'"
|
||||
:disabled="true"
|
||||
>
|
||||
<uni-easyinput
|
||||
v-model="model.returnData"
|
||||
type="textarea"
|
||||
autoHeight
|
||||
:inputBorder="false"
|
||||
:disabled="true"
|
||||
:styles="{ disableColor: '#ffffff', color: '#999999' }"
|
||||
></uni-easyinput>
|
||||
</u-form-item>
|
||||
</u--form>
|
||||
<!-- 按钮控制 -->
|
||||
<view class="bottomPage">
|
||||
<u-button
|
||||
text="标记成功"
|
||||
@click="signSuccess"
|
||||
style="margin-right: 30rpx"
|
||||
></u-button>
|
||||
<u-button
|
||||
text="重新推送"
|
||||
type="primary"
|
||||
size="normal"
|
||||
@click="resend"
|
||||
></u-button>
|
||||
</view>
|
||||
<base-tarbar ref="baseTarbar" pageTitle="查看异常日志"></base-tarbar>
|
||||
<u-toast ref="uToast"></u-toast>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { authApi } from "@/api/login";
|
||||
import baseTarbar from "@/components/baseTarbar/index.vue";
|
||||
export default {
|
||||
onLoad: function (option) {
|
||||
//option为object类型,会序列化上个页面传递的参数
|
||||
if (Object.getOwnPropertyNames(option).length != 0) {
|
||||
this.billID = option.billid;
|
||||
}
|
||||
},
|
||||
components: {
|
||||
baseTarbar,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
billID: "",
|
||||
tarbarHeight: "0",
|
||||
radiolist: [
|
||||
{ id: "1", label: "待发送" },
|
||||
{ id: "2", label: "发送中" },
|
||||
{ id: "3", label: "发送成功" },
|
||||
{ id: "4", label: "发送失败" },
|
||||
],
|
||||
errorRadiolist: [
|
||||
{ id: "1", label: "需要重新发送" },
|
||||
{ id: "2", label: "不需要重新发送" },
|
||||
],
|
||||
model: {},
|
||||
};
|
||||
},
|
||||
onReady() {
|
||||
this.$refs.baseTarbar.currentEnvironment();
|
||||
if (this.$refs.baseTarbar.isOther) {
|
||||
this.tarbarHeight = "84rpx";
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.init();
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
this.messageLogGetById(this.billID);
|
||||
},
|
||||
// 编辑详情
|
||||
async messageLogGetById(id, row) {
|
||||
let params = {
|
||||
id: id,
|
||||
// status: row.status,
|
||||
};
|
||||
|
||||
let res = await authApi(
|
||||
"sysMessageManageLogService",
|
||||
"messageManage",
|
||||
"thirdInterfacequeryEntity",
|
||||
"",
|
||||
params
|
||||
);
|
||||
|
||||
if (res.status == "200") {
|
||||
let res2 = await authApi(
|
||||
"sysApplicationApiService",
|
||||
"application",
|
||||
"queryEntity",
|
||||
"",
|
||||
{ apiCode: res.attribute.receiveCode }
|
||||
);
|
||||
if (res2.status == "200") {
|
||||
this.$set(res.attribute, "apiName", res2.attribute[0].apiName);
|
||||
} else {
|
||||
this.$set(res.attribute, "apiName", "未配置该接口");
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
this.model = {
|
||||
...res.attribute,
|
||||
};
|
||||
});
|
||||
}
|
||||
},
|
||||
async signSuccess() {
|
||||
let params = {
|
||||
id: this.billID,
|
||||
status: "3",
|
||||
};
|
||||
let res = await authApi(
|
||||
"sysMessageManageLogService",
|
||||
"messageManage",
|
||||
"updateEntity",
|
||||
"",
|
||||
params
|
||||
);
|
||||
if (res.status == "200") {
|
||||
this.$vmNews("标记成功", "success");
|
||||
this.$refs.uToast.show({
|
||||
type: "success",
|
||||
message: "标记成功",
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
uni.navigateBack();
|
||||
}, 500);
|
||||
}
|
||||
},
|
||||
async resend() {
|
||||
let formData = new FormData();
|
||||
formData.append("id", this.billID);
|
||||
formData.append("sourceData", this.model.sourceData);
|
||||
|
||||
let res = await request({
|
||||
url: "kangarooDataCenterV3/entranceController/externalCallInterfaceResend",
|
||||
method: "post",
|
||||
data: formData,
|
||||
});
|
||||
if (res.status == "200") {
|
||||
this.handleDialogClose();
|
||||
if (res.msg == "重推成功") {
|
||||
this.$refs.uToast.show({
|
||||
type: "success",
|
||||
message: res.msg,
|
||||
});
|
||||
}
|
||||
if (res.msg == "重推失败") {
|
||||
this.$refs.uToast.show({
|
||||
type: "error",
|
||||
message: res.msg,
|
||||
});
|
||||
}
|
||||
setTimeout(() => {
|
||||
uni.navigateBack();
|
||||
}, 500);
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.bottomPage {
|
||||
width: 100%;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
padding: 20rpx 30rpx 30rpx 30rpx;
|
||||
background-color: #fff;
|
||||
margin-top: 15rpx;
|
||||
display: flex;
|
||||
border-top: 8rpx solid #f1f1f1;
|
||||
}
|
||||
.formBox {
|
||||
padding: 10px 10px 100px 10px;
|
||||
}
|
||||
::v-deep .uni-easyinput__content-textarea {
|
||||
padding-left: 10px !important;
|
||||
}
|
||||
page {
|
||||
height: 100vh;
|
||||
background: #fff;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,420 @@
|
|||
<template>
|
||||
<view class="top-level">
|
||||
<view class="Page_change" :style="{ marginTop: tarbarHeight }">
|
||||
<u-search
|
||||
:clearabled="true"
|
||||
:showAction="false"
|
||||
shape="square"
|
||||
v-model="pageModel.sourceData"
|
||||
:placeholder="'请输入源数据'"
|
||||
@change="handlerSearchEvent"
|
||||
></u-search>
|
||||
</view>
|
||||
<view
|
||||
class="listContent"
|
||||
:style="{ marginTop: isOther ? '220rpx' : '142rpx' }"
|
||||
>
|
||||
<view
|
||||
v-for="(item, index) in tableData"
|
||||
:key="item.billid"
|
||||
class="listData"
|
||||
@click="handlerShowDetails(item, index)"
|
||||
>
|
||||
<view class="content">
|
||||
<text>发送者应用:</text>
|
||||
<view
|
||||
style="width: calc(100% - 90px); display: flex; align-items: center"
|
||||
>
|
||||
<u--text :lines="1" :text="item.sendAppName" :size="14"></u--text>
|
||||
<img
|
||||
src="./push.png"
|
||||
class="pushBtn"
|
||||
@click.stop.prevent="pushDetails(item, index)"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="content">
|
||||
<text>状态:</text>
|
||||
<view :style="[textColor(item.status)]" class="itemName">{{
|
||||
textData(item.status)
|
||||
}}</view>
|
||||
</view>
|
||||
<view class="content">
|
||||
<text>接口名称:</text>
|
||||
<u--text :lines="1" :text="item.receiveApiName" :size="14"></u--text>
|
||||
</view>
|
||||
<view class="content">
|
||||
<text>源数据:</text>
|
||||
<u--text :lines="1" :text="item.sourceData" :size="14"></u--text>
|
||||
</view>
|
||||
<view class="content">
|
||||
<text>目标数据:</text>
|
||||
<u--text :lines="1" :text="item.targetData" :size="14"></u--text>
|
||||
</view>
|
||||
<view class="content">
|
||||
<text>错误状态:</text>
|
||||
<u--text
|
||||
:lines="1"
|
||||
:text="item.errorStatus === '1' ? '需要重新发送' : '不需要重新发送'"
|
||||
:size="14"
|
||||
></u--text>
|
||||
</view>
|
||||
<view class="content">
|
||||
<text>返回信息:</text>
|
||||
<u--text :lines="1" :text="item.returnData" :size="14"></u--text>
|
||||
</view>
|
||||
<view class="content">
|
||||
<text>创建时间:</text>
|
||||
<u--text :lines="1" :text="item.createTime" :size="14"></u--text>
|
||||
</view>
|
||||
<view class="content">
|
||||
<text>备注:</text>
|
||||
<u--text :lines="1" :text="item.remark" :size="14"></u--text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="noData" v-show="noData">
|
||||
<u-divider text="我是有底线哒!" :hairline="true"></u-divider>
|
||||
</view>
|
||||
</view>
|
||||
<view class="plusButton" @click="handlerAddProject">
|
||||
<u-icon name="plus" :color="'#ffffff'"></u-icon
|
||||
></view>
|
||||
<u-toast ref="uToast"></u-toast>
|
||||
<u-loading-page :loading="loading"></u-loading-page>
|
||||
<base-tarbar ref="baseTarbar" :pageTitle="'异常信息'"></base-tarbar>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { authApi } from "@/api/login";
|
||||
import baseTarbar from "@/components/baseTarbar/index.vue";
|
||||
export default {
|
||||
/**
|
||||
* ┌─┐ ┌─┐
|
||||
* ┌──┘ ┴───────┘ ┴──┐
|
||||
* │ │
|
||||
* │ ─── │
|
||||
* │ ─┬┘ └┬─ │
|
||||
* │ │
|
||||
* │ ─┴─ │
|
||||
* │ │
|
||||
* └───┐ ┌───┘
|
||||
* │ │
|
||||
* │ │
|
||||
* │ │
|
||||
* │ └──────────────┐
|
||||
* │ │
|
||||
* │ ├─┐
|
||||
* │ ┌─┘
|
||||
* │ │
|
||||
* └─┐ ┐ ┌───────┬──┐ ┌──┘
|
||||
* │ ─┤ ─┤ │ ─┤ ─┤
|
||||
* └──┴──┘ └──┴──┘
|
||||
* 神兽保佑
|
||||
* 代码无BUG!
|
||||
*/
|
||||
components: {
|
||||
baseTarbar,
|
||||
},
|
||||
onReady() {
|
||||
this.$refs.baseTarbar.currentEnvironment();
|
||||
this.isOther = this.$refs.baseTarbar.isOther;
|
||||
if (this.$refs.baseTarbar.isOther) {
|
||||
this.tarbarHeight = "84rpx";
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
isOther: false,
|
||||
tarbarHeight: "0",
|
||||
msgType: "warn",
|
||||
timer: null,
|
||||
loading: false,
|
||||
noData: false,
|
||||
pageModel: {
|
||||
pageNum: 1,
|
||||
pageSize: 20,
|
||||
sourceData: "",
|
||||
},
|
||||
tableData: [],
|
||||
delBillid: "",
|
||||
appId: "",
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
textColor() {
|
||||
return (item) => {
|
||||
if (item == "1") {
|
||||
return { backgroundColor: "#CFCFCF", color: "#333" };
|
||||
} else if (item == "2") {
|
||||
return { backgroundColor: "#C6DEFF", color: "#1677FF" };
|
||||
} else if (item == "3") {
|
||||
return { backgroundColor: "#D0FFEF", color: "#00B578" };
|
||||
} else if (item == "4") {
|
||||
return { backgroundColor: "#FFE5E3", color: "#FF3B30" };
|
||||
} else {
|
||||
return { backgroundColor: "#CFCFCF", color: "#333" };
|
||||
}
|
||||
};
|
||||
},
|
||||
textData() {
|
||||
return (item) => {
|
||||
if (item == "1") {
|
||||
return "待发送";
|
||||
} else if (item == "2") {
|
||||
return "发送中";
|
||||
} else if (item == "3") {
|
||||
return "发送成功";
|
||||
} else if (item == "4") {
|
||||
return "发送失败";
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
},
|
||||
},
|
||||
onShow() {
|
||||
this.resetTable();
|
||||
},
|
||||
// 下拉刷新
|
||||
onPullDownRefresh() {
|
||||
this.pageModel.pageNum = 1;
|
||||
this.getTableData();
|
||||
setTimeout(function () {
|
||||
uni.stopPullDownRefresh();
|
||||
}, 1000);
|
||||
},
|
||||
onLoad(option) {
|
||||
//option为object类型,会序列化上个页面传递的参数
|
||||
if (Object.getOwnPropertyNames(option).length != 0) {
|
||||
this.appId = option.appId;
|
||||
}
|
||||
uni.$on("resetTable", this.resetTable);
|
||||
},
|
||||
onUnload() {
|
||||
uni.$off("resetTable", this.resetTable);
|
||||
},
|
||||
methods: {
|
||||
resetTable() {
|
||||
this.pageModel.pageNum = 1;
|
||||
this.tableData = [];
|
||||
this.getTableData();
|
||||
},
|
||||
//表格数据
|
||||
async getTableData() {
|
||||
this.noData = false;
|
||||
this.loading = true;
|
||||
setTimeout(() => {
|
||||
this.loading = false;
|
||||
}, 5000);
|
||||
let param = {
|
||||
...this.pageModel,
|
||||
receiveApp: this.appId,
|
||||
status: "4",
|
||||
};
|
||||
let res = await authApi(
|
||||
"sysApplicationService",
|
||||
"application",
|
||||
"thirdInterfacequeryAppApiLog",
|
||||
"",
|
||||
param
|
||||
);
|
||||
if (this.pageModel.pageNum > 1) {
|
||||
this.tableData.push(...res.attribute.list);
|
||||
} else {
|
||||
this.tableData = res.attribute.list;
|
||||
}
|
||||
if (res.attribute.list.length < 20) {
|
||||
this.noData = true;
|
||||
}
|
||||
this.loading = false;
|
||||
},
|
||||
// 触底刷新事件
|
||||
onReachBottom() {
|
||||
if (this.noData != true) {
|
||||
this.pageModel.pageNum++;
|
||||
this.getTableData();
|
||||
}
|
||||
},
|
||||
// 搜索
|
||||
handlerSearchEvent() {
|
||||
if (this.timer !== null) clearTimeout(this.timer);
|
||||
this.timer = setTimeout(() => {
|
||||
this.pageModel.pageNum = 1;
|
||||
this.getTableData();
|
||||
}, 100);
|
||||
},
|
||||
//查看
|
||||
handlerShowDetails(row, index) {
|
||||
let url = "/pages/logsError/show?billid=" + row.id;
|
||||
this.$tab.navigateTo(url);
|
||||
},
|
||||
//推送
|
||||
pushDetails(row, index) {
|
||||
let url = "/pages/logsError/details?billid=" + row.id;
|
||||
this.$tab.navigateTo(url);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.itemName {
|
||||
font-size: 24rpx;
|
||||
margin: 0 20rpx;
|
||||
font-weight: 400;
|
||||
color: #fff;
|
||||
padding: 2rpx 8rpx;
|
||||
height: fit-content;
|
||||
border-radius: 2px;
|
||||
}
|
||||
.pushBtn {
|
||||
width: 19px;
|
||||
height: 19px;
|
||||
}
|
||||
.top-level {
|
||||
.listContent {
|
||||
margin: 20rpx 24rpx 0 24rpx;
|
||||
}
|
||||
|
||||
.swipe-action-item {
|
||||
margin: 20rpx 0 20rpx 0;
|
||||
}
|
||||
.listData {
|
||||
background-color: #fff;
|
||||
border-radius: 16rpx;
|
||||
padding: 20rpx 20rpx;
|
||||
margin-bottom: 20rpx;
|
||||
|
||||
.head {
|
||||
// height: 64rpx;
|
||||
border-bottom: 1px solid #f7f7f7;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.head {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
color: #333;
|
||||
margin-bottom: 16rpx;
|
||||
padding: 10rpx 0 20rpx 0;
|
||||
}
|
||||
.head .itembox {
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
.levelbox {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border: 4rpx solid #3c9cff;
|
||||
border-radius: 50%;
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
color: #3c9cff;
|
||||
font-weight: 700;
|
||||
font-size: 28rpx;
|
||||
margin: 0 10rpx;
|
||||
}
|
||||
}
|
||||
.head .itemName {
|
||||
font-size: 24rpx;
|
||||
color: #999999;
|
||||
margin-left: 10px;
|
||||
font-weight: 400;
|
||||
|
||||
text {
|
||||
color: #fff;
|
||||
padding: 4rpx 8rpx;
|
||||
}
|
||||
}
|
||||
.state {
|
||||
margin: 25rpx 0;
|
||||
}
|
||||
|
||||
.time {
|
||||
margin: 4rpx 0 0;
|
||||
font-size: 28rpx;
|
||||
flex-wrap: wrap;
|
||||
line-height: 1.5;
|
||||
|
||||
text {
|
||||
display: inline-block;
|
||||
font-size: 28rpx;
|
||||
color: #979797;
|
||||
margin-bottom: 15rpx;
|
||||
}
|
||||
|
||||
view {
|
||||
height: 60rpx;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
view:nth-child(4) {
|
||||
text:nth-child(2) {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
line-height: 1.5;
|
||||
font-size: 28rpx;
|
||||
margin-bottom: 15rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
text {
|
||||
font-size: 28rpx;
|
||||
color: #979797;
|
||||
}
|
||||
}
|
||||
}
|
||||
.noData {
|
||||
text-align: center;
|
||||
margin: 20rpx 0 60rpx 0;
|
||||
}
|
||||
|
||||
.Page_change {
|
||||
width: 100%;
|
||||
background-color: #fff;
|
||||
padding: 20rpx 20rpx 20rpx 20rpx;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
|
||||
.buttom {
|
||||
justify-content: space-between;
|
||||
padding-top: 30rpx;
|
||||
|
||||
::v-deep .u-button--circle {
|
||||
width: 30%;
|
||||
}
|
||||
}
|
||||
|
||||
.input_box {
|
||||
margin-top: 20rpx;
|
||||
|
||||
::v-deep .u-input--radius:nth-child(1) {
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
::v-deep .subsetion.u-subsection--button {
|
||||
height: 70rpx;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
::v-deep .u-subsection--button__bar {
|
||||
background-color: #3c9cff;
|
||||
}
|
||||
</style>
|
||||
<style scoped>
|
||||
page {
|
||||
height: 100vh;
|
||||
}
|
||||
</style>
|
After Width: | Height: | Size: 2.8 KiB |
|
@ -0,0 +1,310 @@
|
|||
<template>
|
||||
<view class="taskContent">
|
||||
<u--form
|
||||
:model="model"
|
||||
ref="uForm"
|
||||
:labelAlign="'left'"
|
||||
:labelStyle="{ fontSize: '28rpx' }"
|
||||
labelPosition="top"
|
||||
:style="{ marginTop: tarbarHeight }"
|
||||
class="formBox"
|
||||
>
|
||||
<u-form-item
|
||||
label="发送者应用"
|
||||
prop="sendAppName"
|
||||
ref="item1"
|
||||
required
|
||||
:borderBottom="true"
|
||||
:labelWidth="'180rpx'"
|
||||
>
|
||||
<uni-easyinput
|
||||
v-model="model.sendAppName"
|
||||
:disabled="true"
|
||||
:inputBorder="false"
|
||||
:styles="{ disableColor: '#ffffff' }"
|
||||
></uni-easyinput>
|
||||
</u-form-item>
|
||||
<u-form-item
|
||||
label="接口名称"
|
||||
prop="apiName"
|
||||
ref="item1"
|
||||
required
|
||||
:borderBottom="true"
|
||||
:labelWidth="'180rpx'"
|
||||
>
|
||||
<uni-easyinput
|
||||
v-model="model.apiName"
|
||||
:inputBorder="false"
|
||||
:disabled="true"
|
||||
:styles="{ disableColor: '#ffffff' }"
|
||||
></uni-easyinput>
|
||||
</u-form-item>
|
||||
<u-form-item
|
||||
label="源数据"
|
||||
prop="sourceData"
|
||||
ref="item1"
|
||||
required
|
||||
:borderBottom="true"
|
||||
:labelWidth="'180rpx'"
|
||||
>
|
||||
<uni-easyinput
|
||||
v-model="model.sourceData"
|
||||
type="textarea"
|
||||
autoHeight
|
||||
:disabled="true"
|
||||
:inputBorder="false"
|
||||
:maxlength="-1"
|
||||
:styles="{ disableColor: '#ffffff', paddingLeft: '10px' }"
|
||||
></uni-easyinput>
|
||||
</u-form-item>
|
||||
<u-form-item
|
||||
label="目标数据"
|
||||
prop="targetData"
|
||||
ref="item1"
|
||||
required
|
||||
:borderBottom="true"
|
||||
:labelWidth="'180rpx'"
|
||||
>
|
||||
<uni-easyinput
|
||||
v-model="model.targetData"
|
||||
type="textarea"
|
||||
autoHeight
|
||||
:styles="{ disableColor: '#ffffff', paddingLeft: '10px' }"
|
||||
:inputBorder="false"
|
||||
:maxlength="-1"
|
||||
:disabled="true"
|
||||
></uni-easyinput>
|
||||
</u-form-item>
|
||||
<u-form-item
|
||||
label="状态"
|
||||
prop="status"
|
||||
ref="item1"
|
||||
:borderBottom="true"
|
||||
:labelWidth="'180rpx'"
|
||||
>
|
||||
<u--text :lines="1" :text="textData(model.status)" :size="14" style="padding-left:10px;"></u--text>
|
||||
<!-- <uni-easyinput
|
||||
v-model="model.status"
|
||||
:disabled="true"
|
||||
:inputBorder="false"
|
||||
:styles="{ disableColor: '#ffffff' }"
|
||||
></uni-easyinput> -->
|
||||
</u-form-item>
|
||||
<u-form-item
|
||||
label="错误状态"
|
||||
prop="errorStatus"
|
||||
ref="item1"
|
||||
:borderBottom="true"
|
||||
:labelWidth="'180rpx'"
|
||||
:disabled="true"
|
||||
>
|
||||
<uni-easyinput
|
||||
v-model="
|
||||
model.errorStatus === '1' ? '需要重新发送' : '不需要重新发送'
|
||||
"
|
||||
:disabled="true"
|
||||
:inputBorder="false"
|
||||
:styles="{ disableColor: '#ffffff' }"
|
||||
></uni-easyinput>
|
||||
</u-form-item>
|
||||
<u-form-item
|
||||
label="返回信息"
|
||||
prop="returnData"
|
||||
ref="item1"
|
||||
required
|
||||
:borderBottom="true"
|
||||
:labelWidth="'180rpx'"
|
||||
:disabled="true"
|
||||
>
|
||||
<uni-easyinput
|
||||
v-model="model.returnData"
|
||||
type="textarea"
|
||||
autoHeight
|
||||
:inputBorder="false"
|
||||
:disabled="true"
|
||||
:styles="{ disableColor: '#ffffff' }"
|
||||
></uni-easyinput>
|
||||
</u-form-item>
|
||||
</u--form>
|
||||
<base-tarbar ref="baseTarbar" pageTitle="查看异常日志"></base-tarbar>
|
||||
<u-toast ref="uToast"></u-toast>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { authApi } from "@/api/login";
|
||||
import baseTarbar from "@/components/baseTarbar/index.vue";
|
||||
export default {
|
||||
onLoad: function (option) {
|
||||
//option为object类型,会序列化上个页面传递的参数
|
||||
if (Object.getOwnPropertyNames(option).length != 0) {
|
||||
this.billID = option.billid;
|
||||
}
|
||||
},
|
||||
components: {
|
||||
baseTarbar,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
billID: "",
|
||||
tarbarHeight: "0",
|
||||
radiolist: [
|
||||
{ id: "1", label: "待发送" },
|
||||
{ id: "2", label: "发送中" },
|
||||
{ id: "3", label: "发送成功" },
|
||||
{ id: "4", label: "发送失败" },
|
||||
],
|
||||
errorRadiolist: [
|
||||
{ id: "1", label: "需要重新发送" },
|
||||
{ id: "2", label: "不需要重新发送" },
|
||||
],
|
||||
model: {},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
textData() {
|
||||
return (item) => {
|
||||
if (item == "1") {
|
||||
return "待发送";
|
||||
} else if (item == "2") {
|
||||
return "发送中";
|
||||
} else if (item == "3") {
|
||||
return "发送成功";
|
||||
} else if (item == "4") {
|
||||
return "发送失败";
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
},
|
||||
},
|
||||
onReady() {
|
||||
this.$refs.baseTarbar.currentEnvironment();
|
||||
if (this.$refs.baseTarbar.isOther) {
|
||||
this.tarbarHeight = "84rpx";
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.init();
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
this.messageLogGetById(this.billID);
|
||||
},
|
||||
// 编辑详情
|
||||
async messageLogGetById(id, row) {
|
||||
let params = {
|
||||
id: id,
|
||||
// status: row.status,
|
||||
};
|
||||
|
||||
let res = await authApi(
|
||||
"sysMessageManageLogService",
|
||||
"messageManage",
|
||||
"thirdInterfacequeryEntity",
|
||||
"",
|
||||
params
|
||||
);
|
||||
|
||||
if (res.status == "200") {
|
||||
let res2 = await authApi(
|
||||
"sysApplicationApiService",
|
||||
"application",
|
||||
"queryEntity",
|
||||
"",
|
||||
{ apiCode: res.attribute.receiveCode }
|
||||
);
|
||||
if (res2.status == "200") {
|
||||
this.$set(res.attribute, "apiName", res2.attribute[0].apiName);
|
||||
} else {
|
||||
this.$set(res.attribute, "apiName", "未配置该接口");
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
this.model = {
|
||||
...res.attribute,
|
||||
};
|
||||
});
|
||||
}
|
||||
},
|
||||
async signSuccess() {
|
||||
let params = {
|
||||
id: this.billID,
|
||||
status: "3",
|
||||
};
|
||||
let res = await authApi(
|
||||
"sysMessageManageLogService",
|
||||
"messageManage",
|
||||
"updateEntity",
|
||||
"",
|
||||
params
|
||||
);
|
||||
if (res.status == "200") {
|
||||
this.$vmNews("标记成功", "success");
|
||||
this.$refs.uToast.show({
|
||||
type: "success",
|
||||
message: "标记成功",
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
uni.navigateBack();
|
||||
}, 500);
|
||||
}
|
||||
},
|
||||
async resend() {
|
||||
let formData = new FormData();
|
||||
formData.append("id", this.billID);
|
||||
formData.append("sourceData", this.model.sourceData);
|
||||
|
||||
let res = await request({
|
||||
url: "kangarooDataCenterV3/entranceController/externalCallInterfaceResend",
|
||||
method: "post",
|
||||
data: formData,
|
||||
});
|
||||
if (res.status == "200") {
|
||||
this.handleDialogClose();
|
||||
if (res.msg == "重推成功") {
|
||||
this.$refs.uToast.show({
|
||||
type: "success",
|
||||
message: res.msg,
|
||||
});
|
||||
}
|
||||
if (res.msg == "重推失败") {
|
||||
this.$refs.uToast.show({
|
||||
type: "error",
|
||||
message: res.msg,
|
||||
});
|
||||
}
|
||||
setTimeout(() => {
|
||||
uni.navigateBack();
|
||||
}, 500);
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.bottomPage {
|
||||
width: 100%;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
padding: 20rpx 30rpx 30rpx 30rpx;
|
||||
background-color: #fff;
|
||||
margin-top: 15rpx;
|
||||
display: flex;
|
||||
border-top: 8rpx solid #f1f1f1;
|
||||
}
|
||||
.formBox {
|
||||
padding: 10px 10px 100px 10px;
|
||||
}
|
||||
::v-deep .uni-easyinput__content-textarea {
|
||||
padding-left: 10px !important;
|
||||
}
|
||||
::v-deep .uni-easyinput__content.is-disabled {
|
||||
color: #333333 !important;
|
||||
}
|
||||
page {
|
||||
height: 100vh;
|
||||
background: #fff;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,41 @@
|
|||
import { getToken } from '@/utils/auth'
|
||||
|
||||
// 登录页面
|
||||
const loginPageH5 = "/pages/login"
|
||||
const loginPageDingDing = "/pages/loginAuthen/authenDingDing"
|
||||
const loginPageWeChat = "/pages/loginAuthen/authenWeChat"
|
||||
|
||||
// 页面白名单 //页面进行跳转时,会判断是否是白名单页面,如何不是,不运行跳转
|
||||
const whiteList = [
|
||||
'/pages/login', '/pages/loginAuthen/authenDingDing', '/pages/loginAuthen/authenWeChat', '/pages/common/webview/index','/pages/loginAuthen/loginDingDing','/pages/loginAuthen/loginWeChat','/pages/loginAuthen/authenDingDingAudit','/pages/loginAuthen/selectCompany'
|
||||
]
|
||||
|
||||
// 检查地址白名单
|
||||
function checkWhite(url) {
|
||||
const path = url.split('?')[0]
|
||||
return whiteList.indexOf(path) !== -1
|
||||
}
|
||||
|
||||
// 页面跳转验证拦截器
|
||||
let list = ["navigateTo", "redirectTo", "reLaunch", "switchTab"]
|
||||
list.forEach(item => {
|
||||
uni.addInterceptor(item, {
|
||||
invoke(to) {
|
||||
if (getToken()) {
|
||||
if (to.url === loginPageH5 || to.url === loginPageDingDing || to.url === loginPageWeChat) {
|
||||
uni.reLaunch({ url: "/" })
|
||||
}
|
||||
return true
|
||||
} else {
|
||||
if (checkWhite(to.url)) {
|
||||
return true
|
||||
}
|
||||
// uni.reLaunch({ url: loginPage })
|
||||
return false
|
||||
}
|
||||
},
|
||||
fail(err) {
|
||||
console.log(err)
|
||||
}
|
||||
})
|
||||
})
|
|
@ -0,0 +1,60 @@
|
|||
import store from '@/store'
|
||||
|
||||
function authPermission(permission) {
|
||||
const all_permission = "*:*:*"
|
||||
const permissions = store.getters && store.getters.permissions
|
||||
if (permission && permission.length > 0) {
|
||||
return permissions.some(v => {
|
||||
return all_permission === v || v === permission
|
||||
})
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
function authRole(role) {
|
||||
const super_admin = "admin"
|
||||
const roles = store.getters && store.getters.roles
|
||||
if (role && role.length > 0) {
|
||||
return roles.some(v => {
|
||||
return super_admin === v || v === role
|
||||
})
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
// 验证用户是否具备某权限
|
||||
hasPermi(permission) {
|
||||
return authPermission(permission)
|
||||
},
|
||||
// 验证用户是否含有指定权限,只需包含其中一个
|
||||
hasPermiOr(permissions) {
|
||||
return permissions.some(item => {
|
||||
return authPermission(item)
|
||||
})
|
||||
},
|
||||
// 验证用户是否含有指定权限,必须全部拥有
|
||||
hasPermiAnd(permissions) {
|
||||
return permissions.every(item => {
|
||||
return authPermission(item)
|
||||
})
|
||||
},
|
||||
// 验证用户是否具备某角色
|
||||
hasRole(role) {
|
||||
return authRole(role)
|
||||
},
|
||||
// 验证用户是否含有指定角色,只需包含其中一个
|
||||
hasRoleOr(roles) {
|
||||
return roles.some(item => {
|
||||
return authRole(item)
|
||||
})
|
||||
},
|
||||
// 验证用户是否含有指定角色,必须全部拥有
|
||||
hasRoleAnd(roles) {
|
||||
return roles.every(item => {
|
||||
return authRole(item)
|
||||
})
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
import tab from './tab'
|
||||
import auth from './auth'
|
||||
import modal from './modal'
|
||||
|
||||
export default {
|
||||
install(Vue) {
|
||||
// 页签操作
|
||||
Vue.prototype.$tab = tab
|
||||
// 认证对象
|
||||
Vue.prototype.$auth = auth
|
||||
// 模态框对象
|
||||
Vue.prototype.$modal = modal
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
export default {
|
||||
// 消息提示
|
||||
msg(content) {
|
||||
uni.showToast({
|
||||
title: content,
|
||||
icon: 'none'
|
||||
})
|
||||
},
|
||||
// 错误消息
|
||||
msgError(content) {
|
||||
uni.showToast({
|
||||
title: content,
|
||||
icon: 'error'
|
||||
})
|
||||
},
|
||||
// 成功消息
|
||||
msgSuccess(content) {
|
||||
uni.showToast({
|
||||
title: content,
|
||||
icon: 'success'
|
||||
})
|
||||
},
|
||||
// 隐藏消息
|
||||
hideMsg(content) {
|
||||
uni.hideToast()
|
||||
},
|
||||
// 弹出提示
|
||||
alert(content) {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: content,
|
||||
showCancel: false
|
||||
})
|
||||
},
|
||||
// 确认窗体
|
||||
confirm(content) {
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.showModal({
|
||||
title: '系统提示',
|
||||
content: content,
|
||||
cancelText: '取消',
|
||||
confirmText: '确定',
|
||||
success: function(res) {
|
||||
if (res.confirm) {
|
||||
resolve(res.confirm)
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
// 提示信息
|
||||
showToast(option) {
|
||||
if (typeof option === "object") {
|
||||
uni.showToast(option)
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: option,
|
||||
icon: "none",
|
||||
duration: 2500
|
||||
})
|
||||
}
|
||||
},
|
||||
// 打开遮罩层
|
||||
loading(content) {
|
||||
uni.showLoading({
|
||||
title: content,
|
||||
icon: 'none'
|
||||
})
|
||||
},
|
||||
// 关闭遮罩层
|
||||
closeLoading() {
|
||||
uni.hideLoading()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
export default {
|
||||
// 关闭所有页面,打开到应用内的某个页面
|
||||
reLaunch(url) {
|
||||
return uni.reLaunch({
|
||||
url: url
|
||||
})
|
||||
},
|
||||
// 跳转到tabBar页面,并关闭其他所有非tabBar页面
|
||||
switchTab(url) {
|
||||
return uni.switchTab({
|
||||
url: url
|
||||
})
|
||||
},
|
||||
// 关闭当前页面,跳转到应用内的某个页面
|
||||
redirectTo(url) {
|
||||
return uni.redirectTo({
|
||||
url: url
|
||||
})
|
||||
},
|
||||
// 保留当前页面,跳转到应用内的某个页面
|
||||
navigateTo(url) {
|
||||
return uni.navigateTo({
|
||||
url: url
|
||||
})
|
||||
},
|
||||
// 关闭当前页面,返回上一页面或多级页面
|
||||
navigateBack() {
|
||||
return uni.navigateBack()
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 5.2 KiB |
After Width: | Height: | Size: 198 KiB |
|
@ -0,0 +1,539 @@
|
|||
/* Logo 字体 */
|
||||
@font-face {
|
||||
font-family: "iconfont logo";
|
||||
src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834');
|
||||
src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'),
|
||||
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'),
|
||||
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'),
|
||||
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg');
|
||||
}
|
||||
|
||||
.logo {
|
||||
font-family: "iconfont logo";
|
||||
font-size: 160px;
|
||||
font-style: normal;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
/* tabs */
|
||||
.nav-tabs {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.nav-tabs .nav-more {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
height: 42px;
|
||||
line-height: 42px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
#tabs {
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
#tabs li {
|
||||
cursor: pointer;
|
||||
width: 100px;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
text-align: center;
|
||||
font-size: 16px;
|
||||
border-bottom: 2px solid transparent;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
margin-bottom: -1px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
|
||||
#tabs .active {
|
||||
border-bottom-color: #f00;
|
||||
color: #222;
|
||||
}
|
||||
|
||||
.tab-container .content {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* 页面布局 */
|
||||
.main {
|
||||
padding: 30px 100px;
|
||||
width: 960px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.main .logo {
|
||||
color: #333;
|
||||
text-align: left;
|
||||
margin-bottom: 30px;
|
||||
line-height: 1;
|
||||
height: 110px;
|
||||
margin-top: -50px;
|
||||
overflow: hidden;
|
||||
*zoom: 1;
|
||||
}
|
||||
|
||||
.main .logo a {
|
||||
font-size: 160px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.helps {
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
.helps pre {
|
||||
padding: 20px;
|
||||
margin: 10px 0;
|
||||
border: solid 1px #e7e1cd;
|
||||
background-color: #fffdef;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.icon_lists {
|
||||
width: 100% !important;
|
||||
overflow: hidden;
|
||||
*zoom: 1;
|
||||
}
|
||||
|
||||
.icon_lists li {
|
||||
width: 100px;
|
||||
margin-bottom: 10px;
|
||||
margin-right: 20px;
|
||||
text-align: center;
|
||||
list-style: none !important;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.icon_lists li .code-name {
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.icon_lists .icon {
|
||||
display: block;
|
||||
height: 100px;
|
||||
line-height: 100px;
|
||||
font-size: 42px;
|
||||
margin: 10px auto;
|
||||
color: #333;
|
||||
-webkit-transition: font-size 0.25s linear, width 0.25s linear;
|
||||
-moz-transition: font-size 0.25s linear, width 0.25s linear;
|
||||
transition: font-size 0.25s linear, width 0.25s linear;
|
||||
}
|
||||
|
||||
.icon_lists .icon:hover {
|
||||
font-size: 100px;
|
||||
}
|
||||
|
||||
.icon_lists .svg-icon {
|
||||
/* 通过设置 font-size 来改变图标大小 */
|
||||
width: 1em;
|
||||
/* 图标和文字相邻时,垂直对齐 */
|
||||
vertical-align: -0.15em;
|
||||
/* 通过设置 color 来改变 SVG 的颜色/fill */
|
||||
fill: currentColor;
|
||||
/* path 和 stroke 溢出 viewBox 部分在 IE 下会显示
|
||||
normalize.css 中也包含这行 */
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.icon_lists li .name,
|
||||
.icon_lists li .code-name {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
/* markdown 样式 */
|
||||
.markdown {
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
line-height: 1.8;
|
||||
}
|
||||
|
||||
.highlight {
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.markdown img {
|
||||
vertical-align: middle;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.markdown h1 {
|
||||
color: #404040;
|
||||
font-weight: 500;
|
||||
line-height: 40px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.markdown h2,
|
||||
.markdown h3,
|
||||
.markdown h4,
|
||||
.markdown h5,
|
||||
.markdown h6 {
|
||||
color: #404040;
|
||||
margin: 1.6em 0 0.6em 0;
|
||||
font-weight: 500;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.markdown h1 {
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
.markdown h2 {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
.markdown h3 {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.markdown h4 {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.markdown h5 {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.markdown h6 {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.markdown hr {
|
||||
height: 1px;
|
||||
border: 0;
|
||||
background: #e9e9e9;
|
||||
margin: 16px 0;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.markdown p {
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
.markdown>p,
|
||||
.markdown>blockquote,
|
||||
.markdown>.highlight,
|
||||
.markdown>ol,
|
||||
.markdown>ul {
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
.markdown ul>li {
|
||||
list-style: circle;
|
||||
}
|
||||
|
||||
.markdown>ul li,
|
||||
.markdown blockquote ul>li {
|
||||
margin-left: 20px;
|
||||
padding-left: 4px;
|
||||
}
|
||||
|
||||
.markdown>ul li p,
|
||||
.markdown>ol li p {
|
||||
margin: 0.6em 0;
|
||||
}
|
||||
|
||||
.markdown ol>li {
|
||||
list-style: decimal;
|
||||
}
|
||||
|
||||
.markdown>ol li,
|
||||
.markdown blockquote ol>li {
|
||||
margin-left: 20px;
|
||||
padding-left: 4px;
|
||||
}
|
||||
|
||||
.markdown code {
|
||||
margin: 0 3px;
|
||||
padding: 0 5px;
|
||||
background: #eee;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.markdown strong,
|
||||
.markdown b {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.markdown>table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0px;
|
||||
empty-cells: show;
|
||||
border: 1px solid #e9e9e9;
|
||||
width: 95%;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.markdown>table th {
|
||||
white-space: nowrap;
|
||||
color: #333;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.markdown>table th,
|
||||
.markdown>table td {
|
||||
border: 1px solid #e9e9e9;
|
||||
padding: 8px 16px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.markdown>table th {
|
||||
background: #F7F7F7;
|
||||
}
|
||||
|
||||
.markdown blockquote {
|
||||
font-size: 90%;
|
||||
color: #999;
|
||||
border-left: 4px solid #e9e9e9;
|
||||
padding-left: 0.8em;
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
.markdown blockquote p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.markdown .anchor {
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease;
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.markdown .waiting {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.markdown h1:hover .anchor,
|
||||
.markdown h2:hover .anchor,
|
||||
.markdown h3:hover .anchor,
|
||||
.markdown h4:hover .anchor,
|
||||
.markdown h5:hover .anchor,
|
||||
.markdown h6:hover .anchor {
|
||||
opacity: 1;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.markdown>br,
|
||||
.markdown>p>br {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
background: white;
|
||||
padding: 0.5em;
|
||||
color: #333333;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-meta {
|
||||
color: #969896;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-strong,
|
||||
.hljs-emphasis,
|
||||
.hljs-quote {
|
||||
color: #df5000;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-type {
|
||||
color: #a71d5d;
|
||||
}
|
||||
|
||||
.hljs-literal,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-attribute {
|
||||
color: #0086b3;
|
||||
}
|
||||
|
||||
.hljs-section,
|
||||
.hljs-name {
|
||||
color: #63a35c;
|
||||
}
|
||||
|
||||
.hljs-tag {
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.hljs-title,
|
||||
.hljs-attr,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class,
|
||||
.hljs-selector-attr,
|
||||
.hljs-selector-pseudo {
|
||||
color: #795da3;
|
||||
}
|
||||
|
||||
.hljs-addition {
|
||||
color: #55a532;
|
||||
background-color: #eaffea;
|
||||
}
|
||||
|
||||
.hljs-deletion {
|
||||
color: #bd2c00;
|
||||
background-color: #ffecec;
|
||||
}
|
||||
|
||||
.hljs-link {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* 代码高亮 */
|
||||
/* PrismJS 1.15.0
|
||||
https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */
|
||||
/**
|
||||
* prism.js default theme for JavaScript, CSS and HTML
|
||||
* Based on dabblet (http://dabblet.com)
|
||||
* @author Lea Verou
|
||||
*/
|
||||
code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
color: black;
|
||||
background: none;
|
||||
text-shadow: 0 1px white;
|
||||
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
|
||||
text-align: left;
|
||||
white-space: pre;
|
||||
word-spacing: normal;
|
||||
word-break: normal;
|
||||
word-wrap: normal;
|
||||
line-height: 1.5;
|
||||
|
||||
-moz-tab-size: 4;
|
||||
-o-tab-size: 4;
|
||||
tab-size: 4;
|
||||
|
||||
-webkit-hyphens: none;
|
||||
-moz-hyphens: none;
|
||||
-ms-hyphens: none;
|
||||
hyphens: none;
|
||||
}
|
||||
|
||||
pre[class*="language-"]::-moz-selection,
|
||||
pre[class*="language-"] ::-moz-selection,
|
||||
code[class*="language-"]::-moz-selection,
|
||||
code[class*="language-"] ::-moz-selection {
|
||||
text-shadow: none;
|
||||
background: #b3d4fc;
|
||||
}
|
||||
|
||||
pre[class*="language-"]::selection,
|
||||
pre[class*="language-"] ::selection,
|
||||
code[class*="language-"]::selection,
|
||||
code[class*="language-"] ::selection {
|
||||
text-shadow: none;
|
||||
background: #b3d4fc;
|
||||
}
|
||||
|
||||
@media print {
|
||||
|
||||
code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
text-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Code blocks */
|
||||
pre[class*="language-"] {
|
||||
padding: 1em;
|
||||
margin: .5em 0;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
:not(pre)>code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
background: #f5f2f0;
|
||||
}
|
||||
|
||||
/* Inline code */
|
||||
:not(pre)>code[class*="language-"] {
|
||||
padding: .1em;
|
||||
border-radius: .3em;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.token.comment,
|
||||
.token.prolog,
|
||||
.token.doctype,
|
||||
.token.cdata {
|
||||
color: slategray;
|
||||
}
|
||||
|
||||
.token.punctuation {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.namespace {
|
||||
opacity: .7;
|
||||
}
|
||||
|
||||
.token.property,
|
||||
.token.tag,
|
||||
.token.boolean,
|
||||
.token.number,
|
||||
.token.constant,
|
||||
.token.symbol,
|
||||
.token.deleted {
|
||||
color: #905;
|
||||
}
|
||||
|
||||
.token.selector,
|
||||
.token.attr-name,
|
||||
.token.string,
|
||||
.token.char,
|
||||
.token.builtin,
|
||||
.token.inserted {
|
||||
color: #690;
|
||||
}
|
||||
|
||||
.token.operator,
|
||||
.token.entity,
|
||||
.token.url,
|
||||
.language-css .token.string,
|
||||
.style .token.string {
|
||||
color: #9a6e3a;
|
||||
background: hsla(0, 0%, 100%, .5);
|
||||
}
|
||||
|
||||
.token.atrule,
|
||||
.token.attr-value,
|
||||
.token.keyword {
|
||||
color: #07a;
|
||||
}
|
||||
|
||||
.token.function,
|
||||
.token.class-name {
|
||||
color: #DD4A68;
|
||||
}
|
||||
|
||||
.token.regex,
|
||||
.token.important,
|
||||
.token.variable {
|
||||
color: #e90;
|
||||
}
|
||||
|
||||
.token.important,
|
||||
.token.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.token.italic {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.token.entity {
|
||||
cursor: help;
|
||||
}
|
|
@ -0,0 +1,260 @@
|
|||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 4141561 */
|
||||
src: url('@/static/font/iconfont.ttf') format('truetype');
|
||||
}
|
||||
.iconfont {
|
||||
font-family: "iconfont" !important;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-biaoqian:before {
|
||||
content: "\e606";
|
||||
}
|
||||
|
||||
.icon-approval-opinion2:before {
|
||||
content: "\e60f";
|
||||
}
|
||||
|
||||
.icon-wenjianjiashezhi:before {
|
||||
content: "\e87a";
|
||||
}
|
||||
|
||||
.icon-banxingshezhi:before {
|
||||
content: "\e601";
|
||||
}
|
||||
|
||||
.icon-shezhi-jiemianshezhi:before {
|
||||
content: "\e602";
|
||||
}
|
||||
|
||||
.icon-shiliangzhinengduixiang-:before {
|
||||
content: "\e6ad";
|
||||
}
|
||||
|
||||
.icon-fl-shuazi:before {
|
||||
content: "\e619";
|
||||
}
|
||||
|
||||
.icon-danju:before {
|
||||
content: "\e89b";
|
||||
}
|
||||
|
||||
.icon-lingdang:before {
|
||||
content: "\e8c0";
|
||||
}
|
||||
|
||||
.icon-laba:before {
|
||||
content: "\e628";
|
||||
}
|
||||
|
||||
.icon-zhang:before {
|
||||
content: "\e610";
|
||||
}
|
||||
|
||||
.icon-jiaojieqingkuang:before {
|
||||
content: "\e600";
|
||||
}
|
||||
|
||||
.icon-bianji:before {
|
||||
content: "\e621";
|
||||
}
|
||||
|
||||
.icon-shenhe1:before {
|
||||
content: "\e65d";
|
||||
}
|
||||
|
||||
.icon-gengxinrizhi:before {
|
||||
content: "\e66b";
|
||||
}
|
||||
|
||||
.icon-caidanguanli:before {
|
||||
content: "\e66c";
|
||||
}
|
||||
|
||||
.icon-anniuguanli:before {
|
||||
content: "\e66d";
|
||||
}
|
||||
|
||||
.icon-jihuakanban:before {
|
||||
content: "\e66e";
|
||||
}
|
||||
|
||||
.icon-hetongjieduandangan:before {
|
||||
content: "\e66f";
|
||||
}
|
||||
|
||||
.icon-cunhuodangan:before {
|
||||
content: "\e670";
|
||||
}
|
||||
|
||||
.icon-kehudangan:before {
|
||||
content: "\e671";
|
||||
}
|
||||
|
||||
.icon-lanjierizhi:before {
|
||||
content: "\e672";
|
||||
}
|
||||
|
||||
.icon-quanxianguanli:before {
|
||||
content: "\e674";
|
||||
}
|
||||
|
||||
.icon-fapiaoguanli:before {
|
||||
content: "\e675";
|
||||
}
|
||||
|
||||
.icon-kaoqinguanli:before {
|
||||
content: "\e676";
|
||||
}
|
||||
|
||||
.icon-liuchengguanli:before {
|
||||
content: "\e677";
|
||||
}
|
||||
|
||||
.icon-gongyingshangdangan:before {
|
||||
content: "\e678";
|
||||
}
|
||||
|
||||
.icon-renwushenhe:before {
|
||||
content: "\e679";
|
||||
}
|
||||
|
||||
.icon-tubiaoku:before {
|
||||
content: "\e67a";
|
||||
}
|
||||
|
||||
.icon-sanfangxitong:before {
|
||||
content: "\e67b";
|
||||
}
|
||||
|
||||
.icon-shujuzidian:before {
|
||||
content: "\e67c";
|
||||
}
|
||||
|
||||
.icon-wodejihua:before {
|
||||
content: "\e67d";
|
||||
}
|
||||
|
||||
.icon-shoukuanguanli:before {
|
||||
content: "\e67e";
|
||||
}
|
||||
|
||||
.icon-shangji:before {
|
||||
content: "\e67f";
|
||||
}
|
||||
|
||||
.icon-rizhishenhe:before {
|
||||
content: "\e680";
|
||||
}
|
||||
|
||||
.icon-renwuxiafa:before {
|
||||
content: "\e681";
|
||||
}
|
||||
|
||||
.icon-woderizhi:before {
|
||||
content: "\e682";
|
||||
}
|
||||
|
||||
.icon-xiansuo:before {
|
||||
content: "\e683";
|
||||
}
|
||||
|
||||
.icon-woderenwu:before {
|
||||
content: "\e684";
|
||||
}
|
||||
|
||||
.icon-yewuyuanzhibiaoshezhi:before {
|
||||
content: "\e685";
|
||||
}
|
||||
|
||||
.icon-xiangmuxinzeng:before {
|
||||
content: "\e686";
|
||||
}
|
||||
|
||||
.icon-xiaoshouhetong:before {
|
||||
content: "\e687";
|
||||
}
|
||||
|
||||
.icon-yonghufankui:before {
|
||||
content: "\e688";
|
||||
}
|
||||
|
||||
.icon-yongcheguanli:before {
|
||||
content: "\e689";
|
||||
}
|
||||
|
||||
.icon-xiangmujieduanjihua:before {
|
||||
content: "\e68a";
|
||||
}
|
||||
|
||||
.icon-xiaoxijilu:before {
|
||||
content: "\e68b";
|
||||
}
|
||||
|
||||
.icon-yonghuguanli:before {
|
||||
content: "\e68c";
|
||||
}
|
||||
|
||||
.icon-xiangmuwenti:before {
|
||||
content: "\e68d";
|
||||
}
|
||||
|
||||
.icon-xiangmuqingdan:before {
|
||||
content: "\e68e";
|
||||
}
|
||||
|
||||
.icon-xiangmuchakan:before {
|
||||
content: "\e68f";
|
||||
}
|
||||
|
||||
.icon-shoucangwangzhi:before {
|
||||
content: "\e690";
|
||||
}
|
||||
|
||||
.icon-yuangongguanhuai:before {
|
||||
content: "\e691";
|
||||
}
|
||||
|
||||
.icon-zuzhijigou:before {
|
||||
content: "\e692";
|
||||
}
|
||||
|
||||
.icon-zaixianrenshu:before {
|
||||
content: "\e693";
|
||||
}
|
||||
|
||||
.icon-zuzhijiagou:before {
|
||||
content: "\e694";
|
||||
}
|
||||
|
||||
.icon-bugguanli:before {
|
||||
content: "\e695";
|
||||
}
|
||||
|
||||
.icon-dingshirenwu:before {
|
||||
content: "\e666";
|
||||
}
|
||||
|
||||
.icon-danjuguanli:before {
|
||||
content: "\e667";
|
||||
}
|
||||
|
||||
.icon-caozuorizhi:before {
|
||||
content: "\e668";
|
||||
}
|
||||
|
||||
.icon-chushihuashezhi:before {
|
||||
content: "\e669";
|
||||
}
|
||||
|
||||
.icon-denglurizhi:before {
|
||||
content: "\e66a";
|
||||
}
|
||||
|
||||
.icon-loukong:before {
|
||||
content: "\e673";
|
||||
}
|
||||
|
|
@ -0,0 +1,443 @@
|
|||
{
|
||||
"id": "4141561",
|
||||
"name": "移动端——公司用安数智中台",
|
||||
"font_family": "iconfont",
|
||||
"css_prefix_text": "icon-",
|
||||
"description": "",
|
||||
"glyphs": [
|
||||
{
|
||||
"icon_id": "17930629",
|
||||
"name": "标签",
|
||||
"font_class": "biaoqian",
|
||||
"unicode": "e606",
|
||||
"unicode_decimal": 58886
|
||||
},
|
||||
{
|
||||
"icon_id": "28174575",
|
||||
"name": "approval-opinion2",
|
||||
"font_class": "approval-opinion2",
|
||||
"unicode": "e60f",
|
||||
"unicode_decimal": 58895
|
||||
},
|
||||
{
|
||||
"icon_id": "34220364",
|
||||
"name": "文件夹设置",
|
||||
"font_class": "wenjianjiashezhi",
|
||||
"unicode": "e87a",
|
||||
"unicode_decimal": 59514
|
||||
},
|
||||
{
|
||||
"icon_id": "34586059",
|
||||
"name": "班型设置",
|
||||
"font_class": "banxingshezhi",
|
||||
"unicode": "e601",
|
||||
"unicode_decimal": 58881
|
||||
},
|
||||
{
|
||||
"icon_id": "35472944",
|
||||
"name": "设置-界面设置",
|
||||
"font_class": "shezhi-jiemianshezhi",
|
||||
"unicode": "e602",
|
||||
"unicode_decimal": 58882
|
||||
},
|
||||
{
|
||||
"icon_id": "3629124",
|
||||
"name": "列表空空",
|
||||
"font_class": "shiliangzhinengduixiang-",
|
||||
"unicode": "e6ad",
|
||||
"unicode_decimal": 59053
|
||||
},
|
||||
{
|
||||
"icon_id": "2406018",
|
||||
"name": "刷子",
|
||||
"font_class": "fl-shuazi",
|
||||
"unicode": "e619",
|
||||
"unicode_decimal": 58905
|
||||
},
|
||||
{
|
||||
"icon_id": "1727362",
|
||||
"name": "25单据",
|
||||
"font_class": "danju",
|
||||
"unicode": "e89b",
|
||||
"unicode_decimal": 59547
|
||||
},
|
||||
{
|
||||
"icon_id": "1727435",
|
||||
"name": "211铃铛",
|
||||
"font_class": "lingdang",
|
||||
"unicode": "e8c0",
|
||||
"unicode_decimal": 59584
|
||||
},
|
||||
{
|
||||
"icon_id": "1929807",
|
||||
"name": "喇叭",
|
||||
"font_class": "laba",
|
||||
"unicode": "e628",
|
||||
"unicode_decimal": 58920
|
||||
},
|
||||
{
|
||||
"icon_id": "7933562",
|
||||
"name": "章",
|
||||
"font_class": "zhang",
|
||||
"unicode": "e610",
|
||||
"unicode_decimal": 58896
|
||||
},
|
||||
{
|
||||
"icon_id": "4360975",
|
||||
"name": "交接情况",
|
||||
"font_class": "jiaojieqingkuang",
|
||||
"unicode": "e600",
|
||||
"unicode_decimal": 58880
|
||||
},
|
||||
{
|
||||
"icon_id": "33987167",
|
||||
"name": "编辑",
|
||||
"font_class": "bianji",
|
||||
"unicode": "e621",
|
||||
"unicode_decimal": 58913
|
||||
},
|
||||
{
|
||||
"icon_id": "31716702",
|
||||
"name": "审核",
|
||||
"font_class": "shenhe1",
|
||||
"unicode": "e65d",
|
||||
"unicode_decimal": 58973
|
||||
},
|
||||
{
|
||||
"icon_id": "36301611",
|
||||
"name": "更新日志",
|
||||
"font_class": "gengxinrizhi",
|
||||
"unicode": "e66b",
|
||||
"unicode_decimal": 58987
|
||||
},
|
||||
{
|
||||
"icon_id": "36301612",
|
||||
"name": "菜单管理",
|
||||
"font_class": "caidanguanli",
|
||||
"unicode": "e66c",
|
||||
"unicode_decimal": 58988
|
||||
},
|
||||
{
|
||||
"icon_id": "36301613",
|
||||
"name": "按钮管理",
|
||||
"font_class": "anniuguanli",
|
||||
"unicode": "e66d",
|
||||
"unicode_decimal": 58989
|
||||
},
|
||||
{
|
||||
"icon_id": "36301614",
|
||||
"name": "计划看板",
|
||||
"font_class": "jihuakanban",
|
||||
"unicode": "e66e",
|
||||
"unicode_decimal": 58990
|
||||
},
|
||||
{
|
||||
"icon_id": "36301615",
|
||||
"name": "合同阶段档案",
|
||||
"font_class": "hetongjieduandangan",
|
||||
"unicode": "e66f",
|
||||
"unicode_decimal": 58991
|
||||
},
|
||||
{
|
||||
"icon_id": "36301616",
|
||||
"name": "存货档案",
|
||||
"font_class": "cunhuodangan",
|
||||
"unicode": "e670",
|
||||
"unicode_decimal": 58992
|
||||
},
|
||||
{
|
||||
"icon_id": "36301617",
|
||||
"name": "客户档案",
|
||||
"font_class": "kehudangan",
|
||||
"unicode": "e671",
|
||||
"unicode_decimal": 58993
|
||||
},
|
||||
{
|
||||
"icon_id": "36301618",
|
||||
"name": "拦截日志",
|
||||
"font_class": "lanjierizhi",
|
||||
"unicode": "e672",
|
||||
"unicode_decimal": 58994
|
||||
},
|
||||
{
|
||||
"icon_id": "36301619",
|
||||
"name": "权限管理",
|
||||
"font_class": "quanxianguanli",
|
||||
"unicode": "e674",
|
||||
"unicode_decimal": 58996
|
||||
},
|
||||
{
|
||||
"icon_id": "36301620",
|
||||
"name": "发票管理",
|
||||
"font_class": "fapiaoguanli",
|
||||
"unicode": "e675",
|
||||
"unicode_decimal": 58997
|
||||
},
|
||||
{
|
||||
"icon_id": "36301621",
|
||||
"name": "考勤管理",
|
||||
"font_class": "kaoqinguanli",
|
||||
"unicode": "e676",
|
||||
"unicode_decimal": 58998
|
||||
},
|
||||
{
|
||||
"icon_id": "36301622",
|
||||
"name": "流程管理",
|
||||
"font_class": "liuchengguanli",
|
||||
"unicode": "e677",
|
||||
"unicode_decimal": 58999
|
||||
},
|
||||
{
|
||||
"icon_id": "36301623",
|
||||
"name": "供应商档案",
|
||||
"font_class": "gongyingshangdangan",
|
||||
"unicode": "e678",
|
||||
"unicode_decimal": 59000
|
||||
},
|
||||
{
|
||||
"icon_id": "36301624",
|
||||
"name": "任务审核",
|
||||
"font_class": "renwushenhe",
|
||||
"unicode": "e679",
|
||||
"unicode_decimal": 59001
|
||||
},
|
||||
{
|
||||
"icon_id": "36301625",
|
||||
"name": "图标库",
|
||||
"font_class": "tubiaoku",
|
||||
"unicode": "e67a",
|
||||
"unicode_decimal": 59002
|
||||
},
|
||||
{
|
||||
"icon_id": "36301626",
|
||||
"name": "三方系统",
|
||||
"font_class": "sanfangxitong",
|
||||
"unicode": "e67b",
|
||||
"unicode_decimal": 59003
|
||||
},
|
||||
{
|
||||
"icon_id": "36301627",
|
||||
"name": "数据字典",
|
||||
"font_class": "shujuzidian",
|
||||
"unicode": "e67c",
|
||||
"unicode_decimal": 59004
|
||||
},
|
||||
{
|
||||
"icon_id": "36301628",
|
||||
"name": "我的计划",
|
||||
"font_class": "wodejihua",
|
||||
"unicode": "e67d",
|
||||
"unicode_decimal": 59005
|
||||
},
|
||||
{
|
||||
"icon_id": "36301629",
|
||||
"name": "收款管理",
|
||||
"font_class": "shoukuanguanli",
|
||||
"unicode": "e67e",
|
||||
"unicode_decimal": 59006
|
||||
},
|
||||
{
|
||||
"icon_id": "36301630",
|
||||
"name": "商机",
|
||||
"font_class": "shangji",
|
||||
"unicode": "e67f",
|
||||
"unicode_decimal": 59007
|
||||
},
|
||||
{
|
||||
"icon_id": "36301631",
|
||||
"name": "日志审核",
|
||||
"font_class": "rizhishenhe",
|
||||
"unicode": "e680",
|
||||
"unicode_decimal": 59008
|
||||
},
|
||||
{
|
||||
"icon_id": "36301632",
|
||||
"name": "任务下发",
|
||||
"font_class": "renwuxiafa",
|
||||
"unicode": "e681",
|
||||
"unicode_decimal": 59009
|
||||
},
|
||||
{
|
||||
"icon_id": "36301633",
|
||||
"name": "我的日志",
|
||||
"font_class": "woderizhi",
|
||||
"unicode": "e682",
|
||||
"unicode_decimal": 59010
|
||||
},
|
||||
{
|
||||
"icon_id": "36301634",
|
||||
"name": "线索",
|
||||
"font_class": "xiansuo",
|
||||
"unicode": "e683",
|
||||
"unicode_decimal": 59011
|
||||
},
|
||||
{
|
||||
"icon_id": "36301635",
|
||||
"name": "我的任务",
|
||||
"font_class": "woderenwu",
|
||||
"unicode": "e684",
|
||||
"unicode_decimal": 59012
|
||||
},
|
||||
{
|
||||
"icon_id": "36301636",
|
||||
"name": "业务员指标设置",
|
||||
"font_class": "yewuyuanzhibiaoshezhi",
|
||||
"unicode": "e685",
|
||||
"unicode_decimal": 59013
|
||||
},
|
||||
{
|
||||
"icon_id": "36301637",
|
||||
"name": "项目新增",
|
||||
"font_class": "xiangmuxinzeng",
|
||||
"unicode": "e686",
|
||||
"unicode_decimal": 59014
|
||||
},
|
||||
{
|
||||
"icon_id": "36301638",
|
||||
"name": "销售合同",
|
||||
"font_class": "xiaoshouhetong",
|
||||
"unicode": "e687",
|
||||
"unicode_decimal": 59015
|
||||
},
|
||||
{
|
||||
"icon_id": "36301639",
|
||||
"name": "用户反馈",
|
||||
"font_class": "yonghufankui",
|
||||
"unicode": "e688",
|
||||
"unicode_decimal": 59016
|
||||
},
|
||||
{
|
||||
"icon_id": "36301640",
|
||||
"name": "用车管理",
|
||||
"font_class": "yongcheguanli",
|
||||
"unicode": "e689",
|
||||
"unicode_decimal": 59017
|
||||
},
|
||||
{
|
||||
"icon_id": "36301641",
|
||||
"name": "项目阶段计划",
|
||||
"font_class": "xiangmujieduanjihua",
|
||||
"unicode": "e68a",
|
||||
"unicode_decimal": 59018
|
||||
},
|
||||
{
|
||||
"icon_id": "36301642",
|
||||
"name": "消息记录",
|
||||
"font_class": "xiaoxijilu",
|
||||
"unicode": "e68b",
|
||||
"unicode_decimal": 59019
|
||||
},
|
||||
{
|
||||
"icon_id": "36301643",
|
||||
"name": "用户管理",
|
||||
"font_class": "yonghuguanli",
|
||||
"unicode": "e68c",
|
||||
"unicode_decimal": 59020
|
||||
},
|
||||
{
|
||||
"icon_id": "36301644",
|
||||
"name": "项目问题",
|
||||
"font_class": "xiangmuwenti",
|
||||
"unicode": "e68d",
|
||||
"unicode_decimal": 59021
|
||||
},
|
||||
{
|
||||
"icon_id": "36301645",
|
||||
"name": "项目清单",
|
||||
"font_class": "xiangmuqingdan",
|
||||
"unicode": "e68e",
|
||||
"unicode_decimal": 59022
|
||||
},
|
||||
{
|
||||
"icon_id": "36301646",
|
||||
"name": "项目查看",
|
||||
"font_class": "xiangmuchakan",
|
||||
"unicode": "e68f",
|
||||
"unicode_decimal": 59023
|
||||
},
|
||||
{
|
||||
"icon_id": "36301647",
|
||||
"name": "收藏网址",
|
||||
"font_class": "shoucangwangzhi",
|
||||
"unicode": "e690",
|
||||
"unicode_decimal": 59024
|
||||
},
|
||||
{
|
||||
"icon_id": "36301648",
|
||||
"name": "员工关怀",
|
||||
"font_class": "yuangongguanhuai",
|
||||
"unicode": "e691",
|
||||
"unicode_decimal": 59025
|
||||
},
|
||||
{
|
||||
"icon_id": "36301649",
|
||||
"name": "组织机构",
|
||||
"font_class": "zuzhijigou",
|
||||
"unicode": "e692",
|
||||
"unicode_decimal": 59026
|
||||
},
|
||||
{
|
||||
"icon_id": "36301650",
|
||||
"name": "在线人数",
|
||||
"font_class": "zaixianrenshu",
|
||||
"unicode": "e693",
|
||||
"unicode_decimal": 59027
|
||||
},
|
||||
{
|
||||
"icon_id": "36301651",
|
||||
"name": "组织架构",
|
||||
"font_class": "zuzhijiagou",
|
||||
"unicode": "e694",
|
||||
"unicode_decimal": 59028
|
||||
},
|
||||
{
|
||||
"icon_id": "36301652",
|
||||
"name": "bug管理",
|
||||
"font_class": "bugguanli",
|
||||
"unicode": "e695",
|
||||
"unicode_decimal": 59029
|
||||
},
|
||||
{
|
||||
"icon_id": "36301606",
|
||||
"name": "定时任务",
|
||||
"font_class": "dingshirenwu",
|
||||
"unicode": "e666",
|
||||
"unicode_decimal": 58982
|
||||
},
|
||||
{
|
||||
"icon_id": "36301607",
|
||||
"name": "单据管理",
|
||||
"font_class": "danjuguanli",
|
||||
"unicode": "e667",
|
||||
"unicode_decimal": 58983
|
||||
},
|
||||
{
|
||||
"icon_id": "36301608",
|
||||
"name": "操作日志",
|
||||
"font_class": "caozuorizhi",
|
||||
"unicode": "e668",
|
||||
"unicode_decimal": 58984
|
||||
},
|
||||
{
|
||||
"icon_id": "36301609",
|
||||
"name": "初始化设置",
|
||||
"font_class": "chushihuashezhi",
|
||||
"unicode": "e669",
|
||||
"unicode_decimal": 58985
|
||||
},
|
||||
{
|
||||
"icon_id": "36301610",
|
||||
"name": "登录日志",
|
||||
"font_class": "denglurizhi",
|
||||
"unicode": "e66a",
|
||||
"unicode_decimal": 58986
|
||||
},
|
||||
{
|
||||
"icon_id": "36293495",
|
||||
"name": "镂空",
|
||||
"font_class": "loukong",
|
||||
"unicode": "e673",
|
||||
"unicode_decimal": 58995
|
||||
}
|
||||
]
|
||||
}
|
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 351 B |
After Width: | Height: | Size: 316 B |
After Width: | Height: | Size: 351 B |
After Width: | Height: | Size: 349 B |
After Width: | Height: | Size: 182 B |
After Width: | Height: | Size: 6.0 KiB |
After Width: | Height: | Size: 6.4 KiB |
After Width: | Height: | Size: 5.9 KiB |
After Width: | Height: | Size: 178 B |
After Width: | Height: | Size: 313 B |
After Width: | Height: | Size: 285 B |
After Width: | Height: | Size: 313 B |
After Width: | Height: | Size: 313 B |
After Width: | Height: | Size: 4.4 KiB |
After Width: | Height: | Size: 21 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 88 KiB |
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 79 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.6 KiB |
|
@ -0,0 +1,20 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="renderer" content="webkit">
|
||||
<title><%= htmlWebpackPlugin.options.title %></title>
|
||||
<link rel="shortcut icon" type="image/x-icon" href="<%= BASE_URL %>static/favicon.ico">
|
||||
<script>
|
||||
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') || CSS.supports('top: constant(a)'))
|
||||
document.write('<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' + (coverSupport ? ', viewport-fit=cover' : '') + '" />')
|
||||
</script>
|
||||
<link rel="stylesheet" href="<%= BASE_URL %>static/index.<%= VUE_APP_INDEX_CSS_HASH %>.css" />
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
<strong>本站点必须要开启JavaScript才能运行.</strong>
|
||||
</noscript>
|
||||
<div id="app"></div>
|
||||
</html>
|
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 8.8 KiB |
|
@ -0,0 +1,109 @@
|
|||
.text-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.font-13 {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.font-12 {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.font-11 {
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.text-grey1 {
|
||||
color: #888;
|
||||
}
|
||||
|
||||
.text-grey2 {
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
.list-cell-arrow::before {
|
||||
content: ' ';
|
||||
height: 10px;
|
||||
width: 10px;
|
||||
border-width: 2px 2px 0 0;
|
||||
border-color: #c0c0c0;
|
||||
border-style: solid;
|
||||
-webkit-transform: matrix(0.5, 0.5, -0.5, 0.5, 0, 0);
|
||||
transform: matrix(0.5, 0.5, -0.5, 0.5, 0, 0);
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
margin-top: -6px;
|
||||
right: 30rpx;
|
||||
}
|
||||
|
||||
.list-cell {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
background-color: #fff;
|
||||
color: #333;
|
||||
padding: 26rpx 30rpx;
|
||||
}
|
||||
|
||||
.list-cell:first-child {
|
||||
border-radius: 8rpx 8rpx 0 0;
|
||||
}
|
||||
|
||||
.list-cell:last-child {
|
||||
border-radius: 0 0 8rpx 8rpx;
|
||||
}
|
||||
|
||||
.list-cell::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
border-bottom: 1px solid #eaeef1;
|
||||
-webkit-transform: scaleY(0.5) translateZ(0);
|
||||
transform: scaleY(0.5) translateZ(0);
|
||||
transform-origin: 0 100%;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.menu-list {
|
||||
margin: 15px 15px;
|
||||
}
|
||||
|
||||
.menu-list .menu-item-box {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.menu-list .menu-item-box .menu-icon {
|
||||
color: #007AFF;
|
||||
font-size: 16px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.menu-list .menu-item-box .text-right {
|
||||
margin-left: auto;
|
||||
margin-right: 34rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.requiredStyle .is-input-border {
|
||||
border-color: #e6a23c !important;
|
||||
}
|
||||
|
||||
.requiredStyle .u-radio__icon-wrap.u-radio__icon-wrap--circle {
|
||||
border-color: #e6a23c !important;
|
||||
}
|
||||
|
||||
.contractTitle::before {
|
||||
content: "";
|
||||
background: #3c9cff;
|
||||
display: inline-block;
|
||||
width: 3px;
|
||||
height: 17px;
|
||||
position: relative;
|
||||
margin-right: 10px;
|
||||
top: 4px;
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
.text-center{text-align:center}.font-13{font-size:13px}.font-12{font-size:12px}.font-11{font-size:11px}.text-grey1{color:#888}.text-grey2{color:#aaa}.list-cell-arrow::before{content:' ';height:10px;width:10px;border-width:2px 2px 0 0;border-color:#c0c0c0;border-style:solid;-webkit-transform:matrix(0.5, 0.5, -0.5, 0.5, 0, 0);transform:matrix(0.5, 0.5, -0.5, 0.5, 0, 0);position:absolute;top:50%;margin-top:-6px;right:30rpx}.list-cell{position:relative;width:100%;box-sizing:border-box;background-color:#fff;color:#333;padding:26rpx 30rpx}.list-cell:first-child{border-radius:8rpx 8rpx 0 0}.list-cell:last-child{border-radius:0 0 8rpx 8rpx}.list-cell::after{content:'';position:absolute;border-bottom:1px solid #eaeef1;-webkit-transform:scaleY(0.5) translateZ(0);transform:scaleY(0.5) translateZ(0);transform-origin:0 100%;bottom:0;right:0;left:0;pointer-events:none}.menu-list{margin:15px 15px}.menu-list .menu-item-box{width:100%;display:flex;align-items:center}.menu-list .menu-item-box .menu-icon{color:#007AFF;font-size:16px;margin-right:5px}.menu-list .menu-item-box .text-right{margin-left:auto;margin-right:34rpx;color:#999}.requiredStyle .is-input-border{border-color:#e6a23c !important}.requiredStyle .u-radio__icon-wrap.u-radio__icon-wrap--circle{border-color:#e6a23c !important}.contractTitle::before{content:"";background:#3c9cff;display:inline-block;width:3px;height:17px;position:relative;margin-right:10px;top:4px}
|
|
@ -0,0 +1,110 @@
|
|||
.text-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.font-13 {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.font-12 {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.font-11 {
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.text-grey1 {
|
||||
color: #888;
|
||||
}
|
||||
.text-grey2 {
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
.list-cell-arrow::before {
|
||||
content: ' ';
|
||||
height: 10px;
|
||||
width: 10px;
|
||||
border-width: 2px 2px 0 0;
|
||||
border-color: #c0c0c0;
|
||||
border-style: solid;
|
||||
-webkit-transform: matrix(0.5, 0.5, -0.5, 0.5, 0, 0);
|
||||
transform: matrix(0.5, 0.5, -0.5, 0.5, 0, 0);
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
margin-top: -6px;
|
||||
right: 30rpx;
|
||||
}
|
||||
|
||||
.list-cell {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
background-color: #fff;
|
||||
color: #333;
|
||||
padding: 26rpx 30rpx;
|
||||
}
|
||||
|
||||
.list-cell:first-child {
|
||||
border-radius: 8rpx 8rpx 0 0;
|
||||
}
|
||||
|
||||
.list-cell:last-child {
|
||||
border-radius: 0 0 8rpx 8rpx;
|
||||
}
|
||||
|
||||
.list-cell::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
border-bottom: 1px solid #eaeef1;
|
||||
-webkit-transform: scaleY(0.5) translateZ(0);
|
||||
transform: scaleY(0.5) translateZ(0);
|
||||
transform-origin: 0 100%;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
|
||||
.menu-list {
|
||||
margin: 15px 15px;
|
||||
|
||||
.menu-item-box {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.menu-icon {
|
||||
color: #007AFF;
|
||||
font-size: 16px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.text-right {
|
||||
margin-left: auto;
|
||||
margin-right: 34rpx;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.requiredStyle .is-input-border{
|
||||
border-color: #e6a23c !important;
|
||||
}
|
||||
.requiredStyle .u-radio__icon-wrap.u-radio__icon-wrap--circle{
|
||||
border-color: #e6a23c !important;
|
||||
}
|
||||
.contractTitle {
|
||||
&::before {
|
||||
content: "";
|
||||
background: #3c9cff;
|
||||
display: inline-block;
|
||||
width: 3px;
|
||||
height: 17px;
|
||||
position: relative;
|
||||
margin-right: 10px;
|
||||
top: 4px;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
// global
|
||||
@import "./global.scss";
|
||||
// color-ui
|
||||
@import "@/static/scss/colorui.css";
|
||||
// iconfont
|
||||
@import "@/static/font/iconfont.css";
|
|
@ -0,0 +1,10 @@
|
|||
const getters = {
|
||||
token: state => state.user.token,
|
||||
avatar: state => state.user.avatar,
|
||||
name: state => state.user.name,
|
||||
roles: state => state.user.roles,
|
||||
permissions: state => state.user.permissions,
|
||||
selectsdata: state => state.user.selectsdata,
|
||||
dingcropid: state => state.user.dingcropid,
|
||||
}
|
||||
export default getters
|
|
@ -0,0 +1,15 @@
|
|||
import Vue from 'vue'
|
||||
import Vuex from 'vuex'
|
||||
import user from '@/store/modules/user'
|
||||
import getters from './getters'
|
||||
|
||||
Vue.use(Vuex)
|
||||
|
||||
const store = new Vuex.Store({
|
||||
modules: {
|
||||
user
|
||||
},
|
||||
getters
|
||||
})
|
||||
|
||||
export default store
|
|
@ -0,0 +1,111 @@
|
|||
import config from '@/config'
|
||||
import storage from '@/utils/storage'
|
||||
import constant from '@/utils/constant'
|
||||
import { login, logout, getInfo } from '@/api/login'
|
||||
import { getToken, setToken, removeToken,getUserInfo, setUserInfo,removeUserInfo} from '@/utils/auth'
|
||||
|
||||
const baseUrl = config.baseUrl
|
||||
|
||||
const user = {
|
||||
state: {
|
||||
token: getToken(),
|
||||
name: storage.get(constant.name),
|
||||
avatar: storage.get(constant.avatar),
|
||||
roles: storage.get(constant.roles),
|
||||
permissions: storage.get(constant.permissions),
|
||||
selectsdata: [],
|
||||
dingcropid:'',
|
||||
},
|
||||
|
||||
mutations: {
|
||||
SET_TOKEN: (state, token) => {
|
||||
state.token = token
|
||||
},
|
||||
SET_NAME: (state, name) => {
|
||||
state.name = name
|
||||
storage.set(constant.name, name)
|
||||
},
|
||||
SET_AVATAR: (state, avatar) => {
|
||||
state.avatar = avatar
|
||||
storage.set(constant.avatar, avatar)
|
||||
},
|
||||
SET_ROLES: (state, roles) => {
|
||||
state.roles = roles
|
||||
storage.set(constant.roles, roles)
|
||||
},
|
||||
SET_PERMISSIONS: (state, permissions) => {
|
||||
state.permissions = permissions
|
||||
storage.set(constant.permissions, permissions)
|
||||
},
|
||||
SET_SELECTSDATA: (state,selectsdata)=> {
|
||||
state.selectsdata = selectsdata
|
||||
},
|
||||
SET_DINGCROPID: (state,dingcropid)=> {
|
||||
state.dingcropid = dingcropid
|
||||
},
|
||||
},
|
||||
|
||||
actions: {
|
||||
// 登录
|
||||
Login({ commit }, userInfo) {
|
||||
const username = userInfo.username.trim()
|
||||
const password = userInfo.password
|
||||
const code = userInfo.code
|
||||
const uuid = userInfo.uuid
|
||||
return new Promise((resolve, reject) => {
|
||||
login(username, password, code, uuid).then(res => {
|
||||
setToken(res.attribute.token)
|
||||
setUserInfo(res.attribute.userInfo)
|
||||
resolve()
|
||||
}).catch(error => {
|
||||
reject(error)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
// 获取用户信息
|
||||
GetInfo({ commit, state }) {
|
||||
return new Promise((resolve, reject) => {
|
||||
getInfo().then(res => {
|
||||
const user = res.user
|
||||
const avatar = (user == null || user.avatar == "" || user.avatar == null) ? require("@/static/images/profile.jpg") : baseUrl + user.avatar
|
||||
const username = (user == null || user.userName == "" || user.userName == null) ? "" : user.userName
|
||||
if (res.roles && res.roles.length > 0) {
|
||||
commit('SET_ROLES', res.roles)
|
||||
commit('SET_PERMISSIONS', res.permissions)
|
||||
} else {
|
||||
commit('SET_ROLES', ['ROLE_DEFAULT'])
|
||||
}
|
||||
commit('SET_NAME', username)
|
||||
commit('SET_AVATAR', avatar)
|
||||
resolve(res)
|
||||
}).catch(error => {
|
||||
reject(error)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
// 退出系统
|
||||
LogOut({ commit, state }) {
|
||||
return new Promise((resolve, reject) => {
|
||||
commit('SET_TOKEN', '')
|
||||
removeToken()
|
||||
removeUserInfo()
|
||||
storage.clean()
|
||||
resolve()
|
||||
// logout(state.token).then(() => {
|
||||
// commit('SET_TOKEN', '')
|
||||
// commit('SET_ROLES', [])
|
||||
// commit('SET_PERMISSIONS', [])
|
||||
// removeToken()
|
||||
// storage.clean()
|
||||
// resolve()
|
||||
// }).catch(error => {
|
||||
// reject(error)
|
||||
// })
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default user
|
|
@ -0,0 +1,65 @@
|
|||
/**
|
||||
* uni-app内置的常用样式变量
|
||||
*/
|
||||
@import '@/uni_modules/uview-ui/theme.scss';
|
||||
|
||||
/* 行为相关颜色 */
|
||||
$uni-color-primary: #007aff;
|
||||
$uni-color-success: #4cd964;
|
||||
$uni-color-warning: #f0ad4e;
|
||||
$uni-color-error: #dd524d;
|
||||
|
||||
/* 文字基本颜色 */
|
||||
$uni-text-color:#333;//基本色
|
||||
$uni-text-color-inverse:#fff;//反色
|
||||
$uni-text-color-grey:#999;//辅助灰色,如加载更多的提示信息
|
||||
$uni-text-color-placeholder: #808080;
|
||||
$uni-text-color-disable:#c0c0c0;
|
||||
|
||||
/* 背景颜色 */
|
||||
$uni-bg-color:#ffffff;
|
||||
$uni-bg-color-grey:#f8f8f8;
|
||||
$uni-bg-color-hover:#f1f1f1;//点击状态颜色
|
||||
$uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色
|
||||
|
||||
/* 边框颜色 */
|
||||
$uni-border-color:#e5e5e5;
|
||||
|
||||
/* 尺寸变量 */
|
||||
|
||||
/* 文字尺寸 */
|
||||
$uni-font-size-sm:12px;
|
||||
$uni-font-size-base:14px;
|
||||
$uni-font-size-lg:16px;
|
||||
|
||||
/* 图片尺寸 */
|
||||
$uni-img-size-sm:20px;
|
||||
$uni-img-size-base:26px;
|
||||
$uni-img-size-lg:40px;
|
||||
|
||||
/* Border Radius */
|
||||
$uni-border-radius-sm: 2px;
|
||||
$uni-border-radius-base: 3px;
|
||||
$uni-border-radius-lg: 6px;
|
||||
$uni-border-radius-circle: 50%;
|
||||
|
||||
/* 水平间距 */
|
||||
$uni-spacing-row-sm: 5px;
|
||||
$uni-spacing-row-base: 10px;
|
||||
$uni-spacing-row-lg: 15px;
|
||||
|
||||
/* 垂直间距 */
|
||||
$uni-spacing-col-sm: 4px;
|
||||
$uni-spacing-col-base: 8px;
|
||||
$uni-spacing-col-lg: 12px;
|
||||
|
||||
/* 透明度 */
|
||||
$uni-opacity-disabled: 0.3; // 组件禁用态的透明度
|
||||
|
||||
/* 文章场景相关 */
|
||||
$uni-color-title: #2C405A; // 文章标题颜色
|
||||
$uni-font-size-title:20px;
|
||||
$uni-color-subtitle: #555555; // 二级标题颜色
|
||||
$uni-font-size-subtitle:26px;
|
||||
$uni-color-paragraph: #3F536E; // 文章段落颜色
|
||||
$uni-font-size-paragraph:15px;
|
|
@ -0,0 +1,173 @@
|
|||
## 3.8.0(2023-07-29)
|
||||
- 修复父子联动状态下,数据回显父级半选状态不展示问题
|
||||
- selectChange 返回数据调整
|
||||
- 新增 contentHeight 、disabledList 属性
|
||||
- 文档更新
|
||||
## 3.7.9(2023-07-11)
|
||||
- 文档更新
|
||||
## 3.7.8(2023-07-10)
|
||||
- 修复父元素未完全选中状态显示异常问题
|
||||
## 3.7.7(2023-07-07)
|
||||
- 文档更新
|
||||
## 3.7.6(2023-07-07)
|
||||
- 重写checkbox,解决与colorui样式冲突问题
|
||||
- 父级添加子级未全选状态,更直观了解选中数据情况
|
||||
- 样式优化,提取文件内样式变量
|
||||
- 代码体积优化
|
||||
## 3.7.5(2023-05-15)
|
||||
- 修复visible在数据初始化时配置有时失效问题
|
||||
## 3.7.4(2023-05-11)
|
||||
- 修复父元素下某个子元素设置隐藏时,父子联动状态异常问题
|
||||
- 对性能以及代码体积做了进一步优化
|
||||
## 3.7.3(2023-05-08)
|
||||
- 修复子元素展开懒加载功能被覆盖问题
|
||||
- 优化数据初始化速度
|
||||
## 3.7.2(2023-05-04)
|
||||
- uni.$emit 替换 bus事件
|
||||
## 3.7.1(2023-04-10)
|
||||
- 解决小程序无法折叠或展开问题
|
||||
## 3.7.0(2023-04-09)
|
||||
- 全选默认不开启,并且只在多选模式下生效
|
||||
## 3.6.91(2023-04-09)
|
||||
- 文档更新
|
||||
## 3.6.9(2023-04-09)
|
||||
- 代码整体优化
|
||||
- 新增弹窗安全区配置选项
|
||||
- 新增全选功能配置选项
|
||||
- 新增搜索框清除按钮是否直接重置搜索结果选项
|
||||
- 遗留问题:小程序端搜索后无法折叠或打开
|
||||
## 3.6.8(2023-04-07)
|
||||
- 优化deepClone
|
||||
## 3.6.7(2023-04-03)
|
||||
- 取消对微信小程序的支持
|
||||
## 3.6.6(2023-04-03)
|
||||
- 修复listData刷新后,不能正确渲染勾选状态问题
|
||||
## 3.6.5(2023-03-30)
|
||||
- 修复小程序节点展开或折叠时指示箭头不变换状态
|
||||
- 修复回显数据有时不展示问题
|
||||
## 3.6.3(2023-03-27)
|
||||
- [紧急] 修复单选状态仍可以多选bug
|
||||
## 3.6.2(2023-03-27)
|
||||
- 修复偶尔出现节点无法根据绑定数据改变选中状态问题
|
||||
## 3.6.1(2023-03-24)
|
||||
- 修复引入问题
|
||||
## 3.6.0(2023-03-24)
|
||||
- 重构去除冗余代码,功能不变
|
||||
## 3.5.0(2023-03-23)
|
||||
- 修复没有子元素时点击报错问题
|
||||
## 3.3.9(2023-03-22)
|
||||
- 解决搜索时 toLowerCase 报错问题
|
||||
## 3.3.8(2023-03-22)
|
||||
- 懒加载优化
|
||||
## 3.3.7(2023-03-20)
|
||||
- 样式更新
|
||||
## 3.3.6(2023-03-20)
|
||||
- 修复子元素折叠或展开不触发问题
|
||||
## 3.3.5(2023-03-15)
|
||||
- isArray 替换 instanceof
|
||||
## 3.3.4(2023-03-11)
|
||||
- 修复搜索后无法展开或折叠问题
|
||||
- 搜索后直接展开搜索项
|
||||
## 3.3.3(2023-03-06)
|
||||
- 优化展示效果
|
||||
- 添加引导线选项
|
||||
## 3.3.2(2023-02-22)
|
||||
- 修复搜索内容包含隐藏数据的问题
|
||||
- 优化搜索触发方式
|
||||
## 3.3.1(2023-02-16)
|
||||
- 修复异常
|
||||
## 3.2.9(2023-02-16)
|
||||
- 修复编译到小程序报错问题
|
||||
## 3.2.8(2023-02-16)
|
||||
- 修复多个组件key重复问题
|
||||
## 3.2.7(2023-02-16)
|
||||
- 全新底层架构设计
|
||||
- 修改默认配色,更显成熟稳重
|
||||
## 3.2.6(2023-02-15)
|
||||
- 修改文档
|
||||
## 3.2.5(2023-02-15)
|
||||
- 文档修改
|
||||
## 3.2.3(2023-02-15)
|
||||
- 修复小程序组件无法折叠问题
|
||||
## 3.2.2(2023-02-10)
|
||||
- 文档更新
|
||||
## 3.2.1(2023-02-09)
|
||||
- 增加节点展开和关闭全局配置
|
||||
- 修复搜索后数据无法展开和关闭问题
|
||||
- 修复搜索后不能自动滚动到顶部问题
|
||||
## 3.2.0(2023-01-16)
|
||||
- 修复事件冲突
|
||||
## 3.1.5(2023-01-13)
|
||||
- 样式调整
|
||||
## 3.1.4(2023-01-13)
|
||||
- 样式修复
|
||||
## 3.1.3(2023-01-13)
|
||||
- 文档更新
|
||||
## 3.1.2(2023-01-13)
|
||||
- 修复一些已知问题
|
||||
## 3.1.1(2023-01-12)
|
||||
- 解决微信小程序bus事件冲突问题
|
||||
## 3.1.0(2023-01-11)
|
||||
- 支持微信小程序
|
||||
## 3.0.3(2023-01-10)
|
||||
- 更新文档
|
||||
## 3.0.2(2023-01-09)
|
||||
- 修复了一些已知问题
|
||||
## 3.0.1(2023-01-09)
|
||||
- 修复了一些已知问题
|
||||
## 3.0.0(2023-01-09)
|
||||
- 全面支持懒加载,大量数据也能快速打开
|
||||
## 2.0.01(2022-12-29)
|
||||
- 文档修改
|
||||
## 2.0.0(2022-12-28)
|
||||
- 添加搜索功能
|
||||
- 完善文档
|
||||
## 1.9.2(2022-12-14)
|
||||
- 修复了一些已知问题
|
||||
## 1.9.1(2022-12-14)
|
||||
- 修复了一些已知问题
|
||||
## 1.9.0(2022-12-14)
|
||||
- 增加选项禁用、隐藏功能
|
||||
- 文档添加示例
|
||||
## 1.8.4(2022-12-13)
|
||||
- 文档修复
|
||||
## 1.8.3(2022-12-09)
|
||||
- 样式调整
|
||||
## 1.8.2(2022-12-07)
|
||||
- 修复弹窗不同设备显示高度问题
|
||||
## 1.8.1(2022-12-06)
|
||||
- 修复了一些已知问题
|
||||
## 1.8.0(2022-12-05)
|
||||
- 修复了一些已知问题
|
||||
- 图标替换图片
|
||||
## 1.7.0(2022-12-05)
|
||||
- 增加 disabled 属性,适用于查看页面
|
||||
- 修复了一些已知问题
|
||||
## 1.6.0(2022-12-05)
|
||||
- 修复了一些已知问题
|
||||
## 1.5.0(2022-12-05)
|
||||
- 根据绑定数据类型自动判断返回值类型
|
||||
- 完善文档
|
||||
## 1.4.0(2022-12-02)
|
||||
- 修复了一些已知问题
|
||||
## 1.3.1(2022-12-02)
|
||||
- 修复了一些已知问题
|
||||
## 1.3.0(2022-12-02)
|
||||
- 修复了一些已知问题
|
||||
## 1.2.01(2022-12-02)
|
||||
- 文档更新
|
||||
## 1.2.0(2022-12-02)
|
||||
- 添加一键清除功能
|
||||
- 添加多选、单选功能
|
||||
## 1.1.0(2022-12-02)
|
||||
- 支持数据回显、已选数据移除
|
||||
- 对标 uni-easyinput 默认样式
|
||||
- 支持更多属性和事件
|
||||
## 1.0.3(2022-12-01)
|
||||
- 修改信息
|
||||
## 1.0.2(2022-12-01)
|
||||
- 更新文档
|
||||
## 1.0.1(2022-12-01)
|
||||
- 更新预览截图
|
||||
## 1.0.0(2022-12-01)
|
||||
- 插件更新
|
|
@ -0,0 +1,963 @@
|
|||
<template>
|
||||
<view class="custom-tree-select-content">
|
||||
<view
|
||||
:class="['select-list', { disabled }, { active: selectList.length }]"
|
||||
@click.stop="open"
|
||||
:style="{borderColor:requiredStyle ? '#e6a23c':'#e5e5e5'}"
|
||||
>
|
||||
<view class="left">
|
||||
<view v-if="selectList.length" class="select-items" >
|
||||
<view
|
||||
class="select-item"
|
||||
v-for="item in selectedListBaseinfo"
|
||||
:key="item[dataValue]"
|
||||
>
|
||||
<view class="name">
|
||||
<text>{{ item[dataLabel] }}</text>
|
||||
</view>
|
||||
<view
|
||||
v-if="!disabled && !item.disabled"
|
||||
class="close"
|
||||
@click.stop="removeSelectedItem(item)"
|
||||
>
|
||||
<uni-icons type="closeempty" size="16" color="#999"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-else style="color: #6a6a6a" class="no-data">
|
||||
<text>{{ placeholder }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="right">
|
||||
<uni-icons
|
||||
v-if="!selectList.length || !clearable"
|
||||
type="right"
|
||||
size="16"
|
||||
color="#606266"
|
||||
></uni-icons>
|
||||
<uni-icons
|
||||
v-if="selectList.length && clearable"
|
||||
type="clear"
|
||||
size="22"
|
||||
color="#c0c4cc"
|
||||
@click.native.stop="clear"
|
||||
></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
<u-popup
|
||||
:show="showPopup"
|
||||
ref="popup"
|
||||
@close="showPopup = false"
|
||||
:mode="'bottom'"
|
||||
:zoom="true"
|
||||
:safe-area="safeArea"
|
||||
>
|
||||
<view
|
||||
class="popup-content"
|
||||
:style="{ height: contentHeight || defaultContentHeight }"
|
||||
>
|
||||
<view class="title">
|
||||
<view
|
||||
v-if="mutiple && canSelectAll"
|
||||
class="left"
|
||||
@click.stop="handleSelectAll"
|
||||
>
|
||||
<text>{{ isSelectedAll ? "取消全选" : "全选" }}</text>
|
||||
</view>
|
||||
<view class="center">
|
||||
<text style="font-weight: bold">{{ title }}</text>
|
||||
</view>
|
||||
<view
|
||||
class="right"
|
||||
:style="{ color: confirmTextColor }"
|
||||
@click.stop="close"
|
||||
>
|
||||
<text>{{ confirmText }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="search" class="search-box">
|
||||
<uni-easyinput
|
||||
:maxlength="-1"
|
||||
prefixIcon="search"
|
||||
placeholder="搜索"
|
||||
v-model="searchStr"
|
||||
confirm-type="search"
|
||||
@confirm="handleSearch(false)"
|
||||
@clear="handleSearch(true)"
|
||||
:styles="{borderColor:'e5e5e5'}"
|
||||
>
|
||||
</uni-easyinput>
|
||||
<button
|
||||
type="primary"
|
||||
size="mini"
|
||||
class="search-btn"
|
||||
@click.stop="handleSearch(false)"
|
||||
>
|
||||
搜索
|
||||
</button>
|
||||
</view>
|
||||
<view v-if="treeData.length" class="select-content">
|
||||
<scroll-view
|
||||
class="scroll-view-box"
|
||||
:scroll-top="scrollTop"
|
||||
scroll-y="true"
|
||||
@touchmove.stop
|
||||
>
|
||||
<view v-if="!filterTreeData.length" class="no-data center">
|
||||
<text>暂无数据</text>
|
||||
</view>
|
||||
<data-select-item
|
||||
v-for="item in filterTreeData"
|
||||
:key="item[dataValue]"
|
||||
:node="item"
|
||||
:dataLabel="dataLabel"
|
||||
:dataValue="dataValue"
|
||||
:dataChildren="dataChildren"
|
||||
:choseParent="choseParent"
|
||||
:border="border"
|
||||
:linkage="linkage"
|
||||
@handleNodeClick="handleNodeClick"
|
||||
@handleHideChildren="handleHideChildren"
|
||||
></data-select-item>
|
||||
<!-- <view class="sentry" /> -->
|
||||
</scroll-view>
|
||||
</view>
|
||||
<view v-else class="no-data center">
|
||||
<text>暂无数据</text>
|
||||
</view>
|
||||
</view>
|
||||
</u-popup>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const partCheckedSet = new Set();
|
||||
import { isString, paging } from "./utils";
|
||||
import dataSelectItem from "./data-select-item.vue";
|
||||
export default {
|
||||
name: "custom-tree-select",
|
||||
components: {
|
||||
dataSelectItem,
|
||||
},
|
||||
model: {
|
||||
prop: "value",
|
||||
event: "input",
|
||||
},
|
||||
props: {
|
||||
canSelectAll: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
safeArea: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
search: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
clearResetSearch: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
"is-mask-click": {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
"mask-background-color": {
|
||||
type: String,
|
||||
default: "rgba(0,0,0,0.4)",
|
||||
},
|
||||
"background-color": {
|
||||
type: String,
|
||||
default: "none",
|
||||
},
|
||||
"safe-area": {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
choseParent: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: "请选择",
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: "请选择",
|
||||
},
|
||||
confirmText: {
|
||||
type: String,
|
||||
default: "完成",
|
||||
},
|
||||
confirmTextColor: {
|
||||
type: String,
|
||||
default: "#007aff",
|
||||
},
|
||||
contentHeight: {
|
||||
type: String,
|
||||
},
|
||||
disabledList: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
listData: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
dataLabel: {
|
||||
type: String,
|
||||
default: "name",
|
||||
},
|
||||
dataValue: {
|
||||
type: String,
|
||||
default: "id",
|
||||
},
|
||||
dataChildren: {
|
||||
type: String,
|
||||
default: "children",
|
||||
},
|
||||
linkage: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
requiredStyle: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
clearable: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
mutiple: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
showChildren: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
border: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
value: {
|
||||
type: [Array, String],
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
defaultContentHeight: "400px",
|
||||
treeData: [],
|
||||
filterTreeData: [],
|
||||
clearTimerList: [],
|
||||
selectedListBaseinfo: [],
|
||||
showPopup: false,
|
||||
clickOpenTimer: null,
|
||||
isSelectedAll: false,
|
||||
scrollTop: 0,
|
||||
searchStr: "",
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
selectList() {
|
||||
const newVal = this.value === null ? "" : this.value;
|
||||
return isString(newVal)
|
||||
? newVal.length
|
||||
? newVal.split(",")
|
||||
: []
|
||||
: newVal.map((item) => item.toString());
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
listData: {
|
||||
deep: true,
|
||||
immediate: true,
|
||||
handler(newVal) {
|
||||
if (newVal) {
|
||||
partCheckedSet.clear();
|
||||
this.treeData = this.initData(newVal);
|
||||
if (this.showPopup) {
|
||||
this.resetClearTimerList();
|
||||
this.renderTree(this.treeData);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
value: {
|
||||
immediate: true,
|
||||
handler(newVal) {
|
||||
if (newVal !== null) {
|
||||
const ids = Array.isArray(newVal)
|
||||
? newVal
|
||||
: typeof newVal === "string"
|
||||
? newVal.split(",")
|
||||
: [];
|
||||
this.changeStatus(this.treeData, ids, true);
|
||||
this.filterTreeData.length &&
|
||||
this.changeStatus(this.filterTreeData, ids);
|
||||
}
|
||||
},
|
||||
},
|
||||
// 弹窗状态变化 包括点击回显框和遮罩
|
||||
showPopup: {
|
||||
deep: true,
|
||||
handler(newVal, oldVal) {
|
||||
if (newVal) {
|
||||
uni.$on("custom-tree-select-node-click", this.handleNodeClick);
|
||||
uni.$on("custom-tree-select-name-click", this.handleHideChildren);
|
||||
} else {
|
||||
uni.$off("custom-tree-select-node-click", this.handleNodeClick);
|
||||
uni.$off("custom-tree-select-name-click", this.handleHideChildren);
|
||||
this.resetClearTimerList();
|
||||
this.searchStr = "";
|
||||
}
|
||||
this.change(newVal)
|
||||
},
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.getContentHeight(uni.getSystemInfoSync());
|
||||
},
|
||||
methods: {
|
||||
// 搜索完成返回顶部
|
||||
goTop() {
|
||||
this.scrollTop = 10;
|
||||
this.$nextTick(() => {
|
||||
this.scrollTop = 0;
|
||||
});
|
||||
},
|
||||
change(data){
|
||||
this.$emit('change',data)
|
||||
},
|
||||
// 获取对应数据
|
||||
getReflectNode(node, arr) {
|
||||
const array = [...arr];
|
||||
while (array.length) {
|
||||
const item = array.shift();
|
||||
if (item[this.dataValue] === node[this.dataValue]) {
|
||||
return item;
|
||||
}
|
||||
if (item[this.dataChildren]?.length) {
|
||||
array.push(...item[this.dataChildren]);
|
||||
}
|
||||
}
|
||||
return {};
|
||||
},
|
||||
getContentHeight({ screenHeight }) {
|
||||
this.defaultContentHeight = `${Math.floor(screenHeight * 0.55)}px`;
|
||||
},
|
||||
// 处理搜索
|
||||
handleSearch(isClear = false) {
|
||||
this.resetClearTimerList();
|
||||
if (isClear) {
|
||||
// 点击清空按钮并且设置清空按钮会重置搜索
|
||||
if (this.clearResetSearch) {
|
||||
this.renderTree(this.treeData);
|
||||
}
|
||||
} else {
|
||||
this.renderTree(this.searchValue(this.searchStr, this.treeData));
|
||||
}
|
||||
this.goTop();
|
||||
uni.hideKeyboard();
|
||||
},
|
||||
// 具体搜索方法
|
||||
searchValue(str, arr) {
|
||||
const res = [];
|
||||
arr.forEach((item) => {
|
||||
if (item.visible) {
|
||||
if (
|
||||
item[this.dataLabel]
|
||||
.toString()
|
||||
.toLowerCase()
|
||||
.indexOf(str.toLowerCase()) > -1
|
||||
) {
|
||||
res.push(item);
|
||||
} else {
|
||||
if (item[this.dataChildren]?.length) {
|
||||
const data = this.searchValue(str, item[this.dataChildren]);
|
||||
if (data?.length) {
|
||||
if (
|
||||
str &&
|
||||
!item.showChildren &&
|
||||
item[this.dataChildren]?.length
|
||||
) {
|
||||
item.showChildren = true;
|
||||
}
|
||||
res.push({
|
||||
...item,
|
||||
[this.dataChildren]: data,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return res;
|
||||
},
|
||||
// 懒加载
|
||||
renderTree(arr) {
|
||||
const pagingArr = paging(arr);
|
||||
this.filterTreeData.splice(
|
||||
0,
|
||||
this.filterTreeData.length,
|
||||
...(pagingArr?.[0] || [])
|
||||
);
|
||||
this.lazyRenderList(pagingArr, 1);
|
||||
},
|
||||
// 懒加载具体逻辑
|
||||
lazyRenderList(arr, startIndex) {
|
||||
for (let i = startIndex; i < arr.length; i++) {
|
||||
let timer = null;
|
||||
timer = setTimeout(() => {
|
||||
this.filterTreeData.push(...arr[i]);
|
||||
}, i * 500);
|
||||
this.clearTimerList.push(() => clearTimeout(timer));
|
||||
}
|
||||
},
|
||||
// 中断懒加载
|
||||
resetClearTimerList() {
|
||||
const list = [...this.clearTimerList];
|
||||
this.clearTimerList = [];
|
||||
list.forEach((fn) => fn());
|
||||
},
|
||||
// 打开弹窗
|
||||
open() {
|
||||
// disaled模式下禁止打开弹窗
|
||||
if (this.disabled) return;
|
||||
this.showPopup = true;
|
||||
this.$nextTick(() => {
|
||||
this.renderTree(this.treeData);
|
||||
});
|
||||
},
|
||||
// 关闭弹窗
|
||||
close() {
|
||||
this.showPopup = false;
|
||||
},
|
||||
// 点击遮罩
|
||||
maskClick() {
|
||||
this.$emit("maskClick");
|
||||
},
|
||||
// 初始化数据
|
||||
initData(arr, parentVisible) {
|
||||
if (!Array.isArray(arr)) return [];
|
||||
const res = [];
|
||||
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
const obj = {
|
||||
...arr[i],
|
||||
[this.dataLabel]: arr[i][this.dataLabel],
|
||||
[this.dataValue]: arr[i][this.dataValue],
|
||||
};
|
||||
|
||||
obj.checked = this.selectList.includes(
|
||||
arr[i][this.dataValue].toString()
|
||||
);
|
||||
|
||||
obj.disabled = false;
|
||||
if (
|
||||
Boolean(arr[i].disabled) ||
|
||||
this.disabledList.includes(obj[this.dataValue].toString())
|
||||
) {
|
||||
obj.disabled = true;
|
||||
}
|
||||
|
||||
//半选
|
||||
obj.partChecked = Boolean(
|
||||
arr[i].partChecked === undefined ? false : arr[i].partChecked
|
||||
);
|
||||
obj.partChecked && obj.partCheckedSet.add(obj[this.dataValue]);
|
||||
!obj.partChecked && (this.isSelectedAll = false);
|
||||
|
||||
const parentVisibleState =
|
||||
parentVisible === undefined ? true : parentVisible;
|
||||
const curVisibleState =
|
||||
arr[i].visible === undefined ? true : Boolean(arr[i].visible);
|
||||
if (parentVisibleState === curVisibleState) {
|
||||
obj.visible = parentVisibleState;
|
||||
} else if (!parentVisibleState || !curVisibleState) {
|
||||
obj.visible = false;
|
||||
} else {
|
||||
obj.visible = true;
|
||||
}
|
||||
|
||||
obj.showChildren =
|
||||
"showChildren" in arr[i] && arr[i].showChildren != undefined
|
||||
? arr[i].showChildren
|
||||
: this.showChildren;
|
||||
|
||||
if (arr[i][this.dataChildren]?.length) {
|
||||
const childrenVal = this.initData(
|
||||
arr[i][this.dataChildren],
|
||||
obj.visible
|
||||
);
|
||||
obj[this.dataChildren] = childrenVal;
|
||||
if (
|
||||
!obj.checked &&
|
||||
childrenVal.some((item) => item.checked || item.partChecked)
|
||||
) {
|
||||
obj.partChecked = true;
|
||||
partCheckedSet.add(obj[this.dataValue]);
|
||||
}
|
||||
}
|
||||
|
||||
res.push(obj);
|
||||
}
|
||||
|
||||
return res;
|
||||
},
|
||||
// 获取某个节点后面所有元素
|
||||
getChildren(node) {
|
||||
if (!node[this.dataChildren]?.length) return [];
|
||||
const res = node[this.dataChildren].reduce((pre, val) => {
|
||||
if (val.visible) {
|
||||
return [...pre, val];
|
||||
}
|
||||
return pre;
|
||||
}, []);
|
||||
for (let i = 0; i < node[this.dataChildren].length; i++) {
|
||||
res.push(...this.getChildren(node[this.dataChildren][i]));
|
||||
}
|
||||
return res;
|
||||
},
|
||||
// 获取某个节点所有祖先元素
|
||||
getParentNode(target, arr) {
|
||||
let res = [];
|
||||
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
if (arr[i][this.dataValue] === target[this.dataValue]) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (arr[i][this.dataChildren]?.length) {
|
||||
const childRes = this.getParentNode(
|
||||
target,
|
||||
arr[i][this.dataChildren]
|
||||
);
|
||||
if (typeof childRes === "boolean" && childRes) {
|
||||
res = [arr[i]];
|
||||
} else if (Array.isArray(childRes) && childRes.length) {
|
||||
res = [...childRes, arr[i]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
},
|
||||
// 点击checkbox
|
||||
handleNodeClick(data, status) {
|
||||
const node = this.getReflectNode(data, this.treeData);
|
||||
node.checked = typeof status === "boolean" ? status : !node.checked;
|
||||
node.partChecked = false;
|
||||
partCheckedSet.delete(node[this.dataValue]);
|
||||
// 如果是单选不考虑其他情况
|
||||
if (!this.mutiple) {
|
||||
let emitData = [];
|
||||
if (node.checked) {
|
||||
emitData = [node[this.dataValue].toString()];
|
||||
}
|
||||
this.$emit(
|
||||
"input",
|
||||
isString(this.value) ? emitData.join(",") : emitData
|
||||
);
|
||||
} else {
|
||||
// 多选情况
|
||||
if (!this.linkage) {
|
||||
// 不需要联动
|
||||
let emitData = null;
|
||||
if (node.checked) {
|
||||
emitData = Array.from(
|
||||
new Set([...this.selectList, node[this.dataValue].toString()])
|
||||
);
|
||||
} else {
|
||||
emitData = this.selectList.filter(
|
||||
(id) => id !== node[this.dataValue].toString()
|
||||
);
|
||||
}
|
||||
this.$emit(
|
||||
"input",
|
||||
isString(this.value) ? emitData.join(",") : emitData
|
||||
);
|
||||
} else {
|
||||
// 需要联动
|
||||
let emitData = [...this.selectList];
|
||||
const parentNodes = this.getParentNode(node, this.treeData);
|
||||
const childrenVal = this.getChildren(node).filter(
|
||||
(item) => !item.disabled
|
||||
);
|
||||
if (node.checked) {
|
||||
// 选中
|
||||
emitData = Array.from(
|
||||
new Set([...emitData, node[this.dataValue].toString()])
|
||||
);
|
||||
if (childrenVal.length) {
|
||||
emitData = Array.from(
|
||||
new Set([
|
||||
...emitData,
|
||||
...childrenVal.map((item) => item[this.dataValue].toString()),
|
||||
])
|
||||
);
|
||||
// 孩子节点全部选中并且清除半选状态
|
||||
childrenVal.forEach((childNode) => {
|
||||
childNode.partChecked = false;
|
||||
partCheckedSet.delete(childNode[this.dataValue]);
|
||||
});
|
||||
}
|
||||
if (parentNodes.length) {
|
||||
let flag = false;
|
||||
// 有父元素 如果父元素下所有子元素全部选中,选中父元素
|
||||
while (parentNodes.length) {
|
||||
const item = parentNodes.shift();
|
||||
if (!item.disabled) {
|
||||
if (flag) {
|
||||
// 前一个没选中并且为半选那么之后的全为半选
|
||||
item.partChecked = true;
|
||||
partCheckedSet.add(item[this.dataValue]);
|
||||
} else {
|
||||
const allChecked = item[this.dataChildren]
|
||||
.filter((node) => node.visible && !node.disabled)
|
||||
.every((node) => node.checked);
|
||||
if (allChecked) {
|
||||
item.checked = true;
|
||||
item.partChecked = false;
|
||||
partCheckedSet.delete(item[this.dataValue]);
|
||||
emitData = Array.from(
|
||||
new Set([...emitData, item[this.dataValue].toString()])
|
||||
);
|
||||
} else {
|
||||
item.partChecked = true;
|
||||
partCheckedSet.add(item[this.dataValue]);
|
||||
flag = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 取消选中
|
||||
emitData = emitData.filter(
|
||||
(id) => id !== node[this.dataValue].toString()
|
||||
);
|
||||
if (childrenVal.length) {
|
||||
// 取消选中全部子节点
|
||||
childrenVal.forEach((childNode) => {
|
||||
emitData = emitData.filter(
|
||||
(id) => id !== childNode[this.dataValue].toString()
|
||||
);
|
||||
});
|
||||
}
|
||||
if (parentNodes.length) {
|
||||
parentNodes.forEach((parentNode) => {
|
||||
if (emitData.includes(parentNode[this.dataValue].toString())) {
|
||||
parentNode.checked = false;
|
||||
}
|
||||
emitData = emitData.filter(
|
||||
(id) => id !== parentNode[this.dataValue].toString()
|
||||
);
|
||||
const hasChecked = parentNode[this.dataChildren]
|
||||
.filter((node) => node.visible && !node.disabled)
|
||||
.some((node) => node.checked || node.partChecked);
|
||||
|
||||
parentNode.partChecked = hasChecked;
|
||||
if (hasChecked) {
|
||||
partCheckedSet.add(parentNode[this.dataValue]);
|
||||
} else {
|
||||
partCheckedSet.delete(parentNode[this.dataValue]);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
this.$emit(
|
||||
"input",
|
||||
isString(this.value) ? emitData.join(",") : emitData
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
// 点击名称折叠或展开
|
||||
handleHideChildren(node) {
|
||||
const status = !node.showChildren;
|
||||
this.getReflectNode(node, this.treeData).showChildren = status;
|
||||
this.getReflectNode(node, this.filterTreeData).showChildren = status;
|
||||
},
|
||||
// 根据 dataValue 找节点
|
||||
changeStatus(list, ids, needEmit = false) {
|
||||
const arr = [...list];
|
||||
let flag = true;
|
||||
needEmit && (this.selectedListBaseinfo = []);
|
||||
|
||||
while (arr.length) {
|
||||
const item = arr.shift();
|
||||
|
||||
if (ids.includes(item[this.dataValue].toString())) {
|
||||
this.$set(item, "checked", true);
|
||||
needEmit && this.selectedListBaseinfo.push(item);
|
||||
// 数据被选中清除半选状态
|
||||
item.partChecked = false;
|
||||
partCheckedSet.delete(item[this.dataValue]);
|
||||
} else {
|
||||
this.$set(item, "checked", false);
|
||||
if (item.visible && !item.disabled) {
|
||||
flag = false;
|
||||
}
|
||||
if (partCheckedSet.has(item[this.dataValue])) {
|
||||
this.$set(item, "partChecked", true);
|
||||
} else {
|
||||
this.$set(item, "partChecked", false);
|
||||
}
|
||||
}
|
||||
|
||||
if (item[this.dataChildren]?.length) {
|
||||
arr.push(...item[this.dataChildren]);
|
||||
}
|
||||
}
|
||||
this.isSelectedAll = flag;
|
||||
needEmit && this.$emit("selectChange", [...this.selectedListBaseinfo]);
|
||||
},
|
||||
// 移除选项
|
||||
removeSelectedItem(node) {
|
||||
this.isSelectedAll = false;
|
||||
if (this.linkage) {
|
||||
this.handleNodeClick(node, false);
|
||||
this.$emit("removeSelect", node);
|
||||
} else {
|
||||
const emitData = this.selectList.filter(
|
||||
(item) => item !== node[this.dataValue].toString()
|
||||
);
|
||||
this.$emit("removeSelect", node);
|
||||
this.$emit(
|
||||
"input",
|
||||
isString(this.value) ? emitData.join(",") : emitData
|
||||
);
|
||||
}
|
||||
},
|
||||
// 全部选中
|
||||
handleSelectAll() {
|
||||
this.isSelectedAll = !this.isSelectedAll;
|
||||
if (this.isSelectedAll) {
|
||||
if (!this.mutiple) {
|
||||
uni.showToast({
|
||||
title: "单选模式下不能全选",
|
||||
icon: "none",
|
||||
duration: 1000,
|
||||
});
|
||||
return;
|
||||
}
|
||||
let emitData = [];
|
||||
this.treeData.forEach((item) => {
|
||||
if (item.visible || (item.disabled && item.checked)) {
|
||||
emitData = Array.from(
|
||||
new Set([...emitData, item[this.dataValue].toString()])
|
||||
);
|
||||
if (item[this.dataChildren]?.length) {
|
||||
emitData = Array.from(
|
||||
new Set([
|
||||
...emitData,
|
||||
...this.getChildren(item)
|
||||
.filter(
|
||||
(item) =>
|
||||
!item.disabled || (item.disabled && item.checked)
|
||||
)
|
||||
.map((item) => item[this.dataValue].toString()),
|
||||
])
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
this.$emit(
|
||||
"input",
|
||||
isString(this.value) ? emitData.join(",") : emitData
|
||||
);
|
||||
} else {
|
||||
this.clear();
|
||||
}
|
||||
},
|
||||
// 清空选项
|
||||
clear() {
|
||||
if (this.disabled) return;
|
||||
const emitData = [];
|
||||
partCheckedSet.clear();
|
||||
this.selectedListBaseinfo.forEach((node) => {
|
||||
if (node.visible && node.checked && node.disabled) {
|
||||
emitData.push(node[this.dataValue]);
|
||||
}
|
||||
});
|
||||
this.$emit("input", isString(this.value) ? emitData.join(",") : emitData);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
$primary-color: #007aff;
|
||||
$col-sm: 3px;
|
||||
$col-base: 10px;
|
||||
$col-lg: 12px;
|
||||
$row-sm: 4px;
|
||||
$row-base: 10px;
|
||||
$row-lg: 15px;
|
||||
$radius-sm: 4px;
|
||||
$radius-base: 6px;
|
||||
|
||||
.custom-tree-select-content {
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
|
||||
.select-list {
|
||||
padding-left: $row-base;
|
||||
min-height: 35px;
|
||||
border: 1px solid #e5e5e5;
|
||||
border-radius: $radius-sm;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
background: #fff;
|
||||
|
||||
&.active {
|
||||
padding: calc(#{$col-sm} / 2) 0 calc(#{$col-sm} / 2) $row-base;
|
||||
}
|
||||
|
||||
.left {
|
||||
flex: 1;
|
||||
|
||||
.select-items {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.select-item {
|
||||
margin: $col-sm $row-base $col-sm 0;
|
||||
padding: $col-sm $row-sm;
|
||||
max-width: auto;
|
||||
height: auto;
|
||||
background-color: #eaeaea;
|
||||
border-radius: $radius-sm;
|
||||
color: #333;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.name {
|
||||
flex: 1;
|
||||
padding-right: 5px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.close {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
margin-right: $row-sm;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
background-color: #f5f7fa;
|
||||
|
||||
.left {
|
||||
.select-item {
|
||||
.name {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.popup-content {
|
||||
// flex: 1;
|
||||
background-color: #fff;
|
||||
// border-top-left-radius: 20px;
|
||||
// border-top-right-radius: 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.title {
|
||||
padding: $col-base 3rem;
|
||||
border-bottom: 1px solid $uni-border-color;
|
||||
font-size: 14px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
position: relative;
|
||||
|
||||
.left {
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
}
|
||||
|
||||
.center {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.right {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.search-box {
|
||||
margin: $col-base $row-base 0;
|
||||
background-color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.search-btn {
|
||||
margin-left: $row-base;
|
||||
height: 35px;
|
||||
line-height: 35px;
|
||||
}
|
||||
}
|
||||
|
||||
.select-content {
|
||||
margin: $col-base $row-base;
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.scroll-view-box {
|
||||
touch-action: none;
|
||||
flex: 1;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.sentry {
|
||||
height: 48px;
|
||||
}
|
||||
}
|
||||
|
||||
.no-data {
|
||||
width: auto;
|
||||
color: #999 !important;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.no-data.center {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
.requiredBoxItem{
|
||||
border-color: #e6a23c;
|
||||
}
|
||||
|
||||
</style>
|
|
@ -0,0 +1,302 @@
|
|||
<template>
|
||||
<view
|
||||
class="custom-tree-select-content"
|
||||
:class="{
|
||||
border:
|
||||
border &&
|
||||
node[dataChildren] &&
|
||||
node[dataChildren].length &&
|
||||
node.showChildren
|
||||
}"
|
||||
:style="{ marginLeft: `${level ? 14 : 0}px` }"
|
||||
>
|
||||
<view v-if="node.visible" class="custom-tree-select-item">
|
||||
<view class="item-content">
|
||||
<view class="left">
|
||||
<view
|
||||
v-if="node[dataChildren] && node[dataChildren].length"
|
||||
:class="['right-icon', { active: node.showChildren }]"
|
||||
>
|
||||
<uni-icons type="right" size="14" color="#333"></uni-icons>
|
||||
</view>
|
||||
<!-- <view v-else class="smallcircle-filled">
|
||||
<uni-icons
|
||||
class="smallcircle-filled-icon"
|
||||
type="smallcircle-filled"
|
||||
size="10"
|
||||
color="#333"
|
||||
></uni-icons>
|
||||
</view> -->
|
||||
<view
|
||||
class="name"
|
||||
:style="node.disabled ? 'color: #999' : ''"
|
||||
@click.stop="nameClick(node)"
|
||||
>
|
||||
<text>{{ node[dataLabel] }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view
|
||||
v-if="
|
||||
choseParent ||
|
||||
(!choseParent && !node[dataChildren]) ||
|
||||
(!choseParent && node[dataChildren] && !node[dataChildren].length)
|
||||
"
|
||||
:class="['check-box', { disabled: node.disabled }]"
|
||||
@click.stop="nodeClick(node)"
|
||||
>
|
||||
<view
|
||||
v-if="!node.checked && node.partChecked && linkage"
|
||||
class="part-checked"
|
||||
></view>
|
||||
<uni-icons
|
||||
v-if="node.checked"
|
||||
type="checkmarkempty"
|
||||
size="18"
|
||||
:color="node.disabled ? '#333' : '#007aff'"
|
||||
></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view
|
||||
v-if="
|
||||
node.showChildren && node[dataChildren] && node[dataChildren].length
|
||||
"
|
||||
>
|
||||
<data-select-item
|
||||
v-for="item in listData"
|
||||
:key="item[dataValue]"
|
||||
:node="item"
|
||||
:dataLabel="dataLabel"
|
||||
:dataValue="dataValue"
|
||||
:dataChildren="dataChildren"
|
||||
:choseParent="choseParent"
|
||||
:border="border"
|
||||
:linkage="linkage"
|
||||
:level="level + 1"
|
||||
></data-select-item>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import dataSelectItem from './data-select-item.vue'
|
||||
import { paging } from './utils'
|
||||
export default {
|
||||
name: 'data-select-item',
|
||||
components: {
|
||||
'data-select-item': dataSelectItem
|
||||
},
|
||||
props: {
|
||||
node: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
choseParent: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
dataLabel: {
|
||||
type: String,
|
||||
default: 'name'
|
||||
},
|
||||
dataValue: {
|
||||
type: String,
|
||||
default: 'value'
|
||||
},
|
||||
dataChildren: {
|
||||
type: String,
|
||||
default: 'children'
|
||||
},
|
||||
border: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
linkage: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
level: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
listData: [],
|
||||
clearTimerList: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
watchData() {
|
||||
const { node, dataChildren } = this
|
||||
|
||||
return {
|
||||
node,
|
||||
dataChildren
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
watchData: {
|
||||
immediate: true,
|
||||
handler(newVal) {
|
||||
const { node, dataChildren } = newVal
|
||||
if (
|
||||
node.showChildren &&
|
||||
node[dataChildren] &&
|
||||
node[dataChildren].length
|
||||
) {
|
||||
this.resetClearTimerList()
|
||||
this.renderTree(node[dataChildren])
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 懒加载
|
||||
renderTree(arr) {
|
||||
const pagingArr = paging(arr)
|
||||
this.listData.splice(0, this.listData.length, ...(pagingArr?.[0] || []))
|
||||
this.lazyRenderList(pagingArr, 1)
|
||||
},
|
||||
// 懒加载具体逻辑
|
||||
lazyRenderList(arr, startIndex) {
|
||||
for (let i = startIndex; i < arr.length; i++) {
|
||||
let timer = null
|
||||
timer = setTimeout(() => {
|
||||
this.listData.push(...arr[i])
|
||||
}, i * 500)
|
||||
this.clearTimerList.push(() => clearTimeout(timer))
|
||||
}
|
||||
},
|
||||
// 中断懒加载
|
||||
resetClearTimerList() {
|
||||
const list = [...this.clearTimerList]
|
||||
this.clearTimerList.splice(0, this.clearTimerList.length)
|
||||
list.forEach((item) => item())
|
||||
},
|
||||
nameClick(node) {
|
||||
if (
|
||||
!node.showChildren &&
|
||||
node[this.dataChildren] &&
|
||||
node[this.dataChildren].length
|
||||
) {
|
||||
// 打开
|
||||
this.renderTree(node[this.dataChildren])
|
||||
} else {
|
||||
// 关闭
|
||||
this.resetClearTimerList()
|
||||
this.listData.splice(0, this.listData.length)
|
||||
}
|
||||
uni.$emit('custom-tree-select-name-click', node)
|
||||
},
|
||||
nodeClick(node) {
|
||||
if (!node.disabled) {
|
||||
uni.$emit('custom-tree-select-node-click', node)
|
||||
}
|
||||
}
|
||||
},
|
||||
options: {
|
||||
styleIsolation: 'shared'
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
$primary-color: #007aff;
|
||||
$col-sm: 4px;
|
||||
$col-base: 8px;
|
||||
$col-lg: 12px;
|
||||
$row-sm: 5px;
|
||||
$row-base: 10px;
|
||||
$row-lg: 15px;
|
||||
$radius-sm: 3px;
|
||||
$radius-base: 6px;
|
||||
$border-color: #c8c7cc;
|
||||
|
||||
.custom-tree-select-content {
|
||||
&.border {
|
||||
border-left: 1px solid $border-color;
|
||||
}
|
||||
|
||||
/deep/ .uni-checkbox-input {
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.item-content {
|
||||
margin: 0 0 $col-lg;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 3px;
|
||||
background-color: #fff;
|
||||
transform: translateX(-2px);
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.left {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.right-icon {
|
||||
transition: 0.15s ease;
|
||||
|
||||
&.active {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
}
|
||||
|
||||
// .smallcircle-filled {
|
||||
// width: 14px;
|
||||
// height: 13.6px;
|
||||
// display: flex;
|
||||
// align-items: center;
|
||||
|
||||
// .smallcircle-filled-icon {
|
||||
// transform-origin: center;
|
||||
// transform: scale(0.55);
|
||||
// }
|
||||
// }
|
||||
|
||||
.name {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.check-box {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border: 1px solid $border-color;
|
||||
border-radius: $radius-sm;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
&.disabled {
|
||||
background-color: rgb(225, 225, 225);
|
||||
}
|
||||
|
||||
.part-checked {
|
||||
width: 60%;
|
||||
height: 2px;
|
||||
background-color: $primary-color;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,17 @@
|
|||
export function isString(data) {
|
||||
return typeof data === 'string'
|
||||
}
|
||||
|
||||
// 分页
|
||||
export function paging(data, PAGENUM = 50) {
|
||||
if (!Array.isArray(data) || !data.length) return data
|
||||
const pages = []
|
||||
data.forEach((item, index) => {
|
||||
const i = Math.floor(index / PAGENUM)
|
||||
if (!pages[i]) {
|
||||
pages[i] = []
|
||||
}
|
||||
pages[i].push(item)
|
||||
})
|
||||
return pages
|
||||
}
|