添加uni-modules组件,departSelect
3
.env.development
Normal file
@ -0,0 +1,3 @@
|
||||
# 开发环境
|
||||
# 请求接口地址
|
||||
VITE_REQUEST_BASE_URL = https://36.112.48.190
|
||||
3
.env.production
Normal file
@ -0,0 +1,3 @@
|
||||
# 生产环境
|
||||
# 请求接口地址
|
||||
VITE_REQUEST_BASE_URL = https://36.112.48.190
|
||||
56
.gitignore
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
/unpackage/
|
||||
/unpackage/cache/apk/__UNI__9F097F0_cm.apk
|
||||
/unpackage/cache/apk/apkurl
|
||||
/unpackage/cache/apk/cmManifestCache.json
|
||||
/unpackage/cache/certdata
|
||||
/unpackage/cache/wgt/__UNI__9F097F0/app-config-service.js
|
||||
/unpackage/cache/wgt/__UNI__9F097F0/app-service.js
|
||||
/unpackage/cache/wgt/__UNI__9F097F0/app.css
|
||||
/unpackage/cache/wgt/__UNI__9F097F0/manifest.json
|
||||
/unpackage/cache/wgt/__UNI__9F097F0/pages/checkin/index.css
|
||||
/unpackage/cache/wgt/__UNI__9F097F0/pages/document/detail.css
|
||||
/unpackage/cache/wgt/__UNI__9F097F0/pages/document/index.css
|
||||
/unpackage/cache/wgt/__UNI__9F097F0/pages/leave/application.css
|
||||
/unpackage/cache/wgt/__UNI__9F097F0/pages/login/login.css
|
||||
/unpackage/cache/wgt/__UNI__9F097F0/pages/meeting/detail.css
|
||||
/unpackage/cache/wgt/__UNI__9F097F0/pages/meeting/index.css
|
||||
/unpackage/cache/wgt/__UNI__9F097F0/pages/product/index.css
|
||||
/unpackage/cache/wgt/__UNI__9F097F0/pages/safe/detail.css
|
||||
/unpackage/cache/wgt/__UNI__9F097F0/pages/safe/manage.css
|
||||
/unpackage/cache/wgt/__UNI__9F097F0/pages/tab/index.css
|
||||
/unpackage/cache/wgt/__UNI__9F097F0/pages/tab/my.css
|
||||
/unpackage/cache/wgt/__UNI__9F097F0/pages/tab/office.css
|
||||
/unpackage/cache/wgt/__UNI__9F097F0/pages/talk/conversation.css
|
||||
/unpackage/cache/wgt/__UNI__9F097F0/pages/talk/message_list.css
|
||||
/unpackage/cache/wgt/__UNI__9F097F0/pages/talk/system.css
|
||||
/unpackage/cache/wgt/__UNI__9F097F0/pages/task/handle.css
|
||||
/unpackage/cache/wgt/__UNI__9F097F0/pages/task/index.css
|
||||
/unpackage/cache/wgt/__UNI__9F097F0/pages/task/self.css
|
||||
/unpackage/cache/wgt/__UNI__9F097F0/pages/task/todotask.css
|
||||
/unpackage/cache/wgt/__UNI__9F097F0/pages/useredit/add_address.css
|
||||
/unpackage/cache/wgt/__UNI__9F097F0/pages/useredit/address.css
|
||||
/unpackage/cache/wgt/__UNI__9F097F0/pages/useredit/addressbook.css
|
||||
/unpackage/cache/wgt/__UNI__9F097F0/pages/useredit/useredit.css
|
||||
/unpackage/cache/wgt/__UNI__9F097F0/pages/userlist/index.css
|
||||
/unpackage/cache/wgt/__UNI__9F097F0/pages/zhiban/index.css
|
||||
/unpackage/dist/build/app-plus/__uniappautomator.js
|
||||
/unpackage/dist/build/app-plus/__uniappchooselocation.js
|
||||
/unpackage/dist/build/app-plus/app-config-service.js
|
||||
/unpackage/dist/build/app-plus/app-service.js
|
||||
/unpackage/dist/build/app-plus/app.css
|
||||
/unpackage/dist/build/app-plus/manifest.json
|
||||
/unpackage/dist/build/app-plus/pages/document/detail.css
|
||||
/unpackage/dist/build/app-plus/pages/leave/application.css
|
||||
/unpackage/dist/build/app-plus/pages/login/login.css
|
||||
/unpackage/dist/build/app-plus/pages/tab/index.css
|
||||
/unpackage/dist/build/app-plus/pages/tab/my.css
|
||||
/unpackage/dist/build/app-plus/pages/useredit/useredit.css
|
||||
/unpackage/dist/build/app-plus/uni-app-view.umd.js
|
||||
/unpackage/dist/dev/app-plus/__uniappautomator.js
|
||||
/unpackage/dist/dev/app-plus/__uniappchooselocation.js
|
||||
/unpackage/dist/dev/app-plus/app-config-service.js
|
||||
/unpackage/dist/dev/app-plus/app-service.js
|
||||
/unpackage/dist/dev/app-plus/app.css
|
||||
/unpackage/dist/dev/app-plus/manifest.json
|
||||
/unpackage/dist/dev/app-plus/uni-app-view.umd.js
|
||||
/node_modules
|
||||
26
.hbuilderx/launch.json
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
// launch.json 配置了启动调试时相关设置,configurations下节点名称可为 app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/
|
||||
// launchtype项可配置值为local或remote, local代表前端连本地云函数,remote代表前端连云端云函数
|
||||
"version" : "0.0",
|
||||
"configurations" : [
|
||||
{
|
||||
"app-plus" :
|
||||
{
|
||||
"launchtype" : "local"
|
||||
},
|
||||
"default" :
|
||||
{
|
||||
"launchtype" : "local"
|
||||
},
|
||||
"mp-weixin" :
|
||||
{
|
||||
"launchtype" : "local"
|
||||
},
|
||||
"type" : "uniCloud"
|
||||
},
|
||||
{
|
||||
"playground" : "standard",
|
||||
"type" : "uni-app:app-android"
|
||||
}
|
||||
]
|
||||
}
|
||||
13
.vite/deps/_metadata.json
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"hash": "5610b5a1",
|
||||
"browserHash": "3deef0d9",
|
||||
"optimized": {
|
||||
"base-64": {
|
||||
"src": "../../node_modules/base-64/base64.js",
|
||||
"file": "base-64.js",
|
||||
"fileHash": "768aae23",
|
||||
"needsInterop": true
|
||||
}
|
||||
},
|
||||
"chunks": {}
|
||||
}
|
||||
117
.vite/deps/base-64.js
Normal file
@ -0,0 +1,117 @@
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __commonJS = (cb, mod) => function __require() {
|
||||
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
||||
};
|
||||
|
||||
// ../../../../Documents/HBuilderProjects/B404219-tianranqi/node_modules/base-64/base64.js
|
||||
var require_base64 = __commonJS({
|
||||
"../../../../Documents/HBuilderProjects/B404219-tianranqi/node_modules/base-64/base64.js"(exports, module) {
|
||||
(function(root) {
|
||||
var freeExports = typeof exports == "object" && exports;
|
||||
var freeModule = typeof module == "object" && module && module.exports == freeExports && module;
|
||||
var freeGlobal = typeof global == "object" && global;
|
||||
if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) {
|
||||
root = freeGlobal;
|
||||
}
|
||||
var InvalidCharacterError = function(message) {
|
||||
this.message = message;
|
||||
};
|
||||
InvalidCharacterError.prototype = new Error();
|
||||
InvalidCharacterError.prototype.name = "InvalidCharacterError";
|
||||
var error = function(message) {
|
||||
throw new InvalidCharacterError(message);
|
||||
};
|
||||
var TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
var REGEX_SPACE_CHARACTERS = /[\t\n\f\r ]/g;
|
||||
var decode = function(input) {
|
||||
input = String(input).replace(REGEX_SPACE_CHARACTERS, "");
|
||||
var length = input.length;
|
||||
if (length % 4 == 0) {
|
||||
input = input.replace(/==?$/, "");
|
||||
length = input.length;
|
||||
}
|
||||
if (length % 4 == 1 || // http://whatwg.org/C#alphanumeric-ascii-characters
|
||||
/[^+a-zA-Z0-9/]/.test(input)) {
|
||||
error(
|
||||
"Invalid character: the string to be decoded is not correctly encoded."
|
||||
);
|
||||
}
|
||||
var bitCounter = 0;
|
||||
var bitStorage;
|
||||
var buffer;
|
||||
var output = "";
|
||||
var position = -1;
|
||||
while (++position < length) {
|
||||
buffer = TABLE.indexOf(input.charAt(position));
|
||||
bitStorage = bitCounter % 4 ? bitStorage * 64 + buffer : buffer;
|
||||
if (bitCounter++ % 4) {
|
||||
output += String.fromCharCode(
|
||||
255 & bitStorage >> (-2 * bitCounter & 6)
|
||||
);
|
||||
}
|
||||
}
|
||||
return output;
|
||||
};
|
||||
var encode = function(input) {
|
||||
input = String(input);
|
||||
if (/[^\0-\xFF]/.test(input)) {
|
||||
error(
|
||||
"The string to be encoded contains characters outside of the Latin1 range."
|
||||
);
|
||||
}
|
||||
var padding = input.length % 3;
|
||||
var output = "";
|
||||
var position = -1;
|
||||
var a;
|
||||
var b;
|
||||
var c;
|
||||
var buffer;
|
||||
var length = input.length - padding;
|
||||
while (++position < length) {
|
||||
a = input.charCodeAt(position) << 16;
|
||||
b = input.charCodeAt(++position) << 8;
|
||||
c = input.charCodeAt(++position);
|
||||
buffer = a + b + c;
|
||||
output += TABLE.charAt(buffer >> 18 & 63) + TABLE.charAt(buffer >> 12 & 63) + TABLE.charAt(buffer >> 6 & 63) + TABLE.charAt(buffer & 63);
|
||||
}
|
||||
if (padding == 2) {
|
||||
a = input.charCodeAt(position) << 8;
|
||||
b = input.charCodeAt(++position);
|
||||
buffer = a + b;
|
||||
output += TABLE.charAt(buffer >> 10) + TABLE.charAt(buffer >> 4 & 63) + TABLE.charAt(buffer << 2 & 63) + "=";
|
||||
} else if (padding == 1) {
|
||||
buffer = input.charCodeAt(position);
|
||||
output += TABLE.charAt(buffer >> 2) + TABLE.charAt(buffer << 4 & 63) + "==";
|
||||
}
|
||||
return output;
|
||||
};
|
||||
var base64 = {
|
||||
"encode": encode,
|
||||
"decode": decode,
|
||||
"version": "1.0.0"
|
||||
};
|
||||
if (typeof define == "function" && typeof define.amd == "object" && define.amd) {
|
||||
define(function() {
|
||||
return base64;
|
||||
});
|
||||
} else if (freeExports && !freeExports.nodeType) {
|
||||
if (freeModule) {
|
||||
freeModule.exports = base64;
|
||||
} else {
|
||||
for (var key in base64) {
|
||||
base64.hasOwnProperty(key) && (freeExports[key] = base64[key]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
root.base64 = base64;
|
||||
}
|
||||
})(exports);
|
||||
}
|
||||
});
|
||||
export default require_base64();
|
||||
/*! Bundled license information:
|
||||
|
||||
base-64/base64.js:
|
||||
(*! https://mths.be/base64 v1.0.0 by @mathias | MIT license *)
|
||||
*/
|
||||
//# sourceMappingURL=base-64.js.map
|
||||
7
.vite/deps/base-64.js.map
Normal file
3
.vite/deps/package.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"type": "module"
|
||||
}
|
||||
80
App.vue
Normal file
@ -0,0 +1,80 @@
|
||||
<script setup>
|
||||
import {
|
||||
useUpdateApp
|
||||
} from '@/store/update.js';
|
||||
import {
|
||||
cxcJurisdictionApi
|
||||
} from '@/api/api.js';
|
||||
import {
|
||||
onLaunch,
|
||||
onShow
|
||||
} from "@dcloudio/uni-app";
|
||||
import {
|
||||
getLocation,
|
||||
getWeather,
|
||||
} from './utils/index.js';
|
||||
import {
|
||||
useStore
|
||||
} from '@/store';
|
||||
import {
|
||||
ref
|
||||
} from 'vue';
|
||||
onLaunch(() => {
|
||||
// 检查更新
|
||||
useUpdateApp().checkAppUpdate()
|
||||
// 定位
|
||||
getLocation()
|
||||
})
|
||||
onShow(() => {
|
||||
//是否灰化
|
||||
ifGray()
|
||||
})
|
||||
|
||||
const ifGray = () => {
|
||||
cxcJurisdictionApi({
|
||||
id: "1827997127165677570"
|
||||
}).then((res) => {
|
||||
// console.log(res)
|
||||
// 1为灰化
|
||||
if (res.success) {
|
||||
const store = useStore()
|
||||
uni.setStorageSync('isgray', res.result.value)
|
||||
store.setIsgray(res.result.value)
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
/*每个页面公共css */
|
||||
|
||||
.gray {
|
||||
filter: grayscale(1);
|
||||
}
|
||||
|
||||
.f-row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.f-col {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.jca {
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
.jce {
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
|
||||
.jcb {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.aic {
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
20
README.md
Normal file
@ -0,0 +1,20 @@
|
||||
数智产销APP正式版
|
||||
|
||||
|
||||
发布需要在pages/login/login.vue中
|
||||
将
|
||||
```javascript
|
||||
localLoginApi({
|
||||
username: username.value,
|
||||
password: password.value,
|
||||
captcha: 'app'
|
||||
```
|
||||
改成
|
||||
|
||||
```javascript
|
||||
loginApi({
|
||||
username: un,
|
||||
password: pw,
|
||||
ip: getDeviceIp()
|
||||
```
|
||||
|
||||
271
api/api.js
Normal file
@ -0,0 +1,271 @@
|
||||
import {
|
||||
https
|
||||
} from '@/utils/http.js';
|
||||
export function taskListApi(config) { // 我的任务列表
|
||||
return https({
|
||||
url: '/act/task/list',
|
||||
method: 'get',
|
||||
data: config
|
||||
})
|
||||
}
|
||||
export function taskHistoryListApi(config) { // 我的历史任务列表
|
||||
return https({
|
||||
url: '/act/task/taskHistoryList',
|
||||
method: 'get',
|
||||
data: config
|
||||
})
|
||||
}
|
||||
export function myApplyProcessListApi(config) { // 本人发起列表
|
||||
return https({
|
||||
url: '/act/task/myApplyProcessList',
|
||||
method: 'get',
|
||||
data: config
|
||||
})
|
||||
}
|
||||
|
||||
export function taskEntrustApi(config) { // 任务委托操作
|
||||
return https({
|
||||
url: '/act/task/taskEntrust',
|
||||
method: 'put',
|
||||
data: config
|
||||
})
|
||||
}
|
||||
export function getProcessNodeInfoApi(config) { // 办理任务节点信息获取
|
||||
return https({
|
||||
url: '/process/extActProcessNode/getProcessNodeInfo',
|
||||
method: 'get',
|
||||
data: config
|
||||
})
|
||||
}
|
||||
export function getHisProcessNodeInfoApi(config) { // 历史任务详情
|
||||
return https({
|
||||
url: '/process/extActProcessNode/getHisProcessNodeInfo',
|
||||
method: 'get',
|
||||
data: config
|
||||
})
|
||||
}
|
||||
export function queryMyDeptTreeListApi(config) { // 部门
|
||||
return https({
|
||||
url: '/sys/sysDepart/queryTreeList',
|
||||
method: 'get',
|
||||
data: config
|
||||
})
|
||||
}
|
||||
export function userListApi(config) { // 所有人员列表
|
||||
return https({
|
||||
url: '/sys/user/userList',
|
||||
method: 'get',
|
||||
data: config
|
||||
})
|
||||
}
|
||||
export function queryUserByDepIdApi(config) { // 根据部门id查询该部门下的人员列表
|
||||
return https({
|
||||
url: '/sys/user/queryUserByDepId',
|
||||
method: 'get',
|
||||
data: config
|
||||
})
|
||||
}
|
||||
export function indexChartScdtDataApi(config) { // 首页
|
||||
return https({
|
||||
url: '/scdt.cxcscdtjldrb/cxcScdtJldRb/indexChartScdtData',
|
||||
method: 'get',
|
||||
data: config
|
||||
})
|
||||
}
|
||||
export function bpmlistApi(config) { // 公文
|
||||
return https({
|
||||
url: '/cxcoagwfb/cxcOaGwfb/bpmlist',
|
||||
method: 'get',
|
||||
data: config
|
||||
})
|
||||
}
|
||||
export function gonggaolistApi(config) { // 公告
|
||||
return https({
|
||||
url: '/cxctz/cxcTz/list',
|
||||
method: 'get',
|
||||
data: config
|
||||
})
|
||||
}
|
||||
export function zhibanQueryApi(config) { // 值班按月查看
|
||||
return https({
|
||||
url: '/zhgl_zbgl/zhglZbglZbb/list',
|
||||
method: 'get',
|
||||
data: config
|
||||
})
|
||||
}
|
||||
export function zhibanApi(config) { // 首页值班
|
||||
return https({
|
||||
url: '/zhgl_zbgl/zhglZbglZbb/homepageList',
|
||||
method: 'get',
|
||||
data: config
|
||||
})
|
||||
}
|
||||
export function faguiApi(config) { // 法规
|
||||
return https({
|
||||
url: '/cxcoaflgf/cxcOaFlgf/zslist',
|
||||
method: 'get',
|
||||
data: config
|
||||
})
|
||||
}
|
||||
export function cjzhiduApi(config) { // 上级制度
|
||||
return https({
|
||||
url: '/cxcjyglsjzdgl/cxcJyglSjzdgl/zslist',
|
||||
method: 'get',
|
||||
data: config
|
||||
})
|
||||
}
|
||||
export function zhiduApi(config) { // 厂级制度
|
||||
return https({
|
||||
url: '/cxczd/cxcZdgl/list',
|
||||
method: 'get',
|
||||
data: config
|
||||
})
|
||||
}
|
||||
export function huiyilistApi(config) { // 会议
|
||||
return https({
|
||||
url: '/appConnet/app/list',
|
||||
method: 'get',
|
||||
data: config
|
||||
})
|
||||
}
|
||||
export function huiyiDetailApi(config) { // 会议详情
|
||||
return https({
|
||||
url: '/zhgl_hygl/zhglHyglHyyc/listbymainid',
|
||||
method: 'get',
|
||||
data: config
|
||||
})
|
||||
}
|
||||
export function userProfileApi(config) { // 用户信息
|
||||
return https({
|
||||
url: '/sys/user/userList',
|
||||
method: 'get',
|
||||
data: config
|
||||
})
|
||||
}
|
||||
export function userEditApi(config) { // 用户编辑
|
||||
return https({
|
||||
url: '/sys/user/editApp',
|
||||
method: 'PUT',
|
||||
data: config
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
export function extActFlowDataApi(config) { // 获取审批流程所需参数
|
||||
return https({
|
||||
url: '/process/extActFlowData/getProcessInfo',
|
||||
method: 'get',
|
||||
data: config
|
||||
})
|
||||
}
|
||||
|
||||
export function processHistoryListApi(config) { // 审批流程
|
||||
return https({
|
||||
url: '/act/task/processHistoryList',
|
||||
method: 'get',
|
||||
data: config
|
||||
})
|
||||
}
|
||||
export function startMutilProcessApi(config) { // 发起流程
|
||||
return https({
|
||||
url: '/process/extActProcess/startMutilProcess',
|
||||
method: 'post',
|
||||
data: config
|
||||
})
|
||||
}
|
||||
export function processCompleteApi(config) { // 流程办理
|
||||
return https({
|
||||
url: '/act/task/processComplete',
|
||||
method: 'post',
|
||||
data: config
|
||||
})
|
||||
}
|
||||
export function claimApi(config) { // 流程签收
|
||||
return https({
|
||||
url: '/act/task/claim',
|
||||
method: 'put',
|
||||
data: config
|
||||
})
|
||||
}
|
||||
export function callBackProcessApi(config) { // 流程取回
|
||||
return https({
|
||||
url: '/act/task/callBackProcess',
|
||||
method: 'put',
|
||||
data: config
|
||||
})
|
||||
}
|
||||
export function invalidProcessApi(config) { // 流程作废
|
||||
return https({
|
||||
url: '/act/task/invalidProcess',
|
||||
method: 'put',
|
||||
data: config
|
||||
})
|
||||
}
|
||||
export function getDictItemsApi(dictCode) { // 字典标签专用
|
||||
return https({
|
||||
url: `/sys/dict/getDictItems/${dictCode}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function getCategoryItemsApi(pid) { // 分类字典专用
|
||||
return https({
|
||||
url: '/sys/category/findtree',
|
||||
method: 'get',
|
||||
data: {
|
||||
pid
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export function getProcessTaskTransInfoApi(config) { //
|
||||
return https({
|
||||
url: '/act/task/getProcessTaskTransInfo',
|
||||
method: 'get',
|
||||
data: config
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
export function upDateAppApi(config) { // 更新
|
||||
return https({
|
||||
url: '/sys/common/upDateApp',
|
||||
method: 'get',
|
||||
data: config
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
export function cxcDapingApi(config) { // 首页图片
|
||||
return https({
|
||||
url: '/CxcDaping/cxcDaping/list',
|
||||
method: 'get',
|
||||
data: config
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
export function dbSxxqQueryByIdApi(config) { // 督办事项详情
|
||||
return https({
|
||||
url: '/cxcdbxt/dbSxxq/queryById',
|
||||
method: 'get',
|
||||
data: config
|
||||
})
|
||||
}
|
||||
export function dbJbxxQueryByIdApi(config) { // 督办基本信息
|
||||
return https({
|
||||
url: '/cxcdbxt/dbJbxx/queryById',
|
||||
method: 'get',
|
||||
data: config
|
||||
})
|
||||
}
|
||||
|
||||
export function cxcJurisdictionApi(config) { // 是否灰化
|
||||
return https({
|
||||
url: '/CxcJurisdiction/cxcJurisdiction/queryById',
|
||||
method: 'get',
|
||||
data: config
|
||||
})
|
||||
}
|
||||
23
api/depart.js
Normal file
@ -0,0 +1,23 @@
|
||||
import {
|
||||
https
|
||||
} from '@/utils/http.js';
|
||||
|
||||
export function queryDepByCode(code) { // 获取部门数据
|
||||
return https({
|
||||
url: '/sys/sysDepart/queryDepNameByDepCode',
|
||||
method: 'get',
|
||||
data: {
|
||||
code
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export function queryZbDepByLdhth(ldhth) { // 获取人员主表中人员部门
|
||||
return https({
|
||||
url: '/sys/sysDepart/queryZbDepByLdhth',
|
||||
method: 'get',
|
||||
data: {
|
||||
ldhth
|
||||
}
|
||||
})
|
||||
}
|
||||
29
api/login.js
Normal file
@ -0,0 +1,29 @@
|
||||
import { https } from '@/utils/http.js';
|
||||
export function loginApi(config) { // 登录
|
||||
return https({
|
||||
url: '/sys/sinopecLogin',
|
||||
method: 'post',
|
||||
data: config
|
||||
})
|
||||
}
|
||||
export function localLoginApi(config) { // 本地登录
|
||||
return https({
|
||||
url: '/sys/login',
|
||||
method: 'post',
|
||||
data: config
|
||||
})
|
||||
}
|
||||
export function queryRoleApi(config) { // 获取角色职位
|
||||
return https({
|
||||
url: '/appConnet/app/queryRoleByRoleIds',
|
||||
method: 'get',
|
||||
data: config
|
||||
})
|
||||
}
|
||||
export function getUserPermissionApi(config) { // 获取权限
|
||||
return https({
|
||||
url: '/sys/permission/getUserPermissionByToken',
|
||||
method: 'get',
|
||||
data: config
|
||||
})
|
||||
}
|
||||
29
api/pages.js
Normal file
@ -0,0 +1,29 @@
|
||||
import {
|
||||
https
|
||||
} from '@/utils/http.js';
|
||||
|
||||
export function qjAddApi(config) { // 发起请假流程申请
|
||||
return https({
|
||||
url: '/CxcQxj/cxcQxj/add',
|
||||
method: 'post',
|
||||
data: config
|
||||
})
|
||||
}
|
||||
|
||||
export function queryZwmcAndExaApi(username) { // 根据username获取职位名称和审批领导列表
|
||||
return https({
|
||||
url: '/CxcQxj/cxcQxj/queryZwmcByUsername',
|
||||
method: 'get',
|
||||
data: {
|
||||
username
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export function qjQueryByIdApi(config) { // 通过id查询请假数据 流程用
|
||||
return https({
|
||||
url: '/CxcQxj/cxcQxj/queryById',
|
||||
method: 'get',
|
||||
data: config
|
||||
})
|
||||
}
|
||||
12
api/renyuan.js
Normal file
@ -0,0 +1,12 @@
|
||||
import {
|
||||
https
|
||||
} from '@/utils/http.js';
|
||||
|
||||
export function queryRenyuanByDepartID(orgCode) { // 获取部门所有人员信息
|
||||
return https({
|
||||
url: '/cxc_rlzy.zb/cxcRlzyZb/list',
|
||||
method: 'get',
|
||||
data: orgCode
|
||||
|
||||
})
|
||||
}
|
||||
36
bpm/customNav.vue
Normal file
@ -0,0 +1,36 @@
|
||||
<template>
|
||||
<view class="">
|
||||
<view class="nav ">
|
||||
<slot></slot>
|
||||
</view>
|
||||
<view class="place">
|
||||
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const res = wx.getSystemInfoSync();
|
||||
const statusHeight = res.statusBarHeight; //状态栏高度
|
||||
const cusnavbarheight = (statusHeight + 44) + "px";
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.nav {
|
||||
width: calc(100% - 60rpx);
|
||||
padding: 0 30rpx;
|
||||
height: v-bind(cusnavbarheight);
|
||||
background: linear-gradient(270deg, #256FBC 0%, #044D87 100%);
|
||||
|
||||
font-size: 24rpx;
|
||||
color: #FFFFFF;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 99;
|
||||
}
|
||||
|
||||
.place {
|
||||
height: v-bind(cusnavbarheight);
|
||||
}
|
||||
</style>
|
||||
143
bpm/dataCom.vue
Normal file
@ -0,0 +1,143 @@
|
||||
<template>
|
||||
<view class="">
|
||||
<view class="info">
|
||||
<view class="item_box">
|
||||
<view class="item">
|
||||
<view class="title_box f-row aic jcb">
|
||||
<view class="title">
|
||||
{{title}}
|
||||
</view>
|
||||
<view class="f-row aic more" v-if="list.length>6" @click="open=!open">
|
||||
<text>{{!open?'展开':'收起'}}</text>
|
||||
<uni-icons type="down" color="#999999" v-if="!open"></uni-icons>
|
||||
<uni-icons type="up" color="#999999" v-else></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
<view :class="['data_wrapper',{'close':list.length>6&&open}]">
|
||||
<view class="data_box f-row aic ">
|
||||
<view class="data f-col aic" v-for="item,i in list">
|
||||
<view class="">
|
||||
{{item?.dailyVolume}}
|
||||
</view>
|
||||
<text>{{item.gas}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref,
|
||||
computed,
|
||||
watch,
|
||||
nextTick
|
||||
} from 'vue';
|
||||
const props = defineProps({
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
list: {
|
||||
type: Array,
|
||||
default: function() {
|
||||
return []
|
||||
}
|
||||
},
|
||||
})
|
||||
const open = ref(false)
|
||||
const moreHeight = ref(null)
|
||||
|
||||
watch(() => props.list, () => {
|
||||
nextTick(() => {
|
||||
uni.createSelectorQuery().select('.data_box').boundingClientRect(data => {
|
||||
moreHeight.value = (data?.height || 0) + 'px'
|
||||
}).exec()
|
||||
})
|
||||
|
||||
}, {
|
||||
immediate: true
|
||||
})
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page {
|
||||
background-color: #F8F8F8;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
|
||||
.data_wrapper {
|
||||
height: 288rpx;
|
||||
transition: all .3s;
|
||||
overflow: hidden;
|
||||
}
|
||||
.close {
|
||||
height: v-bind(moreHeight);
|
||||
}
|
||||
|
||||
.info {
|
||||
.item_box {
|
||||
|
||||
.item {
|
||||
width: 690rpx;
|
||||
background: #FFFFFF;
|
||||
box-shadow: 0rpx 2rpx 4rpx 0rpx rgba(0, 0, 0, 0.5);
|
||||
border-radius: 16rpx;
|
||||
padding: 30rpx 0;
|
||||
margin-top: 24rpx;
|
||||
|
||||
.title_box {
|
||||
padding: 0 30rpx;
|
||||
margin-bottom: -20rpx;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
background-image: url('../../static/index/line.png');
|
||||
background-size: 44rpx 13rpx;
|
||||
background-repeat: no-repeat;
|
||||
background-position: left bottom;
|
||||
|
||||
}
|
||||
|
||||
.more {
|
||||
font-size: 24rpx;
|
||||
color: #999999;
|
||||
|
||||
text {
|
||||
margin-right: 6rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.data_box {
|
||||
|
||||
flex-wrap: wrap;
|
||||
.data {
|
||||
width: 33.33%;
|
||||
margin-top: 60rpx;
|
||||
height: 80rpx;
|
||||
|
||||
view {
|
||||
font-size: 32rpx;
|
||||
color: #333333;
|
||||
margin-bottom: 8rpx;
|
||||
|
||||
}
|
||||
|
||||
text {
|
||||
font-size: 24rpx;
|
||||
color: #333333;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
203
bpm/extendCom.vue
Normal file
@ -0,0 +1,203 @@
|
||||
<template>
|
||||
<view class="content">
|
||||
<view class="todo f-col aic">
|
||||
<view class="f-col aic">
|
||||
<view class="title_box f-row aic jcb" @click="tolist('')">
|
||||
<view class="title f-row aic">
|
||||
<image :src="`/static/my/${img}.png`" mode=""></image>
|
||||
{{title}}
|
||||
</view>
|
||||
<view class="num">
|
||||
{{total}}
|
||||
</view>
|
||||
</view>
|
||||
<view class="list" v-if="list.length">
|
||||
<view :class="['box',{'close':list.length>5&&open}]">
|
||||
<view class="item_box">
|
||||
<view @click="tolist(item.title)" class="item f-row aic" v-for="item,i in list" :key="i">
|
||||
<view class="">
|
||||
{{item.title}}
|
||||
</view>
|
||||
<text>{{item.num}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="more" v-show="list.length>5" @click="open = !open">
|
||||
{{!open?'显示更多':'收起'}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref,
|
||||
onMounted,
|
||||
nextTick,
|
||||
computed,
|
||||
watch,
|
||||
getCurrentInstance
|
||||
} from 'vue';
|
||||
import {
|
||||
beforeJump
|
||||
} from '@/utils/index.js';
|
||||
|
||||
const props = defineProps({
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
img: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
list: {
|
||||
type: Array,
|
||||
default: function() {
|
||||
return []
|
||||
}
|
||||
},
|
||||
total: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
type:{
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
})
|
||||
const open = ref(false)
|
||||
const moreHeight = ref(null)
|
||||
const CurrentInstance = getCurrentInstance()
|
||||
watch(() => props.list, () => {
|
||||
nextTick(() => {
|
||||
uni.createSelectorQuery().in(CurrentInstance.proxy).select('.item_box')
|
||||
.boundingClientRect(data => {
|
||||
moreHeight.value = data?.height + 'px'
|
||||
}).exec()
|
||||
})
|
||||
|
||||
}, {
|
||||
immediate: true
|
||||
})
|
||||
const tolist = (title) => {
|
||||
let id = null
|
||||
beforeJump('/pages/task/index', () => {
|
||||
|
||||
if (props.type == '0') {
|
||||
id = 0
|
||||
}
|
||||
if (props.type == '1') {
|
||||
id = 1
|
||||
}
|
||||
if (props.type == '2') {
|
||||
return uni.navigateTo({
|
||||
url: `/pages/task/self?title=${title}`
|
||||
})
|
||||
}
|
||||
uni.navigateTo({
|
||||
url: `/pages/task/index?id=${id}&title=${title}`
|
||||
})
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page {
|
||||
background-color: #F8F8F8;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
.content {
|
||||
padding-top: 30rpx;
|
||||
}
|
||||
|
||||
.todo {
|
||||
.title_box {
|
||||
width: 630rpx;
|
||||
height: 108rpx;
|
||||
background: #FFFFFF;
|
||||
box-shadow: 0rpx 2rpx 6rpx 0rpx rgba(0, 0, 0, 0.16);
|
||||
border-radius: 16rpx;
|
||||
padding: 0 30rpx;
|
||||
|
||||
.title {
|
||||
image {
|
||||
width: 48rpx;
|
||||
height: 48rpx;
|
||||
}
|
||||
|
||||
font-weight: 500;
|
||||
font-size: 32rpx;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.num {
|
||||
width: 54rpx;
|
||||
height: 54rpx;
|
||||
background: url('../../static/my/num.png') no-repeat;
|
||||
background-size: 54rpx 54rpx;
|
||||
font-size: 24rpx;
|
||||
color: #FFFFFF;
|
||||
text-align: center;
|
||||
line-height: 54rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.list {
|
||||
width: 570rpx;
|
||||
padding: 20rpx 30rpx 30rpx 30rpx;
|
||||
background: #FFFFFF;
|
||||
box-shadow: 0rpx 2rpx 6rpx 0rpx rgba(0, 0, 0, 0.16);
|
||||
border-radius: 0rpx 0rpx 16rpx 16rpx;
|
||||
|
||||
.box {
|
||||
|
||||
max-height: 120rpx;
|
||||
transition: all .3s;
|
||||
overflow: hidden;
|
||||
|
||||
.item_box {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.item {
|
||||
font-size: 28rpx;
|
||||
height: 60rpx;
|
||||
width: 50%;
|
||||
|
||||
view {
|
||||
color: #666666;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
-o-text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
text {
|
||||
color: #ED361D;
|
||||
margin: 0 10rpx;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
.close {
|
||||
// height: 300rpx;
|
||||
max-height: v-bind(moreHeight);
|
||||
}
|
||||
|
||||
.more {
|
||||
font-size: 28rpx;
|
||||
color: #008DFF;
|
||||
text-decoration: underline;
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
320
bpm/leaveApplication/index.vue
Normal file
@ -0,0 +1,320 @@
|
||||
<template>
|
||||
<view class="f-col aic">
|
||||
<view class="info_box">
|
||||
<view class="title">
|
||||
申请信息
|
||||
</view>
|
||||
<view class="info f-row aic jcb">
|
||||
<view>
|
||||
请假职工:
|
||||
</view>
|
||||
<text>{{info.username_dictText}}</text>
|
||||
</view>
|
||||
<view class="info f-row aic jcb">
|
||||
<view>
|
||||
所属单位:
|
||||
</view>
|
||||
<text>{{info.sysOrgCode_dictText}}</text>
|
||||
</view>
|
||||
<view class="info f-row aic jcb">
|
||||
<view>
|
||||
联系方式:
|
||||
</view>
|
||||
<text>{{info.phone}}</text>
|
||||
</view>
|
||||
<view class="info f-row aic jcb">
|
||||
<view>
|
||||
请假类型:
|
||||
</view>
|
||||
<text>{{info.type}}</text>
|
||||
</view>
|
||||
<view class="info f-row aic jcb">
|
||||
<view>
|
||||
请假开始时间:
|
||||
</view>
|
||||
<text>{{info.begintime}}</text>
|
||||
</view>
|
||||
<view class="info f-row aic jcb">
|
||||
<view>
|
||||
请假结束时间:
|
||||
</view>
|
||||
<text>{{info.endtime}}</text>
|
||||
</view>
|
||||
<view class="info f-row aic jcb">
|
||||
<view>
|
||||
请假天数:
|
||||
</view>
|
||||
<text>{{info.days}}</text>
|
||||
</view>
|
||||
<view class="info f-row aic jcb">
|
||||
<view>
|
||||
审批人:
|
||||
</view>
|
||||
<text>{{info.examineleader_dictText}}</text>
|
||||
</view>
|
||||
<view class="info f-row aic jcb">
|
||||
<view>
|
||||
出发地:
|
||||
</view>
|
||||
<text>{{info.departure}}</text>
|
||||
</view>
|
||||
<view class="info f-row aic jcb">
|
||||
<view>
|
||||
目的地:
|
||||
</view>
|
||||
<text>{{info.destination}}</text>
|
||||
</view>
|
||||
<view class="info f-row aic jcb">
|
||||
<view>
|
||||
请假原因:
|
||||
</view>
|
||||
<text>{{info.reason}}</text>
|
||||
</view>
|
||||
<view class="info f-row aic jcb" v-if="ifShowFj">
|
||||
<view>
|
||||
附件:
|
||||
</view>
|
||||
<uni-file-picker v-model="imageValue" :image-styles="imageStyles" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="f-col aic">
|
||||
<view class="progress">
|
||||
<view class="title">
|
||||
审批流程
|
||||
</view>
|
||||
<view class="progress_box">
|
||||
<view class="box" v-for="(item,index) in step" :key="index">
|
||||
<view class="topic f-row aic">
|
||||
<view>
|
||||
{{item.name}}
|
||||
</view>
|
||||
<view
|
||||
:class="['status',{'complete':item.deleteReason=='已完成'},{'refuse':item.deleteReason=='已拒绝'}]">
|
||||
{{item.deleteReason}}
|
||||
</view>
|
||||
</view>
|
||||
<view class="name_time">
|
||||
{{item.assigneeName}} | {{item.endTime}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
extActFlowDataApi,
|
||||
processHistoryListApi
|
||||
} from '@/api/api.js';
|
||||
import {
|
||||
qjQueryByIdApi
|
||||
} from '@/api/pages.js';
|
||||
import {
|
||||
ref,
|
||||
onBeforeMount,
|
||||
watch,
|
||||
onMounted
|
||||
} from 'vue'
|
||||
import {
|
||||
imgUrl
|
||||
} from '@/utils/index.js';
|
||||
const props = defineProps({
|
||||
dataId: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
})
|
||||
const imageValue = ref([])
|
||||
const ifShowFj = ref(false)
|
||||
const imageStyles = {
|
||||
width: 64,
|
||||
height: 64,
|
||||
border: {
|
||||
color: "#dce7e1",
|
||||
width: 2,
|
||||
style: 'dashed',
|
||||
radius: '2px'
|
||||
}
|
||||
}
|
||||
const info = ref({})
|
||||
// 申请信息
|
||||
const qjQueryById = () => {
|
||||
qjQueryByIdApi({
|
||||
id: props.dataId
|
||||
}).then((res) => {
|
||||
if (res.success) {
|
||||
info.value = res.result.records[0]
|
||||
// 构造 imageValue 数组
|
||||
if (info.value.path) {
|
||||
ifShowFj.value = true;
|
||||
imageValue.value = info.value.path.split(',').map(path => {
|
||||
const name = path.split('/').pop(); // 获取文件名
|
||||
const extname = name.split('.').pop(); // 获取文件扩展名并转换为大写
|
||||
return {
|
||||
name,
|
||||
extname,
|
||||
url: imgUrl(path)
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
/**审批步骤*/
|
||||
const extActFlowData = () => {
|
||||
extActFlowDataApi({
|
||||
flowCode: "dev_cxc_qxj",
|
||||
dataId: props.dataId
|
||||
}).then((res) => {
|
||||
if (res.success) {
|
||||
processHistoryList(res.result.processInstanceId)
|
||||
}
|
||||
})
|
||||
}
|
||||
const step = ref([])
|
||||
const processHistoryList = (processInstanceId) => {
|
||||
processHistoryListApi({
|
||||
processInstanceId
|
||||
}).then((res) => {
|
||||
if (res.success) {
|
||||
step.value = res.result.records
|
||||
}
|
||||
})
|
||||
}
|
||||
// watch(() => props.dataId, (nval, oval) => {
|
||||
// if (nval) {
|
||||
// qjQueryById()
|
||||
// extActFlowData()
|
||||
// }
|
||||
// })
|
||||
onMounted(() => {
|
||||
qjQueryById()
|
||||
extActFlowData()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.info_box {
|
||||
padding: 40rpx 30rpx 16rpx 30rpx;
|
||||
width: 630rpx;
|
||||
background: #FFFFFF;
|
||||
box-shadow: 0rpx 2rpx 4rpx 0rpx rgba(0, 0, 0, 0.5);
|
||||
border-radius: 16rpx;
|
||||
margin-top: 30rpx;
|
||||
|
||||
|
||||
.title {
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
background-image: url(../../static/index/line.png);
|
||||
background-size: 44rpx 12rpx;
|
||||
background-repeat: no-repeat;
|
||||
background-position: left bottom;
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
.info {
|
||||
font-size: 28rpx;
|
||||
margin-bottom: 24rpx;
|
||||
|
||||
view {
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
text {
|
||||
color: #333333;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.progress {
|
||||
background: #FFFFFF;
|
||||
box-shadow: 0rpx 2rpx 4rpx 0rpx rgba(0, 0, 0, 0.5);
|
||||
border-radius: 16rpx;
|
||||
width: 630rpx;
|
||||
padding: 40rpx 30rpx 16rpx 30rpx;
|
||||
margin-top: 30rpx;
|
||||
margin-bottom: 30rpx;
|
||||
|
||||
.status {
|
||||
padding: 4rpx 8rpx;
|
||||
display: inline-block;
|
||||
|
||||
color: #FFFFFF;
|
||||
font-size: 20rpx;
|
||||
margin-left: 8rpx;
|
||||
border-radius: 8rpx;
|
||||
|
||||
}
|
||||
|
||||
.complete {
|
||||
background-color: #7AC756;
|
||||
}
|
||||
|
||||
.refuse {
|
||||
background-color: #FE4600;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
background-image: url(../../static/index/line.png);
|
||||
background-size: 44rpx 12rpx;
|
||||
background-repeat: no-repeat;
|
||||
background-position: left bottom;
|
||||
margin-bottom: 40rpx;
|
||||
|
||||
}
|
||||
|
||||
// .box:not(:first-child) {
|
||||
// padding-top: 60rpx;
|
||||
// }
|
||||
.box:not(:last-child) {
|
||||
position: relative;
|
||||
padding-bottom: 60rpx;
|
||||
|
||||
&::before {
|
||||
position: absolute;
|
||||
content: ' ';
|
||||
width: 1px;
|
||||
height: 100%;
|
||||
background: #efefef;
|
||||
left: -42rpx;
|
||||
top: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.box {
|
||||
margin-left: 50rpx;
|
||||
|
||||
|
||||
.topic {
|
||||
position: relative;
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
|
||||
&::before {
|
||||
position: absolute;
|
||||
content: ' ';
|
||||
width: 18rpx;
|
||||
height: 18rpx;
|
||||
background: #01508B;
|
||||
border-radius: 14rpx;
|
||||
left: -50rpx;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
}
|
||||
|
||||
.name_time {
|
||||
font-size: 24rpx;
|
||||
color: #888888;
|
||||
margin-top: 12rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
62
bpm/processCom.vue
Normal file
@ -0,0 +1,62 @@
|
||||
<template>
|
||||
<view class="f-col aic">
|
||||
<view class="info_box">
|
||||
<view class="title">
|
||||
申请信息
|
||||
</view>
|
||||
<view class="" v-for="item,i in info" :key="i">
|
||||
<view class="info f-row aic jcb">
|
||||
<view class="">
|
||||
{{item.title}}:
|
||||
</view>
|
||||
<rich-text :nodes="item.data" v-if="item.title=='事项内容'"></rich-text>
|
||||
<text v-else>{{item.data}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const props = defineProps({
|
||||
info: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.info_box {
|
||||
padding: 40rpx 30rpx 16rpx 30rpx;
|
||||
width: 630rpx;
|
||||
background: #FFFFFF;
|
||||
box-shadow: 0rpx 2rpx 4rpx 0rpx rgba(0, 0, 0, 0.5);
|
||||
border-radius: 16rpx;
|
||||
margin-top: 30rpx;
|
||||
|
||||
|
||||
.title {
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
background-image: url(../../static/index/line.png);
|
||||
background-size: 44rpx 12rpx;
|
||||
background-repeat: no-repeat;
|
||||
background-position: left bottom;
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
.info {
|
||||
font-size: 28rpx;
|
||||
margin-bottom: 24rpx;
|
||||
|
||||
view {
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
text {
|
||||
color: #333333;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
54
bpm/safeCom.vue
Normal file
@ -0,0 +1,54 @@
|
||||
<template>
|
||||
<view class="list f-row aic jcb">
|
||||
<view class="item" v-for="item,i in 20" :key="i" @click="jump('/pages/safe/detail')">
|
||||
<view class="">
|
||||
<image src="" mode=""></image>
|
||||
</view>
|
||||
<view class="text">
|
||||
五月天“突然好想你”线上演唱会精彩回放
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
beforeJump
|
||||
} from '@/utils/index.js';
|
||||
const jump = (url) => {
|
||||
beforeJump(url, () => {
|
||||
uni.navigateTo({
|
||||
url
|
||||
})
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.list {
|
||||
flex-wrap: wrap;
|
||||
|
||||
.item {
|
||||
width: 340rpx;
|
||||
background: #FFFFFF;
|
||||
box-shadow: 0rpx 2rpx 4rpx 0rpx rgba(0, 0, 0, 0.5);
|
||||
border-radius: 16rpx;
|
||||
margin-top: 20rpx;
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
line-height: 40rpx;
|
||||
|
||||
.text {
|
||||
padding: 16rpx;
|
||||
}
|
||||
|
||||
image {
|
||||
width: 340rpx;
|
||||
height: 200rpx;
|
||||
border-radius: 16rpx 16rpx 0 0;
|
||||
background-color: #efefef;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
331
bpm/supervise.vue
Normal file
@ -0,0 +1,331 @@
|
||||
<template>
|
||||
<view class="">
|
||||
<view class="tab f-row aic">
|
||||
<view :class="{'active':currentTab==item.id}" v-for="item,i in tabArr" :key="i" @click="changeTab(item.id)">
|
||||
{{item.title}}
|
||||
</view>
|
||||
</view>
|
||||
<processCom :info="info"></processCom>
|
||||
<view class="f-col aic">
|
||||
<view class="progress">
|
||||
<view class="title">
|
||||
审批流程
|
||||
</view>
|
||||
<view class="progress_box">
|
||||
<view class="box" v-for="(item,index) in step" :key="index">
|
||||
<view class="topic f-row aic">
|
||||
<view class="">
|
||||
{{item.name}}
|
||||
</view>
|
||||
<view
|
||||
:class="['status',{'complete':item.deleteReason=='已完成'},{'refuse':item.deleteReason=='已拒绝'}]">
|
||||
{{item.deleteReason}}
|
||||
</view>
|
||||
</view>
|
||||
<view class="name_time">
|
||||
{{item.assigneeName}} | {{item.endTime}}
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
dbSxxqQueryByIdApi,
|
||||
dbJbxxQueryByIdApi,
|
||||
extActFlowDataApi,
|
||||
processHistoryListApi
|
||||
} from '@/api/api.js';
|
||||
import processCom from './processCom.vue';
|
||||
import {
|
||||
ref,
|
||||
onBeforeMount,
|
||||
watch,
|
||||
onMounted
|
||||
} from 'vue';
|
||||
const props = defineProps({
|
||||
dataId: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
})
|
||||
const tabArr = [{
|
||||
title: '基本信息',
|
||||
id: 1
|
||||
}, {
|
||||
title: '事项详情',
|
||||
id: 2
|
||||
}, {
|
||||
title: '添加下级',
|
||||
id: 3
|
||||
}, {
|
||||
title: '节点顺序',
|
||||
id: 4
|
||||
}, {
|
||||
title: '运行计划',
|
||||
id: 5
|
||||
}]
|
||||
const currentTab = ref(1)
|
||||
const changeTab = (id) => {
|
||||
currentTab.value = id
|
||||
dbSxxqQueryById()
|
||||
|
||||
}
|
||||
const info = ref([])
|
||||
/**事项详情*/
|
||||
const dbSxxqQueryById = () => {
|
||||
dbSxxqQueryByIdApi({
|
||||
id: props.dataId
|
||||
}).then((res) => {
|
||||
if (res.success) {
|
||||
|
||||
if(currentTab.value==1){
|
||||
|
||||
dbJbxxQueryById(res.result.jbxxid)
|
||||
}
|
||||
if(currentTab.value==2){
|
||||
let d = res.result
|
||||
info.value = [{
|
||||
title: '承办部门',
|
||||
data: d.zbdw
|
||||
}, {
|
||||
title: '协办部门',
|
||||
data: d.xbdw
|
||||
}, {
|
||||
title: '部门领导',
|
||||
data: d.fgld
|
||||
}, {
|
||||
title: '办理人员',
|
||||
data: d.dbry
|
||||
}, {
|
||||
title: '要求反馈时间',
|
||||
data: d.yqfksj
|
||||
}, {
|
||||
title: '节点名称',
|
||||
data: ''
|
||||
}, {
|
||||
title: '预计完成时间',
|
||||
data: ''
|
||||
}, {
|
||||
title: '实际反馈时间',
|
||||
data: d.sjfksj
|
||||
}, {
|
||||
title: '自评价',
|
||||
data: d.zpj
|
||||
}, {
|
||||
title: '发起时间',
|
||||
data: d.fqsj
|
||||
}, {
|
||||
title: '序号',
|
||||
data: ''
|
||||
}, {
|
||||
title: '概述',
|
||||
data: ''
|
||||
}, {
|
||||
title: '时间进度',
|
||||
data: ''
|
||||
}, {
|
||||
title: '事项内容',
|
||||
data: d.sxnr
|
||||
}]
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
/**基本信息*/
|
||||
const dbJbxxQueryById = (id) => {
|
||||
dbJbxxQueryByIdApi({
|
||||
id
|
||||
}).then((res) => {
|
||||
if (res.success) {
|
||||
let d = res.result
|
||||
info.value = [{
|
||||
title: '督办分类',
|
||||
data: d.fl
|
||||
}, {
|
||||
title: '协办部门',
|
||||
data: d.xbbm
|
||||
}, {
|
||||
title: '督办部门',
|
||||
data: d.cbbm
|
||||
}, {
|
||||
title: '督办人员',
|
||||
data: d.dbry
|
||||
}, {
|
||||
title: '督办部门负责人',
|
||||
data: d.zrr
|
||||
}, {
|
||||
title: '是否涉密',
|
||||
data: d.sfsm
|
||||
}, {
|
||||
title: '计划完成时间',
|
||||
data: d.jhwcsj
|
||||
}, {
|
||||
title: '实际完成时间',
|
||||
data: d.wcsj
|
||||
}, {
|
||||
title: '完成状态',
|
||||
data: d.wczt
|
||||
}, {
|
||||
title: '备注',
|
||||
data: d.bz
|
||||
}, {
|
||||
title: '督办事项',
|
||||
data: d.dbsx
|
||||
}, {
|
||||
title: '时间进度',
|
||||
data: d.sjjd
|
||||
}]
|
||||
}
|
||||
})
|
||||
}
|
||||
const extActFlowData = (dataId) => {
|
||||
extActFlowDataApi({
|
||||
flowCode: "dev_db_sxxq_001",
|
||||
dataId: props.dataId
|
||||
}).then((res) => {
|
||||
if (res.success) {
|
||||
processHistoryList(res.result.processInstanceId)
|
||||
}
|
||||
})
|
||||
}
|
||||
const step = ref([])
|
||||
/**审批步骤*/
|
||||
const processHistoryList = (processInstanceId) => {
|
||||
console.log('000', processInstanceId);
|
||||
processHistoryListApi({
|
||||
processInstanceId
|
||||
}).then((res) => {
|
||||
console.log('0088800', res);
|
||||
if (res.success) {
|
||||
step.value = res.result.records
|
||||
}
|
||||
})
|
||||
}
|
||||
onMounted(() => {
|
||||
dbSxxqQueryById()
|
||||
extActFlowData()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.tab {
|
||||
background-color: #fff;
|
||||
overflow-x: auto;
|
||||
|
||||
view {
|
||||
padding: 20rpx 30rpx;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.active {
|
||||
position: relative;
|
||||
color: #1890ff;
|
||||
|
||||
&::after {
|
||||
content: ' ';
|
||||
position: absolute;
|
||||
width: 100rpx;
|
||||
height: 6rpx;
|
||||
border-radius: 3rpx;
|
||||
background-color: #1890ff;
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
.progress {
|
||||
background: #FFFFFF;
|
||||
box-shadow: 0rpx 2rpx 4rpx 0rpx rgba(0, 0, 0, 0.5);
|
||||
border-radius: 16rpx;
|
||||
width: 630rpx;
|
||||
padding: 40rpx 30rpx 16rpx 30rpx;
|
||||
margin-top: 30rpx;
|
||||
margin-bottom: 30rpx;
|
||||
|
||||
.status {
|
||||
padding: 4rpx 8rpx;
|
||||
display: inline-block;
|
||||
|
||||
color: #FFFFFF;
|
||||
font-size: 20rpx;
|
||||
margin-left: 8rpx;
|
||||
border-radius: 8rpx;
|
||||
|
||||
}
|
||||
|
||||
.complete {
|
||||
background-color: #7AC756;
|
||||
}
|
||||
|
||||
.refuse {
|
||||
background-color: #FE4600;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
background-image: url(../../static/index/line.png);
|
||||
background-size: 44rpx 12rpx;
|
||||
background-repeat: no-repeat;
|
||||
background-position: left bottom;
|
||||
margin-bottom: 40rpx;
|
||||
|
||||
}
|
||||
|
||||
// .box:not(:first-child) {
|
||||
// padding-top: 60rpx;
|
||||
// }
|
||||
.box:not(:last-child) {
|
||||
position: relative;
|
||||
padding-bottom: 60rpx;
|
||||
|
||||
&::before {
|
||||
position: absolute;
|
||||
content: ' ';
|
||||
width: 1px;
|
||||
height: 100%;
|
||||
background: #efefef;
|
||||
left: -42rpx;
|
||||
top: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.box {
|
||||
margin-left: 50rpx;
|
||||
|
||||
|
||||
.topic {
|
||||
position: relative;
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
|
||||
&::before {
|
||||
position: absolute;
|
||||
content: ' ';
|
||||
width: 18rpx;
|
||||
height: 18rpx;
|
||||
background: #01508B;
|
||||
border-radius: 14rpx;
|
||||
left: -50rpx;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
}
|
||||
|
||||
.name_time {
|
||||
font-size: 24rpx;
|
||||
color: #888888;
|
||||
margin-top: 12rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
194
bpm/tasklistCom.vue
Normal file
@ -0,0 +1,194 @@
|
||||
<template>
|
||||
<view class="list_box">
|
||||
<view class="list" v-for="item,i in taskArr" :key="i"
|
||||
@click="tojump(`/pages/task/handle?info=${JSON.stringify(item)}&type=${currentIndex}`)">
|
||||
<view class="title f-row aic jcb">
|
||||
<view>
|
||||
<view>
|
||||
{{item.bpmBizTitle}}
|
||||
</view>
|
||||
</view>
|
||||
<text>{{item.durationStr}}</text>
|
||||
</view>
|
||||
<view class="info">
|
||||
<view>
|
||||
申请理由:{{item.bpmBizTitle}}
|
||||
</view>
|
||||
<view v-if="currentIndex != 2">
|
||||
当前环节:{{item.taskName}}
|
||||
</view>
|
||||
<view>
|
||||
流程名称:{{item.processDefinitionName}}
|
||||
</view>
|
||||
<view>
|
||||
发起人:{{item.processApplyUserName}}
|
||||
</view>
|
||||
<view>
|
||||
开始时间:{{item.taskBeginTime}}
|
||||
</view>
|
||||
<view v-if="item.taskEndTime">
|
||||
结束时间:{{item.taskEndTime}}
|
||||
</view>
|
||||
</view>
|
||||
<view class="btn f-row aic jcb" v-if="currentIndex == 0 && item.taskAssigneeName">
|
||||
<view class="entrust" @click.stop="tojump(`/pages/userlist/index?isradio=1&id=${item.id}`)">
|
||||
委托
|
||||
</view>
|
||||
<view class="handle" @click="tojump(`/pages/task/handle?info=${JSON.stringify(item)}&type=${currentIndex}`)">
|
||||
办理
|
||||
</view>
|
||||
</view>
|
||||
<view class="btn f-row aic jcb" v-if="currentIndex == 0 && !item.taskAssigneeName">
|
||||
<view>
|
||||
</view>
|
||||
<view class="handle" @click.stop="handleClaim(item.id)">
|
||||
签收
|
||||
</view>
|
||||
</view>
|
||||
<view class="btn f-row aic jcb" v-if="currentIndex == 2 && !item.endTime">
|
||||
<view class="entrust" @click.stop="invalidProcess(item.processInstanceId)">
|
||||
作废流程
|
||||
</view>
|
||||
<view class="handle" @click.stop="callBackProcess(item.processInstanceId)">
|
||||
取回流程
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
claimApi,
|
||||
callBackProcessApi,
|
||||
invalidProcessApi
|
||||
} from '@/api/api.js';
|
||||
import {
|
||||
getCurrentInstance,
|
||||
} from 'vue';
|
||||
const {
|
||||
proxy
|
||||
} = getCurrentInstance()
|
||||
|
||||
const props = defineProps({
|
||||
taskArr: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
currentIndex: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
})
|
||||
const emit = defineEmits(['jump'])
|
||||
const tojump = (url) => {
|
||||
emit('jump', url)
|
||||
}
|
||||
|
||||
/**流程签收*/
|
||||
const handleClaim = (id) => {
|
||||
claimApi({
|
||||
taskId: id
|
||||
}).then((res) => {
|
||||
if (res.success) {
|
||||
uni.redirectTo({
|
||||
url: './index?id=0'
|
||||
});
|
||||
proxy.$toast(res.message)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**流程取回*/
|
||||
const callBackProcess = (id) => {
|
||||
callBackProcessApi({
|
||||
processInstanceId: id
|
||||
}).then((res) => {
|
||||
if (res.success) {
|
||||
uni.redirectTo({
|
||||
url: './self'
|
||||
});
|
||||
proxy.$toast(res.message)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**流程作废*/
|
||||
const invalidProcess = (id) => {
|
||||
invalidProcessApi({
|
||||
processInstanceId: id
|
||||
}).then((res) => {
|
||||
if (res.success) {
|
||||
uni.redirectTo({
|
||||
url: './self'
|
||||
});
|
||||
proxy.$toast(res.message)
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.list_box {
|
||||
padding: 0 30rpx 0 30rpx;
|
||||
margin-top: 24rpx;
|
||||
|
||||
.list {
|
||||
background: #FFFFFF;
|
||||
box-shadow: 0rpx 2rpx 4rpx 0rpx rgba(0, 0, 0, 0.5);
|
||||
border-radius: 16rpx;
|
||||
padding: 30rpx;
|
||||
margin-bottom: 30rpx;
|
||||
|
||||
.title {
|
||||
border-bottom: 1px solid #efefef;
|
||||
padding-bottom: 24rpx;
|
||||
margin-bottom: 8rpx;
|
||||
|
||||
view {
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
text {
|
||||
font-size: 28rpx;
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
|
||||
.info {
|
||||
font-size: 28rpx;
|
||||
color: #666666;
|
||||
|
||||
view {
|
||||
padding-top: 16rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.btn {
|
||||
margin-top: 30rpx;
|
||||
|
||||
view {
|
||||
width: 300rpx;
|
||||
height: 64rpx;
|
||||
border-radius: 8rpx;
|
||||
font-size: 28rpx;
|
||||
text-align: center;
|
||||
line-height: 64rpx;
|
||||
}
|
||||
|
||||
.entrust {
|
||||
background: #FFFFFF;
|
||||
border: 2rpx solid #01508B;
|
||||
box-sizing: border-box;
|
||||
color: #01508B;
|
||||
}
|
||||
|
||||
.handle {
|
||||
background: #01508B;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
BIN
certificate/book.keystore
Normal file
9
certificate/证书信息.txt
Normal file
@ -0,0 +1,9 @@
|
||||
证书指纹:
|
||||
MD5: 9A:AD:4D:78:17:EE:17:D3:62:B2:6E:B2:56:0B:18:C3
|
||||
SHA1: B1:1E:CE:4B:70:C7:88:B3:6E:8B:B9:05:98:4B:FD:67:81:C1:3A:8F
|
||||
SHA256: A9:78:BD:BF:BB:DE:35:14:AA:5D:45:E9:6A:D0:E5:17:6D:BE:58:86:7A:1D:66:A2:F3:62:2F:E7:9C:9E:59:F6
|
||||
|
||||
|
||||
别名: __uni__9f097f0
|
||||
证书密码为:uZ6Stufj
|
||||
包名:com.tianranqi.app
|
||||
119
components/departSelect/departSelect.vue
Normal file
@ -0,0 +1,119 @@
|
||||
<template>
|
||||
<view>
|
||||
<view v-if="customReturnValue === 'orgCode'">
|
||||
<uni-data-picker :openSearch="true" placeholder="请选择单位" popup-title="请选择单位" :localdata="dataList"
|
||||
@nodeclick="onNodeClick" @popupclosed="onPopupClosed" v-model="ID"
|
||||
:map="{ text: 'title', value: 'orgCode' }"></uni-data-picker>
|
||||
</view>
|
||||
<view v-else>
|
||||
<uni-data-picker :openSearch="true" placeholder="请选择单位" popup-title="请选择单位" :localdata="dataList"
|
||||
@nodeclick="onNodeClick" @popupclosed="onPopupClosed" v-model="ID"
|
||||
:map="{ text: 'title', value: 'id' }"></uni-data-picker>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
queryDepByCode,
|
||||
queryZbDepByLdhth
|
||||
} from '@/api/depart.js'
|
||||
import {
|
||||
useStore
|
||||
} from '@/store';
|
||||
|
||||
const store = useStore()
|
||||
|
||||
const props = defineProps([{
|
||||
value: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
|
||||
customReturnValue: {
|
||||
require: true,
|
||||
type: String,
|
||||
default: 'orgCode'
|
||||
}
|
||||
}]),
|
||||
|
||||
watch(value,(newValue,oldValue)=>{
|
||||
console.log("新值是"+newValue, "旧址是"+oldValue);
|
||||
this.ID = val;
|
||||
}),
|
||||
watch(value,(newValue,oldValue)=>{
|
||||
console.log("新值是"+newValue, "旧址是"+oldValue);
|
||||
this.ID = val;
|
||||
}),
|
||||
|
||||
|
||||
data() {
|
||||
return {
|
||||
reset: true,
|
||||
url: {
|
||||
list: '/sys/sysDepart/queryTreeList'
|
||||
},
|
||||
pageNo: 1,
|
||||
pageSize: 3000,
|
||||
|
||||
params: {
|
||||
pageNo: this.pageNo,
|
||||
pageSize: this.pageSize
|
||||
},
|
||||
dataList: [],
|
||||
ID: '',
|
||||
bmText: '',
|
||||
tempID: '',
|
||||
field: ''
|
||||
};
|
||||
},
|
||||
onReady() {
|
||||
this.getData();
|
||||
},
|
||||
mounted() {
|
||||
this.getData();
|
||||
},
|
||||
methods: {
|
||||
onNodeClick(e) {
|
||||
console.log(JSON.stringify(e));
|
||||
console.log(e.orgCode, e.title, e.id, this.customReturnValue);
|
||||
this.$nextTick(() => {
|
||||
if (this.customReturnValue == 'orgCode') {
|
||||
this.tempID = e.orgCode;
|
||||
}
|
||||
if (this.customReturnValue == 'id') {
|
||||
this.tempID = e.id;
|
||||
}
|
||||
|
||||
this.bmText = e.title;
|
||||
})
|
||||
},
|
||||
onPopupClosed() {
|
||||
this.$nextTick(() => {
|
||||
this.ID = this.tempID;
|
||||
console.log(this.ID, this.bmText);
|
||||
this.$emit('input', this.ID);
|
||||
this.$emit('change', this.ID, this.bmText);
|
||||
});
|
||||
},
|
||||
onchange(e) {
|
||||
this.$nextTick(() => {
|
||||
this.ID = this.tempID;
|
||||
console.log(this.ID, this.bmText);
|
||||
this.$emit('input', this.ID);
|
||||
this.$emit('change', this.ID, e.detail.value);
|
||||
})
|
||||
},
|
||||
getData() {
|
||||
// console.log(111)
|
||||
let that = this;
|
||||
queryDepByCode(store.userinfo.workNo).then((res) => { //获取工作单位
|
||||
console.log(res)
|
||||
depart.value = res.departName
|
||||
orgCode.value = res.orgCode
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
51
components/kidoki-date-picker/kidoki-date-picker.vue
Normal file
@ -0,0 +1,51 @@
|
||||
<template>
|
||||
<view class="date-picker-container">
|
||||
<picker mode=multiSelector @change="bindPickerChange" :value="index" :range="range">
|
||||
<slot />
|
||||
</picker>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref } from 'vue'
|
||||
import dayjs from 'dayjs'
|
||||
|
||||
// 定义生成 range 的值的方法
|
||||
const getRange = () => {
|
||||
const dateArr = [[], []]
|
||||
for (var i = 2000; i <= 2099; i++) { dateArr[0].push(`${i}年`) }
|
||||
for (var i = 1; i <= 12; i++) { dateArr[1].push(`${i}月`) }
|
||||
return { dateArr }
|
||||
}
|
||||
|
||||
export default {
|
||||
name: 'date-picker',
|
||||
setup(props) {
|
||||
// range: 长度表示多少列,数组的每项表示每列的数据
|
||||
const { dateArr } = getRange()
|
||||
const range = ref(dateArr)
|
||||
|
||||
// index: 索引数组, 每一项的值表示选择了对应项中的第几个。
|
||||
// date 获取时间
|
||||
// 【[year, month]】 year、month 为选中的年月,例如选中2022年3月就是 year = 22、month = 2
|
||||
const date = dayjs(props.date).format("YYYY-MM")
|
||||
const year = Number(date.slice(2, 4))
|
||||
const month = Number(date.slice(5, 7))
|
||||
const index = ref([year, month - 1])
|
||||
console.log(index.value)
|
||||
|
||||
// bindPickerChange: index 改变时触发该事件
|
||||
const bindPickerChange = (e) => {
|
||||
index.value = e.detail.value
|
||||
console.log(`用户选中20${index.value[0]}年${index.value[1] + 1}月`)
|
||||
}
|
||||
|
||||
return { index, range, bindPickerChange }
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.date-picker-container {
|
||||
}
|
||||
</style>
|
||||
289
components/treeSelect/data-select-item.vue
Normal file
@ -0,0 +1,289 @@
|
||||
<template>
|
||||
<view
|
||||
class="customthree-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" @click.stop="handleNameClick(node)">
|
||||
<view class="icon-group">
|
||||
<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>
|
||||
<view v-if="loadingArr.includes(node[props.dataValue].toString())" class="loading-icon-box">
|
||||
<uni-icons class="loading-icon" type="spinner-cycle" size="14" color="#333"></uni-icons>
|
||||
</view>
|
||||
<view class="name" :style="node.disabled ? 'color: #999' : ''">
|
||||
<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 }]"
|
||||
:style="{ 'border-radius': mutiple ? '3px' : '50%' }"
|
||||
@click.stop="!node.disabled && 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"
|
||||
:lazyLoadChildren="lazyLoadChildren"
|
||||
:border="border"
|
||||
:linkage="linkage"
|
||||
:level="level + 1"
|
||||
></data-select-item>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import dataSelectItem from './data-select-item.vue'
|
||||
import { paging } from './utils'
|
||||
import { ref, inject, watchEffect } from 'vue'
|
||||
|
||||
const { nodeClick, nameClick, loadNode, initData, addNode } = inject('nodeFn')
|
||||
|
||||
const props = defineProps({
|
||||
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
|
||||
},
|
||||
lazyLoadChildren: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
level: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
mutiple: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
})
|
||||
|
||||
const listData = ref([])
|
||||
const clearTimerList = ref([])
|
||||
const loadingArr = ref([])
|
||||
|
||||
watchEffect(() => {
|
||||
if (props.node.showChildren && props.node[props.dataChildren] && props.node[props.dataChildren].length) {
|
||||
resetClearTimerList()
|
||||
renderTree(props.node[props.dataChildren])
|
||||
}
|
||||
})
|
||||
|
||||
// 中断懒加载
|
||||
function resetClearTimerList() {
|
||||
const list = [...clearTimerList.value]
|
||||
clearTimerList.value = []
|
||||
list.forEach((fn) => fn())
|
||||
}
|
||||
|
||||
// 懒加载
|
||||
function renderTree(arr: any[]) {
|
||||
const pagingArr = paging(arr)
|
||||
listData.value = pagingArr?.[0] || []
|
||||
lazyRenderList(pagingArr, 1)
|
||||
}
|
||||
|
||||
// 懒加载具体逻辑
|
||||
function lazyRenderList(arr: any[], startIndex: number) {
|
||||
for (let i = startIndex; i < arr.length; i++) {
|
||||
let timer: any = null
|
||||
timer = setTimeout(() => {
|
||||
listData.value.push(...arr[i])
|
||||
}, i * 500)
|
||||
clearTimerList.push(() => clearTimeout(timer))
|
||||
}
|
||||
}
|
||||
|
||||
// 点击名称懒加载子元素
|
||||
function handleNameClick(node: any) {
|
||||
if (!node.visible) return
|
||||
|
||||
if (!node[props.dataChildren]?.length && props.lazyLoadChildren) {
|
||||
loadingArr.value.push(node[props.dataValue].toString())
|
||||
|
||||
loadNode(node)
|
||||
.then((res: any) => {
|
||||
addNode(node, initData(res, node.visible))
|
||||
})
|
||||
.finally(() => {
|
||||
loadingArr.value = []
|
||||
})
|
||||
} else {
|
||||
nameClick(node)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
$primary-color: #007aff;
|
||||
$col-sm: 4px;
|
||||
$col-base: 8px;
|
||||
$col-lg: 12px;
|
||||
$row-sm: 5px;
|
||||
$row-base: 10px;
|
||||
$row-lg: 15px;
|
||||
$radius-base: 6px;
|
||||
$border-color: #c8c7cc;
|
||||
|
||||
.customthree-tree-select-content {
|
||||
&.border {
|
||||
border-left: 1px solid $border-color;
|
||||
}
|
||||
|
||||
::v-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);
|
||||
}
|
||||
}
|
||||
|
||||
.loading-icon-box {
|
||||
margin-right: $row-sm;
|
||||
width: 14px;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.loading-icon {
|
||||
transform-origin: center;
|
||||
animation: rotating infinite 0.2s ease;
|
||||
}
|
||||
}
|
||||
|
||||
.name {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.check-box {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
width: 23.6px;
|
||||
height: 23.6px;
|
||||
border: 1px solid $border-color;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes rotating {
|
||||
from {
|
||||
transform: rotate(0);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
240
components/treeSelect/readme.md
Normal file
@ -0,0 +1,240 @@
|
||||
# customthree-tree-select 使用指南
|
||||
|
||||
**提示:** 使用该插件前确保你已经导入 `uni-popup` `uni-icons` `uni-easyinput` 插件。
|
||||
|
||||
**有问题可以加 QQ 群:297080738**
|
||||
|
||||
## 优势
|
||||
|
||||
💪:基于 `uni-popup`、 `uni-icons`、 `uni-easyinput` 插件进行开发,默认样式与 `uni-easyinput` 样式对标。
|
||||
|
||||
⚡:全面支持懒加载应对大量数据。
|
||||
|
||||
🚀:v-model 绑定数据、数据回显、移除选项。
|
||||
|
||||
⚙ :提供更多配置项。
|
||||
|
||||
📦:开箱即用。
|
||||
|
||||
## Props
|
||||
|
||||
| 属性名 | 类型 | 默认值 | 说明 |
|
||||
| :--------------------: | :-----------------: | :-------------: | :----------------------------------------------------------: |
|
||||
| canSelectAll | Boolean | false | 开启一键全选功能 |
|
||||
| clearResetSearch | Boolean | false | 设置为 `true` 并且搜索之后,点击输入框清除按钮,会清空搜索内容并且会直接重置整个弹窗内树形选择器内容,默认情况下只有清除之后再次进行查询才会重置选择器 |
|
||||
| animation | Boolean | ture | 是否开启弹窗动画 |
|
||||
| is-mask-click | Boolean | true | 点击遮罩关闭弹窗 |
|
||||
| mask-background-color | String | rgba(0,0,0,0.4) | 蒙版颜色,建议使用 rgba 颜色值 |
|
||||
| background-color | String | none | 主窗口背景色 |
|
||||
| safe-area | Boolean | true | 是否适配底部安全区 |
|
||||
| **choseParent** | **Boolean** | **false** | **父节点是否可选** |
|
||||
| **linkage** | **Boolean** | **false** | **父子节点是否联动** |
|
||||
| placeholder | String | 请选择 | 空状态信息提示、弹窗标题 |
|
||||
| confirmText | String | 完成 | 确定按钮文字 |
|
||||
| confirmTextColor | String | #007aff | 确定按钮文字颜色 |
|
||||
| dataSource | Array | - | 展示的数据 |
|
||||
| **dataLabel** | **String** | **name** | **dataSource 中对应数据的 label** |
|
||||
| **dataValue** | **String** | **id** | **dataSource 中对应数据的 value** |
|
||||
| **dataChildren** | **String** | **children** | **dataSource 中对应数据的 children** |
|
||||
| clearable | Boolean | false | 是否显示清除按钮,点击清除所有已选项 |
|
||||
| **mutiple** | **Boolean** | **false** | **是否可以多选** |
|
||||
| **disabled** | **Boolean** | **false** | **是否允许修改** |
|
||||
| search | Boolean | false | 是否可以搜索(常用于数据较多的情况) |
|
||||
| showChildren | Boolean | false | 默认不展开(数据内部 showChildren 属性优先级更高,可以设置全局收起,单独展开某一条数据) |
|
||||
| border | Boolean | false | 显示引导线 |
|
||||
| load | Function | function(){} | lazyLoadChildren 设置为true 后,点击某个节点发送请求获取子节点数据,用法见下方异步懒加载示例 |
|
||||
| lazyLoadChildren | Boolean | false | 是否开启异步懒加载节点 |
|
||||
| **v-model/modelValue** | **Array \| String** | **[ ]** | **已选择的值,通过 v-model 进行绑定,例如:v-model="formData.selectedList" ,根据你绑定数据的类型自动返回相同类型的数据,String 类型通过 `,` 进行分隔** |
|
||||
| deleteSource | Boolean | false | 是否可删除已选数据
|
||||
## Events
|
||||
|
||||
| 事件名称 | 说明 | 返回值 |
|
||||
| ----------------- | ------------------------ | ------------------------------------------- |
|
||||
| change | 弹窗组件状态发生变化触发 | e={show: true | false,type:当前模式} |
|
||||
| maskClick | 点击遮罩层触发 | |
|
||||
| update:modelValue | 选中数据或取消选中时触发 | 以数组形式返回已选择数据的 dataValue 对应值 |
|
||||
| select-change | 选中数据或取消选中时触发 | 以数组形式返回选中数据完整信息 |
|
||||
| removeSelect | 从选择框内删除元素时触发 | |
|
||||
|
||||
## 基础使用示例
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<customthree-tree-select :listData="listData" v-model="formData.selectedArr" />
|
||||
<customthree-tree-select :listData="listData" v-model="formData.selectedString" />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { reactive } from 'vue'
|
||||
|
||||
const formData = reactive({
|
||||
selectedArr: [],
|
||||
selectedString: ''
|
||||
})
|
||||
|
||||
const listData = [
|
||||
{
|
||||
id: 1,
|
||||
name: '城市1',
|
||||
children: [
|
||||
{
|
||||
id: 3,
|
||||
name: '街道1',
|
||||
children: [
|
||||
{
|
||||
id: 4,
|
||||
name: '小区1'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: '城市2',
|
||||
children: [
|
||||
{
|
||||
id: 6,
|
||||
name: '街道2'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
</script>
|
||||
```
|
||||
|
||||
## 禁用某些选项,或隐藏某些选项
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<customthree-tree-select
|
||||
mutiple
|
||||
linkage
|
||||
clearable
|
||||
search
|
||||
dataLabel="text"
|
||||
dataValue="value"
|
||||
:listData="listData"
|
||||
v-model="formData.selected"
|
||||
></custom-tree-select>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { reactive } from 'vue'
|
||||
|
||||
const formData = reactive({
|
||||
selected: ''
|
||||
})
|
||||
|
||||
const listData = [
|
||||
{
|
||||
id: 1,
|
||||
name: '城市1',
|
||||
children: [
|
||||
{
|
||||
id: 3,
|
||||
name: '街道1',
|
||||
disabled: true
|
||||
children: [
|
||||
{
|
||||
id: 4,
|
||||
name: '小区1'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: '城市2',
|
||||
children: [
|
||||
{
|
||||
id: 6,
|
||||
name: '街道2',
|
||||
visible: false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
</script>
|
||||
```
|
||||
|
||||
## 异步懒加载
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<view class="content">
|
||||
<customthree-tree-select
|
||||
search
|
||||
linkage
|
||||
clearable
|
||||
clearResetSearch
|
||||
border
|
||||
mutiple
|
||||
lazyLoadChildren
|
||||
canSelectAll
|
||||
:showChildren="false"
|
||||
:listData="listData"
|
||||
:load="loadNode"
|
||||
dataLabel="text"
|
||||
dataValue="value"
|
||||
v-model="selectedStr"
|
||||
></customthree-tree-select>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
selectedStr: '',
|
||||
listData: [
|
||||
{
|
||||
value: '0',
|
||||
text: '测试懒加载'
|
||||
},
|
||||
{
|
||||
value: '1',
|
||||
text: '城市1',
|
||||
children: [
|
||||
{
|
||||
value: '1-1',
|
||||
text: '街道1',
|
||||
disabled: true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
loadNode(node) {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
const item = this.listData.find((item) => item.value === node.value)
|
||||
if (item) {
|
||||
resolve([
|
||||
{
|
||||
value: '0-1',
|
||||
text: '懒加载子元素'
|
||||
}
|
||||
])
|
||||
}
|
||||
resolve([])
|
||||
}, 500)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
811
components/treeSelect/treeSelect.vue
Normal file
@ -0,0 +1,811 @@
|
||||
<template>
|
||||
<view :class="['select-list', { disabled }, { active: selectList.length }]" @click="open">
|
||||
<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 && deleteSource" class="close"
|
||||
@click.stop="removeSelectedItem(item)">
|
||||
<uni-icons type="closeempty" size="16" color="#999"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-else class="no-data">
|
||||
<text>{{ placeholder }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view>
|
||||
<uni-icons v-if="!selectList.length || !clearable" type="bottom" color="#333333"></uni-icons>
|
||||
<view @click.stop>
|
||||
<uni-icons v-if="selectList.length && clearable" type="clear" size="24" color="#c0c4cc"
|
||||
@click="clearSelectList"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<uni-popup ref="popup" :animation="animation" :is-mask-click="isMaskClick"
|
||||
:mask-background-color="maskBackgroundColor" :background-color="backgroundColor" :safe-area="safeArea"
|
||||
type="bottom" @change="change" @maskClick="maskClick">
|
||||
<view class="popup-content" :style="{ height: contentHeight }">
|
||||
<view class="title">
|
||||
<view v-if="mutiple && canSelectAll" class="left" @click="handleSelectAll">
|
||||
<text>{{ isSelectedAll ? '取消全选' : '全选' }}</text>
|
||||
</view>
|
||||
<view class="center">
|
||||
<text>{{ placeholder }}</text>
|
||||
</view>
|
||||
<view class="right" :style="{ color: confirmTextColor }" @click="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)">
|
||||
</uni-easyinput>
|
||||
<button type="primary" size="mini" class="search-btn" @click="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"
|
||||
:lazyLoadChildren="lazyLoadChildren"></data-select-item>
|
||||
<view class="sentry" />
|
||||
</scroll-view>
|
||||
</view>
|
||||
<view v-else class="no-data center">
|
||||
<text>暂无数据</text>
|
||||
</view>
|
||||
</view>
|
||||
</uni-popup>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed, watch, onMounted, nextTick, provide } from 'vue'
|
||||
import dataSelectItem from './data-select-item.vue';
|
||||
import { isString, paging } from './utils';
|
||||
const props = defineProps({
|
||||
canSelectAll: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
safeArea: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
search: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
clearResetSearch: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
animation: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
'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: false
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: '请选择'
|
||||
},
|
||||
confirmText: {
|
||||
type: String,
|
||||
default: '确认'
|
||||
},
|
||||
confirmTextColor: {
|
||||
type: String,
|
||||
default: '#007aff'
|
||||
},
|
||||
dataSource: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
dataLabel: {
|
||||
type: String,
|
||||
default: 'name'
|
||||
},
|
||||
dataValue: {
|
||||
type: String,
|
||||
default: 'id'
|
||||
},
|
||||
dataChildren: {
|
||||
type: String,
|
||||
default: 'children'
|
||||
},
|
||||
linkage: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
removeLinkage: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
clearable: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
mutiple: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
deleteSource: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
showChildren: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
border: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
lazyLoadChildren: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
load: {
|
||||
type: Function,
|
||||
default: function () { }
|
||||
},
|
||||
modelValue: {
|
||||
type: [Array, String],
|
||||
default: () => []
|
||||
}
|
||||
})
|
||||
|
||||
const emits = defineEmits(['update:modelValue', 'change', 'maskClick', 'select-change', 'removeSelect'])
|
||||
|
||||
const contentHeight = ref('500px')
|
||||
const treeData = ref([])
|
||||
const filterTreeData = ref([])
|
||||
const clearTimerList = ref([])
|
||||
const selectedListBaseinfo = ref([])
|
||||
const showPopup = ref(false)
|
||||
const isSelectedAll = ref(false)
|
||||
const scrollTop = ref(0)
|
||||
const searchStr = ref('')
|
||||
const popup = ref<any>(null)
|
||||
|
||||
const partCheckedSet = new Set()
|
||||
|
||||
provide('nodeFn', {
|
||||
nodeClick: handleNodeClick,
|
||||
nameClick: handleHideChildren,
|
||||
loadNode: props.load,
|
||||
initData: initData,
|
||||
addNode: addNode
|
||||
})
|
||||
|
||||
const selectList = computed(() => {
|
||||
const newVal = props.modelValue === null ? '' : props.modelValue
|
||||
return isString(newVal) ? (newVal.length ? newVal.split(',') : []) : newVal.map((item : any) => item.toString())
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
getContentHeight(uni.getSystemInfoSync())
|
||||
})
|
||||
|
||||
function getContentHeight({ screenHeight } : { screenHeight : number }) {
|
||||
contentHeight.value = `${Math.floor(screenHeight * 0.7)}px`
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.dataSource,
|
||||
(newVal : any[]) => {
|
||||
if (newVal) {
|
||||
treeData.value = initData(newVal)
|
||||
if (showPopup.value) {
|
||||
resetClearTimerList()
|
||||
renderTree(treeData.value)
|
||||
}
|
||||
}
|
||||
},
|
||||
{ immediate: true, deep: true }
|
||||
)
|
||||
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(newVal : any[] | string) => {
|
||||
const ids = newVal ? (Array.isArray(newVal) ? newVal : newVal.split(',')) : []
|
||||
changeStatus(treeData.value, ids, true)
|
||||
filterTreeData.value.length && changeStatus(filterTreeData.value, ids)
|
||||
},
|
||||
{ immediate: true }
|
||||
)
|
||||
|
||||
// 搜索完成返回顶部
|
||||
function goTop() {
|
||||
scrollTop.val = 10
|
||||
nextTick(() => {
|
||||
scrollTop.value = 0
|
||||
})
|
||||
}
|
||||
|
||||
// 处理搜索
|
||||
function handleSearch(isClear = false) {
|
||||
resetClearTimerList()
|
||||
if (isClear) {
|
||||
// 点击清空按钮并且设置清空按钮会重置搜索
|
||||
if (props.clearResetSearch) {
|
||||
renderTree(treeData.value)
|
||||
}
|
||||
} else {
|
||||
renderTree(searchValue(searchStr.value, treeData.value))
|
||||
}
|
||||
goTop()
|
||||
uni.hideKeyboard()
|
||||
}
|
||||
|
||||
// 具体搜索方法
|
||||
function searchValue(str : any, arr : any[]) {
|
||||
const res : any = []
|
||||
arr.forEach((item) => {
|
||||
if (item.visible) {
|
||||
if (item[props.dataLabel].toString().toLowerCase().indexOf(str.toLowerCase()) > -1) {
|
||||
res.push(item)
|
||||
} else {
|
||||
if (item[props.dataChildren]?.length) {
|
||||
const data = searchValue(str, item[props.dataChildren])
|
||||
if (data?.length) {
|
||||
if (str && !item.showChildren && item[props.dataChildren]?.length) {
|
||||
item.showChildren = true
|
||||
}
|
||||
res.push({
|
||||
...item,
|
||||
[props.dataChildren]: data
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
return res
|
||||
}
|
||||
|
||||
// 打开弹窗
|
||||
async function open() {
|
||||
// disaled模式下禁止打开弹窗
|
||||
if (props.disabled) return
|
||||
showPopup.value = true
|
||||
popup.value.open()
|
||||
renderTree(treeData.value)
|
||||
}
|
||||
|
||||
// 关闭弹窗
|
||||
function close() {
|
||||
popup.value.close()
|
||||
}
|
||||
|
||||
// 弹窗状态变化 包括点击回显框和遮罩
|
||||
function change(data : any) {
|
||||
if (!data.show) {
|
||||
resetClearTimerList()
|
||||
searchStr.value = ''
|
||||
showPopup.value = false
|
||||
}
|
||||
emits('change', data)
|
||||
}
|
||||
|
||||
// 点击遮罩
|
||||
function maskClick() {
|
||||
emits('maskClick')
|
||||
}
|
||||
|
||||
// 初始化数据
|
||||
function initData(arr : any[], parentVisible ?: undefined | boolean) {
|
||||
if (!Array.isArray(arr)) return []
|
||||
const res = []
|
||||
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
const obj : any = {
|
||||
[props.dataLabel]: arr[i][props.dataLabel],
|
||||
[props.dataValue]: arr[i][props.dataValue]
|
||||
}
|
||||
|
||||
obj.checked = selectList.value.includes(arr[i][props.dataValue].toString())
|
||||
|
||||
obj.disabled = Boolean(arr[i].disabled)
|
||||
|
||||
//半选
|
||||
obj.partChecked = Boolean(arr[i].partChecked === undefined ? false : arr[i].partChecked)
|
||||
obj.partChecked && obj.partCheckedSet.add(obj[props.dataValue])
|
||||
!obj.partChecked && (isSelectedAll.value = 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 : props.showChildren
|
||||
|
||||
if (arr[i].visible && !arr[i].disabled && !arr[i].checked) {
|
||||
isSelectedAll.value = false
|
||||
}
|
||||
|
||||
if (arr[i][props.dataChildren]?.length) {
|
||||
obj[props.dataChildren] = initData(arr[i][props.dataChildren], obj.visible)
|
||||
}
|
||||
|
||||
res.push(obj)
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
function addNode(node : any, children : any[]) {
|
||||
getReflectNode(node, treeData.value)[props.dataChildren] = children
|
||||
handleHideChildren(node)
|
||||
}
|
||||
|
||||
// 中断懒加载
|
||||
function resetClearTimerList() {
|
||||
const list = [...clearTimerList.value]
|
||||
clearTimerList.value = []
|
||||
list.forEach((fn) => fn())
|
||||
}
|
||||
|
||||
// 懒加载
|
||||
function renderTree(arr : any[]) {
|
||||
const pagingArr = paging(arr)
|
||||
filterTreeData.value = pagingArr?.[0] || []
|
||||
lazyRenderList(pagingArr, 1)
|
||||
}
|
||||
|
||||
// 懒加载具体逻辑
|
||||
function lazyRenderList(arr : any[], startIndex : number) {
|
||||
for (let i = startIndex; i < arr.length; i++) {
|
||||
let timer : any = null
|
||||
timer = setTimeout(() => {
|
||||
filterTreeData.value.push(...arr[i])
|
||||
}, i * 500)
|
||||
clearTimerList.push(() => clearTimeout(timer))
|
||||
}
|
||||
}
|
||||
|
||||
// 根据 dataValue 找节点
|
||||
function changeStatus(list : any[], ids : any[] | string, needEmit = false) {
|
||||
const arr = [...list]
|
||||
let flag = true
|
||||
needEmit && (selectedListBaseinfo.value = [])
|
||||
while (arr.length) {
|
||||
const item = arr.shift()
|
||||
|
||||
if (ids.includes(item[props.dataValue].toString())) {
|
||||
item.checked = true
|
||||
// 数据被选中清除半选状态
|
||||
item.partChecked = false
|
||||
partCheckedSet.delete(item[props.dataValue])
|
||||
needEmit && selectedListBaseinfo.value.push(item)
|
||||
} else {
|
||||
item.checked = false
|
||||
if (item.visible && !item.disabled) {
|
||||
flag = false
|
||||
}
|
||||
if (partCheckedSet.has(item[props.dataValue])) {
|
||||
// filtertreedata 更新状态
|
||||
item.partChecked = true
|
||||
} else {
|
||||
item.partChecked = false
|
||||
}
|
||||
}
|
||||
|
||||
if (item[props.dataChildren]?.length) {
|
||||
arr.push(...item[props.dataChildren])
|
||||
}
|
||||
}
|
||||
isSelectedAll.value = flag
|
||||
|
||||
needEmit && emits('select-change', [...selectedListBaseinfo.value])
|
||||
}
|
||||
|
||||
// 移除选项
|
||||
function removeSelectedItem(node : any) {
|
||||
isSelectedAll.value = false
|
||||
if (props.linkage) {
|
||||
handleNodeClick(node, false)
|
||||
emits('removeSelect', node)
|
||||
} else {
|
||||
const emitData = selectList.value.filter((item : any) => item !== node[props.dataValue].toString())
|
||||
emits('removeSelect', node)
|
||||
emits('update:modelValue', isString(props.modelValue) ? emitData.join(',') : emitData)
|
||||
}
|
||||
}
|
||||
|
||||
// 获取对应数据
|
||||
function getReflectNode(node : any, arr : any[]) {
|
||||
const array = [...arr]
|
||||
while (array.length) {
|
||||
const item = array.shift()
|
||||
if (item[props.dataValue] === node[props.dataValue]) {
|
||||
return item
|
||||
}
|
||||
if (item[props.dataChildren]?.length) {
|
||||
array.push(...item[props.dataChildren])
|
||||
}
|
||||
}
|
||||
return {}
|
||||
}
|
||||
|
||||
// 获取某个节点孩子节点
|
||||
function getChildren(node : any) {
|
||||
if (!node[props.dataChildren]?.length) return []
|
||||
const res = node[props.dataChildren].reduce((pre : any, val : any) => {
|
||||
if (val.visible) {
|
||||
return [...pre, val]
|
||||
}
|
||||
return pre
|
||||
}, [])
|
||||
for (let i = 0; i < node[props.dataChildren].length; i++) {
|
||||
res.push(...getChildren(node[props.dataChildren][i]))
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// 获取某个节点祖先元素
|
||||
function getParentNode(target : any, arr : any[]) {
|
||||
let res : any[] = []
|
||||
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
if (arr[i][props.dataValue] === target[props.dataValue]) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (arr[i][props.dataChildren]?.length) {
|
||||
const childRes = getParentNode(target, arr[i][props.dataChildren])
|
||||
if (typeof childRes === 'boolean' && childRes) {
|
||||
res = [arr[i]]
|
||||
} else if (Array.isArray(childRes) && childRes.length) {
|
||||
res = [...childRes, arr[i]]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
// 点击checkbox
|
||||
function handleNodeClick(data : any, status : boolean | undefined) {
|
||||
const node = getReflectNode(data, treeData.value)
|
||||
node.checked = typeof status === 'boolean' ? status : !node.checked
|
||||
node.partChecked = false
|
||||
partCheckedSet.delete(node[props.dataValue])
|
||||
// 如果是单选不考虑其他情况
|
||||
if (!props.mutiple) {
|
||||
let emitData : any[] = []
|
||||
if (node.checked) {
|
||||
emitData = [node[props.dataValue].toString()]
|
||||
}
|
||||
emits('update:modelValue', isString(props.modelValue) ? emitData.join(',') : emitData)
|
||||
} else {
|
||||
// 多选情况
|
||||
if (!props.linkage) {
|
||||
// 不需要联动
|
||||
let emitData = null
|
||||
if (node.checked) {
|
||||
emitData = Array.from(new Set([...selectList.value, node[props.dataValue].toString()]))
|
||||
} else {
|
||||
emitData = selectList.value.filter((id : number | string) => id !== node[props.dataValue].toString())
|
||||
}
|
||||
emits('update:modelValue', isString(props.modelValue) ? emitData.join(',') : emitData)
|
||||
} else {
|
||||
// 需要联动
|
||||
let emitData = [...selectList.value]
|
||||
const parentNodes : any = getParentNode(node, treeData.value)
|
||||
const childrenVal = getChildren(node).filter((item : any) => !item.disabled)
|
||||
if (node.checked) {
|
||||
// 选中
|
||||
emitData = Array.from(new Set([...emitData, node[props.dataValue].toString()]))
|
||||
if (childrenVal.length) {
|
||||
emitData = Array.from(
|
||||
new Set([...emitData, ...childrenVal.map((item : any) => item[props.dataValue].toString())])
|
||||
)
|
||||
// 孩子节点全部选中并且清除半选状态
|
||||
childrenVal.forEach((childNode : any) => {
|
||||
childNode.partChecked = false
|
||||
partCheckedSet.delete(childNode[props.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[props.dataValue])
|
||||
} else {
|
||||
const allChecked = item[props.dataChildren]
|
||||
.filter((node : any) => node.visible && !node.disabled)
|
||||
.every((node : any) => node.checked)
|
||||
if (allChecked) {
|
||||
item.checked = true
|
||||
item.partChecked = false
|
||||
partCheckedSet.delete(item[props.dataValue])
|
||||
emitData = Array.from(new Set([...emitData, item[props.dataValue].toString()]))
|
||||
} else {
|
||||
item.partChecked = true
|
||||
partCheckedSet.add(item[props.dataValue])
|
||||
flag = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 取消选中
|
||||
emitData = emitData.filter((id) => id !== node[props.dataValue].toString())
|
||||
if (childrenVal.length) {
|
||||
// 取消选中全部子节点
|
||||
childrenVal.forEach((childNode : any) => {
|
||||
emitData = emitData.filter((id) => id !== childNode[props.dataValue].toString())
|
||||
})
|
||||
}
|
||||
if (parentNodes.length) {
|
||||
parentNodes.forEach((parentNode : any) => {
|
||||
if (emitData.includes(parentNode[props.dataValue].toString())) {
|
||||
parentNode.checked = false
|
||||
}
|
||||
emitData = emitData.filter((id) => id !== parentNode[props.dataValue].toString())
|
||||
const hasChecked = parentNode[props.dataChildren]
|
||||
.filter((node : any) => node.visible && !node.disabled)
|
||||
.some((node : any) => node.checked || node.partChecked)
|
||||
|
||||
parentNode.partChecked = hasChecked
|
||||
if (hasChecked) {
|
||||
partCheckedSet.add(parentNode[props.dataValue])
|
||||
} else {
|
||||
partCheckedSet.delete(parentNode[props.dataValue])
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
emits('update:modelValue', isString(props.modelValue) ? emitData.join(',') : emitData)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 点击名称折叠或展开
|
||||
function handleHideChildren(node : any) {
|
||||
const status = !node.showChildren
|
||||
getReflectNode(node, treeData.value).showChildren = status
|
||||
getReflectNode(node, filterTreeData.value).showChildren = status
|
||||
}
|
||||
|
||||
// 全部选中
|
||||
function handleSelectAll() {
|
||||
isSelectedAll.value = !isSelectedAll.value
|
||||
if (isSelectedAll.value) {
|
||||
if (!props.mutiple) {
|
||||
uni.showToast({
|
||||
title: '单选模式下不能全选',
|
||||
icon: 'none',
|
||||
duration: 1000
|
||||
})
|
||||
return
|
||||
}
|
||||
let emitData : any[] = []
|
||||
treeData.value.forEach((item : any) => {
|
||||
if (item.visible || (item.disabled && item.checked)) {
|
||||
emitData = Array.from(new Set([...emitData, item[props.dataValue].toString()]))
|
||||
if (item[props.dataChildren]?.length) {
|
||||
emitData = Array.from(
|
||||
new Set([
|
||||
...emitData,
|
||||
...getChildren(item)
|
||||
.filter((item : any) => !item.disabled || (item.disabled && item.checked))
|
||||
.map((item : any) => item[props.dataValue].toString())
|
||||
])
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
emits('update:modelValue', isString(props.modelValue) ? emitData.join(',') : emitData)
|
||||
} else {
|
||||
clearSelectList()
|
||||
}
|
||||
}
|
||||
// 清空选项
|
||||
function clearSelectList() {
|
||||
if (props.disabled) return
|
||||
partCheckedSet.clear()
|
||||
const emitData : any[] = []
|
||||
selectedListBaseinfo.value.forEach((node : any) => {
|
||||
if (node.visible && node.checked && node.disabled) {
|
||||
emitData.push(node[props.dataValue])
|
||||
}
|
||||
})
|
||||
emits('update:modelValue', isString(props.modelValue) ? emitData.join(',') : emitData)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
$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;
|
||||
|
||||
.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;
|
||||
|
||||
&.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 {
|
||||
max-width: auto;
|
||||
height: auto;
|
||||
// background-color: #eaeaea;
|
||||
// border-radius: $radius-sm;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.name {
|
||||
flex: 1;
|
||||
// padding-right: $row-base;
|
||||
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 {
|
||||
font-size: 28rpx;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
// .no-data.center {
|
||||
// text-align: center;
|
||||
// }
|
||||
</style>
|
||||
17
components/treeSelect/utils.ts
Normal file
@ -0,0 +1,17 @@
|
||||
export function isString(data: any) {
|
||||
return typeof data === 'string'
|
||||
}
|
||||
|
||||
// 分页
|
||||
export function paging(data: any[], PAGENUM = 50) {
|
||||
if (!Array.isArray(data) || !data.length) return data
|
||||
const pages: any[] = []
|
||||
data.forEach((item, index) => {
|
||||
const i = Math.floor(index / PAGENUM)
|
||||
if (!pages[i]) {
|
||||
pages[i] = []
|
||||
}
|
||||
pages[i].push(item)
|
||||
})
|
||||
return pages
|
||||
}
|
||||
20
index.html
Normal file
@ -0,0 +1,20 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<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>
|
||||
<title></title>
|
||||
<!--preload-links-->
|
||||
<!--app-context-->
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"><!--app-html--></div>
|
||||
<script type="module" src="/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
38
main.js
Normal file
@ -0,0 +1,38 @@
|
||||
import App from './App';
|
||||
import {
|
||||
toast
|
||||
} from './utils/index.js';
|
||||
import {
|
||||
createPinia
|
||||
} from "pinia";
|
||||
import leaveApplication from '@/bpm/leaveApplication/index.vue';
|
||||
import supervise from '@/bpm/supervise.vue'
|
||||
const pinia = createPinia();
|
||||
|
||||
// #ifndef VUE3
|
||||
import Vue from 'vue'
|
||||
import './uni.promisify.adaptor'
|
||||
Vue.config.productionTip = false
|
||||
App.mpType = 'app'
|
||||
const app = new Vue({
|
||||
...App
|
||||
})
|
||||
app.$mount()
|
||||
// #endif
|
||||
|
||||
// #ifdef VUE3
|
||||
import {
|
||||
createSSRApp
|
||||
} from 'vue'
|
||||
|
||||
export function createApp() {
|
||||
const app = createSSRApp(App)
|
||||
app.use(pinia)
|
||||
app.component('leaveApplication', leaveApplication)
|
||||
app.component('supervise', supervise)
|
||||
app.config.globalProperties.$toast = toast
|
||||
return {
|
||||
app
|
||||
}
|
||||
}
|
||||
// #endif
|
||||
123
manifest.json
Normal file
@ -0,0 +1,123 @@
|
||||
{
|
||||
"name" : "数智产销",
|
||||
"appid" : "__UNI__9F097F0",
|
||||
"description" : "",
|
||||
"versionName" : "1.1.1",
|
||||
"versionCode" : 20250106,
|
||||
"transformPx" : false,
|
||||
/* 5+App特有相关 */
|
||||
"app-plus" : {
|
||||
"usingComponents" : true,
|
||||
"nvueStyleCompiler" : "uni-app",
|
||||
"compilerVersion" : 3,
|
||||
"splashscreen" : {
|
||||
"alwaysShowBeforeRender" : true,
|
||||
"waiting" : true,
|
||||
"autoclose" : true,
|
||||
"delay" : 0
|
||||
},
|
||||
"compatible" : {
|
||||
"ignoreVersion" : true
|
||||
},
|
||||
/* 模块配置 */
|
||||
"modules" : {
|
||||
"Geolocation" : {},
|
||||
"Fingerprint" : {},
|
||||
"Camera" : {},
|
||||
"Barcode" : {}
|
||||
},
|
||||
/* 应用发布信息 */
|
||||
"distribute" : {
|
||||
/* android打包配置 */
|
||||
"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打包配置 */
|
||||
"ios" : {
|
||||
"dSYMs" : false
|
||||
},
|
||||
/* SDK配置 */
|
||||
"sdkConfigs" : {
|
||||
"ad" : {},
|
||||
"geolocation" : {
|
||||
"system" : {
|
||||
"__platform__" : [ "android" ]
|
||||
}
|
||||
}
|
||||
},
|
||||
"icons" : {
|
||||
"android" : {
|
||||
"hdpi" : "unpackage/res/icons/72x72.png",
|
||||
"xhdpi" : "unpackage/res/icons/96x96.png",
|
||||
"xxhdpi" : "unpackage/res/icons/144x144.png",
|
||||
"xxxhdpi" : "unpackage/res/icons/192x192.png"
|
||||
},
|
||||
"ios" : {
|
||||
"appstore" : "unpackage/res/icons/1024x1024.png",
|
||||
"ipad" : {
|
||||
"app" : "unpackage/res/icons/76x76.png",
|
||||
"app@2x" : "unpackage/res/icons/152x152.png",
|
||||
"notification" : "unpackage/res/icons/20x20.png",
|
||||
"notification@2x" : "unpackage/res/icons/40x40.png",
|
||||
"proapp@2x" : "unpackage/res/icons/167x167.png",
|
||||
"settings" : "unpackage/res/icons/29x29.png",
|
||||
"settings@2x" : "unpackage/res/icons/58x58.png",
|
||||
"spotlight" : "unpackage/res/icons/40x40.png",
|
||||
"spotlight@2x" : "unpackage/res/icons/80x80.png"
|
||||
},
|
||||
"iphone" : {
|
||||
"app@2x" : "unpackage/res/icons/120x120.png",
|
||||
"app@3x" : "unpackage/res/icons/180x180.png",
|
||||
"notification@2x" : "unpackage/res/icons/40x40.png",
|
||||
"notification@3x" : "unpackage/res/icons/60x60.png",
|
||||
"settings@2x" : "unpackage/res/icons/58x58.png",
|
||||
"settings@3x" : "unpackage/res/icons/87x87.png",
|
||||
"spotlight@2x" : "unpackage/res/icons/80x80.png",
|
||||
"spotlight@3x" : "unpackage/res/icons/120x120.png"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
/* 快应用特有相关 */
|
||||
"quickapp" : {},
|
||||
/* 小程序特有相关 */
|
||||
"mp-weixin" : {
|
||||
"appid" : "",
|
||||
"setting" : {
|
||||
"urlCheck" : false
|
||||
},
|
||||
"usingComponents" : true
|
||||
},
|
||||
"mp-alipay" : {
|
||||
"usingComponents" : true
|
||||
},
|
||||
"mp-baidu" : {
|
||||
"usingComponents" : true
|
||||
},
|
||||
"mp-toutiao" : {
|
||||
"usingComponents" : true
|
||||
},
|
||||
"uniStatistics" : {
|
||||
"enable" : false
|
||||
},
|
||||
"vueVersion" : "3"
|
||||
}
|
||||
/* 模块配置 */
|
||||
|
||||
47
package-lock.json
generated
Normal file
@ -0,0 +1,47 @@
|
||||
{
|
||||
"name": "cxc-szcx-uniapp",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"dependencies": {
|
||||
"@dcloudio/uni-ui": "^1.5.6",
|
||||
"base-64": "^1.0.0",
|
||||
"dayjs": "^1.11.13"
|
||||
}
|
||||
},
|
||||
"node_modules/@dcloudio/uni-ui": {
|
||||
"version": "1.5.6",
|
||||
"resolved": "https://registry.npmjs.org/@dcloudio/uni-ui/-/uni-ui-1.5.6.tgz",
|
||||
"integrity": "sha512-jmb98PasFvZkrIDXGh94GbdWg2/jyhgs1HUG+bU8eyL7Ltias/5XBz4q8w9RXyWUfqepJRqapPA2IIQpLCuTIg==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/base-64": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/base-64/-/base-64-1.0.0.tgz",
|
||||
"integrity": "sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg=="
|
||||
},
|
||||
"node_modules/dayjs": {
|
||||
"version": "1.11.13",
|
||||
"resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.13.tgz",
|
||||
"integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg=="
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@dcloudio/uni-ui": {
|
||||
"version": "1.5.6",
|
||||
"resolved": "https://registry.npmjs.org/@dcloudio/uni-ui/-/uni-ui-1.5.6.tgz",
|
||||
"integrity": "sha512-jmb98PasFvZkrIDXGh94GbdWg2/jyhgs1HUG+bU8eyL7Ltias/5XBz4q8w9RXyWUfqepJRqapPA2IIQpLCuTIg=="
|
||||
},
|
||||
"base-64": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/base-64/-/base-64-1.0.0.tgz",
|
||||
"integrity": "sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg=="
|
||||
},
|
||||
"dayjs": {
|
||||
"version": "1.11.13",
|
||||
"resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.13.tgz",
|
||||
"integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg=="
|
||||
}
|
||||
}
|
||||
}
|
||||
7
package.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"@dcloudio/uni-ui": "^1.5.6",
|
||||
"base-64": "^1.0.0",
|
||||
"dayjs": "^1.11.13"
|
||||
}
|
||||
}
|
||||
271
pages.json
Normal file
@ -0,0 +1,271 @@
|
||||
{
|
||||
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
|
||||
{
|
||||
"path": "pages/login/login",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/tab/index",
|
||||
"style": {
|
||||
"navigationStyle": "custom",
|
||||
"enablePullDownRefresh": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/task/todotask",
|
||||
"style": {
|
||||
"navigationStyle": "custom",
|
||||
"enablePullDownRefresh": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/tab/office",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/tab/my",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "pages/task/index",
|
||||
"style": {
|
||||
"enablePullDownRefresh": true,
|
||||
"app-plus": {
|
||||
"titleNView": {
|
||||
"titleText": "我的任务",
|
||||
"titleColor": "#fff"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/task/handle",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/talk/message_list",
|
||||
"style": {
|
||||
"navigationBarTitleText": "消息",
|
||||
"enablePullDownRefresh": true,
|
||||
"navigationBarTextStyle": "white"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/talk/conversation",
|
||||
"style": {
|
||||
"navigationBarTitleText": "昵称",
|
||||
"enablePullDownRefresh": true,
|
||||
"navigationBarTextStyle": "white"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/talk/system",
|
||||
"style": {
|
||||
"navigationBarTitleText": "系统通知",
|
||||
"enablePullDownRefresh": true,
|
||||
"navigationBarTextStyle": "white"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/document/index",
|
||||
"style": {
|
||||
"navigationStyle": "custom",
|
||||
"enablePullDownRefresh": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/document/detail",
|
||||
"style": {
|
||||
"navigationBarTitleText": "详情",
|
||||
"navigationBarTextStyle": "white"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/document/onlinePreview",
|
||||
"style": {
|
||||
"navigationBarTitleText": "在线预览",
|
||||
"navigationBarTextStyle": "white"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/views/zhongheguanli/meeting/index",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/views/zhongheguanli/meeting/detail",
|
||||
"style": {
|
||||
"navigationBarTitleText": "详情",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationBarTextStyle": "white"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/leave/application",
|
||||
"style": {
|
||||
"navigationBarTitleText": "请假申请",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationBarTextStyle": "white"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/checkin/index",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/useredit/useredit",
|
||||
"style": {
|
||||
"navigationBarTitleText": "资料编辑",
|
||||
"navigationBarTextStyle": "white"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/useredit/address",
|
||||
"style": {
|
||||
"navigationBarTitleText": "地址",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationBarTextStyle": "white"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/useredit/add_address",
|
||||
"style": {
|
||||
"navigationBarTitleText": "添加地址",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationBarTextStyle": "white"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/useredit/addressbook",
|
||||
"style": {
|
||||
"navigationBarTitleText": "通讯录",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationBarTextStyle": "white"
|
||||
}
|
||||
},
|
||||
// {
|
||||
// "path": "pages/task/todotask",
|
||||
// "style": {
|
||||
// "navigationBarTitleText": "个人办公",
|
||||
// "enablePullDownRefresh": false,
|
||||
// "navigationBarTextStyle": "white"
|
||||
// }
|
||||
// },
|
||||
{
|
||||
"path": "pages/safe/manage",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/product/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "生产数据",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationBarTextStyle": "white"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/userlist/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"navigationBarTextStyle": "white"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/safe/detail",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/views/zhongheguanli/zhiban/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "值班信息",
|
||||
"navigationBarTextStyle": "white"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/task/self",
|
||||
"style": {
|
||||
"navigationBarTitleText": "本人发起",
|
||||
"navigationBarTextStyle": "white"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/views/renliziyuan/renyuanxinxi/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "人员信息",
|
||||
"navigationBarTextStyle": "white"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/views/renliziyuan/renyuanxinxi/taizhang",
|
||||
"style": {
|
||||
"navigationBarTitleText": "台账信息",
|
||||
"navigationBarTextStyle": "white"
|
||||
|
||||
}
|
||||
}
|
||||
],
|
||||
"tabBar": {
|
||||
"color": "#333333",
|
||||
"selectedColor": "#01508B",
|
||||
"borderStyle": "black",
|
||||
"backgroundColor": "#FFFFFF",
|
||||
|
||||
"list": [{
|
||||
"text": "首页",
|
||||
"pagePath": "pages/tab/index",
|
||||
"iconPath": "static/tab/index1.png",
|
||||
"selectedIconPath": "static/tab/index2.png"
|
||||
},
|
||||
{
|
||||
"text": "任务",
|
||||
"pagePath": "pages/task/todotask",
|
||||
"iconPath": "static/tab/office1.png",
|
||||
"selectedIconPath": "static/tab/office2.png"
|
||||
},
|
||||
{
|
||||
"text": "办公",
|
||||
"pagePath": "pages/tab/office",
|
||||
"iconPath": "static/tab/product1.png",
|
||||
"selectedIconPath": "static/tab/product2.png"
|
||||
},
|
||||
{
|
||||
"text": "我的",
|
||||
"pagePath": "pages/tab/my",
|
||||
"iconPath": "static/tab/user1.png",
|
||||
"selectedIconPath": "static/tab/user2.png"
|
||||
}
|
||||
]
|
||||
|
||||
// "midButton": {
|
||||
// "width": "65px",
|
||||
// "height": "75px",
|
||||
// "text": "",
|
||||
// "iconPath": "static/tab/todo.png",
|
||||
// "iconWidth": "50px",
|
||||
// }
|
||||
},
|
||||
"globalStyle": {
|
||||
"app-plus": {
|
||||
"titleNView": {
|
||||
"backgroundImage": "linear-gradient(to left , #256FBC, #044D87)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"uniIdRouter": {}
|
||||
}
|
||||
232
pages/checkin/index.vue
Normal file
@ -0,0 +1,232 @@
|
||||
<template>
|
||||
<view :class="['content',{'gray':store.isgray==1}]">
|
||||
<customNav>
|
||||
<view class="nav_box f-row aic">
|
||||
<view class="back" @click="back">
|
||||
<uni-icons type="left" size="20" color="#fff"></uni-icons>
|
||||
</view>
|
||||
<view class="avatar">
|
||||
<image :src="store.userinfo.avatar" mode=""></image>
|
||||
</view>
|
||||
<view class="f-col">
|
||||
<view class="name">
|
||||
{{store.userinfo.realname}}
|
||||
</view>
|
||||
<view class="position">
|
||||
{{store.role}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</customNav>
|
||||
<view class="time_box f-row aic jcb">
|
||||
<view class="box">
|
||||
<view class="time f-row aic">
|
||||
<view class="">
|
||||
上班 9:30
|
||||
</view>
|
||||
<image src="../../static/checkin/chenggong.png" mode=""></image>
|
||||
</view>
|
||||
<view class="text">
|
||||
重庆市渝北区上弯路
|
||||
</view>
|
||||
</view>
|
||||
<view class="box">
|
||||
<view class="time f-row aic">
|
||||
<view class="">
|
||||
下班 16:30
|
||||
</view>
|
||||
<image src="../../static/checkin/shibai.png" mode=""></image>
|
||||
</view>
|
||||
<view class="text">
|
||||
打卡已超时
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="checkin">
|
||||
<view class=" f-col aic">
|
||||
<view class="status f-col aic">
|
||||
<!-- <image src="../../static/checkin/position1.png" mode=""></image>
|
||||
<image src="../../static/checkin/position2.png" mode=""></image>
|
||||
<image src="../../static/checkin/position3.png" mode=""></image> -->
|
||||
<image src="../../static/checkin/position4.png" mode=""></image>
|
||||
<text>打卡失败</text>
|
||||
</view>
|
||||
<view :class="['circle', 'f-col', 'aic','out','check','success','fail']">
|
||||
<view class="title">
|
||||
上班打卡
|
||||
</view>
|
||||
<view class="time">
|
||||
9:00
|
||||
</view>
|
||||
<view class="ontime">
|
||||
已超时
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
useStore
|
||||
} from '@/store';
|
||||
const store = useStore();
|
||||
import customNav from '../../bpm/customNav.vue';
|
||||
const back = () => {
|
||||
uni.navigateBack()
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page {
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
.content {
|
||||
padding-bottom: 120rpx;
|
||||
}
|
||||
|
||||
.nav_box {
|
||||
position: absolute;
|
||||
bottom: 16rpx;
|
||||
left: 0;
|
||||
width: calc(100% - 60rpx);
|
||||
}
|
||||
|
||||
.back {
|
||||
padding-left: 30rpx;
|
||||
}
|
||||
|
||||
image {
|
||||
width: 64rpx;
|
||||
height: 64rpx;
|
||||
border-radius: 32rpx;
|
||||
background-color: #fff;
|
||||
margin-right: 20rpx;
|
||||
margin-left: 50rpx;
|
||||
}
|
||||
|
||||
.name {
|
||||
font-size: 28rpx;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
.position {
|
||||
font-size: 24rpx;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
|
||||
.time_box {
|
||||
padding: 30rpx;
|
||||
|
||||
.box {
|
||||
padding: 40rpx 30rpx;
|
||||
flex: 1;
|
||||
|
||||
box-shadow: 0rpx 2rpx 4rpx 0rpx rgba(0, 0, 0, 0.5);
|
||||
border-radius: 16rpx;
|
||||
|
||||
|
||||
}
|
||||
|
||||
.box:nth-child(1) {
|
||||
border: 1rpx solid #3AC050;
|
||||
background: #F5FFF7;
|
||||
margin-right: 30rpx;
|
||||
}
|
||||
|
||||
.box:nth-child(2) {
|
||||
background: #FFF7F5;
|
||||
border: 1rpx solid #F05C43;
|
||||
}
|
||||
|
||||
.time {
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
|
||||
image {
|
||||
width: 28rpx;
|
||||
height: 28rpx;
|
||||
margin-left: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.text {
|
||||
font-size: 24rpx;
|
||||
color: #888888;
|
||||
margin-top: 18rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.checkin {
|
||||
margin: 0 30rpx;
|
||||
background: #FFFFFF;
|
||||
box-shadow: 0rpx 2rpx 4rpx 0rpx rgba(0, 0, 0, 0.5);
|
||||
border-radius: 16rpx;
|
||||
height: 818rpx;
|
||||
|
||||
.status {
|
||||
image {
|
||||
width: 58rpx;
|
||||
height: 69rpx;
|
||||
margin-top: 71rpx;
|
||||
}
|
||||
|
||||
font-weight: 600;
|
||||
font-size: 46rpx;
|
||||
color: #F05C43;
|
||||
|
||||
text {
|
||||
margin-top: 23rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.out {
|
||||
background-image: url('../../static/checkin/circle1.png');
|
||||
}
|
||||
|
||||
.check {
|
||||
background-image: url('../../static/checkin/circle2.png');
|
||||
}
|
||||
|
||||
.success {
|
||||
background-image: url('../../static/checkin/circle3.png');
|
||||
}
|
||||
|
||||
.fail {
|
||||
background-image: url('../../static/checkin/circle4.png');
|
||||
}
|
||||
|
||||
.circle {
|
||||
width: 350rpx;
|
||||
height: 350rpx;
|
||||
|
||||
background-size: 350rpx 350rpx;
|
||||
margin-top: 150rpx;
|
||||
|
||||
.title,
|
||||
.time {
|
||||
font-weight: 600;
|
||||
font-size: 46rpx;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-top: 80rpx;
|
||||
}
|
||||
|
||||
.time {
|
||||
margin-top: 8rpx;
|
||||
}
|
||||
|
||||
.ontime {
|
||||
font-size: 28rpx;
|
||||
color: #888888;
|
||||
margin-top: 12rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
120
pages/document/detail.vue
Normal file
@ -0,0 +1,120 @@
|
||||
<template>
|
||||
<view :class="['content',{'gray':store.isgray==1}]">
|
||||
<view class="title_box">
|
||||
<view class="title">
|
||||
{{detail._title}}
|
||||
</view>
|
||||
<view class="time">
|
||||
{{detail._time}}
|
||||
</view>
|
||||
</view>
|
||||
<view class="document f-row">
|
||||
<text class="">
|
||||
附件:
|
||||
</text>
|
||||
<view class="f-col">
|
||||
<view v-if="ifH5">
|
||||
<!-- 在线预览 by 闵 -->
|
||||
<view class="" style="padding: 5rpx 0;" @click="onlinePreview(`/pages/document/onlinePreview?data=${JSON.stringify(item)}`)"
|
||||
v-for="item,i in detail?.pdf?.split(',')">
|
||||
{{item}}
|
||||
|
||||
</view>
|
||||
</view>
|
||||
<view v-else>
|
||||
<view class="" style="padding: 5rpx 0;" @click="opendocument(item)"
|
||||
v-for="item,i in detail?.pdf?.split(',')">
|
||||
{{item}}
|
||||
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref
|
||||
} from 'vue'
|
||||
import {
|
||||
onLoad
|
||||
} from '@dcloudio/uni-app';
|
||||
import {
|
||||
opendocument
|
||||
} from '@/utils/index.js';
|
||||
import {
|
||||
useStore
|
||||
} from '@/store';
|
||||
const store = useStore();
|
||||
|
||||
const detail = ref({})
|
||||
//判断是否h5 by 闵
|
||||
var ifH5 = false;
|
||||
|
||||
const onlinePreview = (url)=>{ //在线预览文件 by 闵
|
||||
uni.navigateTo({
|
||||
url
|
||||
})
|
||||
}
|
||||
|
||||
onLoad((options) => {
|
||||
detail.value = JSON.parse(options.data)
|
||||
if (options.id == 0) {
|
||||
detail.value.pdf = detail.value.wjbt
|
||||
} else if (options.id == 2) {
|
||||
if (detail.value.jdwj) {
|
||||
detail.value.pdf = detail.value.jdwj + ',' + detail.value.sszd
|
||||
} else {
|
||||
detail.value.pdf = detail.value.sszd
|
||||
}
|
||||
|
||||
} else if (options.id == 3) {
|
||||
detail.value.pdf = detail.value.mingcheng
|
||||
}
|
||||
//#ifdef H5 || MP-WEIXIN
|
||||
ifH5 = true;
|
||||
//#endif
|
||||
})
|
||||
</script>
|
||||
|
||||
<style>
|
||||
/* page{
|
||||
background-color: #f8f8f8;
|
||||
} */
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
.content {
|
||||
padding: 0 30rpx;
|
||||
}
|
||||
|
||||
.title_box {
|
||||
|
||||
.title {
|
||||
font-size: 32rpx;
|
||||
color: #333333;
|
||||
padding: 30rpx 0 20rpx 0;
|
||||
}
|
||||
|
||||
.time {
|
||||
font-size: 24rpx;
|
||||
color: #888888;
|
||||
padding-bottom: 30rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.document {
|
||||
text {
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
view {
|
||||
font-size: 28rpx;
|
||||
color: #5A79F8;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
329
pages/document/index.vue
Normal file
@ -0,0 +1,329 @@
|
||||
<template>
|
||||
<view :class="['content',{'gray':store.isgray==1}]">
|
||||
<customNav>
|
||||
<view class="nav_box f-row aic jcb">
|
||||
<view class="back f-row aic" @click="back">
|
||||
<uni-icons type="left" size="20" color="#fff"></uni-icons>
|
||||
</view>
|
||||
<view class="search f-row aic">
|
||||
<input type="text" v-model="searchKey" @confirm="search" @blur="showicon=true&&!searchKey"
|
||||
@focus="showicon=false" />
|
||||
<view class="f-row aic" v-if="showicon">
|
||||
<image src="../../static/search.png" mode=""></image>
|
||||
<text>搜索</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</customNav>
|
||||
<view class="list">
|
||||
<view class="item" v-for="item,i in list" :key="i"
|
||||
@click="jump(`/pages/document/detail?data=${JSON.stringify(item)}&id=${id}`,item)">
|
||||
<!-- <view class="dot">
|
||||
|
||||
</view> -->
|
||||
<view class="title">
|
||||
{{item._title}}
|
||||
</view>
|
||||
<view class="time_box f-row aic">
|
||||
<view class="time">
|
||||
{{item._time}}
|
||||
</view>
|
||||
<view class="look f-row aic" v-if="item._depart">
|
||||
{{item._depart}}
|
||||
</view>
|
||||
<!-- <view class="look f-row aic">
|
||||
<image src="../../static/index/eye.png" mode=""></image>
|
||||
999+
|
||||
</view> -->
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref,
|
||||
watch
|
||||
} from 'vue';
|
||||
import {
|
||||
onReachBottom,
|
||||
onPullDownRefresh,
|
||||
onLoad
|
||||
} from '@dcloudio/uni-app';
|
||||
import {
|
||||
bpmlistApi,
|
||||
faguiApi,
|
||||
zhiduApi,
|
||||
gonggaolistApi,
|
||||
cjzhiduApi
|
||||
} from '@/api/api.js';
|
||||
import {
|
||||
useStore
|
||||
} from '@/store';
|
||||
const store = useStore();
|
||||
import customNav from '../../bpm/customNav.vue';
|
||||
import {
|
||||
beforeJump,
|
||||
opendocument
|
||||
} from '@/utils/index.js';
|
||||
const showicon = ref(true)
|
||||
const searchKey = ref('')
|
||||
const list = ref([])
|
||||
let pageNo = 1
|
||||
let pageSize = 15
|
||||
let loading = false
|
||||
/**公文接口*/
|
||||
const bpmlist = () => {
|
||||
loading = true
|
||||
bpmlistApi({
|
||||
pageNo,
|
||||
pageSize,
|
||||
fwbt: formatSearchkey()
|
||||
}).then((res) => {
|
||||
if (res.success) {
|
||||
list.value = [...list.value, ...formatObj(res.result.records, 'fwbt', 'fwtime', null)]
|
||||
}
|
||||
loading = false
|
||||
}).catch((err) => {
|
||||
console.log('err', err);
|
||||
})
|
||||
}
|
||||
|
||||
/**制度接口*/
|
||||
const zhidu = () => {
|
||||
loading = true
|
||||
let getzhidu = zhiduid == 0 ? zhiduApi : cjzhiduApi
|
||||
getzhidu({
|
||||
pageNo,
|
||||
pageSize,
|
||||
zdmc: formatSearchkey()
|
||||
}).then((res) => {
|
||||
if (res.success) {
|
||||
let str = zhiduid == 0 ? 'zbbm_dictText' : 'sbbm'
|
||||
list.value = [...list.value, ...formatObj(res.result.records, 'zdmc', str, null)]
|
||||
}
|
||||
loading = false
|
||||
}).catch((err) => {
|
||||
console.log('err', err);
|
||||
})
|
||||
}
|
||||
/**法规接口*/
|
||||
const fagui = () => {
|
||||
loading = true
|
||||
faguiApi({
|
||||
pageNo,
|
||||
pageSize,
|
||||
flfgmc: formatSearchkey()
|
||||
}).then((res) => {
|
||||
if (res.success) {
|
||||
list.value = [...list.value, ...formatObj(res.result.records, 'flfgmc', 'ssbm', null)]
|
||||
|
||||
}
|
||||
loading = false
|
||||
}).catch((err) => {
|
||||
console.log('err', err);
|
||||
})
|
||||
}
|
||||
|
||||
/**公告接口*/
|
||||
const gonggaolist = () => {
|
||||
loading = true
|
||||
gonggaolistApi({
|
||||
pageNo,
|
||||
pageSize,
|
||||
neirong:formatSearchkey()
|
||||
}).then((res) => {
|
||||
if (res.success) {
|
||||
list.value = [...list.value, ...formatObj(res.result.records, 'neirong', 'fbdw', 'createTime')]
|
||||
}
|
||||
loading = false
|
||||
}).catch((err) => {
|
||||
console.log('err', err);
|
||||
})
|
||||
}
|
||||
const formatObj = (arr, title, time, depart) => {
|
||||
arr.map((item) => {
|
||||
item['_title'] = item[title]
|
||||
item['_time'] = item[time]
|
||||
item['_depart'] = item[depart]
|
||||
})
|
||||
return arr
|
||||
}
|
||||
const formatSearchkey = () => {
|
||||
if (searchKey.value.trim()) {
|
||||
return '*' + searchKey.value + '*'
|
||||
}
|
||||
}
|
||||
const search = () => {
|
||||
pageNo = 1
|
||||
loading = false
|
||||
list.value = []
|
||||
getlist()
|
||||
}
|
||||
watch(searchKey, (nval, oval) => {
|
||||
if (!nval.trim()) {
|
||||
getlist()
|
||||
}
|
||||
})
|
||||
const back = () => {
|
||||
uni.navigateBack()
|
||||
}
|
||||
const jump = (url, item) => {
|
||||
if (id.value == 3) {
|
||||
return opendocument(item.mingcheng)
|
||||
}
|
||||
beforeJump(url, () => {
|
||||
uni.navigateTo({
|
||||
url
|
||||
})
|
||||
})
|
||||
}
|
||||
const id = ref(null)
|
||||
let zhiduid = null
|
||||
onLoad((options) => {
|
||||
id.value = options.id
|
||||
zhiduid = options.zhiduid
|
||||
getlist()
|
||||
})
|
||||
const getlist = () => {
|
||||
if (id.value == 0) {
|
||||
bpmlist()
|
||||
} else if (id.value == 1) {
|
||||
gonggaolist()
|
||||
} else if (id.value == 2) {
|
||||
zhidu()
|
||||
} else if (id.value == 3) {
|
||||
fagui()
|
||||
}
|
||||
}
|
||||
onPullDownRefresh(() => {
|
||||
pageNo = 1
|
||||
loading = false
|
||||
list.value = []
|
||||
getlist()
|
||||
uni.stopPullDownRefresh()
|
||||
})
|
||||
onReachBottom(() => {
|
||||
if (loading) return
|
||||
pageNo++
|
||||
getlist()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page {
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
.content {
|
||||
padding-top: v-bind(cusnavbarheight);
|
||||
padding-bottom: 24rpx;
|
||||
|
||||
}
|
||||
|
||||
.list {
|
||||
padding: 0 30rpx;
|
||||
|
||||
.item {
|
||||
background: #FFFFFF;
|
||||
box-shadow: 0rpx 2rpx 4rpx 0rpx rgba(0, 0, 0, 0.5);
|
||||
border-radius: 16rpx;
|
||||
padding: 30rpx;
|
||||
margin-top: 24rpx;
|
||||
position: relative;
|
||||
|
||||
.dot {
|
||||
width: 12rpx;
|
||||
height: 12rpx;
|
||||
background: #ED361D;
|
||||
position: absolute;
|
||||
border-radius: 50%;
|
||||
left: 9rpx;
|
||||
top: 44rpx;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-bottom: 20rpx;
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.time_box {
|
||||
font-size: 24rpx;
|
||||
color: #888888;
|
||||
|
||||
|
||||
|
||||
.look {
|
||||
position: relative;
|
||||
margin-left: 60rpx;
|
||||
|
||||
&::after {
|
||||
position: absolute;
|
||||
content: ' ';
|
||||
width: 2rpx;
|
||||
height: 20rpx;
|
||||
background: #999999;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
left: -30rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
image {
|
||||
width: 28rpx;
|
||||
height: 22rpx;
|
||||
margin-left: 62rpx;
|
||||
margin-right: 8rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
.nav_box {
|
||||
position: absolute;
|
||||
bottom: 14rpx;
|
||||
width: 100%;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.back {
|
||||
padding: 0 30rpx;
|
||||
}
|
||||
|
||||
.search {
|
||||
position: relative;
|
||||
padding-right: 30rpx;
|
||||
flex: 1;
|
||||
|
||||
view {
|
||||
position: absolute;
|
||||
left: 28rpx;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
|
||||
font-size: 28rpx;
|
||||
color: #999999;
|
||||
|
||||
}
|
||||
|
||||
input {
|
||||
flex: 1;
|
||||
height: 72rpx;
|
||||
background: #F8F8F8;
|
||||
border-radius: 44rpx;
|
||||
padding: 0 28rpx;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
image {
|
||||
width: 34rpx;
|
||||
height: 34rpx;
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
44
pages/document/onlinePreview.vue
Normal file
@ -0,0 +1,44 @@
|
||||
<template>
|
||||
<view :class="['content',{'gray':store.isgray==1}]">
|
||||
<iframe id="bdIframe" :src="fileUrl" ref="bdIframe" style="border: none;" class="iframe" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
useStore
|
||||
} from '@/store';
|
||||
import {
|
||||
onLoad
|
||||
} from '@dcloudio/uni-app';
|
||||
import Base64 from '@/utils/code.js';
|
||||
const baseUrl = import.meta.env.VITE_REQUEST_BASE_URL + '/jeecg-boot/sys/common/static/'
|
||||
const store = useStore();
|
||||
|
||||
var fileUrl = "";
|
||||
|
||||
onLoad((options) => {
|
||||
let base64 = new Base64();
|
||||
var url= JSON.parse(options.data)
|
||||
url = baseUrl + url;
|
||||
fileUrl = 'https://10.75.166.6/preview/onlinePreview' + '?url=' + encodeURIComponent(base64.encode(url))
|
||||
})
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
|
||||
}
|
||||
#bdIframe {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
|
||||
}
|
||||
</style>
|
||||
366
pages/leave/application.vue
Normal file
@ -0,0 +1,366 @@
|
||||
<template>
|
||||
<view :class="{'gray':store.isgray==1}">
|
||||
<view class="form">
|
||||
<view class="f-row aic jcb input_box">
|
||||
<view class="title">
|
||||
职工姓名:
|
||||
</view>
|
||||
<input v-model="realname" disabled />
|
||||
</view>
|
||||
<view class="f-row aic jcb input_box">
|
||||
<view class="title">
|
||||
工作单位:
|
||||
</view>
|
||||
<input v-model="depart" disabled />
|
||||
</view>
|
||||
<view class="f-row aic jcb input_box">
|
||||
<view class="title">
|
||||
联系方式:
|
||||
</view>
|
||||
<input v-model="phone" />
|
||||
</view>
|
||||
<view class="f-row aic jcb input_box">
|
||||
<view class="title">
|
||||
请假类型:
|
||||
</view>
|
||||
<tree-select :dataSource="dataSource" v-model="type" dataValue="name" />
|
||||
</view>
|
||||
<picker mode="date" fields="day" @change="chooseStart" :value="beginTime" :end="endTime">
|
||||
<view class="f-row aic jcb box">
|
||||
<view class="title">
|
||||
开始时间:
|
||||
</view>
|
||||
<view class="f-row aic">
|
||||
<view :class="[{'choose':!beginTime},{'choosed':beginTime}]">
|
||||
{{beginTime?beginTime:'请选择'}}
|
||||
</view>
|
||||
<uni-icons type="bottom" color="#333333"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
</picker>
|
||||
<picker mode="date" fields="day" @change="chooseEnd" :value="endTime" :start="beginTime">
|
||||
<view class="f-row aic jcb box">
|
||||
<view class="title">
|
||||
截止时间:
|
||||
</view>
|
||||
<view class="f-row aic">
|
||||
<view :class="[{'choose':!endTime},{'choosed':endTime}]">
|
||||
{{endTime?endTime:'请选择'}}
|
||||
</view>
|
||||
<uni-icons type="bottom" color="#333333"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
</picker>
|
||||
<picker @change="bindType" :value="typeIndex" :range="typeArr" range-key="realname" v-if="ifShow">
|
||||
<view class="f-row aic jcb box">
|
||||
<view class="title">
|
||||
审批领导:
|
||||
</view>
|
||||
<view class="f-row aic">
|
||||
<view :class="[{'choose':typeIndex==null},{'choosed':typeIndex!=null}]">
|
||||
{{typeIndex!=null?typeArr[typeIndex].realname:'请选择'}}
|
||||
</view>
|
||||
<uni-icons type="bottom" color="#333333"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
</picker>
|
||||
<view class="f-row aic jcb input_box">
|
||||
<view class="title">
|
||||
出发地:
|
||||
</view>
|
||||
<input v-model="departure" placeholder="请输入" nplaceholder-style="font-size: 28rpx;color: #999999;" />
|
||||
</view>
|
||||
<view class="f-row aic jcb input_box">
|
||||
<view class="title">
|
||||
目的地:
|
||||
</view>
|
||||
<input v-model="destination" placeholder="请输入" nplaceholder-style="font-size: 28rpx;color: #999999;" />
|
||||
</view>
|
||||
<view class="f-row aic jcb input_box">
|
||||
<view class="title">
|
||||
请假事由:
|
||||
</view>
|
||||
<input v-model="reason" placeholder="请输入" placeholder-style="font-size: 28rpx;color: #999999;" />
|
||||
</view>
|
||||
<view class="f-row aic jcb input_box">
|
||||
<view class="title">
|
||||
上传附件:
|
||||
</view>
|
||||
<uni-file-picker @select="select" :image-styles="imageStyles" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="btn f-col aic">
|
||||
<view @click="qjAdd">
|
||||
提交
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref,
|
||||
getCurrentInstance
|
||||
} from 'vue';
|
||||
import {
|
||||
startMutilProcessApi,
|
||||
getCategoryItemsApi,
|
||||
} from '@/api/api.js';
|
||||
import {
|
||||
qjAddApi,
|
||||
queryZwmcAndExaApi
|
||||
} from '@/api/pages.js';
|
||||
import {
|
||||
queryDepByCode,
|
||||
queryZbDepByLdhth
|
||||
} from '@/api/depart.js'
|
||||
import {
|
||||
onLoad
|
||||
} from '@dcloudio/uni-app'
|
||||
import {
|
||||
useStore
|
||||
} from '@/store';
|
||||
import treeSelect from "@/components/treeSelect/treeSelect.vue"
|
||||
|
||||
const store = useStore()
|
||||
const {
|
||||
proxy
|
||||
} = getCurrentInstance()
|
||||
|
||||
/**职工姓名*/
|
||||
const realname = ref(store.userinfo.realname)
|
||||
/**工作单位*/
|
||||
const depart = ref('')
|
||||
/**工作单位*/
|
||||
const orgCode = ref('')
|
||||
/**联系方式*/
|
||||
const phone = ref(store.userinfo.phone)
|
||||
/**请假类型*/
|
||||
const type = ref('')
|
||||
const dataSource = ref([])
|
||||
/**开始时间*/
|
||||
const beginTime = ref('')
|
||||
const chooseStart = (e) => {
|
||||
beginTime.value = e.detail.value
|
||||
}
|
||||
/**结束时间*/
|
||||
const endTime = ref('')
|
||||
const chooseEnd = (e) => {
|
||||
endTime.value = e.detail.value
|
||||
}
|
||||
/**审批领导*/
|
||||
const typeArr = ref([])
|
||||
const typeIndex = ref(null)
|
||||
/**判断是否显示审批领导字段*/
|
||||
const ifShow = ref(true)
|
||||
/**职位层级*/
|
||||
const zwcj = ref('')
|
||||
/**出发地*/
|
||||
const departure = ref('')
|
||||
/**目的地*/
|
||||
const destination = ref('')
|
||||
/**请假事由*/
|
||||
const reason = ref('')
|
||||
/**附件路径*/
|
||||
const path = ref([])
|
||||
const baseUrl = import.meta.env.VITE_REQUEST_BASE_URL + '/jeecg-boot/sys/common/upload/'
|
||||
const imageStyles = {
|
||||
width: 64,
|
||||
height: 64,
|
||||
border: {
|
||||
color: "#dce7e1",
|
||||
width: 2,
|
||||
style: 'dashed',
|
||||
radius: '2px'
|
||||
}
|
||||
}
|
||||
onLoad(() => {
|
||||
loadData()
|
||||
getTomorrowDate()
|
||||
})
|
||||
|
||||
const select = (e) => {
|
||||
const tempFilePaths = e.tempFilePaths
|
||||
for (let i = 0; i < e.tempFilePaths.length; i++) {
|
||||
let photoPath = '职工请假/' + depart.value + '/' + store.userinfo.realname
|
||||
uni.uploadFile({
|
||||
url: baseUrl,
|
||||
filePath: e.tempFilePaths[i],
|
||||
name: 'file',
|
||||
formData: {
|
||||
appPath: photoPath
|
||||
},
|
||||
success: (res) => {
|
||||
path.value.push(JSON.parse(res.data).message)
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const qjAdd = () => {
|
||||
if (!phone.value.trim()) return proxy.$toast('请输入联系方式')
|
||||
if (!type.value) return proxy.$toast('请选择请假类型')
|
||||
if (!beginTime.value) return proxy.$toast('请选择开始时间')
|
||||
if (!endTime.value) return proxy.$toast('请选择结束时间')
|
||||
if (ifShow.value) {
|
||||
if (typeIndex.value == null) { //副职、员工需要选择审批领导
|
||||
return proxy.$toast('请选择审批领导')
|
||||
}
|
||||
}
|
||||
if (!departure.value.trim()) return proxy.$toast('请输入出发地')
|
||||
if (!destination.value.trim()) return proxy.$toast('请输入目的地')
|
||||
if (!reason.value.trim()) return proxy.$toast('请输入请假事由')
|
||||
|
||||
qjAddApi({
|
||||
sysOrgCode: orgCode.value,
|
||||
username: store.userinfo.username,
|
||||
phone: phone.value,
|
||||
type: type.value,
|
||||
begintime: beginTime.value,
|
||||
endtime: endTime.value,
|
||||
examineleader: typeArr.value[typeIndex.value] ? typeArr.value[typeIndex.value].username : '',
|
||||
departure: departure.value,
|
||||
destination: destination.value,
|
||||
reason: reason.value,
|
||||
zwmc: zwcj.value,
|
||||
path: path.value.toString()
|
||||
}).then((res) => {
|
||||
if (res.success) {
|
||||
startMutilProcess(res.message)
|
||||
} else {
|
||||
proxy.$toast(res.message);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const startMutilProcess = (id) => {
|
||||
startMutilProcessApi({
|
||||
flowCode: "dev_cxc_qxj",
|
||||
id,
|
||||
formUrl: "modules/qxj/modules/CxcQxjBpmModel",
|
||||
formUrlMobile: "leaveApplication" //对应main.js里全局注册createApp()里的 app.component('leaveApplication',index)
|
||||
}).then((res) => {
|
||||
if (res.success) {
|
||||
proxy.$toast(res.message)
|
||||
setTimeout(() => {
|
||||
uni.navigateBack()
|
||||
}, 2000)
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.log(err);
|
||||
})
|
||||
}
|
||||
const loadData = () => {
|
||||
getCategoryItemsApi('1838487445813645313').then((res) => { //请假类型
|
||||
if (res.success) {
|
||||
dataSource.value = res.result
|
||||
}
|
||||
})
|
||||
|
||||
queryZbDepByLdhth(store.userinfo.workNo).then((res) => { //获取工作单位
|
||||
depart.value = res.departName
|
||||
orgCode.value = res.orgCode
|
||||
})
|
||||
|
||||
queryZwmcAndExaApi(store.userinfo.username).then((res) => { //本人职位及审批领导列表
|
||||
if (res.success) {
|
||||
typeArr.value = res.result.list
|
||||
zwcj.value = res.result.zwmc
|
||||
if (zwcj.value == '单位专家' || zwcj.value == '基层正职' || zwcj.value == '高级主管') {
|
||||
ifShow.value = false;
|
||||
}
|
||||
} else {
|
||||
proxy.$toast(res.message);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const bindType = (e) => {
|
||||
typeIndex.value = e.detail.value
|
||||
}
|
||||
|
||||
const getTomorrowDate = () => {
|
||||
let today = new Date();
|
||||
let tomorrow = new Date(today);
|
||||
tomorrow.setDate(today.getDate() + 1);
|
||||
// 格式化日期为 yyyy-mm-dd
|
||||
let year = tomorrow.getFullYear();
|
||||
let month = String(tomorrow.getMonth() + 1).padStart(2, '0'); // 月份从0开始,需要加1
|
||||
let day = String(tomorrow.getDate()).padStart(2, '0');
|
||||
beginTime.value = year + '-' + month + '-' + day;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page {
|
||||
background-color: #fff;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
.btn {
|
||||
border-top: 1px solid #EFEFEF;
|
||||
height: 120rpx;
|
||||
justify-content: center;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
width: 100vw;
|
||||
|
||||
view {
|
||||
width: 690rpx;
|
||||
height: 88rpx;
|
||||
background: #01508B;
|
||||
border-radius: 16rpx;
|
||||
font-size: 28rpx;
|
||||
color: #FFFFFF;
|
||||
text-align: center;
|
||||
line-height: 88rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.input_box {
|
||||
height: 100rpx;
|
||||
|
||||
.title {
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
input {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
text-align: right;
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
}
|
||||
}
|
||||
|
||||
.form {
|
||||
padding: 0 30rpx;
|
||||
background-color: #fff;
|
||||
|
||||
.title {
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.box {
|
||||
height: 100rpx;
|
||||
}
|
||||
|
||||
.box:not(:last-child) {
|
||||
border-bottom: 1px solid #EFEFEF;
|
||||
|
||||
}
|
||||
|
||||
.choose {
|
||||
font-size: 28rpx;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.choosed {
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
322
pages/login/login.vue
Normal file
@ -0,0 +1,322 @@
|
||||
<template>
|
||||
<view :class="{'gray':store.isgray==1}">
|
||||
<view class="logo f-col aic">
|
||||
<image src="@/static/login/logo.png"></image>
|
||||
</view>
|
||||
<view class="form f-col aic">
|
||||
<view class="box f-row aic">
|
||||
<image src="@/static/login/phone.png"></image>
|
||||
<input v-model="username" type="text" placeholder="请输入统一身份认证"
|
||||
placeholder-style="font-size: 28rpx;color: #999999;" />
|
||||
</view>
|
||||
<view class="box f-row aic">
|
||||
<image src="@/static/login/pwd.png"></image>
|
||||
<input v-model="password" :type="!showpwd?'password':'text'" placeholder="请输入密码"
|
||||
placeholder-style="font-size: 28rpx;color: #999999;" />
|
||||
<image v-if="showpwd" src="@/static/login/eye.png" @click="showpwd = !showpwd"></image>
|
||||
<image v-else src="@/static/login/eye-off.png" @click="showpwd = !showpwd"></image>
|
||||
</view>
|
||||
</view>
|
||||
<view class="pwd f-row aic">
|
||||
<view style="display: inline-block;" @click="check = !check">
|
||||
<view class="f-row aic">
|
||||
<image v-if="!check" src="@/static/login/nocheck.png"></image>
|
||||
<image v-else src="@/static/login/checked.png"></image>
|
||||
<text>记住密码</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="login f-col aic">
|
||||
<view @click="login">
|
||||
登录
|
||||
</view>
|
||||
</view>
|
||||
<view class="login f-col aic">
|
||||
<text style="font-size: 10px;">Copyright (c) 2024 天然气产销厂</text>
|
||||
<text style="font-size: 10px;">版本号:{{systemInfo.appWgtVersion}}</text>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref,
|
||||
getCurrentInstance,
|
||||
watch
|
||||
} from 'vue';
|
||||
import {
|
||||
loginApi,
|
||||
localLoginApi,
|
||||
queryRoleApi
|
||||
} from '@/api/login.js';
|
||||
import {
|
||||
taskListApi
|
||||
} from '@/api/api.js';
|
||||
import Base64 from 'base-64';
|
||||
import {
|
||||
onLoad
|
||||
} from '@dcloudio/uni-app'
|
||||
import {
|
||||
useStore
|
||||
} from '@/store'
|
||||
const store = useStore()
|
||||
const {
|
||||
proxy
|
||||
} = getCurrentInstance()
|
||||
|
||||
/** 系统信息 */
|
||||
const systemInfo = uni.getSystemInfoSync()
|
||||
/**是否明文显示密码*/
|
||||
const showpwd = ref(false)
|
||||
/**用于用户缓存账号和密码*/
|
||||
let localObj = {}
|
||||
/**记住账号和密码*/
|
||||
const savePwd = () => {
|
||||
let localObj = {
|
||||
un: username.value
|
||||
}
|
||||
if (check.value) {
|
||||
localObj.pw = password.value
|
||||
}
|
||||
uni.setStorageSync('accountObj', JSON.stringify(localObj))
|
||||
}
|
||||
|
||||
/**是否选中记住密码*/
|
||||
const check = ref(true);
|
||||
/**账号*/
|
||||
const username = ref('')
|
||||
/**密码*/
|
||||
const password = ref('')
|
||||
const login = () => {
|
||||
if (!username.value.trim()) return proxy.$toast('请输入账号')
|
||||
if (!password.value.trim()) return proxy.$toast('请输入密码')
|
||||
let un = Base64.encode(encodeURIComponent(username.value))
|
||||
let pw = Base64.encode(encodeURIComponent(password.value))
|
||||
uni.showLoading({
|
||||
title: '登录中...'
|
||||
});
|
||||
|
||||
/*生产环境 begin */
|
||||
// loginApi({
|
||||
// username: un,
|
||||
// password: pw,
|
||||
// ip: getDeviceIp()
|
||||
/*生产环境 end */
|
||||
|
||||
/*开发环境 begin */
|
||||
localLoginApi({
|
||||
username: username.value,
|
||||
password: password.value,
|
||||
captcha: 'app'
|
||||
/*开发环境 end */
|
||||
}).then((loginres) => {
|
||||
if (loginres.success) {
|
||||
uni.setStorageSync('token', loginres.result.token)
|
||||
store.setToken(loginres.result.token)
|
||||
savePwd()
|
||||
queryRoleApi({
|
||||
roles: loginres.result.userInfo.roles
|
||||
}).then((roleres) => {
|
||||
//登录时间
|
||||
uni.setStorageSync('logintime', Date.now())
|
||||
// 登录人的角色
|
||||
uni.setStorageSync('role', roleres)
|
||||
store.setRole(roleres)
|
||||
|
||||
// 登录人信息
|
||||
uni.setStorageSync('user', JSON.stringify(loginres.result
|
||||
.userInfo))
|
||||
store.setUserInfo(loginres.result.userInfo)
|
||||
//获取任务列表角标
|
||||
loadBadge()
|
||||
|
||||
// 跳转首页
|
||||
uni.switchTab({
|
||||
url: '/pages/tab/index'
|
||||
})
|
||||
})
|
||||
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.log(err);
|
||||
})
|
||||
}
|
||||
|
||||
let localAccountArr = []
|
||||
const accountArr = ref([])
|
||||
onLoad(() => {
|
||||
if (uni.getStorageSync('accountObj')) {
|
||||
let obj = JSON.parse(uni.getStorageSync('accountObj'))
|
||||
username.value = obj.un ? obj.un : ''
|
||||
password.value = obj.pw ? obj.pw : ''
|
||||
}
|
||||
// localAccountArr = uni.getStorageSync('accountArr') ? JSON.parse(uni.getStorageSync('accountArr')) : []
|
||||
// accountArr.value = localAccountArr
|
||||
})
|
||||
|
||||
const loadBadge = () => {
|
||||
taskListApi().then((res) => {
|
||||
if (res.success) {
|
||||
if (res.result.total > 0) {
|
||||
uni.setTabBarBadge({
|
||||
index: '1',
|
||||
text: res.result.total // 角标内容
|
||||
});
|
||||
} else {
|
||||
uni.removeTabBarBadge({ // 移除角标
|
||||
index: '1',
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
function getDeviceIp() {
|
||||
// #ifdef APP-PLUS
|
||||
|
||||
let deviceIp
|
||||
if (plus.os.name == "Android") {
|
||||
let Context = plus.android.importClass('android.content.Context')
|
||||
let main = plus.android.runtimeMainActivity()
|
||||
let cm = main.getSystemService(Context.CONNECTIVITY_SERVICE)
|
||||
plus.android.importClass(cm)
|
||||
let linkProperties = cm.getLinkProperties(cm.getActiveNetwork())
|
||||
let linkAddrs = plus.android.invoke(linkProperties, 'getLinkAddresses')
|
||||
plus.android.importClass(linkAddrs)
|
||||
for (var i = 0; i < linkAddrs.size(); i++) {
|
||||
let inetAddr = plus.android.invoke(linkAddrs.get(i), 'getAddress')
|
||||
deviceIp = plus.android.invoke(inetAddr, 'getHostAddress')
|
||||
}
|
||||
//再看有没有wifi
|
||||
if (deviceIp == '') {
|
||||
var wifiManager = plus.android.runtimeMainActivity().getSystemService(Context.WIFI_SERVICE);
|
||||
var wifiInfo = plus.android.invoke(wifiManager, "getConnectionInfo");
|
||||
var ipAddress = plus.android.invoke(wifiInfo, "getIpAddress");
|
||||
if (ipAddress != 0) {
|
||||
deviceIp = ((ipAddress & 0xff) + "." + (ipAddress >> 8 & 0xff) + "." + (ipAddress >> 16 &
|
||||
0xff) + "." + (ipAddress >> 24 & 0xff));
|
||||
}
|
||||
}
|
||||
}
|
||||
console.log(deviceIp)
|
||||
return deviceIp;
|
||||
// #endif
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.uni-select) {
|
||||
border: none;
|
||||
padding-left: 0;
|
||||
height: 88rpx;
|
||||
}
|
||||
|
||||
:deep(.uni-select__input-placeholder) {
|
||||
font-size: 28rpx;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
:deep(.uni-icons) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.logo {
|
||||
padding-top: 184rpx;
|
||||
|
||||
image {
|
||||
width: 475rpx;
|
||||
height: 199rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.form {
|
||||
margin-top: 60rpx;
|
||||
|
||||
.box {
|
||||
width: 570rpx;
|
||||
height: 88rpx;
|
||||
background: #F8F8F8;
|
||||
border-radius: 44rpx;
|
||||
padding: 0 30rpx;
|
||||
margin-top: 40rpx;
|
||||
position: relative;
|
||||
|
||||
.account_box {
|
||||
position: absolute;
|
||||
top: 100rpx;
|
||||
left: 90rpx;
|
||||
width: 500rpx;
|
||||
background-color: #fff;
|
||||
box-shadow: 0px 0px 3px 1px #dfdfdf;
|
||||
z-index: 99;
|
||||
border-radius: 10rpx;
|
||||
|
||||
// &::after {
|
||||
// position: absolute;
|
||||
// content: ' ';
|
||||
// border: 15rpx solid;
|
||||
// border-color: transparent transparent #fff transparent;
|
||||
// top: -30rpx;
|
||||
// left: 30rpx;
|
||||
// z-index: 999;
|
||||
// }
|
||||
|
||||
|
||||
.account {
|
||||
max-height: 200rpx;
|
||||
|
||||
overflow-y: auto;
|
||||
|
||||
view {
|
||||
padding: 10rpx;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
image {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
input {
|
||||
height: 100%;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.pwd {
|
||||
image {
|
||||
width: 34rpx;
|
||||
height: 34rpx;
|
||||
margin-right: 4rpx;
|
||||
}
|
||||
|
||||
justify-content: flex-end;
|
||||
margin-top: 20rpx;
|
||||
margin-right: 60rpx;
|
||||
font-size: 24rpx;
|
||||
color: #01508B;
|
||||
}
|
||||
|
||||
.login {
|
||||
margin-top: 63rpx;
|
||||
|
||||
view {
|
||||
width: 630rpx;
|
||||
height: 88rpx;
|
||||
background: #4e74fb;
|
||||
border-radius: 44rpx;
|
||||
font-size: 32rpx;
|
||||
color: #FFFFFF;
|
||||
text-align: center;
|
||||
line-height: 88rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
32
pages/product/index.vue
Normal file
@ -0,0 +1,32 @@
|
||||
<template>
|
||||
<view :class="['f-col','aic',{'gray':store.isgray==1}]">
|
||||
<dataCom title="实时输差" :list="shishiArr"></dataCom>
|
||||
<dataCom title="偏远计量点" :list="shishiArr"></dataCom>
|
||||
<dataCom title="生产实时数据" :list="productArr"></dataCom>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import dataCom from '@/bpm/dataCom.vue';
|
||||
import {
|
||||
onLoad
|
||||
} from '@dcloudio/uni-app';
|
||||
import {
|
||||
ref
|
||||
} from 'vue';
|
||||
import {
|
||||
useStore
|
||||
} from '@/store'
|
||||
const store = useStore()
|
||||
const shishiArr = ref([])
|
||||
const productArr = ref([])
|
||||
onLoad((options) => {
|
||||
shishiArr.value = JSON.parse(options.shishi)
|
||||
productArr.value = JSON.parse(options.product)
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
||||
47
pages/safe/detail.vue
Normal file
@ -0,0 +1,47 @@
|
||||
<template>
|
||||
<view :class="['content',{'gray':store.isgray==1}]">
|
||||
<view class="">
|
||||
<video src=""></video>
|
||||
<view class="title">
|
||||
五月天“突然好想你”线上演唱会精彩回放,这里就是标题
|
||||
</view>
|
||||
</view>
|
||||
<view class="listcom">
|
||||
<safeCom></safeCom>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import safeCom from '../../bpm/safeCom.vue';
|
||||
import {
|
||||
useStore
|
||||
} from '@/store'
|
||||
const store = useStore()
|
||||
</script>
|
||||
<style>
|
||||
page{
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
.content {
|
||||
.title{
|
||||
background-color: #fff;
|
||||
font-size: 32rpx;
|
||||
color: #333333;
|
||||
line-height: 45rpx;
|
||||
padding: 30rpx;
|
||||
}
|
||||
|
||||
video{
|
||||
width: 750rpx;
|
||||
height: 500rpx;
|
||||
}
|
||||
}
|
||||
.listcom{
|
||||
padding:0 30rpx 30rpx 30rpx;
|
||||
margin-top: 20rpx;
|
||||
background-color: #fff;
|
||||
}
|
||||
</style>
|
||||
86
pages/safe/manage.vue
Normal file
@ -0,0 +1,86 @@
|
||||
<template>
|
||||
<view :class="['content',{'gray':store.isgray==1}]">
|
||||
<customNav>
|
||||
<view class="nav_box f-row aic jcb">
|
||||
<view class="back f-row aic" @click="back">
|
||||
<uni-icons type="left" size="20" color="#fff"></uni-icons>
|
||||
</view>
|
||||
<view class="search f-row aic">
|
||||
<input type="text" v-model="searchKey" @confirm="search" @blur="showicon=true&&!searchKey"
|
||||
@focus="showicon=false" />
|
||||
<view class="f-row aic" v-if="showicon">
|
||||
<image src="../../static/search.png" mode=""></image>
|
||||
<text>搜索</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</customNav>
|
||||
<view class="">
|
||||
<safeCom></safeCom>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref
|
||||
} from 'vue';
|
||||
import safeCom from '../../bpm/safeCom.vue';
|
||||
import customNav from '../../bpm/customNav.vue';
|
||||
import {
|
||||
useStore
|
||||
} from '@/store';
|
||||
const store = useStore()
|
||||
const showicon = ref(true)
|
||||
const searchKey = ref('')
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.content {
|
||||
padding: 0 30rpx 30rpx 30rpx;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.nav_box {
|
||||
position: absolute;
|
||||
bottom: 14rpx;
|
||||
width: 100%;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.back {
|
||||
padding: 0 30rpx;
|
||||
}
|
||||
|
||||
.search {
|
||||
position: relative;
|
||||
padding-right: 30rpx;
|
||||
flex: 1;
|
||||
|
||||
view {
|
||||
position: absolute;
|
||||
left: 28rpx;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
|
||||
font-size: 28rpx;
|
||||
color: #999999;
|
||||
|
||||
}
|
||||
|
||||
input {
|
||||
flex: 1;
|
||||
height: 72rpx;
|
||||
background: #F8F8F8;
|
||||
border-radius: 44rpx;
|
||||
padding: 0 28rpx;
|
||||
}
|
||||
|
||||
image {
|
||||
width: 34rpx;
|
||||
height: 34rpx;
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
666
pages/tab/index.vue
Normal file
@ -0,0 +1,666 @@
|
||||
<template>
|
||||
<view :class="['content',{'gray':store.isgray==1}]">
|
||||
<view class="nav">
|
||||
<view class="nav_box f-row aic jcb">
|
||||
<!-- <view class="menu" @click="showDrawer()">
|
||||
<image src="../../static/index/menu.png" mode=""></image>
|
||||
</view> -->
|
||||
<view class="weather_calender f-row aic">
|
||||
<view class="position f-row aic">
|
||||
<image src="../../static/index/position.png" mode=""></image>
|
||||
<text>{{!store.position?'暂未定位':store.position}}</text>
|
||||
</view>
|
||||
<view class="position f-row aic">
|
||||
<image style="height:80rpx;width:80rpx;"
|
||||
:src="`http://openweathermap.org/img/w/${store.wenduIcon}.png`" mode=""></image>
|
||||
<text>{{store.wendu}}℃</text>
|
||||
</view>
|
||||
<uni-datetime-picker type="date">
|
||||
<view class="position f-row aic">
|
||||
<image src="../../static/index/calendar.png" mode=""></image>
|
||||
<text>{{getTime()}}</text>
|
||||
</view>
|
||||
</uni-datetime-picker>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="f-col aic">
|
||||
<swiper class="swiper" autoplay>
|
||||
<swiper-item v-for="item,i in banner" :key="i" class="swiper-item">
|
||||
<image :src="item" mode="aspectFill"></image>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
</view>
|
||||
<view class="wrapper f-col aic">
|
||||
<view class="onduty">
|
||||
<view class="title f-row aic jcb">
|
||||
值班信息
|
||||
<view class="more" @click="jump(`/pages/zhiban/index`)">
|
||||
查看更多
|
||||
<image src="../../static/index/back.png" mode=""></image>
|
||||
</view>
|
||||
</view>
|
||||
<view class="info">
|
||||
<view class="info_title f-row aic">
|
||||
<view class="">
|
||||
日期
|
||||
</view>
|
||||
<view class="">
|
||||
带班领导
|
||||
</view>
|
||||
<view class="">
|
||||
值班领导
|
||||
</view>
|
||||
<view class="">
|
||||
值班干部
|
||||
</view>
|
||||
</view>
|
||||
<view class="data_box">
|
||||
<view :class="['data',' f-row', 'aic',{'first':i==0}]" v-for="item,i in zhibanArr">
|
||||
<view class="">
|
||||
{{item.date}}
|
||||
</view>
|
||||
<view class="">
|
||||
{{item.dbld_dictText}}
|
||||
</view>
|
||||
<view class="">
|
||||
{{item.zbld_dictText}}
|
||||
</view>
|
||||
<view class="">
|
||||
{{item.zbgbrealname}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="list_wrapper">
|
||||
<view class="">
|
||||
<view class="list_title f-row aic jca">
|
||||
<view v-for="item,i in tabArr" :class="{'active':current==i}" @click="changeTab(i)">
|
||||
{{item}}
|
||||
</view>
|
||||
</view>
|
||||
<view class="f-row aic zhidu" v-if="current==2">
|
||||
<view :class="{'active':current_zhidu==0}" @click="changeZhidu(0)">
|
||||
厂级制度
|
||||
</view>
|
||||
<view :class="{'active':current_zhidu==1}" @click="changeZhidu(1)">
|
||||
上级制度
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view style="padding-top: 24rpx;" class="more"
|
||||
@click="jump(`/pages/document/index?id=${current}`,current)">
|
||||
查看更多
|
||||
<image src="../../static/index/back.png" mode=""></image>
|
||||
</view>
|
||||
<view class="list_box">
|
||||
<view class="list" v-for="item,i in list" :key="i"
|
||||
@click="jump(`/pages/document/detail?data=${JSON.stringify(item)}&id=${current}`,current,item,'detail')">
|
||||
<view class="topic">
|
||||
{{item._title}}
|
||||
</view>
|
||||
<view class="time_Box f-row aic" v-if="item._time||item._depart">
|
||||
<view class="time" v-if="item._time">
|
||||
{{item._time}}
|
||||
</view>
|
||||
<view class="look f-row aic" v-if="item._depart">
|
||||
{{item._depart}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- <uni-drawer ref="showLeft" mode="left" :width="156">
|
||||
<view class="menu_list">
|
||||
<view class="f-row aic jcb" v-for="item,i in menu" :key="i" @click="totask(item.path)">
|
||||
<text>{{item.text}}</text>
|
||||
<uni-icons type="right" size="20" color="#333333"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
</uni-drawer> -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref
|
||||
} from 'vue';
|
||||
import {
|
||||
onLoad,
|
||||
onPullDownRefresh,
|
||||
// onReachBottom
|
||||
} from '@dcloudio/uni-app';
|
||||
import {
|
||||
bpmlistApi,
|
||||
gonggaolistApi,
|
||||
zhibanApi,
|
||||
faguiApi,
|
||||
cjzhiduApi,
|
||||
zhiduApi,
|
||||
cxcDapingApi
|
||||
} from '@/api/api.js';
|
||||
import {
|
||||
getUserPermissionApi
|
||||
} from '@/api/login.js';
|
||||
import customNav from '../../bpm/customNav.vue';
|
||||
import {
|
||||
useStore
|
||||
} from '@/store';
|
||||
import {
|
||||
beforeJump,
|
||||
getTime,
|
||||
opendocument,
|
||||
preview
|
||||
} from '@/utils/index.js';
|
||||
const baseurl = import.meta.env.VITE_REQUEST_BASE_URL + '/jeecg-boot'
|
||||
|
||||
const store = useStore();
|
||||
onLoad(() => {
|
||||
// list.value = []
|
||||
// if (!uni.getStorageSync('token')) {
|
||||
// return uni.navigateTo({
|
||||
// url: '/pages/login/login'
|
||||
// })
|
||||
// }
|
||||
cxcDaping()
|
||||
zhiban()
|
||||
// bpmlist()
|
||||
// gonggaolist()
|
||||
// zhidu()
|
||||
// fagui()
|
||||
getlist()
|
||||
})
|
||||
|
||||
|
||||
const banner = ref([])
|
||||
/**轮播图*/
|
||||
const cxcDaping = () => {
|
||||
cxcDapingApi({
|
||||
zslb: 6
|
||||
}).then((res) => {
|
||||
if (res.success) {
|
||||
let arr = res.result.records[0].wenjian.split(',')
|
||||
banner.value = arr.map((item) => {
|
||||
return baseurl + '/sys/common/static/' + item
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**公文公告制度法规切换index*/
|
||||
const current = ref(0)
|
||||
/**厂级制度上级制度index 默认厂级*/
|
||||
const current_zhidu = ref(0)
|
||||
/**公文公告制度法规*/
|
||||
const tabArr = ['公文', '公告', '制度', '法规']
|
||||
/**公文公告制度法规切换*/
|
||||
const changeTab = (i) => {
|
||||
current.value = i
|
||||
pageNo = 1
|
||||
loading = false
|
||||
list.value = []
|
||||
getlist()
|
||||
}
|
||||
/**厂级制度上级制度切换*/
|
||||
const changeZhidu = (i) => {
|
||||
current_zhidu.value = i
|
||||
pageNo = 1
|
||||
loading = false
|
||||
list.value = []
|
||||
zhidu()
|
||||
}
|
||||
const res = wx.getSystemInfoSync();
|
||||
const statusHeight = res.statusBarHeight; //状态栏高度
|
||||
const cusnavbarheight = (statusHeight + 44) + "px";
|
||||
const showLeft = ref(null)
|
||||
const showDrawer = (e) => {
|
||||
showLeft.value.open()
|
||||
}
|
||||
// 关闭窗口
|
||||
const closeDrawer = (e) => {
|
||||
showLeft.value.close()
|
||||
}
|
||||
|
||||
const totask = (url) => {
|
||||
closeDrawer()
|
||||
jump(url)
|
||||
}
|
||||
const jump = (url, type, item, page) => {
|
||||
// 公告不可进入详情
|
||||
if (type && type == 1 && page == 'detail') return
|
||||
// 法规点击直接打开附件
|
||||
if (type && type == 3 && item) {
|
||||
return opendocument(item.mingcheng)
|
||||
}
|
||||
// 制度查看更多 判断是厂级还是上级
|
||||
if (type && type == 2) {
|
||||
url = url + `&zhiduid=${current_zhidu.value}`
|
||||
}
|
||||
beforeJump(url, () => {
|
||||
uni.navigateTo({
|
||||
url
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// const menu = ref([{
|
||||
// text: '我的任务',
|
||||
// path: '/pages/task/index?id=0'
|
||||
// },{
|
||||
// text: '历史任务',
|
||||
// path: '/pages/task/index?id=2'
|
||||
// }])
|
||||
let pageNo = 1
|
||||
let pageSize = 5
|
||||
let loading = false
|
||||
const list = ref([])
|
||||
/**公文接口*/
|
||||
const bpmlist = () => {
|
||||
loading = true
|
||||
bpmlistApi({
|
||||
pageNo,
|
||||
pageSize
|
||||
}).then((res) => {
|
||||
if (res.success) {
|
||||
list.value = [...list.value, ...formatObj(res.result.records, 'fwbt', 'fwtime', null)]
|
||||
}
|
||||
loading = false
|
||||
}).catch((err) => {
|
||||
console.log('err', err);
|
||||
})
|
||||
}
|
||||
/**公告接口*/
|
||||
const gonggaolist = () => {
|
||||
loading = true
|
||||
gonggaolistApi({
|
||||
pageNo,
|
||||
pageSize
|
||||
}).then((res) => {
|
||||
if (res.success) {
|
||||
list.value = [...list.value, ...formatObj(res.result.records, 'neirong', 'fbdw', 'createTime')]
|
||||
}
|
||||
loading = false
|
||||
}).catch((err) => {
|
||||
console.log('err', err);
|
||||
})
|
||||
}
|
||||
const zhibanArr = ref([])
|
||||
/**值班接口*/
|
||||
const zhiban = () => {
|
||||
zhibanApi().then((res) => {
|
||||
if (res.success) {
|
||||
zhibanArr.value = res.result.records.slice(0, 2)
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.log('err', err);
|
||||
})
|
||||
}
|
||||
/**法规接口*/
|
||||
const fagui = () => {
|
||||
loading = true
|
||||
faguiApi({
|
||||
pageNo,
|
||||
pageSize
|
||||
}).then((res) => {
|
||||
if (res.success) {
|
||||
list.value = [...list.value, ...formatObj(res.result.records, 'flfgmc', 'ssbm', null)]
|
||||
|
||||
}
|
||||
loading = false
|
||||
}).catch((err) => {
|
||||
console.log('err', err);
|
||||
})
|
||||
}
|
||||
/**制度接口*/
|
||||
const zhidu = () => {
|
||||
loading = true
|
||||
let getzhidu = current_zhidu.value == 0 ? zhiduApi : cjzhiduApi
|
||||
getzhidu({
|
||||
pageNo,
|
||||
pageSize
|
||||
}).then((res) => {
|
||||
if (res.success) {
|
||||
let str = current_zhidu.value == 0 ? 'zbbm_dictText' : 'sbbm'
|
||||
list.value = [...list.value, ...formatObj(res.result.records, 'zdmc', str, null)]
|
||||
}
|
||||
loading = false
|
||||
}).catch((err) => {
|
||||
console.log('err', err);
|
||||
})
|
||||
}
|
||||
const formatObj = (arr, title, time, depart) => {
|
||||
arr.map((item) => {
|
||||
item['_title'] = item[title]
|
||||
item['_time'] = item[time]
|
||||
item['_depart'] = item[depart]
|
||||
})
|
||||
return arr
|
||||
}
|
||||
onPullDownRefresh(() => {
|
||||
loading = false
|
||||
list.value = []
|
||||
cxcDaping()
|
||||
zhiban()
|
||||
getlist()
|
||||
uni.stopPullDownRefresh()
|
||||
})
|
||||
|
||||
const getlist = () => {
|
||||
if (current.value == 0) {
|
||||
bpmlist()
|
||||
} else if (current.value == 1) {
|
||||
gonggaolist()
|
||||
} else if (current.value == 2) {
|
||||
zhidu()
|
||||
} else if (current.value == 3) {
|
||||
fagui()
|
||||
}
|
||||
}
|
||||
// onReachBottom(() => {
|
||||
// if (loading) return
|
||||
// pageNo++
|
||||
// getlist()
|
||||
// })
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.content {
|
||||
padding-top: v-bind(cusnavbarheight);
|
||||
}
|
||||
|
||||
::v-deep .uni-drawer {
|
||||
margin-top: v-bind(cusnavbarheight);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// .menu_list {
|
||||
// padding: 0 30rpx;
|
||||
// font-size: 28rpx;
|
||||
// color: #333333;
|
||||
|
||||
// view {
|
||||
// height: 110rpx;
|
||||
// border-bottom: 1px solid #EFEFEF;
|
||||
// }
|
||||
|
||||
// image {
|
||||
// width: 13rpx;
|
||||
// height: 23rpx;
|
||||
// }
|
||||
// }
|
||||
|
||||
.nav {
|
||||
width: calc(100% - 60rpx);
|
||||
padding: 0 30rpx;
|
||||
height: v-bind(cusnavbarheight);
|
||||
|
||||
font-size: 24rpx;
|
||||
color: #333333;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 99;
|
||||
background-image: url('../../static/my/navbg.png');
|
||||
background-repeat: no-repeat;
|
||||
background-size: 750rpx 458rpx;
|
||||
}
|
||||
|
||||
.nav_box {
|
||||
position: absolute;
|
||||
bottom: 26rpx;
|
||||
width: calc(100% - 60rpx);
|
||||
}
|
||||
|
||||
// .menu {
|
||||
// image {
|
||||
// width: 36rpx;
|
||||
// height: 46rpx;
|
||||
// }
|
||||
// }
|
||||
|
||||
.weather_calender {
|
||||
image {
|
||||
width: 36rpx;
|
||||
height: 36rpx;
|
||||
margin-right: 8rpx;
|
||||
}
|
||||
|
||||
.position:not(:last-child) {
|
||||
position: relative;
|
||||
margin-right: 60rpx;
|
||||
|
||||
&::after {
|
||||
position: absolute;
|
||||
content: ' ';
|
||||
width: 2rpx;
|
||||
height: 20rpx;
|
||||
background: #EFEFEF;
|
||||
right: -30rpx;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.swiper {
|
||||
width: 100vw;
|
||||
height: 400rpx;
|
||||
|
||||
.swiper-item {
|
||||
image {
|
||||
width: 100vw;
|
||||
height: 400rpx;
|
||||
background-color: #a8a8a8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
padding: 0 30rpx;
|
||||
transform: translateY(-50rpx);
|
||||
|
||||
.onduty {
|
||||
background: #FFFFFF;
|
||||
box-shadow: 0rpx 2rpx 4rpx 0rpx rgba(0, 0, 0, 0.5);
|
||||
border-radius: 16rpx;
|
||||
padding: 20rpx 24rpx 24rpx 24rpx;
|
||||
|
||||
.title {
|
||||
font-size: 32rpx;
|
||||
color: #333333;
|
||||
background-size: 44rpx 12rpx;
|
||||
background-repeat: no-repeat;
|
||||
background-position: left bottom;
|
||||
}
|
||||
|
||||
.info {
|
||||
background: #F8F8F8;
|
||||
border-radius: 8rpx;
|
||||
text-align: center;
|
||||
width: 642rpx;
|
||||
margin-top: 23rpx;
|
||||
|
||||
.info_title {
|
||||
font-size: 24rpx;
|
||||
color: #333333;
|
||||
padding: 24rpx 0;
|
||||
border-bottom: 1px solid #EFEFEF;
|
||||
|
||||
view {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.data_box {
|
||||
font-size: 24rpx;
|
||||
padding-bottom: 24rpx;
|
||||
color: #888888;
|
||||
|
||||
.first {
|
||||
font-weight: bold;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.data {
|
||||
margin-top: 23rpx;
|
||||
|
||||
view {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.more {
|
||||
font-size: 24rpx;
|
||||
color: #999999;
|
||||
text-align: right;
|
||||
|
||||
image {
|
||||
width: 10rpx;
|
||||
height: 18rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.list_wrapper {
|
||||
background: #FFFFFF;
|
||||
box-shadow: 0rpx 2rpx 4rpx 0rpx rgba(0, 0, 0, 0.5);
|
||||
border-radius: 16rpx;
|
||||
padding: 26rpx 24rpx 24rpx 24rpx;
|
||||
position: relative;
|
||||
margin-top: 30rpx;
|
||||
width: 642rpx;
|
||||
|
||||
&::after {
|
||||
position: absolute;
|
||||
top: 100rpx;
|
||||
left: 0;
|
||||
content: ' ';
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
background-color: #EFEFEF;
|
||||
}
|
||||
|
||||
.zhidu {
|
||||
font-size: 24rpx;
|
||||
color: #666666;
|
||||
justify-content: flex-end;
|
||||
padding-top: 40rpx;
|
||||
|
||||
view {
|
||||
width: 120rpx;
|
||||
height: 60rpx;
|
||||
line-height: 60rpx;
|
||||
text-align: center;
|
||||
|
||||
&:first-child {
|
||||
margin-right: 40rpx;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.active {
|
||||
position: relative;
|
||||
color: #3179d6;
|
||||
|
||||
&::after {
|
||||
content: ' ';
|
||||
width: 120rpx;
|
||||
height: 60rpx;
|
||||
border-radius: 60rpx;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
position: absolute;
|
||||
background-color: rgba(49, 121, 214, 0.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.list_title {
|
||||
|
||||
text-align: center;
|
||||
padding-bottom: 29rpx;
|
||||
font-size: 32rpx;
|
||||
color: #666666;
|
||||
|
||||
.active {
|
||||
position: relative;
|
||||
color: #3179d6;
|
||||
|
||||
&::after {
|
||||
content: ' ';
|
||||
width: 120rpx;
|
||||
height: 70rpx;
|
||||
border-radius: 70rpx;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
position: absolute;
|
||||
background-color: rgba(49, 121, 214, 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
.list_box {
|
||||
margin-top: 24rpx;
|
||||
|
||||
.list {
|
||||
margin-bottom: 24rpx;
|
||||
padding: 30rpx 30rpx 35rpx 30rpx;
|
||||
// width: 570rpx;
|
||||
background: #F8F8F8;
|
||||
border-radius: 8rpx;
|
||||
|
||||
.topic {
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.time_Box {
|
||||
font-size: 24rpx;
|
||||
color: #888888;
|
||||
margin-top: 20rpx;
|
||||
|
||||
.time {
|
||||
margin-right: 62rpx;
|
||||
}
|
||||
|
||||
.look {
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
position: absolute;
|
||||
left: -30rpx;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
content: ' ';
|
||||
width: 2rpx;
|
||||
height: 20rpx;
|
||||
background: #999999;
|
||||
}
|
||||
}
|
||||
|
||||
image {
|
||||
width: 28rpx;
|
||||
height: 22rpx;
|
||||
margin-right: 8rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
339
pages/tab/my.vue
Normal file
@ -0,0 +1,339 @@
|
||||
<template>
|
||||
<view :class="{'gray':store.isgray==1}">
|
||||
<view class="nav">
|
||||
<view class="user f-row aic">
|
||||
<view class="avatar">
|
||||
<image @click="toProfile('/pages/useredit/useredit')" :src="imgUrl(store.userinfo.avatar)" mode="">
|
||||
</image>
|
||||
</view>
|
||||
<view class="f-row aic jcb right">
|
||||
<view class="name_job " @click="toProfile('/pages/useredit/useredit')">
|
||||
<view class="f-row aic">
|
||||
<view class="name">
|
||||
{{store.userinfo.realname}}
|
||||
</view>
|
||||
</view>
|
||||
<view class="job">
|
||||
{{store.role}}
|
||||
</view>
|
||||
</view>
|
||||
<view class="shezhi">
|
||||
<image @click="scan" style="width: 50rpx;height: 50rpx;margin-right: 20rpx;"
|
||||
src="../../static/tab/scan.png"></image>
|
||||
<!-- <image src="../../static/my/shezhi.png" mode="" @click="toProfile('/pages/useredit/useredit')">
|
||||
</image> -->
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="f-col aic">
|
||||
<view class="msg f-row aic jca">
|
||||
<!-- <view class="box f-col aic" @click="jump('/pages/task/todotask')">
|
||||
<view class="num">
|
||||
{{todoNum}}
|
||||
</view>
|
||||
<text>个人办公</text>
|
||||
</view> -->
|
||||
<view class="box f-col aic">
|
||||
<view class="num">
|
||||
{{0}}
|
||||
</view>
|
||||
<text>步数</text>
|
||||
</view>
|
||||
<view class="box f-col aic" @click="jump('/pages/useredit/addressbook')">
|
||||
<view class="num">
|
||||
0
|
||||
</view>
|
||||
<text>通讯录</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="operate">
|
||||
<view class="f-row aic jcb item" v-for="item,i in arr" :key="i" @click="jump(item.path)">
|
||||
<view class="left f-row aic">
|
||||
<image :src="item.img" mode=""></image>
|
||||
<text>{{item.text}}</text>
|
||||
</view>
|
||||
<view class="right f-row aic">
|
||||
<!-- <view class="" v-show="i==0">
|
||||
<uni-icons type="right" color="#2C2C2C"></uni-icons>
|
||||
</view> -->
|
||||
<view class="switch" v-show="i==0" @click="messageSwitch=!messageSwitch">
|
||||
<image v-show="messageSwitch" src="../../static/my/open.png" mode=""></image>
|
||||
<image v-show="!messageSwitch" src="../../static/my/close.png" mode=""></image>
|
||||
</view>
|
||||
<view class="switch" v-show="i==2" @click="position">
|
||||
<image v-show="positionSwitch" src="../../static/my/open.png" mode=""></image>
|
||||
<image v-show="!positionSwitch" src="../../static/my/close.png" mode=""></image>
|
||||
</view>
|
||||
<view class="version" v-show="i==3">
|
||||
当前版本v{{currentVersion}}
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="btn" @click="loginout">
|
||||
退出登录
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref
|
||||
} from 'vue';
|
||||
import {
|
||||
useStore
|
||||
} from '@/store';
|
||||
import {
|
||||
queryRoleApi
|
||||
} from '@/api/login.js';
|
||||
import {
|
||||
onLoad,
|
||||
onShow
|
||||
} from '@dcloudio/uni-app';
|
||||
import {
|
||||
beforeJump,
|
||||
getLocation,
|
||||
toast,
|
||||
getWeather
|
||||
} from '@/utils/index.js';
|
||||
import {
|
||||
imgUrl
|
||||
} from '@/utils/index.js';
|
||||
|
||||
const store = useStore();
|
||||
// h5没法访问plus 这里进行处理 by 闵
|
||||
// #ifdef APP_PLUS
|
||||
const currentVersion = ref(plus.runtime.version)
|
||||
// #endif
|
||||
const arr = ref([
|
||||
// {
|
||||
// img: '../../static/my/biao.png',
|
||||
// text: '值班表查询',
|
||||
// path: '/pages/zhiban/index'
|
||||
// },
|
||||
// {
|
||||
// img: '../../static/my/xiaoxi.png',
|
||||
// text: '接受消息推送',
|
||||
// path: ''
|
||||
// }
|
||||
// , {
|
||||
// img: '../../static/my/dingwei.png',
|
||||
// text: '开启定位',
|
||||
// path: ''
|
||||
// }, {
|
||||
// img: '../../static/my/shengji.png',
|
||||
// text: '软件升级',
|
||||
// path: ''
|
||||
// },
|
||||
])
|
||||
const messageSwitch = ref(false)
|
||||
const positionSwitch = ref(store.positionSwitch)
|
||||
const jump = (url) => {
|
||||
if (!url) return
|
||||
beforeJump(url, () => {
|
||||
uni.navigateTo({
|
||||
url
|
||||
})
|
||||
})
|
||||
}
|
||||
/**跳转个人资料*/
|
||||
const toProfile = (url) => {
|
||||
uni.navigateTo({
|
||||
url
|
||||
})
|
||||
}
|
||||
/**定位*/
|
||||
const position = () => {
|
||||
positionSwitch.value = !positionSwitch.value
|
||||
uni.setStorageSync('positionSwitch', positionSwitch.value)
|
||||
store.setPositionSwitch(positionSwitch.value)
|
||||
if (!positionSwitch.value) {
|
||||
toast('定位已关闭')
|
||||
}
|
||||
getLocation()
|
||||
}
|
||||
/**扫码*/
|
||||
const scan = () => {
|
||||
uni.scanCode({
|
||||
success: function(res) {
|
||||
plus.runtime.openWeb(res.result)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const loginout = () => {
|
||||
uni.showModal({
|
||||
title: '退出登录',
|
||||
content: '您确认要退出登录吗?',
|
||||
success(res) {
|
||||
if (res.confirm) {
|
||||
uni.removeStorageSync('token')
|
||||
uni.removeStorageSync('user')
|
||||
uni.removeStorageSync('role')
|
||||
uni.removeStorageSync('logintime')
|
||||
uni.reLaunch({
|
||||
url: '/pages/login/login'
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
// onShow(() => {
|
||||
// taskList()
|
||||
// })
|
||||
// const todoNum = ref(0)
|
||||
// const taskList = () => {
|
||||
// taskListApi({
|
||||
// pageNo: 1,
|
||||
// pageSize: 4,
|
||||
// _t: new Date().getTime()
|
||||
// }).then((res) => {
|
||||
// if (res.success) {
|
||||
// todoNum.value = res.result.total
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.btn {
|
||||
position: fixed;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
text-align: center;
|
||||
font-size: 32rpx;
|
||||
color: #DB4B31;
|
||||
}
|
||||
|
||||
.operate {
|
||||
padding: 0 30rpx;
|
||||
transform: translateY(-10rpx);
|
||||
|
||||
|
||||
.item {
|
||||
height: 104rpx;
|
||||
border-bottom: 1px solid #EFEFEF;
|
||||
|
||||
.version {
|
||||
font-size: 24rpx;
|
||||
color: #888888;
|
||||
}
|
||||
}
|
||||
|
||||
.switch {
|
||||
image {
|
||||
width: 68rpx;
|
||||
height: 38rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.left {
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
|
||||
image {
|
||||
width: 44rpx;
|
||||
height: 44rpx;
|
||||
margin-right: 30rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.msg {
|
||||
width: 690rpx;
|
||||
height: 142rpx;
|
||||
background-image: url('../../static/my/bg1.png');
|
||||
background-size: 690rpx 142rpx;
|
||||
margin-top: 30rpx;
|
||||
|
||||
.box {
|
||||
justify-content: center;
|
||||
width: 33.33%;
|
||||
|
||||
.num {
|
||||
font-size: 32rpx;
|
||||
color: #333333;
|
||||
margin-bottom: 4rpx;
|
||||
}
|
||||
|
||||
text {
|
||||
font-size: 24rpx;
|
||||
color: #888888;
|
||||
}
|
||||
}
|
||||
|
||||
.box:not(:last-child) {
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
content: ' ';
|
||||
width: 1rpx;
|
||||
height: 32rpx;
|
||||
background: #D8D8D8;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.nav {
|
||||
height: 458rpx;
|
||||
background-image: url('../../static/my/navbg.png');
|
||||
background-size: 750rpx 458rpx;
|
||||
|
||||
.user {
|
||||
padding: 128rpx 30rpx 0 30rpx;
|
||||
|
||||
.right {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
margin-right: 24rpx;
|
||||
|
||||
image {
|
||||
width: 110rpx;
|
||||
height: 110rpx;
|
||||
border-radius: 50%;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.name_job {
|
||||
.name {
|
||||
font-size: 36rpx;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.status {
|
||||
padding: 4rpx 12rpx;
|
||||
background: #55B800;
|
||||
border-radius: 8rpx;
|
||||
font-size: 20rpx;
|
||||
color: #FFFFFF;
|
||||
display: inline-block;
|
||||
margin-left: 8rpx;
|
||||
}
|
||||
|
||||
.job {
|
||||
font-size: 24rpx;
|
||||
color: #666666;
|
||||
margin-top: 6rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.shezhi {
|
||||
image {
|
||||
width: 42rpx;
|
||||
height: 42rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
197
pages/tab/office.vue
Normal file
@ -0,0 +1,197 @@
|
||||
<template>
|
||||
<view :class="{'gray':store.isgray==1}">
|
||||
<view class="nav"></view>
|
||||
<view class="placeholder"></view>
|
||||
<!-- <view class="drag" v-if="listorder?.length"> //20240929 yzq 注释 这部分是拖拽组件
|
||||
<view class="title">
|
||||
{{ listtitle}}
|
||||
</view>
|
||||
<l-drag :list="listorder" @change="change" :column="4" gridHeight="100px">
|
||||
<template #grid="{active, content}">
|
||||
<view class="inner f-col aic" :class="{'active': active}" @click="jump(content.path)">
|
||||
<view class="img f-row aic">
|
||||
<image :src="`../../static/office/${content.meta.icon}.png`" mode=""></image>
|
||||
</view>
|
||||
<view class="text">
|
||||
{{content?.meta.title}}
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
</l-drag>
|
||||
</view> -->
|
||||
<view class="title f-col aic" style="padding-top: 30rpx;" v-if="!listorder?.length&&!arr?.length">
|
||||
暂无权限,请联系管理员!
|
||||
</view>
|
||||
|
||||
<view class="content">
|
||||
<view class="list" v-if="arr?.length">
|
||||
<view class="item" v-for="item,i in arr" :key="i">
|
||||
<view class="title">
|
||||
{{item.meta.title}}
|
||||
</view>
|
||||
<view class="info_box f-row aic">
|
||||
<view class="info f-col aic" @click="jump(e.path)" v-for="e,i in item.children" :key="i">
|
||||
<view class="img f-row aic">
|
||||
<image :src="`../../static/office/${e.meta.icon}.png`"></image>
|
||||
</view>
|
||||
<view class="text">
|
||||
{{e.meta.title}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref
|
||||
} from 'vue';
|
||||
import {
|
||||
beforeJump
|
||||
} from '@/utils/index.js';
|
||||
import {
|
||||
onLoad
|
||||
} from '@dcloudio/uni-app';
|
||||
import {
|
||||
getUserPermissionApi
|
||||
} from '@/api/login.js';
|
||||
import {
|
||||
useStore
|
||||
} from '@/store';
|
||||
const store = useStore();
|
||||
|
||||
const list = new Array(7).fill(0).map((v, i) => i);
|
||||
// 拖拽后新的数据
|
||||
const newList = ref([])
|
||||
const change = v => newList.value = v
|
||||
|
||||
const res = wx.getSystemInfoSync();
|
||||
const statusHeight = res.statusBarHeight; //状态栏高度
|
||||
const cusnavbarheight = (statusHeight + 44) + "px";
|
||||
const jump = (url) => {
|
||||
beforeJump(url, () => {
|
||||
uni.navigateTo({
|
||||
url
|
||||
})
|
||||
})
|
||||
}
|
||||
onLoad(() => {
|
||||
getUserPermission()
|
||||
})
|
||||
const arr = ref([])
|
||||
const listorder = ref([]) //拖动排序传递数据
|
||||
const listtitle = ref([]) //拖动排序的title
|
||||
const getUserPermission = () => {
|
||||
getUserPermissionApi({
|
||||
token: store.token,
|
||||
type: 'mobile'
|
||||
}).then((res) => {
|
||||
if (res.success) {
|
||||
let data = res.result.menu
|
||||
data.map(item => item.children = item?.children.filter(e => e?.meta?.icon))
|
||||
data = data.filter(item => item?.children?.length)
|
||||
listtitle.value = data[0]?.meta?.title
|
||||
// arr.value = data.slice(1, data?.length)
|
||||
arr.value = data;
|
||||
listorder.value = data.slice(0, 1)[0]?.children
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.log(err);
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.drag {
|
||||
background: #FFFFFF;
|
||||
box-shadow: 0rpx 2rpx 4rpx 0rpx rgba(0, 0, 0, 0.5);
|
||||
border-radius: 16rpx;
|
||||
margin: 24rpx 30rpx 0 30rpx;
|
||||
|
||||
.title {
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
padding: 30rpx 0 0 30rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.inner {
|
||||
image {
|
||||
width: 98rpx;
|
||||
height: 98rpx;
|
||||
background-color: #efefef;
|
||||
}
|
||||
|
||||
.text {
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.placeholder {
|
||||
height: v-bind(cusnavbarheight);
|
||||
}
|
||||
|
||||
.nav {
|
||||
width: calc(100% - 60rpx);
|
||||
padding: 0 30rpx;
|
||||
height: v-bind(cusnavbarheight);
|
||||
|
||||
font-size: 24rpx;
|
||||
color: #FFFFFF;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 99;
|
||||
background-image: url('../../static/my/navbg.png');
|
||||
background-repeat: no-repeat;
|
||||
background-size: 750rpx 458rpx;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 0 30rpx 20rpx 30rpx;
|
||||
}
|
||||
|
||||
.list {
|
||||
margin-bottom: 24rpx;
|
||||
|
||||
.item {
|
||||
background: #FFFFFF;
|
||||
box-shadow: 0rpx 2rpx 4rpx 0rpx rgba(0, 0, 0, 0.5);
|
||||
border-radius: 16rpx;
|
||||
padding: 30rpx 0;
|
||||
margin-top: 24rpx;
|
||||
|
||||
.title {
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
padding-left: 30rpx;
|
||||
}
|
||||
}
|
||||
|
||||
image {
|
||||
width: 98rpx;
|
||||
height: 98rpx;
|
||||
}
|
||||
|
||||
.info_box {
|
||||
flex-wrap: wrap;
|
||||
|
||||
.info {
|
||||
margin-top: 40rpx;
|
||||
width: 25%;
|
||||
|
||||
.text {
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
244
pages/tab/product.vue
Normal file
@ -0,0 +1,244 @@
|
||||
<template>
|
||||
<view :class="{'gray':store.isgray==1}">
|
||||
<view class="nav">
|
||||
|
||||
</view>
|
||||
<view class="content">
|
||||
<view class="info f-col aic">
|
||||
<view class="item_box">
|
||||
<dataCom title="实时输差" :list="shishiArr"></dataCom>
|
||||
<dataCom title="偏远计量点" :list="shishiArr"></dataCom>
|
||||
<dataCom title="生产实时数据" :list="productArr"></dataCom>
|
||||
|
||||
<view class="item">
|
||||
<view class="title_box other f-row aic jcb">
|
||||
<view class="title">
|
||||
其他信息
|
||||
</view>
|
||||
</view>
|
||||
<view class="other_box f-row aic">
|
||||
<view class="data" v-for="other,i in otherArr" :key="i" @click="jump(other.path)">
|
||||
<view class="f-col aic">
|
||||
<image :src="other.img" mode=""></image>
|
||||
<view class="">
|
||||
{{other.text}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref
|
||||
} from 'vue';
|
||||
import {
|
||||
onLoad
|
||||
} from '@dcloudio/uni-app';
|
||||
import {
|
||||
indexChartScdtDataApi
|
||||
} from '@/api/api.js';
|
||||
import {
|
||||
beforeJump
|
||||
} from '@/utils/index.js';
|
||||
import {
|
||||
useStore
|
||||
} from '@/store';
|
||||
const store = useStore();
|
||||
import dataCom from '@/bpm/dataCom.vue';
|
||||
const shishiArr = [{
|
||||
gas: '今日进气总量',
|
||||
dailyVolume: '28392'
|
||||
}, {
|
||||
gas: '今日进气总量',
|
||||
dailyVolume: '28392'
|
||||
}, {
|
||||
gas: '今日输差百分数',
|
||||
dailyVolume: '0.32'
|
||||
}, {
|
||||
gas: '实时进气总量',
|
||||
dailyVolume: '28392'
|
||||
}, {
|
||||
gas: '实时进气总量',
|
||||
dailyVolume: '28392'
|
||||
}, {
|
||||
gas: '实时输差百分数',
|
||||
dailyVolume: '0.32'
|
||||
}, ]
|
||||
const productArr = ref([])
|
||||
let otherArr
|
||||
onLoad(() => {
|
||||
indexChartScdtData()
|
||||
})
|
||||
const res = wx.getSystemInfoSync();
|
||||
const statusHeight = res.statusBarHeight; //状态栏高度
|
||||
const cusnavbarheight = (statusHeight + 44) + "px";
|
||||
const indexChartScdtData = () => {
|
||||
indexChartScdtDataApi().then((res) => {
|
||||
if (res.success) {
|
||||
productArr.value = handleData(res.result.today)
|
||||
otherArr = [{
|
||||
text: '安全管理',
|
||||
img: '../../static/tab/anquan.png',
|
||||
path: '/pages/safe/manage'
|
||||
}, {
|
||||
text: '生产数据',
|
||||
img: '../../static/tab/product.png',
|
||||
path: `/pages/product/index?shishi=${JSON.stringify(shishiArr)}&product=${JSON.stringify(productArr.value)}`
|
||||
}, {
|
||||
text: '运输管理',
|
||||
img: '../../static/tab/yunshu.png',
|
||||
path: ''
|
||||
}, {
|
||||
text: '设备台账',
|
||||
img: '../../static/tab/taizhang.png',
|
||||
path: ''
|
||||
}, {
|
||||
text: '车辆派遣',
|
||||
img: '../../static/tab/cheliang.png',
|
||||
path: ''
|
||||
}, {
|
||||
text: '事项审批',
|
||||
img: '../../static/tab/shenpi.png',
|
||||
path: ''
|
||||
}]
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.log(err);
|
||||
})
|
||||
}
|
||||
const handleData = (arr) => {
|
||||
let arrMap = new Map()
|
||||
arr.forEach(el => {
|
||||
if (arrMap.has(el.gas)) {
|
||||
let obj = arrMap.get(el.gas)
|
||||
arrMap.set(el.gas, {
|
||||
...el,
|
||||
dailyVolume: Number(el.dailyVolume + +obj.dailyVolume).toFixed(4)
|
||||
})
|
||||
} else {
|
||||
arrMap.set(el.gas, el)
|
||||
}
|
||||
})
|
||||
return [...arrMap.values()]
|
||||
}
|
||||
const jump = (url) => {
|
||||
beforeJump(url, () => {
|
||||
if (!url) return
|
||||
uni.navigateTo({
|
||||
url
|
||||
})
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page {
|
||||
background-color: #F8F8F8;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
.nav {
|
||||
width: calc(100% - 60rpx);
|
||||
padding: 0 30rpx;
|
||||
height: v-bind(cusnavbarheight);
|
||||
|
||||
font-size: 24rpx;
|
||||
color: #FFFFFF;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 99;
|
||||
background-image: url('../../static/my/navbg.png');
|
||||
background-repeat: no-repeat;
|
||||
background-size: 750rpx 458rpx;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: v-bind(cusnavbarheight) 0 42rpx 0;
|
||||
}
|
||||
|
||||
.info {
|
||||
.item_box {
|
||||
|
||||
.item {
|
||||
width: 690rpx;
|
||||
background: #FFFFFF;
|
||||
box-shadow: 0rpx 2rpx 4rpx 0rpx rgba(0, 0, 0, 0.5);
|
||||
border-radius: 16rpx;
|
||||
padding: 30rpx 0;
|
||||
margin-top: 24rpx;
|
||||
|
||||
.title_box {
|
||||
padding: 0 30rpx;
|
||||
margin-bottom: -20rpx;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
background-image: url('../../static/index/line.png');
|
||||
background-size: 44rpx 13rpx;
|
||||
background-repeat: no-repeat;
|
||||
background-position: left bottom;
|
||||
|
||||
}
|
||||
|
||||
.more {
|
||||
font-size: 24rpx;
|
||||
color: #999999;
|
||||
|
||||
text {
|
||||
margin-right: 6rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.data_box {
|
||||
.data {
|
||||
width: 33.33%;
|
||||
margin-top: 60rpx;
|
||||
}
|
||||
|
||||
flex-wrap: wrap;
|
||||
|
||||
view {
|
||||
font-size: 32rpx;
|
||||
color: #333333;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
text {
|
||||
font-size: 24rpx;
|
||||
color: #333333;
|
||||
}
|
||||
}
|
||||
|
||||
.other {
|
||||
margin-bottom: -10rpx;
|
||||
}
|
||||
|
||||
.other_box {
|
||||
flex-wrap: wrap;
|
||||
|
||||
.data {
|
||||
width: 25%;
|
||||
margin-top: 40rpx;
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
|
||||
image {
|
||||
width: 98rpx;
|
||||
height: 98rpx;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
120
pages/talk/conversation.vue
Normal file
@ -0,0 +1,120 @@
|
||||
<template>
|
||||
<view :class="['content',{'gray':store.isgray==1}]">
|
||||
<view class="list">
|
||||
<view class="item" v-for="item,i in 14" :key="i">
|
||||
<view class="left f-row aic" v-show="i%2==0">
|
||||
<view class="avatar f-row aic">
|
||||
<image src="../../static/system.png" mode=""></image>
|
||||
</view>
|
||||
|
||||
<view class="content">
|
||||
你今天在干嘛呢?为什么这么久不回我信息,真的生气了
|
||||
</view>
|
||||
</view>
|
||||
<view class="right f-row aic" v-show="i%2!=0">
|
||||
<view class="content">
|
||||
请问如何退款?
|
||||
</view>
|
||||
<view class="avatar f-row aic">
|
||||
<image src="" mode=""></image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="input_box f-row aic jce">
|
||||
<input type="text" placeholder="请输入内容......" placeholder-style="font-size: 28rpx;color: #999999;" />
|
||||
<view class="send">
|
||||
发送
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
useStore
|
||||
} from '@/store';
|
||||
const store = useStore();
|
||||
</script>
|
||||
<style>
|
||||
page {
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.content {
|
||||
padding-bottom: 120rpx;
|
||||
}
|
||||
|
||||
.input_box {
|
||||
position: fixed;
|
||||
width: 750rpx;
|
||||
height: 120rpx;
|
||||
background: #FFFFFF;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
|
||||
input {
|
||||
width: 467rpx;
|
||||
height: 80rpx;
|
||||
background: #F8F8F8;
|
||||
border-radius: 8rpx;
|
||||
padding: 0 30rpx;
|
||||
|
||||
}
|
||||
|
||||
.send {
|
||||
width: 133rpx;
|
||||
height: 80rpx;
|
||||
background: #01508B;
|
||||
border-radius: 8rpx;
|
||||
text-align: center;
|
||||
line-height: 80rpx;
|
||||
font-size: 28rpx;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.list {
|
||||
padding: 40rpx 30rpx;
|
||||
|
||||
.item:not(:first-child) {
|
||||
margin-top: 60rpx;
|
||||
}
|
||||
|
||||
.item {
|
||||
image {
|
||||
width: 86rpx;
|
||||
height: 86rpx;
|
||||
border-radius: 50%;
|
||||
background-color: maroon;
|
||||
}
|
||||
|
||||
.left {
|
||||
.content {
|
||||
padding: 24rpx 30rpx;
|
||||
background: #FFFFFF;
|
||||
border-radius: 0rpx 16rpx 16rpx 16rpx;
|
||||
margin-left: 24rpx;
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
justify-content: flex-end;
|
||||
|
||||
.content {
|
||||
margin-right: 24rpx;
|
||||
padding: 24rpx 30rpx;
|
||||
background: #01508B;
|
||||
border-radius: 16rpx 0rpx 16rpx 16rpx;
|
||||
font-size: 28rpx;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
105
pages/talk/message_list.vue
Normal file
@ -0,0 +1,105 @@
|
||||
<template>
|
||||
<view :class="{'gray':store.isgray==1}">
|
||||
<view class="list">
|
||||
<view class="item f-row aic">
|
||||
<view class="f-row aic">
|
||||
<image src="../../static/system.png" mode=""></image>
|
||||
</view>
|
||||
<view class="name_info">
|
||||
<view class="name_time f-row aic jcb">
|
||||
<view class="name">
|
||||
系统通知
|
||||
</view>
|
||||
<view class="time">
|
||||
1分钟前
|
||||
</view>
|
||||
</view>
|
||||
<view class="info">
|
||||
关于年假通知关于年假通知关于年假通知关于年假通知关于年假通知关于年假通知关于年假通知
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="item f-row aic" v-for="item,i in 5" :key="i" @click="jump('/pages/talk/conversation')">
|
||||
<view class="f-row aic">
|
||||
<image src="" mode=""></image>
|
||||
</view>
|
||||
<view class="name_info">
|
||||
<view class="name_time f-row aic jcb">
|
||||
<view class="name">
|
||||
系统通知
|
||||
</view>
|
||||
<view class="time">
|
||||
1分钟前
|
||||
</view>
|
||||
</view>
|
||||
<view class="info">
|
||||
关于年假通知
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
beforeJump
|
||||
} from '@/utils/index.js';
|
||||
import {
|
||||
useStore
|
||||
} from '@/store';
|
||||
const store = useStore();
|
||||
const jump = (url) => {
|
||||
beforeJump(url, () => {
|
||||
uni.navigateTo({
|
||||
url
|
||||
})
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.list {
|
||||
padding: 0 30rpx;
|
||||
}
|
||||
|
||||
.item:not(:last-child) {
|
||||
border-bottom: 1px solid #EFEFEF;
|
||||
}
|
||||
|
||||
.item {
|
||||
height: 150rpx;
|
||||
|
||||
|
||||
.name_info {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.name {
|
||||
font-size: 32rpx;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.info {
|
||||
margin-top: 4rpx;
|
||||
width: 540rpx;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.time,
|
||||
.info {
|
||||
font-size: 28rpx;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
image {
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
border-radius: 50%;
|
||||
background-color: #f8f8f8;
|
||||
margin-right: 24rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
60
pages/talk/system.vue
Normal file
@ -0,0 +1,60 @@
|
||||
<template>
|
||||
<view :class="['content',{'gray':store.isgray==1}]">
|
||||
<view class="list">
|
||||
<view class="item" v-for="item,i in 3" :key="i">
|
||||
<view class="left f-row aic">
|
||||
<view class="avatar f-row aic">
|
||||
<image src="../../static/system.png" mode=""></image>
|
||||
</view>
|
||||
<view class="content">
|
||||
你今天在干嘛呢?为什么这么久不回我信息,真的生气了
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
useStore
|
||||
} from '@/store';
|
||||
const store = useStore();
|
||||
</script>
|
||||
<style>
|
||||
page {
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.content{
|
||||
padding-bottom: 120rpx;
|
||||
}
|
||||
.list {
|
||||
padding: 40rpx 30rpx;
|
||||
|
||||
.item:not(:first-child) {
|
||||
margin-top: 60rpx;
|
||||
}
|
||||
|
||||
.item {
|
||||
image {
|
||||
width: 86rpx;
|
||||
height: 86rpx;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.left {
|
||||
.content {
|
||||
padding: 24rpx 30rpx;
|
||||
background: #FFFFFF;
|
||||
border-radius: 0rpx 16rpx 16rpx 16rpx;
|
||||
margin-left: 24rpx;
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
374
pages/task/handle.vue
Normal file
@ -0,0 +1,374 @@
|
||||
<template>
|
||||
<view :class="['content',{'gray':store.isgray==1}]">
|
||||
<customNav>
|
||||
<view class="f-row aic box">
|
||||
<view class="back" @click="back">
|
||||
<uni-icons type="left" size="20" color="#fff"></uni-icons>
|
||||
</view>
|
||||
<view class="avatar">
|
||||
<image :src="imgUrl(store.userinfo.avatar)" mode=""></image>
|
||||
</view>
|
||||
<view class="name">
|
||||
{{taskInfo.processApplyUserName}}的{{taskInfo.processDefinitionName}}
|
||||
</view>
|
||||
<view class="status" v-if="type==0">
|
||||
待审批
|
||||
</view>
|
||||
<view class="status" v-if="type==1" style="background-color: #7AC756;">
|
||||
已处理
|
||||
</view>
|
||||
</view>
|
||||
</customNav>
|
||||
<component :is="comp" :dataId="dataId"></component>
|
||||
<view class="btn f-row aic jcb" v-if="type == 0">
|
||||
<view class="refuse" @click="openpop(1)">
|
||||
拒绝
|
||||
</view>
|
||||
<view class="agree" @click="openpop(2)">
|
||||
同意
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<uni-popup ref="popup" type="center">
|
||||
<view class="popup">
|
||||
<view class="title">
|
||||
审批意见
|
||||
</view>
|
||||
<view class="f-col aic">
|
||||
<view class="input f-col">
|
||||
<textarea v-model="reason" name="" id="" maxlength="200" placeholder="请输入"></textarea>
|
||||
<view class="">
|
||||
{{reason.length}}/200
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="status==2" class="agree_operate f-row aic" @click="chooseNextPerson=!chooseNextPerson">
|
||||
<image v-if="chooseNextPerson" src="../../static/login/checked.png" mode=""></image>
|
||||
<image v-else src="../../static/login/nocheck.png" mode=""></image>
|
||||
<view class="">
|
||||
指定下一步操作人
|
||||
</view>
|
||||
</view>
|
||||
<view class="" v-else>
|
||||
<picker :value="currentnode" :range="stepNode" range-key="NAME_" @change="nodeChange">
|
||||
<view class="node">{{currentnode!=null?stepNode[currentnode].NAME_:'请选择驳回节点'}}</view>
|
||||
</picker>
|
||||
</view>
|
||||
<view class="popbtn f-row aic">
|
||||
<view class="cancel" @click="closepop">
|
||||
取消
|
||||
</view>
|
||||
<view class="confirm" @click="handleProcess">
|
||||
确定
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</uni-popup>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref,
|
||||
getCurrentInstance
|
||||
} from 'vue';
|
||||
import {
|
||||
onLoad
|
||||
} from '@dcloudio/uni-app';
|
||||
import {
|
||||
getProcessNodeInfoApi,
|
||||
processCompleteApi,
|
||||
getProcessTaskTransInfoApi,
|
||||
getHisProcessNodeInfoApi,
|
||||
} from '@/api/api.js';
|
||||
import {
|
||||
beforeJump
|
||||
} from '@/utils/index.js';
|
||||
import customNav from '../../bpm/customNav.vue';
|
||||
import {
|
||||
imgUrl
|
||||
} from '@/utils/index.js';
|
||||
import {
|
||||
useStore
|
||||
} from '@/store';
|
||||
const store = useStore()
|
||||
const {
|
||||
proxy
|
||||
} = getCurrentInstance()
|
||||
const popup = ref(null)
|
||||
const reason = ref('')
|
||||
/**拒绝(1)||同意(2)*/
|
||||
const status = ref(null)
|
||||
const openpop = (val) => {
|
||||
status.value = val
|
||||
popup.value.open()
|
||||
reason.value = val == 2 ? '同意' : ''
|
||||
}
|
||||
const closepop = () => {
|
||||
popup.value.close()
|
||||
}
|
||||
const comp = ref(null)
|
||||
const dataId = ref('')
|
||||
const getProcessNodeInfo = (taskId) => {
|
||||
getProcessNodeInfoApi({
|
||||
taskId
|
||||
}).then((res) => {
|
||||
if (res.success) {
|
||||
dataId.value = res.result.dataId
|
||||
comp.value = res.result.formUrlMobile
|
||||
}
|
||||
})
|
||||
}
|
||||
const back = () => {
|
||||
uni.navigateBack()
|
||||
}
|
||||
/**是否指定下一步操作人*/
|
||||
const chooseNextPerson = ref(false)
|
||||
let nextnode = null
|
||||
/**流程办理判断*/
|
||||
const handleProcess = () => {
|
||||
// if (!reason.value.trim()) return proxy.$toast('请输入审批意见')
|
||||
let params = {}
|
||||
if (status.value == 1) { // 拒绝
|
||||
if (currentnode.value == null) return proxy.$toast('请选择驳回节点')
|
||||
params.processModel = 3
|
||||
params.rejectModelNode = stepNode.value[currentnode.value].TASK_DEF_KEY_
|
||||
processComplete(params)
|
||||
} else { // 同意
|
||||
if (chooseNextPerson.value) { //去选下一步操作人
|
||||
beforeJump('/pages/userlist/index', () => {
|
||||
closepop()
|
||||
uni.navigateTo({
|
||||
url: `/pages/userlist/index?id=${taskInfo.value.id}&isradio=1&nextnode=${JSON.stringify(nextnode)}&reason=${reason.value}`
|
||||
})
|
||||
})
|
||||
} else {
|
||||
params.processModel = 1
|
||||
processComplete(params)
|
||||
}
|
||||
}
|
||||
}
|
||||
/**流程办理接口*/
|
||||
const processComplete = (params) => {
|
||||
processCompleteApi({
|
||||
taskId: taskInfo.value.id,
|
||||
reason: reason.value,
|
||||
...params
|
||||
}).then((res) => {
|
||||
if (res.success) {
|
||||
proxy.$toast(res.message)
|
||||
setTimeout(() => {
|
||||
uni.navigateBack()
|
||||
}, 2000)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
/**审批流程节点*/
|
||||
const stepNode = ref([])
|
||||
/**当前选择的节点*/
|
||||
const currentnode = ref(null)
|
||||
/**切换节点*/
|
||||
const nodeChange = (e) => {
|
||||
currentnode.value = e.detail.value
|
||||
}
|
||||
|
||||
const getProcessTaskTransInfo = (e) => {
|
||||
getProcessTaskTransInfoApi({
|
||||
taskId: taskInfo.value.id
|
||||
}).then((res) => {
|
||||
if (res.success) {
|
||||
stepNode.value = res.result.histListNode
|
||||
nextnode = res.result.transitionList
|
||||
}
|
||||
})
|
||||
}
|
||||
/**历史任务详情*/
|
||||
const getHisProcessNodeInfo = (procInstId) => {
|
||||
getHisProcessNodeInfoApi({
|
||||
procInstId
|
||||
}).then((res) => {
|
||||
if (res.success) {
|
||||
dataId.value = res.result.dataId
|
||||
comp.value = res.result.formUrlMobile
|
||||
}
|
||||
})
|
||||
}
|
||||
const taskInfo = ref(null)
|
||||
let type = null
|
||||
onLoad((options) => {
|
||||
taskInfo.value = JSON.parse(options.info)
|
||||
type = options.type
|
||||
if (type == 1 || type == 2) {
|
||||
return getHisProcessNodeInfo(taskInfo.value.processInstanceId)
|
||||
}
|
||||
getProcessNodeInfo(taskInfo.value.id)
|
||||
getProcessTaskTransInfo()
|
||||
|
||||
})
|
||||
</script>
|
||||
<style>
|
||||
page {
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
.popup {
|
||||
width: 690rpx;
|
||||
background: #FFFFFF;
|
||||
border-radius: 8rpx;
|
||||
|
||||
.node {
|
||||
margin: 24rpx;
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
padding: 0 20rpx;
|
||||
}
|
||||
|
||||
.agree_operate {
|
||||
padding: 24rpx;
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
|
||||
image {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 32rpx;
|
||||
color: #000000;
|
||||
text-align: center;
|
||||
padding: 40rpx 0;
|
||||
}
|
||||
|
||||
.input {
|
||||
width: 582rpx;
|
||||
height: 226rpx;
|
||||
background: #F8F8F8;
|
||||
border-radius: 8rpx;
|
||||
padding: 24rpx;
|
||||
|
||||
textarea {
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
view {
|
||||
text-align: right;
|
||||
font-size: 28rpx;
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
|
||||
.popbtn {
|
||||
font-size: 32rpx;
|
||||
border-top: 1px solid #E5E5E5;
|
||||
margin-top: 40rpx;
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
position: absolute;
|
||||
content: ' ';
|
||||
height: 100rpx;
|
||||
width: 1px;
|
||||
background-color: #E5E5E5;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
view {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
height: 100rpx;
|
||||
line-height: 100rpx;
|
||||
}
|
||||
|
||||
.cancel {
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
.confirm {
|
||||
color: #007FFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
|
||||
// margin-top: 88rpx;
|
||||
padding-bottom: 120rpx;
|
||||
}
|
||||
|
||||
.btn {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
width: 690rpx;
|
||||
height: 120rpx;
|
||||
background: #FFFFFF;
|
||||
padding: 0 30rpx;
|
||||
|
||||
view {
|
||||
|
||||
width: 330rpx;
|
||||
height: 88rpx;
|
||||
font-size: 28rpx;
|
||||
border-radius: 16rpx;
|
||||
text-align: center;
|
||||
line-height: 88rpx;
|
||||
}
|
||||
|
||||
.refuse {
|
||||
box-sizing: border-box;
|
||||
background: #FFFFFF;
|
||||
border: 2rpx solid #01508B;
|
||||
color: #01508B;
|
||||
}
|
||||
|
||||
.agree {
|
||||
background: #01508B;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.box {
|
||||
position: absolute;
|
||||
bottom: 12rpx;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.back {
|
||||
padding-left: 30rpx;
|
||||
}
|
||||
|
||||
image {
|
||||
width: 64rpx;
|
||||
height: 64rpx;
|
||||
border-radius: 32rpx;
|
||||
background-color: #fff;
|
||||
margin-right: 16rpx;
|
||||
margin-left: 50rpx;
|
||||
}
|
||||
|
||||
.name {
|
||||
font-size: 28rpx;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
.status {
|
||||
padding: 4rpx 8rpx;
|
||||
display: inline-block;
|
||||
background-color: #FE4600;
|
||||
color: #FFFFFF;
|
||||
font-size: 20rpx;
|
||||
margin-left: 8rpx;
|
||||
border-radius: 8rpx;
|
||||
|
||||
}
|
||||
</style>
|
||||
184
pages/task/index.vue
Normal file
@ -0,0 +1,184 @@
|
||||
<template>
|
||||
<view :class="{'gray':store.isgray==1}">
|
||||
<view class="nav">
|
||||
<view class="tab_box f-row aic jca">
|
||||
<view :class="{'active':i==currentIndex}" v-for="item,i in tabArr" :key="i" @click="change(i)">
|
||||
{{item.text}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="tasklist">
|
||||
<tasklistCom @jump="jump" :taskArr="taskArr" :currentIndex="currentIndex"></tasklistCom>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref
|
||||
} from 'vue';
|
||||
import tasklistCom from '../../bpm/tasklistCom.vue';
|
||||
import { toast } from '@/utils/index.js';
|
||||
import {
|
||||
taskListApi,
|
||||
taskHistoryListApi
|
||||
} from '@/api/api.js';
|
||||
import {
|
||||
onLoad,
|
||||
onShow,
|
||||
onReachBottom,
|
||||
onPullDownRefresh
|
||||
} from '@dcloudio/uni-app';
|
||||
import {
|
||||
beforeJump
|
||||
} from '@/utils/index.js';
|
||||
import {
|
||||
useStore
|
||||
} from '@/store';
|
||||
const store = useStore()
|
||||
let processDefinitionName = ''
|
||||
onLoad((options) => {
|
||||
currentIndex.value = +options.id
|
||||
processDefinitionName = options.title
|
||||
})
|
||||
onShow(() => {
|
||||
taskArr.value = []
|
||||
pageNo = 1
|
||||
pageSize = 10
|
||||
loading = false
|
||||
taskList()
|
||||
})
|
||||
const tabArr = ref([{
|
||||
text: '我的任务',
|
||||
id: 0
|
||||
},
|
||||
{
|
||||
text: '历史任务',
|
||||
id: 1
|
||||
}])
|
||||
const date = ref('')
|
||||
const currentIndex = ref(0)
|
||||
let pageNo = 1
|
||||
let pageSize = 10
|
||||
let loading = false
|
||||
const taskArr = ref([])
|
||||
const taskList = () => {
|
||||
loading = true
|
||||
uni.showLoading({
|
||||
title: '加载中...'
|
||||
})
|
||||
let getlist = currentIndex.value == 0 ? taskListApi : taskHistoryListApi
|
||||
getlist({
|
||||
// createTime: date.value ? date.value + ' 00:00:00' : '',
|
||||
pageNo,
|
||||
pageSize,
|
||||
_t: new Date().getTime(),
|
||||
processDefinitionName
|
||||
}).then((res) => {
|
||||
if (res.success) {
|
||||
if (!res.result.records.length) return toast('没有更多了~')
|
||||
taskArr.value = [...taskArr.value, ...(res?.result?.records || [])]
|
||||
loading = false
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.log(err);
|
||||
})
|
||||
}
|
||||
|
||||
const change = (i) => {
|
||||
taskArr.value = []
|
||||
pageNo = 1
|
||||
pageSize = 10
|
||||
loading = false
|
||||
currentIndex.value = i
|
||||
taskList()
|
||||
}
|
||||
const chooseTime = () => {
|
||||
taskArr.value = []
|
||||
taskList()
|
||||
}
|
||||
onReachBottom(() => {
|
||||
if (loading) return
|
||||
pageNo++
|
||||
taskList()
|
||||
})
|
||||
onPullDownRefresh(() => {
|
||||
pageNo = 1
|
||||
pageSize = 10
|
||||
loading = false
|
||||
taskArr.value = []
|
||||
taskList()
|
||||
uni.stopPullDownRefresh()
|
||||
})
|
||||
const jump = (url) => {
|
||||
beforeJump(url, () => {
|
||||
uni.navigateTo({
|
||||
url
|
||||
})
|
||||
})
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
page {
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
.tasklist {
|
||||
padding-top: 100rpx;
|
||||
}
|
||||
|
||||
.nav {
|
||||
background-color: #fff;
|
||||
// height: 200rpx;
|
||||
height: 100rpx;
|
||||
width: 100vw;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 99;
|
||||
|
||||
.tab_box {
|
||||
padding: 24rpx 0;
|
||||
|
||||
view {
|
||||
position: relative;
|
||||
font-size: 28rpx;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.active {
|
||||
font-size: 28rpx;
|
||||
color: #01508B;
|
||||
|
||||
&::after {
|
||||
position: absolute;
|
||||
width: 230rpx;
|
||||
height: 2rpx;
|
||||
background: #01508B;
|
||||
content: ' ';
|
||||
bottom: -22rpx;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.time_box {
|
||||
padding: 20rpx 0;
|
||||
|
||||
.time {
|
||||
padding: 0 30rpx;
|
||||
width: 630rpx;
|
||||
height: 72rpx;
|
||||
background: #F8F8F8;
|
||||
border-radius: 8rpx;
|
||||
|
||||
image {
|
||||
width: 34rpx;
|
||||
height: 34rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
79
pages/task/self.vue
Normal file
@ -0,0 +1,79 @@
|
||||
<template>
|
||||
<view :class="{'gray':store.isgray==1}">
|
||||
<tasklistCom @jump="jump" :taskArr="taskArr" :currentIndex="2"></tasklistCom>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
beforeJump
|
||||
} from '@/utils/index.js';
|
||||
import tasklistCom from '../../bpm/tasklistCom.vue';
|
||||
import {
|
||||
ref
|
||||
} from 'vue';
|
||||
import {
|
||||
onLoad,
|
||||
onReachBottom
|
||||
} from '@dcloudio/uni-app';
|
||||
import {
|
||||
useStore
|
||||
} from '@/store';
|
||||
import {
|
||||
myApplyProcessListApi
|
||||
} from '@/api/api.js';
|
||||
import { toast } from '@/utils/index.js';
|
||||
const store = useStore()
|
||||
const taskArr = ref([])
|
||||
let processName = ''
|
||||
onLoad((options) => {
|
||||
processName = options.title
|
||||
getmyApply()
|
||||
})
|
||||
let pageNo = 1
|
||||
let pageSize = 10
|
||||
let loading = false
|
||||
const getmyApply = () => {
|
||||
loading = true
|
||||
uni.showLoading({
|
||||
title:'加载中...'
|
||||
})
|
||||
myApplyProcessListApi({
|
||||
pageNo,
|
||||
pageSize,
|
||||
_t: new Date().getTime(),
|
||||
processName
|
||||
}).then((res) => {
|
||||
if (res.success) {
|
||||
if(!res.result.records.length)return toast('没有更多了~')
|
||||
let arr = res.result.records
|
||||
arr.map((item) => {
|
||||
item['processApplyUserName'] = item['startUserName']
|
||||
item['processDefinitionName'] = item['prcocessDefinitionName']
|
||||
item['taskBeginTime'] = item['startTime']
|
||||
})
|
||||
taskArr.value = [...taskArr.value, ...arr]
|
||||
loading = false
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.log(err);
|
||||
})
|
||||
|
||||
}
|
||||
const jump = (url) => {
|
||||
beforeJump(url, () => {
|
||||
uni.navigateTo({
|
||||
url
|
||||
})
|
||||
})
|
||||
}
|
||||
onReachBottom(() => {
|
||||
if (loading) return
|
||||
pageNo++
|
||||
getmyApply()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
||||
264
pages/task/todotask.vue
Normal file
@ -0,0 +1,264 @@
|
||||
<template>
|
||||
<view :class="[{'gray':store.isgray==1}]">
|
||||
<view class="nav"></view>
|
||||
<view class="placeholder"></view>
|
||||
<view class="content">
|
||||
<extendCom title="我的任务" img="process" :list="todoArr" :total="todoTotal" type="0"></extendCom>
|
||||
<extendCom title="历史任务" img="done" :list="doneArr" :total="doneTotal" type="1"></extendCom>
|
||||
<extendCom title="本人发起" img="self" :list="selfArr" :total="selfTotal" type="2"></extendCom>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const res = wx.getSystemInfoSync();
|
||||
const statusHeight = res.statusBarHeight; //状态栏高度
|
||||
const cusnavbarheight = (statusHeight + 44) + "px";
|
||||
import extendCom from '../../bpm/extendCom.vue';
|
||||
import {
|
||||
ref
|
||||
} from 'vue';
|
||||
import {
|
||||
taskListApi,
|
||||
myApplyProcessListApi,
|
||||
taskHistoryListApi
|
||||
} from '@/api/api.js';
|
||||
import {
|
||||
onShow,
|
||||
onReachBottom,
|
||||
onPullDownRefresh
|
||||
} from '@dcloudio/uni-app';
|
||||
import {
|
||||
useStore
|
||||
} from '@/store'
|
||||
const store = useStore()
|
||||
onShow(() => {
|
||||
initArr()
|
||||
taskList()
|
||||
taskHistoryList()
|
||||
myApplyProcessList()
|
||||
uni.removeTabBarBadge({ // 移除角标
|
||||
index: '1',
|
||||
});
|
||||
})
|
||||
const todoArr = ref([])
|
||||
const todoTotal = ref(0)
|
||||
/**待办事项*/
|
||||
const taskList = () => {
|
||||
taskListApi({
|
||||
pageNo: 1,
|
||||
pageSize: 4,
|
||||
_t: new Date().getTime()
|
||||
}).then((res) => {
|
||||
if (res?.success) {
|
||||
if (res?.result?.total > 4) {
|
||||
taskListApi({
|
||||
pageNo: 1,
|
||||
pageSize: res?.result?.total,
|
||||
_t: new Date().getTime()
|
||||
}).then((res1) => {
|
||||
console.log('---', res1)
|
||||
if (res1?.success) {
|
||||
todoArr.value = [...todoArr.value, ...handleData(res1?.result?.records)]
|
||||
todoTotal.value = res1?.result?.total
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.log('err', err);
|
||||
})
|
||||
|
||||
} else {
|
||||
todoArr.value = [...todoArr.value, ...handleData(res?.result?.records)]
|
||||
todoTotal.value = res?.result?.total
|
||||
}
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.log(err);
|
||||
})
|
||||
|
||||
}
|
||||
const doneArr = ref([])
|
||||
const doneTotal = ref(0)
|
||||
/**已办事项*/
|
||||
const taskHistoryList = () => {
|
||||
taskHistoryListApi().then((res) => {
|
||||
if (res.success) {
|
||||
if (res.result.total > 4) {
|
||||
taskHistoryListApi({
|
||||
pageNo: 1,
|
||||
pageSize: res.result.total,
|
||||
_t: new Date().getTime()
|
||||
}).then((res1) => {
|
||||
if (res1.success) {
|
||||
doneArr.value = [...doneArr.value, ...handleData(res1.result.records)]
|
||||
doneTotal.value = res1.result.total
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.log(err);
|
||||
})
|
||||
|
||||
} else {
|
||||
doneArr.value = [...doneArr.value, ...handleData(res.result.records)]
|
||||
doneTotal.value = res.result.total
|
||||
}
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.log(err);
|
||||
})
|
||||
}
|
||||
const selfArr = ref([])
|
||||
const selfTotal = ref(0)
|
||||
/**本人发起*/
|
||||
const myApplyProcessList = () => {
|
||||
myApplyProcessListApi().then((res) => {
|
||||
if (res.success) {
|
||||
if (res.result.total > 4) {
|
||||
myApplyProcessListApi({
|
||||
pageNo: 1,
|
||||
pageSize: res.result.total,
|
||||
_t: new Date().getTime()
|
||||
}).then((res1) => {
|
||||
if (res1.success) {
|
||||
selfArr.value = [...selfArr.value, ...handleData(res1.result.records)]
|
||||
selfTotal.value = res1.result.total
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.log(err);
|
||||
})
|
||||
|
||||
} else {
|
||||
|
||||
selfArr.value = [...selfArr.value, ...handleData(res.result.records)]
|
||||
selfTotal.value = res.result.total
|
||||
}
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.log(err);
|
||||
})
|
||||
}
|
||||
const handleData = (titlearr) => {
|
||||
let titleArr = titlearr.length ? titlearr.map(item => item.processDefinitionName || item
|
||||
.prcocessDefinitionName) : []
|
||||
let res = titleArr.reduce((obj, title) => {
|
||||
if (title in obj) {
|
||||
obj[title]++
|
||||
} else {
|
||||
obj[title] = 1
|
||||
}
|
||||
return obj
|
||||
}, {})
|
||||
return Object.entries(res).map(([k, v]) => ({
|
||||
title: k,
|
||||
num: v
|
||||
}))
|
||||
}
|
||||
|
||||
const initArr = () => {
|
||||
todoArr.value = []
|
||||
selfArr.value = []
|
||||
doneArr.value = []
|
||||
todoTotal.value = 0
|
||||
doneTotal.value = 0
|
||||
selfTotal.value = 0
|
||||
}
|
||||
|
||||
let loading = false
|
||||
onPullDownRefresh(() => {
|
||||
loading = false
|
||||
initArr()
|
||||
taskList()
|
||||
taskHistoryList()
|
||||
myApplyProcessList()
|
||||
uni.stopPullDownRefresh()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.drag {
|
||||
background: #FFFFFF;
|
||||
box-shadow: 0rpx 2rpx 4rpx 0rpx rgba(0, 0, 0, 0.5);
|
||||
border-radius: 16rpx;
|
||||
margin: 24rpx 30rpx 0 30rpx;
|
||||
|
||||
.title {
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
padding: 30rpx 0 0 30rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.inner {
|
||||
image {
|
||||
width: 98rpx;
|
||||
height: 98rpx;
|
||||
background-color: #efefef;
|
||||
}
|
||||
|
||||
.text {
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.placeholder {
|
||||
height: v-bind(cusnavbarheight);
|
||||
}
|
||||
|
||||
.nav {
|
||||
width: calc(100% - 60rpx);
|
||||
padding: 0 30rpx;
|
||||
height: v-bind(cusnavbarheight);
|
||||
|
||||
font-size: 24rpx;
|
||||
color: #FFFFFF;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 99;
|
||||
background-image: url('../../static/my/navbg.png');
|
||||
background-repeat: no-repeat;
|
||||
background-size: 750rpx 458rpx;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 0 30rpx 20rpx 30rpx;
|
||||
}
|
||||
|
||||
.list {
|
||||
margin-bottom: 24rpx;
|
||||
|
||||
.item {
|
||||
background: #FFFFFF;
|
||||
box-shadow: 0rpx 2rpx 4rpx 0rpx rgba(0, 0, 0, 0.5);
|
||||
border-radius: 16rpx;
|
||||
padding: 30rpx 0;
|
||||
margin-top: 24rpx;
|
||||
|
||||
.title {
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
padding-left: 30rpx;
|
||||
}
|
||||
}
|
||||
|
||||
image {
|
||||
width: 98rpx;
|
||||
height: 98rpx;
|
||||
}
|
||||
|
||||
.info_box {
|
||||
flex-wrap: wrap;
|
||||
|
||||
.info {
|
||||
margin-top: 40rpx;
|
||||
width: 25%;
|
||||
|
||||
.text {
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
106
pages/useredit/add_address.vue
Normal file
@ -0,0 +1,106 @@
|
||||
<template>
|
||||
<view :class="['content',{'gray':store.isgray==1}]">
|
||||
<view class="area f-row jcb">
|
||||
<view class="title topic">
|
||||
所在地区
|
||||
</view>
|
||||
<input type="text" placeholder="省、市、区、街道" />
|
||||
</view>
|
||||
<view class="area f-row jcb">
|
||||
<view class="title topic">
|
||||
详细地址
|
||||
</view>
|
||||
<textarea placeholder="小区楼栋/乡村名称"></textarea>
|
||||
</view>
|
||||
<view class="area f-row jcb">
|
||||
<view class="title">
|
||||
设为默认地址
|
||||
</view>
|
||||
<image src="../../static/login/checked.png" mode=""></image>
|
||||
<!-- <image src="../../static/login/nocheck.png" mode=""></image> -->
|
||||
</view>
|
||||
<view class="btn f-col aic">
|
||||
<view class="">
|
||||
保存
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
useStore
|
||||
} from '@/store'
|
||||
const store = useStore()
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page {
|
||||
background-color: #fff;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
.content {
|
||||
padding: 30rpx 30rpx 120rpx 30rpx;
|
||||
}
|
||||
|
||||
.area:not(:first-child) {
|
||||
margin-top: 40rpx;
|
||||
}
|
||||
|
||||
.area {
|
||||
|
||||
image {
|
||||
width: 38rpx;
|
||||
height: 38rpx;
|
||||
}
|
||||
|
||||
|
||||
.topic {
|
||||
margin-top: 28rpx;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 32rpx;
|
||||
color: #333333;
|
||||
|
||||
}
|
||||
|
||||
input {
|
||||
width: 472rpx;
|
||||
height: 96rpx;
|
||||
background: #F6F6F6;
|
||||
border-radius: 16rpx;
|
||||
padding: 0 30rpx;
|
||||
}
|
||||
|
||||
textarea {
|
||||
width: 472rpx;
|
||||
height: 104rpx;
|
||||
background: #F6F6F6;
|
||||
border-radius: 16rpx;
|
||||
padding: 28rpx 30rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.btn {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
width: 750rpx;
|
||||
height: 120rpx;
|
||||
background: #FFFFFF;
|
||||
justify-content: center;
|
||||
left: 0;
|
||||
|
||||
view {
|
||||
width: 690rpx;
|
||||
height: 88rpx;
|
||||
background: #01508B;
|
||||
border-radius: 8rpx;
|
||||
font-size: 32rpx;
|
||||
color: #FFFFFF;
|
||||
text-align: center;
|
||||
line-height: 88rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
143
pages/useredit/address.vue
Normal file
@ -0,0 +1,143 @@
|
||||
<template>
|
||||
<view :class="['content',{'gray':store.isgray==1}]">
|
||||
<view class="list">
|
||||
<view class="item" v-for="item,i in 2" :key="i">
|
||||
<view class="province f-row aic">
|
||||
<view class="">
|
||||
浙江省,杭州市
|
||||
</view>
|
||||
<image src="../../static/my/default.png" mode=""></image>
|
||||
</view>
|
||||
<view class="address f-row jcb">
|
||||
<view class="">
|
||||
重庆 重庆市 渝北区 龙溪街道花卉园东路黄金
|
||||
宝高级住宅小区
|
||||
</view>
|
||||
<image src="../../static/my/edit.png" mode=""></image>
|
||||
</view>
|
||||
<view class="set f-row aic jcb">
|
||||
<view class="f-row aic">
|
||||
<!-- <image src="../../static/login/checked.png" mode=""></image> -->
|
||||
<image src="../../static/login/nocheck.png" mode=""></image>
|
||||
设为默认地址
|
||||
</view>
|
||||
<view class="">
|
||||
删除
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="btn f-col aic">
|
||||
<view class="" @click="jump('/pages/useredit/add_address')">
|
||||
+添加收货地址
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
beforeJump
|
||||
} from '@/utils/index.js';
|
||||
import {
|
||||
useStore
|
||||
} from '@/store'
|
||||
const store = useStore()
|
||||
const jump = (url) => {
|
||||
beforeJump(url, () => {
|
||||
uni.navigateTo({
|
||||
url
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page {
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
.content {
|
||||
padding-bottom: 120rpx;
|
||||
}
|
||||
|
||||
.list {
|
||||
padding: 30rpx;
|
||||
|
||||
.item:not(:first-child) {
|
||||
margin-top: 30rpx;
|
||||
}
|
||||
|
||||
.item {
|
||||
|
||||
padding: 30rpx;
|
||||
background: #FFFFFF;
|
||||
box-shadow: 0rpx 2rpx 4rpx 0rpx rgba(0, 0, 0, 0.5);
|
||||
border-radius: 16rpx;
|
||||
|
||||
.province {
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
margin-bottom: 10rpx;
|
||||
|
||||
image {
|
||||
width: 56rpx;
|
||||
height: 36rpx;
|
||||
margin-left: 16rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.address {
|
||||
font-size: 24rpx;
|
||||
color: #666666;
|
||||
padding-bottom: 30rpx;
|
||||
border-bottom: 1px solid #EFEFEF;
|
||||
|
||||
view {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
image {
|
||||
width: 28rpx;
|
||||
height: 30rpx;
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.set {
|
||||
margin-top: 30rpx;
|
||||
font-size: 24rpx;
|
||||
color: #666666;
|
||||
|
||||
image {
|
||||
width: 38rpx;
|
||||
height: 38rpx;
|
||||
margin-right: 12rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.btn {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
width: 750rpx;
|
||||
height: 120rpx;
|
||||
background: #FFFFFF;
|
||||
justify-content: center;
|
||||
|
||||
view {
|
||||
width: 690rpx;
|
||||
height: 88rpx;
|
||||
background: #01508B;
|
||||
border-radius: 8rpx;
|
||||
font-size: 32rpx;
|
||||
color: #FFFFFF;
|
||||
text-align: center;
|
||||
line-height: 88rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
65
pages/useredit/addressbook.vue
Normal file
@ -0,0 +1,65 @@
|
||||
<template>
|
||||
<view :class="{'gray':store.isgray==1}">
|
||||
<view class="list">
|
||||
<view class="item f-row aic jcb" v-for="item,i in 4" :key="i">
|
||||
<view class="user f-row aic">
|
||||
<image src="" mode=""></image>
|
||||
<view class="name_job">
|
||||
<view class="name">
|
||||
我是晴天
|
||||
</view>
|
||||
<view class="job">
|
||||
销售部-销售总监
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="btn">
|
||||
电话联系
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
useStore
|
||||
} from '@/store'
|
||||
const store = useStore()
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.list{
|
||||
padding: 0 30rpx;
|
||||
.item{
|
||||
padding: 30rpx 0;
|
||||
border-bottom: 1px solid #EFEFEF;
|
||||
image{
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
border-radius: 50rpx;
|
||||
background-color: #EFEFEF;
|
||||
margin-right: 30rpx;
|
||||
}
|
||||
.name{
|
||||
font-size: 32rpx;
|
||||
color: #333333;
|
||||
}
|
||||
.job{
|
||||
font-size: 24rpx;
|
||||
color: #999999;
|
||||
margin-top: 8rpx;
|
||||
}
|
||||
.btn{
|
||||
width: 132rpx;
|
||||
height: 60rpx;
|
||||
background: #01508B;
|
||||
border-radius: 8rpx;
|
||||
text-align: center;
|
||||
line-height: 60rpx;
|
||||
font-size: 24rpx;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
182
pages/useredit/useredit.vue
Normal file
@ -0,0 +1,182 @@
|
||||
<template>
|
||||
<view :class="['content',{'gray':store.isgray==1}]">
|
||||
<view class="box">
|
||||
<view>头像</view>
|
||||
<view style="display: flex;align-items: center;">
|
||||
<button class="head-btn" @click="chooseAvatar">
|
||||
<image class="head-img" v-if="!form.avatar" :src="imgUrl(store.userinfo.avatar)" mode="">
|
||||
</image>
|
||||
<image class="head-img" v-else :src="imgUrl(form.avatar)"></image>
|
||||
</button>
|
||||
<uni-icons type="right" size="24"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
<view class="box" style="padding-top: 30rpx;padding-bottom: 30rpx;">
|
||||
<view>姓名</view>
|
||||
<input disabled style="text-align: right;" type="nickname"
|
||||
placeholder-style="font-size: 32rpx;color: #999999;" v-model="store.userinfo.realname"
|
||||
placeholder="请输入姓名" />
|
||||
</view>
|
||||
<view class="box" style="padding-top: 30rpx;padding-bottom: 30rpx;">
|
||||
<view>手机号</view>
|
||||
<input style="text-align: right;" type="nickname" v-model="store.userinfo.phone"
|
||||
placeholder="请输入手机号" placeholder-style="font-size: 32rpx;color: #999999;" />
|
||||
</view>
|
||||
<view class="box" style="padding-top: 30rpx;padding-bottom: 30rpx;">
|
||||
<view>劳动合同号</view>
|
||||
<input style="text-align: right;" type="nickname" disabled v-model="store.userinfo.workNo"
|
||||
placeholder="请输入劳动合同号" placeholder-style="font-size: 32rpx;color: #999999;" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="line">
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
reactive,
|
||||
ref
|
||||
} from "vue";
|
||||
import {
|
||||
onLoad
|
||||
} from '@dcloudio/uni-app';
|
||||
import {
|
||||
userEditApi,
|
||||
} from '@/api/api.js';
|
||||
import {
|
||||
beforeJump,
|
||||
imgUrl
|
||||
} from '@/utils/index.js';
|
||||
import {
|
||||
useStore
|
||||
} from '@/store';
|
||||
const baseUrl = import.meta.env.VITE_REQUEST_BASE_URL + '/jeecg-boot/sys/common/upload'
|
||||
const store = useStore()
|
||||
|
||||
const jump = (url) => {
|
||||
beforeJump(url, () => {
|
||||
uni.navigateTo({
|
||||
url
|
||||
})
|
||||
})
|
||||
}
|
||||
const chooseAvatar = () => {
|
||||
uni.chooseImage({
|
||||
count: 1,
|
||||
success: (chooseImageRes) => {
|
||||
const tempFilePaths = chooseImageRes.tempFilePaths;
|
||||
const photoPath = '用户头像/' + store.userinfo.realname
|
||||
uni.uploadFile({
|
||||
url: baseUrl, //仅为示例,非真实的接口地址
|
||||
filePath: tempFilePaths[0],
|
||||
name: 'file',
|
||||
formData: {
|
||||
appPath: photoPath
|
||||
},
|
||||
success: (res) => {
|
||||
uni.showLoading({
|
||||
title: '上传中...'
|
||||
})
|
||||
form.avatar = JSON.parse(res.data).message
|
||||
userEditApi({
|
||||
avatar: form.avatar,
|
||||
id: store.userinfo.id
|
||||
}).then((res) => {
|
||||
if (res) {
|
||||
uni.showToast({
|
||||
title: res,
|
||||
icon: 'success',
|
||||
duration: 2000
|
||||
})
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.log(err);
|
||||
})
|
||||
},
|
||||
fail(err) {
|
||||
console.log('图片上传出错', err);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
const form = reactive({
|
||||
avatar: '',
|
||||
realname: '',
|
||||
phone: ''
|
||||
})
|
||||
onLoad(() => {
|
||||
uni.setNavigationBarColor({
|
||||
frontColor: "#ffffff",
|
||||
backgroundColor: '#bebebe'
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.choose {
|
||||
font-size: 32rpx;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.choosed {
|
||||
font-size: 32rpx;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
button::after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 30rpx 30rpx 0 30rpx;
|
||||
|
||||
.box:not(:last-child) {
|
||||
border-bottom: 1rpx solid #EFEFEF;
|
||||
}
|
||||
|
||||
.box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
font-size: 32rpx;
|
||||
color: #333333;
|
||||
|
||||
button {
|
||||
background-color: #fff;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: none;
|
||||
|
||||
image {
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
border-radius: 50%;
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
}
|
||||
|
||||
.value {
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
|
||||
.out_login {
|
||||
color: #ED361D;
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
margin-top: 60rpx;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.line {
|
||||
height: 10rpx;
|
||||
background: #F8F8F8;
|
||||
}
|
||||
|
||||
</style>
|
||||
338
pages/userlist/index.vue
Normal file
@ -0,0 +1,338 @@
|
||||
<template>
|
||||
<view :class="['content',{'gray':store.isgray==1}]">
|
||||
<uni-data-picker @popupclosed="popclose($event)" :step-searh="false" :map="{text:'departName',value:'id'}"
|
||||
:localdata="departList" popup-title="请选择部门" placeholder="请选择部门" @nodeclick="onnodeclick">
|
||||
</uni-data-picker>
|
||||
<view class="search_box">
|
||||
<view class="username f-row aic">
|
||||
用户姓名:<input v-model="realname" type="text" placeholder="请输入姓名"
|
||||
placeholder-style="color: grey;font-size: 28rpx;">
|
||||
</view>
|
||||
<view class="username f-row aic">
|
||||
用户账号:<input v-model="username" type="text" placeholder="请输入账号"
|
||||
placeholder-style="color: grey;font-size: 28rpx;">
|
||||
</view>
|
||||
<view class="btn f-row aic jca">
|
||||
<view class="f-row aic" @click="search">
|
||||
<uni-icons type="search" size="15" color="#fff"></uni-icons>
|
||||
查询
|
||||
</view>
|
||||
<view class="f-row aic" @click="refresh">
|
||||
<uni-icons type="refreshempty" size="15" color="#fff"></uni-icons>
|
||||
重置
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="list">
|
||||
<view class="title f-row aic box">
|
||||
<view class="">
|
||||
|
||||
</view>
|
||||
<view class="">
|
||||
序号
|
||||
</view>
|
||||
<view class="username">
|
||||
用户账号
|
||||
</view>
|
||||
<view class="">
|
||||
用户姓名
|
||||
</view>
|
||||
</view>
|
||||
<view class="item f-row aic box" v-for="item,i in userlist" :key="i">
|
||||
<view class="f-row aic img" @click="choose(item.id)">
|
||||
<image v-if="chooseArr.includes(item.id)" src="../../static/login/checked.png" mode=""></image>
|
||||
<image v-else src="../../static/login/nocheck.png" mode=""></image>
|
||||
</view>
|
||||
<view class="order">
|
||||
{{i+1}}
|
||||
</view>
|
||||
<view class="username f-col aic">
|
||||
<view class="">
|
||||
{{item.username}}
|
||||
</view>
|
||||
</view>
|
||||
<view class="realname">
|
||||
<view class="">
|
||||
{{item.realname}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="confirm f-col aic">
|
||||
<view class="" @click="handleprocess">
|
||||
确认
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
onLoad
|
||||
} from '@dcloudio/uni-app';
|
||||
import {
|
||||
ref,
|
||||
getCurrentInstance
|
||||
} from 'vue';
|
||||
import {
|
||||
queryMyDeptTreeListApi,
|
||||
queryUserByDepIdApi,
|
||||
taskEntrustApi,
|
||||
processCompleteApi
|
||||
} from '@/api/api.js';
|
||||
import {
|
||||
useStore
|
||||
} from '@/store';
|
||||
const store = useStore()
|
||||
const {
|
||||
proxy
|
||||
} = getCurrentInstance()
|
||||
const departList = ref([])
|
||||
/**部门列表*/
|
||||
const queryMyDeptTreeList = () => {
|
||||
queryMyDeptTreeListApi().then((res) => {
|
||||
departList.value = res.result
|
||||
currentId = res.result[0].id
|
||||
queryUserByDepId(res.result[0].id)
|
||||
}).catch((err) => {
|
||||
console.log(err);
|
||||
})
|
||||
}
|
||||
const userlist = ref([])
|
||||
/**根据部门查询人员*/
|
||||
const queryUserByDepId = (id, username, realname) => {
|
||||
queryUserByDepIdApi({
|
||||
id,
|
||||
username: username || '',
|
||||
realname: realname || ''
|
||||
}).then((res) => {
|
||||
if (res.success) {
|
||||
userlist.value = res.result
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.log(err);
|
||||
})
|
||||
}
|
||||
let currentId = null
|
||||
let departArr = []
|
||||
const onnodeclick = (e) => {
|
||||
queryUserByDepId(e.id)
|
||||
currentId = e.id
|
||||
if (departArr.indexOf(e.title) != -1) {
|
||||
departArr.splice(departArr.indexOf(e.title), 1, e.title)
|
||||
} else {
|
||||
departArr.push(e.title)
|
||||
|
||||
}
|
||||
}
|
||||
const popclose = (e) => {
|
||||
console.log('qqq', e);
|
||||
}
|
||||
const chooseArr = ref([])
|
||||
const choose = (id) => {
|
||||
if (isradio) { //单选
|
||||
if (chooseArr.value.indexOf(id) != -1) return
|
||||
chooseArr.value.splice(chooseArr.value.indexOf(id), 1, id)
|
||||
} else { //多选
|
||||
if (chooseArr.value.indexOf(id) != -1) {
|
||||
chooseArr.value.splice(chooseArr.value.indexOf(id), 1)
|
||||
} else {
|
||||
chooseArr.value.push(id)
|
||||
}
|
||||
}
|
||||
}
|
||||
/**0为多选,1单选*/
|
||||
let isradio = 0
|
||||
/**任务id*/
|
||||
let taskId = null
|
||||
/**nextnode*/
|
||||
let nextnode = null
|
||||
/**reason*/
|
||||
let reason = null
|
||||
onLoad((options) => {
|
||||
isradio = options.isradio
|
||||
taskId = options.id
|
||||
reason = options.reason
|
||||
if (options.nextnode) {
|
||||
nextnode = JSON.parse(options.nextnode)
|
||||
}
|
||||
queryMyDeptTreeList()
|
||||
|
||||
})
|
||||
const username = ref('')
|
||||
const realname = ref('')
|
||||
const search = () => {
|
||||
if (username.value.trim() || realname.value.trim()) {
|
||||
userlist.value = []
|
||||
queryUserByDepId(currentId, username.value, realname.value)
|
||||
}
|
||||
}
|
||||
const refresh = () => {
|
||||
username.value = ''
|
||||
realname.value = ''
|
||||
userlist.value = []
|
||||
queryUserByDepId(currentId, username.value, realname.value)
|
||||
}
|
||||
/**委托*/
|
||||
const taskEntrust = () => {
|
||||
if (!chooseArr.value.length) return proxy.$toast('请选择被委托人')
|
||||
taskEntrustApi({
|
||||
taskAssignee: userlist.value.filter(item => item.id == chooseArr.value[0])[0].username,
|
||||
taskId
|
||||
}).then((res) => {
|
||||
if (res.success) {
|
||||
proxy.$toast(res.message)
|
||||
setTimeout(() => {
|
||||
uni.navigateBack()
|
||||
}, 2000)
|
||||
}
|
||||
})
|
||||
}
|
||||
const handleprocess = () => {
|
||||
if (nextnode) {
|
||||
processComplete()
|
||||
} else {
|
||||
taskEntrust()
|
||||
}
|
||||
}
|
||||
/**流程办理接口*/
|
||||
const processComplete = () => {
|
||||
processCompleteApi({
|
||||
taskId,
|
||||
reason,
|
||||
processModel: 1,
|
||||
nextnode: nextnode[0].nextnode,
|
||||
nextUserName: userlist.value.filter(item => item.id == chooseArr.value[0])[0].realname,
|
||||
nextUserId: chooseArr.value[0],
|
||||
}).then((res) => {
|
||||
proxy.$toast(res.message)
|
||||
setTimeout(() => {
|
||||
uni.navigateBack()
|
||||
}, 2000)
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.content {
|
||||
padding-bottom: 130rpx;
|
||||
}
|
||||
|
||||
.confirm {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
background-color: #fff;
|
||||
border-top: 1px solid #efefef;
|
||||
width: 100%;
|
||||
padding: 20rpx 0;
|
||||
|
||||
view {
|
||||
width: 630rpx;
|
||||
height: 88rpx;
|
||||
background: #01508B;
|
||||
border-radius: 44rpx;
|
||||
font-size: 32rpx;
|
||||
color: #FFFFFF;
|
||||
text-align: center;
|
||||
line-height: 88rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.search_box {
|
||||
|
||||
font-size: 28rpx;
|
||||
|
||||
.username {
|
||||
padding: 0 20rpx;
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
height: 100rpx;
|
||||
|
||||
input {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.btn {
|
||||
color: #fff;
|
||||
padding: 20rpx 0;
|
||||
|
||||
view {
|
||||
width: 178rpx;
|
||||
height: 80rpx;
|
||||
background-color: #01508B;
|
||||
border-radius: 40rpx;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.list {
|
||||
word-break: break-all;
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
|
||||
.box {
|
||||
view:first-child {
|
||||
flex: 0.3;
|
||||
}
|
||||
|
||||
view:nth-child(2) {
|
||||
flex: 0.3;
|
||||
}
|
||||
|
||||
view:nth-child(3) {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
view:nth-child(4) {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
text-align: center;
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
background-color: #f8f8f8;
|
||||
height: 100rpx;
|
||||
}
|
||||
|
||||
.item {
|
||||
text-align: center;
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
|
||||
.order {
|
||||
border-right: 1px solid #e5e5e5;
|
||||
height: 100rpx;
|
||||
line-height: 100rpx;
|
||||
}
|
||||
|
||||
.username {
|
||||
border-right: 1px solid #e5e5e5;
|
||||
height: 100rpx;
|
||||
justify-content: center;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.realname {
|
||||
height: 100rpx;
|
||||
line-height: 100rpx;
|
||||
overflow-y: auto;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.img {
|
||||
border-right: 1px solid #e5e5e5;
|
||||
height: 100rpx;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
image {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
41
pages/views/renliziyuan/renyuanxinxi/index.vue
Normal file
@ -0,0 +1,41 @@
|
||||
<template>
|
||||
<view>
|
||||
<uni-card :is-shadow="false">
|
||||
<uni-section title="台账信息" type="line">
|
||||
<uni-card :is-shadow="false">
|
||||
<button type="primary" @click="getTaizhang">人员台账</button>
|
||||
</uni-card>
|
||||
</uni-section>
|
||||
<uni-section title="统计信息" type="line">
|
||||
<uni-card :is-shadow="false">
|
||||
<text class="uni-body">这是一个基础卡片示例,内容较少,此示例展示了一个没有任何属性不带阴影的卡片。</text>
|
||||
</uni-card>
|
||||
</uni-section>
|
||||
|
||||
</uni-card>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
components: {
|
||||
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getTaizhang() {
|
||||
uni.navigateTo({
|
||||
url:"/pages/views/renliziyuan/renyuanxinxi/taizhang"
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
183
pages/views/renliziyuan/renyuanxinxi/taizhang.vue
Normal file
@ -0,0 +1,183 @@
|
||||
<template>
|
||||
<view>
|
||||
<scroll-view :scroll-y="true">
|
||||
<uni-card>
|
||||
<uni-title title="" type="h1" align="center"></uni-title>
|
||||
<view>
|
||||
<uni-row>
|
||||
<uni-col :span="11"><uni-title title="姓名 " align="left" type="h5"></uni-title></uni-col>
|
||||
<uni-col :span="11" :push="2"><uni-title title="劳动合同号" align="left"
|
||||
type="h5"></uni-title></uni-col>
|
||||
</uni-row>
|
||||
<uni-row>
|
||||
<uni-col :span="11"><uni-easyinput v-model="xm" focus suffixIcon="search" placeholder="姓名模糊查询"
|
||||
@change="Search" @iconClick="Search" /></uni-col>
|
||||
<uni-col :span="11" :push="2">
|
||||
<uni-easyinput v-model="ldhth" focus suffixIcon="search" placeholder="劳动合同号模糊查询"
|
||||
@change="Search" @iconClick="Search" />
|
||||
</uni-col>
|
||||
</uni-row>
|
||||
</view>
|
||||
<view style="margin-bottom: 10rpx;">
|
||||
<uni-row>
|
||||
<uni-col :span="24"><uni-title title="所属单位" align="left" type="h5"></uni-title></uni-col>
|
||||
</uni-row>
|
||||
<uni-row>
|
||||
<uni-col :span="24">
|
||||
<trq-depart-select returnCodeOrID="orgCode" @change="departChange"></trq-depart-select>
|
||||
</uni-col>
|
||||
</uni-row>
|
||||
</view>
|
||||
</uni-card>
|
||||
<uni-card>
|
||||
{{rrr}}
|
||||
<zb-table :show-header="true" :highlight="true" :columns="column" :stripe="true" :fit="false"
|
||||
:border="true" :data="ryDataList"></zb-table>
|
||||
</uni-card>
|
||||
</scroll-view>
|
||||
<uni-load-more :status="status" :content-text="contentText"></uni-load-more>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
onReady,
|
||||
onLoad
|
||||
} from '@dcloudio/uni-app';
|
||||
import {
|
||||
reactive,
|
||||
ref
|
||||
} from 'vue';
|
||||
import {
|
||||
useStore
|
||||
} from '@/store';
|
||||
import {
|
||||
queryDepByCode,
|
||||
queryZbDepByLdhth
|
||||
} from '@/api/depart.js'
|
||||
import {
|
||||
queryRenyuanByDepartID
|
||||
} from '@/api/renyuan.js'
|
||||
let xm = ref("")
|
||||
let ldhth = ref("")
|
||||
let departID = ref("") //部门树选中的ID
|
||||
let ryDataList = ref([])
|
||||
let rrr=ref("")
|
||||
|
||||
let status = ref("false")
|
||||
let contentText = reactive({
|
||||
contentdown: '点击查看更多',
|
||||
contentrefresh: '加载中',
|
||||
contentnomore: '没有更多'
|
||||
})
|
||||
|
||||
let pageNo = ref(1)
|
||||
let pageSize = ref(10)
|
||||
let params = reactive({
|
||||
pageNo: pageNo,
|
||||
pageSize: pageSize
|
||||
})
|
||||
let column = ref([{
|
||||
label: '序号',
|
||||
width: 60,
|
||||
type: 'index',
|
||||
color: 'blue',
|
||||
align: 'center'
|
||||
},
|
||||
|
||||
{
|
||||
name: 'xm',
|
||||
label: '姓名',
|
||||
width: 70,
|
||||
align: 'center'
|
||||
},
|
||||
|
||||
{
|
||||
name: 'gzdw',
|
||||
label: '单位',
|
||||
align: 'center',
|
||||
width: 150
|
||||
},
|
||||
{
|
||||
name: 'xb_dictText',
|
||||
label: '性别',
|
||||
align: 'center',
|
||||
width: 60
|
||||
},
|
||||
{
|
||||
name: 'nl',
|
||||
label: '年龄',
|
||||
align: 'center',
|
||||
width: 60
|
||||
},
|
||||
{
|
||||
name: 'operation',
|
||||
type: 'operation',
|
||||
label: '操作',
|
||||
align: 'center',
|
||||
renders: [{
|
||||
name: '详情',
|
||||
func: 'detail',
|
||||
size: 'mini'
|
||||
}]
|
||||
}
|
||||
])
|
||||
|
||||
onLoad((e) => {
|
||||
|
||||
})
|
||||
function detail() {
|
||||
|
||||
}
|
||||
function departChange (e){
|
||||
ryDataList = []
|
||||
departID.value = e
|
||||
let queryParm = {
|
||||
pageNo: pageNo.value,
|
||||
pageSize: pageSize.value
|
||||
};
|
||||
queryParm.orgCode = departID.value
|
||||
queryRenyuanByDepartID(queryParm).then((res) => {
|
||||
if (res.success) {
|
||||
ryDataList.value = res.result.records
|
||||
rrr.value=ryDataList[0].xm
|
||||
console.log(ryDataList)
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.log(err);
|
||||
})
|
||||
}
|
||||
|
||||
const Search = () => {
|
||||
ryDataList = [];
|
||||
let queryParm = {
|
||||
pageNo: pageNo.value,
|
||||
pageSize: pageSize.value
|
||||
};
|
||||
if ((ldhth.value == '') & (xm.value == '')) {
|
||||
return;
|
||||
}
|
||||
if (xm.value !== '') {
|
||||
queryParm.xm = '*' + xm.value + '*';
|
||||
}
|
||||
if (ldhth.value !== '') {
|
||||
queryParm.ldhth = '*' + ldhth.value + '*';
|
||||
}
|
||||
queryRenyuanByDepartID(queryParm).then((res) => {
|
||||
if (res.success) {
|
||||
ryDataList = res.result.records
|
||||
console.log(ryDataList)
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.log(err);
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.uni-group {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
212
pages/views/zhongheguanli/meeting/detail.vue
Normal file
@ -0,0 +1,212 @@
|
||||
<template>
|
||||
<view :class="['content',{'gray':store.isgray==1}]">
|
||||
<view class="list_box">
|
||||
<view class="list">
|
||||
<view class="title f-row aic jcb">
|
||||
<view class="">
|
||||
年度部门讨论会议
|
||||
</view>
|
||||
<text>1分钟前</text>
|
||||
</view>
|
||||
<view class="info">
|
||||
<view class="f-row aic jcb">
|
||||
<view class="">
|
||||
会议状态:
|
||||
</view>
|
||||
<text>待开始/已开始/已结束</text>
|
||||
</view>
|
||||
<view class="f-row aic jcb">
|
||||
<view class="">
|
||||
发起人:
|
||||
</view>
|
||||
<text>周如意</text>
|
||||
</view>
|
||||
<view class="f-row aic jcb">
|
||||
<view class="">
|
||||
会议日期:
|
||||
</view>
|
||||
<text>周如意</text>
|
||||
</view>
|
||||
<view class="f-row aic jcb">
|
||||
<view class="">
|
||||
会议地点:
|
||||
</view>
|
||||
<text>周如意</text>
|
||||
</view>
|
||||
<view class="f-row aic jcb">
|
||||
<view class="">
|
||||
会议内容:
|
||||
</view>
|
||||
<text>周如意</text>
|
||||
</view>
|
||||
<view class="">
|
||||
<view class="">
|
||||
参与人员:
|
||||
</view>
|
||||
<view class="person f-row aic">
|
||||
<view class="item f-col aic" v-for="item,i in 7" :key="i">
|
||||
<image src="" mode=""></image>
|
||||
<view class="name">
|
||||
周如意
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="btn f-row aic jcb">
|
||||
<view class="refuse">
|
||||
拒绝
|
||||
</view>
|
||||
<view class="agree" @click="openpop">
|
||||
同意
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref
|
||||
} from 'vue';
|
||||
import {
|
||||
huiyiDetailApi
|
||||
} from '@/api/api.js';
|
||||
import {
|
||||
onLoad
|
||||
} from '@dcloudio/uni-app';
|
||||
import {
|
||||
useStore
|
||||
} from '@/store'
|
||||
const store = useStore()
|
||||
onLoad(() => {
|
||||
huiyiDetail()
|
||||
})
|
||||
const huiyiDetail = () => {
|
||||
huiyiDetailApi({
|
||||
mainid:1
|
||||
}).then((res) => {
|
||||
if (res.success) {
|
||||
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.log(err);
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.content{
|
||||
padding-bottom: 120rpx;
|
||||
}
|
||||
.btn {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
width: 690rpx;
|
||||
height: 120rpx;
|
||||
background: #FFFFFF;
|
||||
padding: 0 30rpx;
|
||||
border-top: 1px solid #EFEFEF;
|
||||
|
||||
view {
|
||||
|
||||
width: 330rpx;
|
||||
height: 88rpx;
|
||||
font-size: 28rpx;
|
||||
border-radius: 16rpx;
|
||||
text-align: center;
|
||||
line-height: 88rpx;
|
||||
}
|
||||
|
||||
.refuse {
|
||||
box-sizing: border-box;
|
||||
background: #FFFFFF;
|
||||
border: 2rpx solid #01508B;
|
||||
color: #01508B;
|
||||
}
|
||||
|
||||
.agree {
|
||||
background: #01508B;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
}
|
||||
.list_box {
|
||||
|
||||
.list {
|
||||
padding: 30rpx;
|
||||
margin-bottom: 30rpx;
|
||||
|
||||
.title {
|
||||
border-bottom: 1px solid #efefef;
|
||||
padding-bottom: 24rpx;
|
||||
margin-bottom: 8rpx;
|
||||
|
||||
view {
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
text {
|
||||
font-size: 28rpx;
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
|
||||
.info {
|
||||
font-size: 28rpx;
|
||||
color: #666666;
|
||||
|
||||
view {
|
||||
padding-top: 16rpx;
|
||||
|
||||
font-size: 28rpx;
|
||||
color: #666666;
|
||||
}
|
||||
text{
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
}
|
||||
.person{
|
||||
flex-wrap: wrap;
|
||||
.item{
|
||||
width: 16.66%;
|
||||
|
||||
}
|
||||
image{
|
||||
width: 78rpx;
|
||||
height: 78rpx;
|
||||
border-radius: 38rpx;
|
||||
background-color: #01508B;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.btn {
|
||||
margin-top: 30rpx;
|
||||
|
||||
view {
|
||||
width: 300rpx;
|
||||
height: 64rpx;
|
||||
border-radius: 8rpx;
|
||||
font-size: 28rpx;
|
||||
text-align: center;
|
||||
line-height: 64rpx;
|
||||
}
|
||||
|
||||
.entrust {
|
||||
background: #FFFFFF;
|
||||
border: 2rpx solid #01508B;
|
||||
box-sizing: border-box;
|
||||
color: #01508B;
|
||||
}
|
||||
|
||||
.handle {
|
||||
background: #01508B;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
247
pages/views/zhongheguanli/meeting/index.vue
Normal file
@ -0,0 +1,247 @@
|
||||
<template>
|
||||
<view :class="{'gray':store.isgray==1}">
|
||||
<customNav>
|
||||
<view class="nav_box f-row aic jcb">
|
||||
<view class="back f-row aic" @click="back">
|
||||
<uni-icons type="left" size="20" color="#fff"></uni-icons>
|
||||
</view>
|
||||
<view class="search f-row aic">
|
||||
<input type="text" v-model="searchKey" @confirm="search" @blur="showicon=true&&!searchKey"
|
||||
@focus="showicon=false" />
|
||||
<view class="f-row aic" v-if="showicon">
|
||||
<image src="@/static/search.png" mode=""></image>
|
||||
<text>搜索</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</customNav>
|
||||
<view class="list_box">
|
||||
<view class="list" v-for="item,i in 3" :key="i" @click="jump(`/pages/meeting/detail?id=1`)">
|
||||
<view class="title f-row aic jcb">
|
||||
<view class="">
|
||||
年度部门讨论会议
|
||||
</view>
|
||||
<text>1分钟前</text>
|
||||
</view>
|
||||
<view class="info">
|
||||
<view class="f-row aic jcb">
|
||||
<view class="">
|
||||
发起人:
|
||||
</view>
|
||||
<text>周如意</text>
|
||||
</view>
|
||||
<view class="f-row aic jcb">
|
||||
<view class="">
|
||||
会议日期:
|
||||
</view>
|
||||
<text>周如意</text>
|
||||
</view>
|
||||
<view class="f-row aic jcb">
|
||||
<view class="">
|
||||
会议地点:
|
||||
</view>
|
||||
<text>周如意</text>
|
||||
</view>
|
||||
<view class="f-row aic jcb">
|
||||
<view class="">
|
||||
会议内容:
|
||||
</view>
|
||||
<text>周如意</text>
|
||||
</view>
|
||||
</view>
|
||||
<!-- <view class="btn f-row aic jcb">
|
||||
<view class="entrust">
|
||||
拒绝
|
||||
</view>
|
||||
<view class="handle">
|
||||
同意
|
||||
</view>
|
||||
</view> -->
|
||||
<view class="handled f-row">
|
||||
<view class="refused">
|
||||
已拒绝
|
||||
</view>
|
||||
<!-- <view class="agreed">
|
||||
已同意
|
||||
</view> -->
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref
|
||||
} from 'vue';
|
||||
import {
|
||||
useStore
|
||||
} from '@/store'
|
||||
const store = useStore()
|
||||
import {
|
||||
huiyilistApi
|
||||
} from '@/api/api.js';
|
||||
import customNav from '@/bpm/customNav.vue';
|
||||
import {
|
||||
onLoad
|
||||
} from '@dcloudio/uni-app';
|
||||
import {
|
||||
beforeJump
|
||||
} from '@/utils/index.js';
|
||||
const showicon = ref(true)
|
||||
const searchKey = ref('')
|
||||
onLoad(() => {
|
||||
// huiyilist()
|
||||
})
|
||||
const huiyilist = () => {
|
||||
huiyilistApi().then((res) => {
|
||||
if (res.success) {
|
||||
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.log(err);
|
||||
})
|
||||
}
|
||||
const jump = (url) => {
|
||||
beforeJump(url, () => {
|
||||
uni.navigateTo({
|
||||
url
|
||||
})
|
||||
})
|
||||
}
|
||||
const back = () => {
|
||||
uni.navigateBack()
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.nav_box {
|
||||
position: absolute;
|
||||
bottom: 14rpx;
|
||||
width: 100%;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.back {
|
||||
padding: 0 30rpx;
|
||||
}
|
||||
|
||||
.search {
|
||||
position: relative;
|
||||
padding-right: 30rpx;
|
||||
flex: 1;
|
||||
|
||||
view {
|
||||
position: absolute;
|
||||
left: 28rpx;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
|
||||
font-size: 28rpx;
|
||||
color: #999999;
|
||||
|
||||
}
|
||||
|
||||
input {
|
||||
flex: 1;
|
||||
height: 72rpx;
|
||||
background: #F8F8F8;
|
||||
border-radius: 44rpx;
|
||||
padding: 0 28rpx;
|
||||
}
|
||||
|
||||
image {
|
||||
width: 34rpx;
|
||||
height: 34rpx;
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.list_box {
|
||||
padding: 14rpx 30rpx 0 30rpx;
|
||||
margin-top: 24rpx;
|
||||
|
||||
.list {
|
||||
background: #FFFFFF;
|
||||
box-shadow: 0rpx 2rpx 4rpx 0rpx rgba(0, 0, 0, 0.5);
|
||||
border-radius: 16rpx;
|
||||
padding: 30rpx;
|
||||
margin-bottom: 30rpx;
|
||||
|
||||
.title {
|
||||
border-bottom: 1px solid #efefef;
|
||||
padding-bottom: 24rpx;
|
||||
margin-bottom: 8rpx;
|
||||
|
||||
view {
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
text {
|
||||
font-size: 28rpx;
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
|
||||
.info {
|
||||
font-size: 28rpx;
|
||||
color: #666666;
|
||||
|
||||
view {
|
||||
padding-top: 16rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.btn {
|
||||
margin-top: 30rpx;
|
||||
|
||||
view {
|
||||
width: 300rpx;
|
||||
height: 64rpx;
|
||||
border-radius: 8rpx;
|
||||
font-size: 28rpx;
|
||||
text-align: center;
|
||||
line-height: 64rpx;
|
||||
}
|
||||
|
||||
.entrust {
|
||||
background: #FFFFFF;
|
||||
border: 2rpx solid #01508B;
|
||||
box-sizing: border-box;
|
||||
color: #01508B;
|
||||
}
|
||||
|
||||
.handle {
|
||||
background: #01508B;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.refused {
|
||||
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.agreed {
|
||||
|
||||
color: #01508B;
|
||||
}
|
||||
|
||||
.handled {
|
||||
justify-content: flex-end;
|
||||
margin-top: 30rpx;
|
||||
|
||||
view {
|
||||
width: 150rpx;
|
||||
height: 64rpx;
|
||||
background: #EFEFEF;
|
||||
border-radius: 8rpx;
|
||||
text-align: center;
|
||||
line-height: 64rpx;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
118
pages/views/zhongheguanli/zhiban/index.vue
Normal file
@ -0,0 +1,118 @@
|
||||
<template>
|
||||
<view :class="['f-col','aic',{'gray':store.isgray==1}]">
|
||||
<picker fields="month" mode="date" @change="bindPickerChange" :value="index">
|
||||
<view class="date">{{index}} 点击选择月份</view>
|
||||
</picker>
|
||||
<view class="info">
|
||||
<view class="info_title f-row aic">
|
||||
<view class="">
|
||||
日期
|
||||
</view>
|
||||
<view class="">
|
||||
带班领导
|
||||
</view>
|
||||
<view class="">
|
||||
值班领导
|
||||
</view>
|
||||
<view class="">
|
||||
值班干部
|
||||
</view>
|
||||
</view>
|
||||
<view class="data_box">
|
||||
<view class="data f-row aic" v-for="item,i in zhibanArr">
|
||||
<view class="">
|
||||
{{item.date}}
|
||||
</view>
|
||||
<view class="">
|
||||
{{item.dbld_dictText}}
|
||||
</view>
|
||||
<view class="">
|
||||
{{item.zbld_dictText}}
|
||||
</view>
|
||||
<view class="">
|
||||
{{item.zbgbrealname}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref
|
||||
} from 'vue';
|
||||
import {
|
||||
onLoad
|
||||
} from '@dcloudio/uni-app';
|
||||
import {
|
||||
zhibanQueryApi
|
||||
} from '@/api/api.js';
|
||||
import {
|
||||
useStore
|
||||
} from '@/store';
|
||||
const store = useStore()
|
||||
import dayjs from 'dayjs';
|
||||
const zhibanArr = ref([])
|
||||
onLoad(() => {
|
||||
zhibanQuery()
|
||||
})
|
||||
const index = ref(dayjs().format("YYYY-MM"))
|
||||
const bindPickerChange = (e) => {
|
||||
index.value = e.detail.value
|
||||
zhibanQuery()
|
||||
}
|
||||
const zhibanQuery = () => {
|
||||
let [year, month] = index.value.split('-')
|
||||
zhibanQueryApi({
|
||||
year,
|
||||
month
|
||||
}).then((res) => {
|
||||
zhibanArr.value = res.result.records
|
||||
}).catch((err) => {
|
||||
console.log(err);
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.date {
|
||||
width: 690rpx;
|
||||
padding: 20rpx 30rpx 0 30rpx;
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.info {
|
||||
background: #F8F8F8;
|
||||
border-radius: 8rpx;
|
||||
text-align: center;
|
||||
width: 690rpx;
|
||||
margin-top: 23rpx;
|
||||
|
||||
.info_title {
|
||||
font-size: 24rpx;
|
||||
color: #333333;
|
||||
padding: 24rpx 0;
|
||||
border-bottom: 1px solid #EFEFEF;
|
||||
|
||||
view {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.data_box {
|
||||
font-size: 24rpx;
|
||||
padding-bottom: 24rpx;
|
||||
color: #888888;
|
||||
|
||||
.data {
|
||||
margin-top: 23rpx;
|
||||
|
||||
view {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
BIN
static/checkin/chenggong.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
static/checkin/circle1.png
Normal file
|
After Width: | Height: | Size: 62 KiB |
BIN
static/checkin/circle2.png
Normal file
|
After Width: | Height: | Size: 63 KiB |
BIN
static/checkin/circle3.png
Normal file
|
After Width: | Height: | Size: 63 KiB |
BIN
static/checkin/circle4.png
Normal file
|
After Width: | Height: | Size: 64 KiB |
BIN
static/checkin/position1.png
Normal file
|
After Width: | Height: | Size: 7.0 KiB |
BIN
static/checkin/position2.png
Normal file
|
After Width: | Height: | Size: 8.3 KiB |
BIN
static/checkin/position3.png
Normal file
|
After Width: | Height: | Size: 8.4 KiB |
BIN
static/checkin/position4.png
Normal file
|
After Width: | Height: | Size: 8.8 KiB |
BIN
static/checkin/shibai.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
static/index/back.png
Normal file
|
After Width: | Height: | Size: 570 B |
BIN
static/index/calendar.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
static/index/eye.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
static/index/line.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
static/index/menu.png
Normal file
|
After Width: | Height: | Size: 791 B |
BIN
static/index/position.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
static/index/rili.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
static/line.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
static/login/checked.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
static/login/eye-off.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
static/login/eye.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
static/login/logo.png
Normal file
|
After Width: | Height: | Size: 84 KiB |
BIN
static/login/nocheck.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
static/login/phone.png
Normal file
|
After Width: | Height: | Size: 816 B |
BIN
static/login/pwd.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
static/my/bg1.png
Normal file
|
After Width: | Height: | Size: 9.5 KiB |
BIN
static/my/biao.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
static/my/chart.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
BIN
static/my/close.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
static/my/default.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
BIN
static/my/dingwei.png
Normal file
|
After Width: | Height: | Size: 4.5 KiB |
BIN
static/my/done.png
Normal file
|
After Width: | Height: | Size: 6.0 KiB |
BIN
static/my/edit.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |