Commit 8b3bb328 authored by 罗超's avatar 罗超

提交样本子应用

parent fc4e5678
...@@ -9,7 +9,7 @@ function resolve (dir) { ...@@ -9,7 +9,7 @@ function resolve (dir) {
} }
const createLintingRule = () => ({ const createLintingRule = () => ({
}) })
module.exports = { module.exports = {
...@@ -25,9 +25,13 @@ module.exports = { ...@@ -25,9 +25,13 @@ module.exports = {
output: { output: {
path: config.build.assetsRoot, path: config.build.assetsRoot,
filename: '[name].js', filename: '[name].js',
publicPath: process.env.NODE_ENV === 'production' // publicPath: process.env.NODE_ENV === 'production'
? config.build.assetsPublicPath // ? config.build.assetsPublicPath
: config.dev.assetsPublicPath // : config.dev.assetsPublicPath,
publicPath: process.env.NODE_ENV === 'production' ? '/crm/' : '/',
library: 'erp', // 子应用名称,需与主应用注册的一致
libraryTarget: 'umd',
jsonpFunction: `webpackJsonp_erp`, // 避免与其他子应用冲突
}, },
resolve: { resolve: {
extensions: ['.js', '.vue', '.json'], extensions: ['.js', '.vue', '.json'],
...@@ -59,7 +63,7 @@ module.exports = { ...@@ -59,7 +63,7 @@ module.exports = {
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
type: "asset", type: "asset",
generator: { generator: {
filename: utils.assetsPath('img/[name].[hash:7].[ext]') filename: utils.assetsPath('img/[name].[hash:7].[ext]')
}, },
}, },
...@@ -67,26 +71,56 @@ module.exports = { ...@@ -67,26 +71,56 @@ module.exports = {
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
type: "asset", type: "asset",
generator: { generator: {
filename: utils.assetsPath('media/[name].[hash:7].[ext]') filename: utils.assetsPath('media/[name].[hash:7].[ext]')
}, },
}, },
{ {
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
type: "asset", include: /node_modules[\\/]element-ui[\\/]lib[\\/]theme-chalk[\\/]fonts/,
type: 'asset/inline',
generator: {
dataUrl: {
mimetype: 'application/font-woff',
encoding: 'base64',
},
},
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/i,
exclude: /node_modules[\\/]element-ui/,
type: 'asset/resource',
generator: { generator: {
filename: 'static/fonts/[name][ext][query]', // 输出路径与错误中的路径匹配
filename: utils.assetsPath('fonts/[name].[hash:7].[ext]')
}, },
}, },
// {
// test: /\.(woff|eot|ttf|otf)(\?.*)?$/,
// include: /node_modules\/element-ui/, // 仅匹配 Element UI 的字体
// type: 'asset/inline', // Webpack 5 内置方式(替代 url-loader)
// generator: {
// dataUrl: {
// encoding: 'base64',
// mimetype: 'application/font-woff',
// },
// },
// },
// {
// test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
// type: "asset",
// generator: {
// filename: utils.assetsPath('fonts/[name].[hash:7].[ext]')
// },
// },
{ {
test: /\.(mp3)(\?.*)?$/, test: /\.(mp3)(\?.*)?$/,
type: "asset", type: "asset",
generator: { generator: {
filename: utils.assetsPath('assets/[name].[hash:7].[ext]') filename: utils.assetsPath('assets/[name].[hash:7].[ext]')
}, },
} }
] ]
}, },
} }
...@@ -7,10 +7,6 @@ const CopyWebpackPlugin = require('copy-webpack-plugin') ...@@ -7,10 +7,6 @@ const CopyWebpackPlugin = require('copy-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin') const HtmlWebpackPlugin = require('html-webpack-plugin')
const vueLoaderConfig = require('./vue-loader.conf') const vueLoaderConfig = require('./vue-loader.conf')
const workerConfig = require('./worker.conf') const workerConfig = require('./worker.conf')
// const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
// const ESLintPlugin = require('eslint-webpack-plugin');
// const VueLoaderPlugin = require('vue-loader/lib/plugin');
// const {VueLoaderPlugin} = require('vue-loader')
const portfinder = require('portfinder') const portfinder = require('portfinder')
function resolve (dir) { function resolve (dir) {
return path.join(__dirname, '..', dir) return path.join(__dirname, '..', dir)
...@@ -23,15 +19,12 @@ const devWebpackConfig = { ...@@ -23,15 +19,12 @@ const devWebpackConfig = {
type: 'filesystem', type: 'filesystem',
allowCollectingMemory: true, allowCollectingMemory: true,
buildDependencies: { buildDependencies: {
// This makes all dependencies of this file - build dependencies
config: [__filename], config: [__filename],
// 默认情况下 webpack 与 loader 是构建依赖。
}, },
}, },
target: 'web', target: 'web',
entry: { entry: {
app: './src/main.js', app: './src/main.js',
// sdk: path.join(__dirname, '../src/sdk/NIM_Web_SDK_v5.0.0.js')
}, },
externals:{ externals:{
'BMap':'BMap', 'BMap':'BMap',
...@@ -50,19 +43,17 @@ resolve: { ...@@ -50,19 +43,17 @@ resolve: {
} }
}, },
mode: 'development', mode: 'development',
// 避免额外的优化步骤 Webpack 通过执行额外的算法任务,来优化输出结果的体积和加载性能。这些优化适用于小型代码库,但是在大型代码库中却非常耗费性能
// optimization: {
// removeAvailableModules: false,
// removeEmptyChunks: false,
// splitChunks: false,
// },
output: { //Webpack 会在输出的 bundle 中生成路径信息。然而,在打包数千个模块的项目中,这会导致造成垃圾回收性能压力。在 options.output.pathinfo 设置中关闭 output: { //Webpack 会在输出的 bundle 中生成路径信息。然而,在打包数千个模块的项目中,这会导致造成垃圾回收性能压力。在 options.output.pathinfo 设置中关闭
pathinfo: false, pathinfo: false,
path: config.build.assetsRoot, path: config.build.assetsRoot,
filename: '[name].js', filename: '[name].js',
crossOriginLoading: 'anonymous',
publicPath: process.env.NODE_ENV === 'production' publicPath: process.env.NODE_ENV === 'production'
? config.build.assetsPublicPath ? config.build.assetsPublicPath
: config.dev.assetsPublicPath : config.dev.assetsPublicPath,
// publicPath: process.env.NODE_ENV === 'production' ? '/erp/' : '/',
library: 'erp', // 子应用名称,需与主应用注册的一致
libraryTarget: 'umd'
}, },
module: { module: {
rules: [ rules: [
...@@ -93,13 +84,32 @@ resolve: { ...@@ -93,13 +84,32 @@ resolve: {
filename: utils.assetsPath('media/[name].[hash:7].[ext]') filename: utils.assetsPath('media/[name].[hash:7].[ext]')
}, },
}, },
{ {
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
type: "asset", include: /node_modules[\\/]element-ui[\\/]lib[\\/]theme-chalk[\\/]fonts/,
type: 'asset/inline',
generator: {
dataUrl: {
mimetype: 'application/font-woff',
encoding: 'base64',
},
},
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/i,
exclude: /node_modules[\\/]element-ui/,
type: 'asset/resource',
generator: { generator: {
filename: utils.assetsPath('fonts/[name].[hash:7].[ext]') filename: 'static/fonts/[name][ext][query]', // 输出路径与错误中的路径匹配
}, },
}, },
// {
// test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
// type: "asset",
// generator: {
// filename: utils.assetsPath('fonts/[name].[hash:7].[ext]')
// },
// },
{ {
test: /\.(mp3)(\?.*)?$/, test: /\.(mp3)(\?.*)?$/,
type: "asset", type: "asset",
...@@ -109,36 +119,21 @@ resolve: { ...@@ -109,36 +119,21 @@ resolve: {
} }
] ]
}, },
// cheap-module-eval-source-map is faster for development
devtool: config.dev.devtool, devtool: config.dev.devtool,
// these devServer options should be customized in /config/index.js
devServer: { devServer: {
allowedHosts: [HOST || config.dev.host], allowedHosts: [HOST || config.dev.host],
client: { client: {
logging: 'warn', logging: 'warn',
reconnect: 5, //告诉 dev-server 它应该尝试重新连接客户端的次数。当为 true 时,它将无限次尝试重新连接 reconnect: 5,
}, },
// clientLogLevel: 'warning', headers: {
// historyApiFallback: { 'Access-Control-Allow-Origin': '*'
// rewrites: [ },
// { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') }, port:8082,
// ], open:false,
// }, historyApiFallback:true,
// contentBase: false, // since we use CopyWebpackPlugin. allowedHosts: 'all',
// compress: true,
// host: HOST || config.dev.host,
// port: PORT || config.dev.port,
// open: config.dev.autoOpenBrowser,
// overlay: config.dev.errorOverlay
// ? { warnings: false, errors: true }
// : false,
// publicPath: config.dev.assetsPublicPath,
// proxy: config.dev.proxyTable,
// quiet: true, // necessary for FriendlyErrorsPlugin
// watchOptions: {
// poll: config.dev.poll,
// }
}, },
plugins: [ plugins: [
new webpack.DefinePlugin({ new webpack.DefinePlugin({
...@@ -166,28 +161,4 @@ resolve: { ...@@ -166,28 +161,4 @@ resolve: {
} }
const SpeedMeasurePlugin = require("speed-measure-webpack-plugin"); const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");
const smp = new SpeedMeasurePlugin(); const smp = new SpeedMeasurePlugin();
// module.exports = new Promise((resolve, reject) => {
// portfinder.basePort = process.env.PORT || config.dev.port
// portfinder.getPort((err, port) => {
// if (err) {
// reject(err)
// } else {
// // publish the new Port, necessary for e2e tests
// process.env.PORT = port
// // add port to devServer config
// devWebpackConfig.devServer.port = port
// // Add FriendlyErrorsPlugin
// // devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({
// // compilationSuccessInfo: {
// // messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`],
// // },
// // onErrors: config.dev.notifyOnErrors
// // ? utils.createNotifierCallback()
// // : undefined
// // }))
// resolve(smp.wrap(devWebpackConfig))
// }
// })
// })
module.exports = smp.wrap(devWebpackConfig) module.exports = smp.wrap(devWebpackConfig)
...@@ -8,6 +8,9 @@ module.exports = { ...@@ -8,6 +8,9 @@ module.exports = {
// Paths // Paths
assetsSubDirectory: `static`, assetsSubDirectory: `static`,
assetsPublicPath: '/', assetsPublicPath: '/',
headers: {
'Access-Control-Allow-Origin': '*'
},
proxyTable: { proxyTable: {
// '/boundsearch': { // 矩形区域检索entity // '/boundsearch': { // 矩形区域检索entity
// target: 'http://yingyan.baidu.com/api/v3/entity/boundsearch', // target: 'http://yingyan.baidu.com/api/v3/entity/boundsearch',
...@@ -15,14 +18,14 @@ module.exports = { ...@@ -15,14 +18,14 @@ module.exports = {
// pathRewrite: { // pathRewrite: {
// '^/boundsearch': '' // '^/boundsearch': ''
// } // }
// }, // },
// '/getdistance': { // 获取track的distance // '/getdistance': { // 获取track的distance
// target: 'http://yingyan.baidu.com/api/v3/track/getdistance', // target: 'http://yingyan.baidu.com/api/v3/track/getdistance',
// changeOrigin: true, // changeOrigin: true,
// pathRewrite: { // pathRewrite: {
// '^/getdistance': '' // '^/getdistance': ''
// } // }
// }, // },
// '/api': { // 获取track信息 // '/api': { // 获取track信息
// target: 'http://yingyan.baidu.com/api/v3/track/gettrack', // target: 'http://yingyan.baidu.com/api/v3/track/gettrack',
// changeOrigin: true, // changeOrigin: true,
...@@ -44,38 +47,38 @@ module.exports = { ...@@ -44,38 +47,38 @@ module.exports = {
// '^/getAddress': '' // '^/getAddress': ''
// } // }
// }, // },
// '/searchEntity': { // 通过新的search接口获取数据,包括所有entity、模糊搜索entity、在线entity、离线entity // '/searchEntity': { // 通过新的search接口获取数据,包括所有entity、模糊搜索entity、在线entity、离线entity
// target: 'http://yingyan.baidu.com/api/v3/entity/search', // target: 'http://yingyan.baidu.com/api/v3/entity/search',
// changeOrigin: true, // changeOrigin: true,
// pathRewrite: { // pathRewrite: {
// '^/searchEntity': '' // '^/searchEntity': ''
// } // }
// }, // },
// '/trackList': { // 获取track列表 // '/trackList': { // 获取track列表
// target: 'http://yingyan.baidu.com/api/v2/track/gethistory', // target: 'http://yingyan.baidu.com/api/v2/track/gethistory',
// changeOrigin: true, // changeOrigin: true,
// pathRewrite: { // pathRewrite: {
// '^/trackList': '' // '^/trackList': ''
// } // }
// }, // },
// '/getstaypoint': { // 获取停留点 // '/getstaypoint': { // 获取停留点
// target: 'http://yingyan.baidu.com/api/v2/analysis/staypoint', // target: 'http://yingyan.baidu.com/api/v2/analysis/staypoint',
// changeOrigin: true, // changeOrigin: true,
// pathRewrite: { // pathRewrite: {
// '^/getstaypoint': '' // '^/getstaypoint': ''
// } // }
// }, // },
// '/getBehaviorAnalysis': { // 获取驾驶行为分析信息 // '/getBehaviorAnalysis': { // 获取驾驶行为分析信息
// target: 'http://yingyan.baidu.com/api/v2/analysis/drivingbehavior', // target: 'http://yingyan.baidu.com/api/v2/analysis/drivingbehavior',
// changeOrigin: true, // changeOrigin: true,
// pathRewrite: { // pathRewrite: {
// '^/getBehaviorAnalysis': '' // '^/getBehaviorAnalysis': ''
// } // }
// }, // },
}, },
// // 矩形区域检索entity // // 矩形区域检索entity
// boundsearchEntity: '//yingyan.baidu.com/api/v3/entity/boundsearch', // boundsearchEntity: '//yingyan.baidu.com/api/v3/entity/boundsearch',
// // 获取track的distance // // 获取track的distance
...@@ -84,7 +87,7 @@ module.exports = { ...@@ -84,7 +87,7 @@ module.exports = {
// getTrack: '//yingyan.baidu.com/api/v3/track/gettrack', // getTrack: '//yingyan.baidu.com/api/v3/track/gettrack',
// // 获取自定义字段列表 // // 获取自定义字段列表
// columnsList: '//yingyan.baidu.com/api/v3/entity/listcolumn', // columnsList: '//yingyan.baidu.com/api/v3/entity/listcolumn',
// //
// // 经纬度解析 // // 经纬度解析
// getAddress: '//api.map.baidu.com/geocoder/v2/', // getAddress: '//api.map.baidu.com/geocoder/v2/',
// // 通过新的search接口获取数据,包括所有entity、模糊搜索entity、在线entity、离线entity // // 通过新的search接口获取数据,包括所有entity、模糊搜索entity、在线entity、离线entity
...@@ -94,14 +97,15 @@ module.exports = { ...@@ -94,14 +97,15 @@ module.exports = {
// // 获取停留点 // // 获取停留点
// getstaypoint: '//yingyan.baidu.com/api/v2/analysis/staypoint', // getstaypoint: '//yingyan.baidu.com/api/v2/analysis/staypoint',
// // 获取驾驶行为分析信息 // // 获取驾驶行为分析信息
// getBehaviorAnalysis: '//yingyan.baidu.com/api/v2/analysis/drivingbehavior', // getBehaviorAnalysis: '//yingyan.baidu.com/api/v2/analysis/drivingbehavior',
// Various Dev Server settings // Various Dev Server settings
host: 'localhost', // can be overwritten by process.env.HOST host: 'localhost', // can be overwritten by process.env.HOST
port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined port: 8082, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
autoOpenBrowser: false, autoOpenBrowser: false,
errorOverlay: true, errorOverlay: true,
notifyOnErrors: true, notifyOnErrors: true,
poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions- poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
......
...@@ -8,21 +8,21 @@ ...@@ -8,21 +8,21 @@
<meta http-equiv="Pragma" content="no-cache"> <meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-Control" content="no-cache, must-revalidate, no-store"> <meta http-equiv="Cache-Control" content="no-cache, must-revalidate, no-store">
<meta http-equiv="Expires" content="0"> <meta http-equiv="Expires" content="0">
<script type="text/javascript" src="http://api.map.baidu.com/api?v=3.0&ak=L5Qw0GlbbCIMwgR4Uug3ogM40Imkd3CV"></script> <!-- <script type="text/javascript" src="http://api.map.baidu.com/api?v=3.0&ak=L5Qw0GlbbCIMwgR4Uug3ogM40Imkd3CV"></script>
<script type="text/javascript" src="http://api.map.baidu.com/library/TextIconOverlay/1.2/src/TextIconOverlay_min.js"> <script type="text/javascript" src="http://api.map.baidu.com/library/TextIconOverlay/1.2/src/TextIconOverlay_min.js"> -->
</script> </script>
<script type="text/javascript" src="static/MarkerClusterer.js"></script> <script type="text/javascript" src="static/MarkerClusterer.js"></script>
<script type="text/javascript" src="static/CurveLine.min.js"></script> <script type="text/javascript" src="static/CurveLine.min.js"></script>
<link href="https://api.mapbox.com/mapbox-gl-js/v2.6.1/mapbox-gl.css" rel="stylesheet"> <!-- <link href="https://api.mapbox.com/mapbox-gl-js/v2.6.1/mapbox-gl.css" rel="stylesheet">
<script src="https://api.mapbox.com/mapbox-gl-js/v2.6.1/mapbox-gl.js"></script> <script src="https://api.mapbox.com/mapbox-gl-js/v2.6.1/mapbox-gl.js"></script>
<script charset="utf-8" src="https://map.qq.com/api/js?v=2.exp&key=OV7BZ-ZT3HP-6W3DE-LKHM3-RSYRV-ULFZV"></script> <script charset="utf-8" src="https://map.qq.com/api/js?v=2.exp&key=OV7BZ-ZT3HP-6W3DE-LKHM3-RSYRV-ULFZV"></script> -->
<script type="text/javascript" <!-- <script type="text/javascript"
src="https://api.map.baidu.com/api?v=1.0&type=webgl&ak=OBd2bhrqKUSbQGpniCZ996suti9YG7Bc"></script> src="https://api.map.baidu.com/api?v=1.0&type=webgl&ak=OBd2bhrqKUSbQGpniCZ996suti9YG7Bc"></script> -->
<!--HK 2024-08-15 新加(避免提示为商用授权) Start--> <!--HK 2024-08-15 新加(避免提示为商用授权) Start-->
<script type="text/javascript" src="//api.map.baidu.com/api?key=&v=1.1&services=true&s=1"></script> <!-- <script type="text/javascript" src="//api.map.baidu.com/api?key=&v=1.1&services=true&s=1"></script>
<script type="text/javascript" src="https://api.map.baidu.com/getscript?v=2.0&ak=&services=&t=20240731110958"></script> <script type="text/javascript" src="https://api.map.baidu.com/getscript?v=2.0&ak=&services=&t=20240731110958"></script> -->
<!-- <!--
<script charset="utf8" src="https://dlswbr.baidu.com/heicha/mw/abclite-2063-s.original.js?_=9975"></script> <script charset="utf8" src="https://dlswbr.baidu.com/heicha/mw/abclite-2063-s.original.js?_=9975"></script>
<script type="text/javascript" src="https://api.map.baidu.com/getscript?v=1.1&ak=&services=true&t=20130716024058"></script> <script type="text/javascript" src="https://api.map.baidu.com/getscript?v=1.1&ak=&services=true&t=20130716024058"></script>
<script type="text/javascript" src="//api.map.baidu.com/api?v=2.0&s=1"></script> <script type="text/javascript" src="//api.map.baidu.com/api?v=2.0&s=1"></script>
......
This diff is collapsed.
<template> <template>
<div id="app" :class="[isRed?'red-theme':'',typeSystem==1?'appBoxActive':'']"> <div id="app" :class="{'red-theme':isRed || isQiankun,'appBoxActive':typeSystem==1,'qiankun-erp':isQiankun}">
<keep-alive> <keep-alive>
<router-view v-if="$route.meta.keepAlive" /> <router-view v-if="$route.meta.keepAlive" />
</keep-alive> </keep-alive>
...@@ -7,9 +7,9 @@ ...@@ -7,9 +7,9 @@
<viewer :images="images" :options='imageOptions' @inited="inited" class="viewer" ref="viewer"> <viewer :images="images" :options='imageOptions' @inited="inited" class="viewer" ref="viewer">
<img v-for="src in images" :src="src" :key="src"> <img v-for="src in images" :src="src" :key="src">
</viewer> </viewer>
<chosen-open-mode v-if="haveOpenMode&&typeSystem==0" :settingSys="settingSys"></chosen-open-mode> <chosen-open-mode v-if="haveOpenMode&&typeSystem==0 && !isQiankun" :settingSys="settingSys"></chosen-open-mode>
<!-- --> <!-- -->
<div class="showMyCareer" v-if="showCareer"> <div class="showMyCareer" v-if="showCareer&& !isQiankun">
<mycareer :show-close="true" :uid="careerId" @close="closeCareer"></mycareer> <mycareer :show-close="true" :uid="careerId" @close="closeCareer"></mycareer>
</div> </div>
</div> </div>
...@@ -162,6 +162,7 @@ ...@@ -162,6 +162,7 @@
document.URL.indexOf("TravelContractConfirm") == -1 && document.URL.indexOf("TravelContractConfirm") == -1 &&
document.URL.indexOf("ViittoContractConfirm") == -1 document.URL.indexOf("ViittoContractConfirm") == -1
) { ) {
console.log('--------------------------------app login-------------------------------')
this.$router.push({ this.$router.push({
path: "/login" path: "/login"
}); });
...@@ -239,15 +240,20 @@ ...@@ -239,15 +240,20 @@
body { body {
margin: 0; margin: 0;
padding: 0; padding: 0;
background: #f9f9f9 url(assets/img/img-bg.png) no-repeat bottom left/100% auto; /* background: #f9f9f9 url(assets/img/img-bg.png) no-repeat bottom left/100% auto; */
height: 100%; height: 100%;
} }
div[data-qiankun="erp"] {
background:unset;
}
.qiankun-erp .productQuerySearch li:last-child {
top: 42px !important;
}
#app { #app {
height: 100%; height: 100%;
} }
#app>div { #app .myIndexStyle {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
height: 100%; height: 100%;
......
...@@ -629,7 +629,7 @@ input:-webkit-autofill { ...@@ -629,7 +629,7 @@ input:-webkit-autofill {
border: 1px solid #33B3FF; border: 1px solid #33B3FF;
cursor: pointer; cursor: pointer;
border-radius: 3px; border-radius: 3px;
margin-left: 10px; /* margin-left: 10px; */
} }
.normalBtn:hover { .normalBtn:hover {
...@@ -1877,4 +1877,4 @@ input[type="number"] { ...@@ -1877,4 +1877,4 @@ input[type="number"] {
padding-left: 20px; padding-left: 20px;
} }
/************************** luochao 重新定义表格样式 END *******************************/ /************************** luochao 重新定义表格样式 END *******************************/
\ No newline at end of file
<style> <style>
@import "../assets/css/Details.css"; @import "../assets/css/Details.css";
div[data-qiankun="erp"] .flexDiv {
background-color: transparent !important;
}
div[data-qiankun="erp"] .flexParent {
background-color: transparent !important;
}
</style> </style>
<template> <template>
<div class="flexDiv"> <div class="flexDiv" :style="{background:isQiankun?'transparent':'#f2f2f2'}">
<div v-if="typeSystem==0" class="secondMenu" :class="{'big':!isCollapse}"> <div v-if="typeSystem==0 && !isQiankun" class="secondMenu" :class="{'big':!isCollapse}">
<div class="secondMenu_l"> <div class="secondMenu_l">
<div class="menuItem"> <div class="menuItem">
<el-menu default-active="1" :background-color="!isRed?'#282733':'#FBFBFB'" <el-menu default-active="1" :background-color="!isRed?'#282733':'#FBFBFB'"
...@@ -30,7 +35,7 @@ ...@@ -30,7 +35,7 @@
<img src="../assets/img/extends.png" :class="{'close-extend':isCollapse}" /> <img src="../assets/img/extends.png" :class="{'close-extend':isCollapse}" />
</div> </div>
</div> </div>
<div class="flexParent" v-if="openMode==1"> <div class="flexParent" :style="{padding:isQiankun?'0':'0 20px',background:isQiankun?'transparent':'#f2f2f2'}" v-if="openMode==1">
<div v-if="typeSystem==0" class="nav-tabs-box" @contextmenu.prevent="showRightMenu" :style="{width:`${navWidth}px`}"> <div v-if="typeSystem==0" class="nav-tabs-box" @contextmenu.prevent="showRightMenu" :style="{width:`${navWidth}px`}">
<el-tabs v-if='tabs && tabs.length>0' v-model="currentTabName" style="margin-left: 120px;" <el-tabs v-if='tabs && tabs.length>0' v-model="currentTabName" style="margin-left: 120px;"
:closable="tabs.length>1" type="card" @edit="handleTabsEdit"> :closable="tabs.length>1" type="card" @edit="handleTabsEdit">
...@@ -51,13 +56,13 @@ ...@@ -51,13 +56,13 @@
v-show="tabs.indexOf(currentTag)==i" :componentTemp='item.comp' v-for="(item,i) in tabs" v-if='item.comp' v-show="tabs.indexOf(currentTag)==i" :componentTemp='item.comp' v-for="(item,i) in tabs" v-if='item.comp'
:path='item.path' :name='item.name'></analogIFrame> :path='item.path' :name='item.name'></analogIFrame>
</div> </div>
<div class="flexParent" v-if="openMode==0"> <div class="flexParent" :style="{padding:isQiankun?'0':'0 20px',background:isQiankun?'transparent':'#f2f2f2'}" v-if="openMode==0">
<a :href='blankUrl' id='blankLink' target="_blank" style="display:none">1</a> <a :href='blankUrl' id='blankLink' target="_blank" style="display:none">1</a>
<div class="resource-ttop" style="font-family:PingFangSC-Semibold" v-if="rootName!=''"> <div class="resource-ttop" style="font-family:PingFangSC-Semibold" v-if="rootName!=''">
{{rootName}}<i class="iconfont icon-weibiaoti102"></i>{{parentName}}<i {{rootName}}<i class="iconfont icon-weibiaoti102"></i>{{parentName}}<i
class="iconfont icon-weibiaoti102"></i><span class="active">{{currentName}}</span> class="iconfont icon-weibiaoti102"></i><span class="active">{{currentName}}</span>
</div> </div>
<div class="frame-box" ref="frameBox" name="frameBox"> <div class="frame-box" :style="{'inset':isQiankun?'0':'41px 0px 0px',padding:isQiankun?'0':'0 20px'}" ref="frameBox" name="frameBox">
<router-view></router-view> <router-view></router-view>
</div> </div>
</div> </div>
...@@ -972,11 +977,28 @@ ...@@ -972,11 +977,28 @@
// dom.target = '_blank'; // dom.target = '_blank';
// dom.href = `http://${window.location.host}/#${to.fullPath}` // dom.href = `http://${window.location.host}/#${to.fullPath}`
// dom.click() // dom.click()
var el = document.createElement("a"); if(!this.isQiankun){
document.body.appendChild(el); var el = document.createElement("a");
el.href = `http://${window.location.host}/#${to.fullPath}`; document.body.appendChild(el);
el.target = '_blank'; el.href = `http://${window.location.host}/#${to.fullPath}`;
el.click(); el.target = '_blank';
el.click();
}else{
// if(!to.fullPath.startsWith('/erp/')) {
// const qiankunPath ='/erp'+to.fullPath
// console.log(qiankunPath)
// next({
// path:qiankunPath,
// query:to.query,
// replace:false,
// params:to.params,
// meta:to.meta,
// })
// } else
next()
}
} else { } else {
next() next()
} }
......
This diff is collapsed.
...@@ -36,9 +36,6 @@ ...@@ -36,9 +36,6 @@
mapboxgl.accessToken = mapboxgl.accessToken =
"pk.eyJ1IjoiYWxleDkwMTIiLCJhIjoiY2xtOGw4NHdkMGFndTNjcnFkeWZncGc2dyJ9.lVrAdPHE0Dg5zoWFidfj4Q"; "pk.eyJ1IjoiYWxleDkwMTIiLCJhIjoiY2xtOGw4NHdkMGFndTNjcnFkeWZncGc2dyJ9.lVrAdPHE0Dg5zoWFidfj4Q";
import html2Canvas from "html2canvas"; import html2Canvas from "html2canvas";
import {
continueRobotMsg
} from '../../../store/actions/msgs';
export default { export default {
props: ["PostConfig"], props: ["PostConfig"],
data() { data() {
......
...@@ -748,7 +748,7 @@ ...@@ -748,7 +748,7 @@
</template> </template>
<script> <script>
import getters from '../../store/getters';
export default { export default {
data() { data() {
return { return {
......
// The Vue build version to load with the `import` command // The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias. // (runtime-only or standalone) has been set in webpack.base.conf with an alias.
if (window.__POWERED_BY_QIANKUN__) {
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
import Vue from 'vue' import Vue from 'vue'
import axios from 'axios' import axios from 'axios'
import VueI18n from 'vue-i18n' import VueI18n from 'vue-i18n'
...@@ -27,7 +30,6 @@ import calendarUtils from './assets/utils/calendarUtils' //日历帮助类 ...@@ -27,7 +30,6 @@ import calendarUtils from './assets/utils/calendarUtils' //日历帮助类
import lunarCalendar from './assets/utils/lunarCalendar' //农历日历帮助类 import lunarCalendar from './assets/utils/lunarCalendar' //农历日历帮助类
import googleMap from './assets/utils/googleMap' //引入谷歌地图 import googleMap from './assets/utils/googleMap' //引入谷歌地图
import AuthCode from './assets/utils/AuthCode' //权限编码JS import AuthCode from './assets/utils/AuthCode' //权限编码JS
import store from './store'
import languageUtils from './assets/utils/languageUtils' //引入语言转换帮助类 import languageUtils from './assets/utils/languageUtils' //引入语言转换帮助类
// import htmlToPdf from './assets/utils/htmlToPdf' // import htmlToPdf from './assets/utils/htmlToPdf'
import DMCUtils from './assets/utils/DMCUtils' import DMCUtils from './assets/utils/DMCUtils'
...@@ -79,7 +81,6 @@ Vue.use(ElementUI) ...@@ -79,7 +81,6 @@ Vue.use(ElementUI)
Vue.use(vueQuillEditor) Vue.use(vueQuillEditor)
//Vue.use(VueAMap); //Vue.use(VueAMap);
Vue.use(VueBarcode); //声明条形码组件 Vue.use(VueBarcode); //声明条形码组件
Vue.use(store);
Vue.use(Viewer, { Vue.use(Viewer, {
defaultOptions: { defaultOptions: {
zIndex: 9999 zIndex: 9999
...@@ -113,7 +114,7 @@ Vue.prototype.DateDiff = function (sDate1, sDate2) { ...@@ -113,7 +114,7 @@ Vue.prototype.DateDiff = function (sDate1, sDate2) {
oDate1 = new Date(aDate[1] + '-' + aDate[2] + '-' + aDate[0]) oDate1 = new Date(aDate[1] + '-' + aDate[2] + '-' + aDate[0])
aDate = sDate2.split("-") aDate = sDate2.split("-")
oDate2 = new Date(aDate[1] + '-' + aDate[2] + '-' + aDate[0]) oDate2 = new Date(aDate[1] + '-' + aDate[2] + '-' + aDate[0])
iDays = parseInt(Math.abs(oDate1 - oDate2) / 1000 / 60 / 60 / 24) //把相差的毫秒数转换为天数 iDays = parseInt(Math.abs(oDate1 - oDate2) / 1000 / 60 / 60 / 24) //把相差的毫秒数转换为天数
return iDays return iDays
} }
...@@ -183,18 +184,86 @@ const i18n = new VueI18n({ ...@@ -183,18 +184,86 @@ const i18n = new VueI18n({
locale.i18n((key, value) => i18n.t(key, value)) locale.i18n((key, value) => i18n.t(key, value))
import Router from 'vue-router' // new Vue({
// el: '#app',
// router,
// i18n,
// cookie,
// store,
// components: { App },
// template: '<App/>'
// }).$mount('#app')
let instance = null;
let originFn = document.body.appendChild.bind(document.body)
function render(props = {}) {
Vue.prototype.isQiankun = window.__POWERED_BY_QIANKUN__? true:false;
const { container } = props;
redirectPopup(props)
if(props.initData && props.initData.baseInfo){
localStorage.setItem('userInfo', JSON.stringify(props.initData.baseInfo));
}
instance = new Vue({
router,
i18n,
cookie,
render: h => h(App)
}).$mount(container ? container.querySelector('#app') : '#app'); // 根据容器挂载
}
// 独立运行时直接渲染
if (!window.__POWERED_BY_QIANKUN__) {
render();
}
// 导出生命周期
export async function bootstrap() {
console.log('[vue2] bootstrap');
}
export async function mount(props) {
if (instance) {
instance.$destroy()
instance.$el.innerHTML = ''
}
if (props && props.setPublicPath) {
props.setPublicPath(__webpack_public_path__);
}
render(props);
}
function redirectPopup(container) {
// 子应用中需要挂载到子应用的弹窗className。样式class白名单,用子应用的样式。
const whiteList = ['el-select-dropdown', 'el-popper', 'el-popover','el-image-viewer__wrapper', 'el-dialog__wrapper','el-tooltip','el-message-box__wrapper']
// 保存原有document.body.appendChild方法
originFn = document.body.appendChild.bind(document.body)
// 重写appendChild方法
document.body.appendChild = (dom) => {
// 根据标记,来区分是否用新的挂载方式
let count = 0
whiteList.forEach((x) => {
if (dom.className.includes(x)) count++
})
if (count > 0 && container.container) {
// 有弹出框的时候,挂载的元素挂载到子应用上,而不是主应用的body上
container.container.querySelector('#app').appendChild(dom)
} else {
originFn(dom)
}
}
}
const originalPush = Router.prototype.push export async function unmount() {
Router.prototype.push = function push(location) { console.log('[vue2] unmount');
return originalPush.call(this, location).catch(err => err) // appScopeManager.stop();
// instance.$destroy();
// instance.$el.innerHTML = '';
// instance = null;
instance.$destroy()
instance.$el.innerHTML = ''
instance = null
document.body.appendChild = originFn
} }
new Vue({
el: '#app',
router,
i18n,
cookie,
store,
components: { App },
template: '<App/>'
}).$mount('#app')
import { initGlobalState } from 'qiankun';
// 初始化空状态(主应用调用时会覆盖)
const initialState = {
baseInfo: {},
token: '',
menus: [],
};
// 封装状态管理类
class GlobalState {
constructor() {
this.actions = initGlobalState(initialState);
this.state = initialState;
this.listeners = new Set();
// 监听主应用状态变化
this.actions.onGlobalStateChange((state, prevState) => {
this.state = state;
this.notifyListeners();
});
}
// 获取当前状态
getState() {
console.log(this.state)
return this.state;
}
// 更新状态(会自动同步到主应用和其他子应用)
setState(newState) {
this.actions.setGlobalState({ ...this.state, ...newState });
}
// 添加状态监听
subscribe(listener) {
this.listeners.add(listener);
return () => this.listeners.delete(listener);
}
// 通知所有监听器
notifyListeners() {
this.listeners.forEach(listener => listener(this.state));
}
}
// 单例模式导出
export const globalState = new GlobalState();
\ No newline at end of file
__webpack_public_path__ = window.__POWERED_BY_QIANKUN__
? window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__
: `http://localhost:8081/`;
const appScopeManager = {
currentApp: null,
scopeAttribute: 'data-qk-scope',
start(appName) {
this.currentApp = appName
document.documentElement.setAttribute(this.scopeAttribute, appName)
},
stop() {
document.documentElement.removeAttribute(this.scopeAttribute)
this.currentApp = null
}
}
// 重写DOM操作方法
function patchDOM() {
const rawCreateElement = Document.prototype.createElement
Document.prototype.createElement = function(tagName, options) {
const element = rawCreateElement.call(this, tagName, options)
if (appScopeManager.currentApp) {
element.setAttribute(appScopeManager.scopeAttribute, appScopeManager.currentApp)
}
return element
}
}
\ No newline at end of file
...@@ -2,6 +2,17 @@ import Vue from 'vue' ...@@ -2,6 +2,17 @@ import Vue from 'vue'
import Router from 'vue-router' import Router from 'vue-router'
import routerConfig from '../router/config' import routerConfig from '../router/config'
Vue.use(Router) Vue.use(Router)
const isQiankun = window.__POWERED_BY_QIANKUN__;
const originalPush = Router.prototype.push
Router.prototype.push = function push(location) {
return originalPush.call(this, location).catch(err => {
if (err.name !== 'NavigationDuplicated') {
console.log('路由错误,已经抛出错误:',err)
}
})
}
export default new Router({ export default new Router({
mode: isQiankun?"history":"hash",
base: isQiankun ? '/erp' : process.env.BASE_URL,
routes:routerConfig.routes routes:routerConfig.routes
}) })
/*
* 黑名单及静音列表
*/
import store from '../'
// 完成添加/删除黑名单,初始化获取黑名单列表,都会触发此函数
export function onBlacklist (blacks) {
blacks = blacks.map(item => {
if (typeof item.isBlack !== 'boolean') {
item.isBlack = true
}
return item
})
// 更新黑名单列表
store.commit('updateBlacklist', blacks)
// 在好友身上打上标记
store.commit('updateFriends', blacks)
// 更新好友信息字典
store.commit('updateUserInfo', blacks)
}
export function onMarkInBlacklist (obj) {
obj = obj || obj2
let account = obj.account
// 说明是自己,被别人加入黑名单
if (account === store.state.userUID) {
} else {
// 说明是别人的帐号,黑名单通知
if (typeof obj.isAdd === 'boolean') {
onBlacklist([{
account,
isBlack: obj.isAdd
}])
}
}
}
export function updateBlack ({state}, {account, isBlack}) {
const nim = state.nim
if (account && (typeof isBlack === 'boolean')) {
nim.markInBlacklist({
account,
// `true`表示加入黑名单, `false`表示从黑名单移除
isAdd: isBlack,
done: function (error, obj) {
if (error) {
alert(error)
return
}
onMarkInBlacklist(obj)
}
})
}
}
import store from '../'
import config from '../../configs'
// 用于demo记录封面
export function initChatroomInfos ({state, commit}, obj) {
commit('initChatroomInfos', obj)
}
export function getChatroomInfo ({state, commit, dispatch}) {
const chatroom = state.currChatroom
if (chatroom) {
chatroom.getChatroom({
done: function getChatroomDone (error, info) {
if (error) {
alert(error.message)
return
}
info = info.chatroom || {creator: ''}
let creator = info.creator
chatroom.getChatroomMembersInfo({
accounts: [creator],
done: function getChatroomMembersInfoDone (error, user) {
if (error) {
alert(error.message)
return
}
commit('getChatroomInfo', Object.assign(info, {actor: user.members[0]}))
}
})
}
})
}
}
export function getChatroomMembers ({state, commit, dispatch}) {
// 先拉管理员
getChatroomMembersLocal(false, function (obj) {
commit('updateChatroomMembers', Object.assign(obj, {type: 'put'}))
// 再拉成员列表
getChatroomMembersLocal(true, function (obj) {
commit('updateChatroomMembers', Object.assign(obj, {type: 'put'}))
})
})
}
function getChatroomMembersLocal (isGuest, callback) {
const chatroom = store.state.currChatroom
if (chatroom) {
chatroom.getChatroomMembers({
guest: isGuest,
limit: 100,
done: function getChatroomMembersDone (error, obj) {
if (error) {
alert(error.message)
return
}
callback(obj)
}
})
}
}
export function clearChatroomMembers ({state, commit}) {
commit('updateChatroomMembers', {type: 'destroy'})
}
import store from '../'
import config from '../../configs'
import util from '../../utils'
import {formatMsg} from './msgs'
export function onChatroomMsgs (msgs) {
if (!Array.isArray(msgs)) {
msgs = [msgs]
}
msgs = msgs.map(msg => {
return formatMsg(msg)
})
if (store.state.currChatroomId) {
store.commit('updateCurrChatroomMsgs', {
type: 'put',
msgs
})
}
}
function onSendMsgDone (error, msg) {
store.dispatch('hideLoading')
if (error) {
alert(error.message)
return
}
onChatroomMsgs([msg])
}
export function sendChatroomMsg ({state, commit}, obj) {
const chatroom = state.currChatroom
obj = obj || {}
let type = obj.type || ''
store.dispatch('showLoading')
switch (type) {
case 'text':
chatroom.sendText({
text: obj.text,
done: onSendMsgDone
})
break
case 'custom':
chatroom.sendCustomMsg({
content: JSON.stringify(obj.content),
pushContent: obj.pushContent,
done: onSendMsgDone
})
}
}
export function sendChatroomRobotMsg ({state, commit}, obj) {
const chatroom = state.currChatroom
let {type, robotAccid, content, params, target, body} = obj
if (type === 'text') {
chatroom.sendRobotMsg({
robotAccid,
content: {
type: 'text',
content
},
body,
done: onSendMsgDone
})
} else if (type === 'welcome') {
chatroom.sendRobotMsg({
robotAccid,
content: {
type: 'welcome'
},
body,
done: onSendMsgDone
})
} else if (type === 'link') {
chatroom.sendRobotMsg({
robotAccid,
content: {
type: 'link',
params,
target
},
body,
done: onSendMsgDone
})
}
}
export function sendChatroomFileMsg ({state, commit}, obj) {
const chatroom = state.currChatroom
let {fileInput} = Object.assign({}, obj)
let type = 'file'
if (/\.(png|jpg|bmp|jpeg|gif)$/i.test(fileInput.value)) {
type = 'image'
} else if (/\.(mov|mp4|ogg|webm)$/i.test(fileInput.value)) {
type = 'video'
}
store.dispatch('showLoading')
chatroom.sendFile({
type,
fileInput,
uploadprogress: function (data) {
},
uploaderror: function () {
},
uploaddone: function (error, file) {
},
beforesend: function (msg) {
},
done: function (error, msg) {
onSendMsgDone(error, msg)
}
})
}
export function getChatroomHistoryMsgs ({state, commit}, obj) {
const chatroom = state.currChatroom
if (chatroom) {
let {timetag} = Object.assign({}, obj)
let options = {
timetag,
limit: config.localMsglimit || 20,
done: function getChatroomHistoryMsgsDone (error, obj) {
if (obj.msgs) {
if (obj.msgs.length === 0) {
commit('setNoMoreHistoryMsgs')
} else {
let msgs = obj.msgs.map(msg => {
return formatMsg(msg)
})
commit('updateCurrChatroomMsgs', {
type: 'concat',
msgs
})
}
}
store.dispatch('hideLoading')
}
}
store.dispatch('showLoading')
nim.getHistoryMsgs(options)
}
}
/*
* 用户关系及好友关系托管
*/
import store from '../'
// 好友关系,回调
export function onFriends (friends) {
friends = friends.map(item => {
if (typeof item.isFriend !== 'boolean') {
item.isFriend = true
}
return item
})
store.commit('updateFriends', friends)
// 更新好友信息字典,诸如昵称
store.commit('updateUserInfo', friends)
}
// 更新好友资料,添加好友成功
export function onUpdateFriend (error, friends) {
if (error) {
alert(error)
return
}
if (!Array.isArray(friends)) {
friends = [friends]
}
friends = friends.map(item => {
if (typeof item.isFriend !== 'boolean') {
item.isFriend = true
}
return item
})
// 补充好友资料
store.dispatch('searchUsers', {
accounts: friends.map(item => {
return item.account
}),
done: (users) => {
const nim = store.state.nim
friends = nim.mergeFriends(friends, users)
// 更新好友列表
store.commit('updateFriends', friends)
// 更新好友资料
store.commit('updateUserInfo', friends)
}
})
}
// 删除好友,这里使用标记删除
export function onDeleteFriend (error, friends) {
if (error) {
alert(error)
return
}
if (!Array.isArray(friends)) {
friends = [friends]
}
friends = friends.map(item => {
item.isFriend = false
return item
})
// 更新好友列表
store.commit('updateFriends', [], friends)
// 更新好友资料
store.commit('updateUserInfo', friends)
}
export function onSyncFriendAction (obj) {
switch (obj.type) {
case 'addFriend':
// alert('你在其它端直接加了一个好友' + obj.account + ', 附言' + obj.ps);
onUpdateFriend(null, obj.friend)
break
case 'applyFriend':
// alert('你在其它端申请加了一个好友' + obj.account + ', 附言' + obj.ps);
break
case 'passFriendApply':
alert('你在其它端通过了一个好友申请' + obj.account + ', 附言' + obj.ps)
onUpdateFriend(null, obj.friend)
break
case 'rejectFriendApply':
// alert('你在其它端拒绝了一个好友申请' + obj.account + ', 附言' + obj.ps);
break
case 'deleteFriend':
// alert('你在其它端删了一个好友' + obj.account);
onDeleteFriend(null, {
account: obj.account
})
break
case 'updateFriend':
// alert('你在其它端更新了一个好友', obj.friend);
onUpdateFriend(null, obj.friend)
break
}
}
// 更新好友昵称
export function updateFriend ({state, commit}, friend) {
const nim = state.nim
nim.updateFriend({
account: friend.account,
alias: friend.alias,
done: onUpdateFriend
})
}
export function addFriend ({state, commit}, account) {
const nim = state.nim
nim.addFriend({
account,
ps: '',
done: onUpdateFriend
})
}
export function deleteFriend ({state, commit}, account) {
const nim = state.nim
nim.deleteFriend({
account,
done: onDeleteFriend
})
}
// Action 提交的是 mutation,而不是直接变更状态。
// Action 可以包含任意异步操作。
import cookie from '../../utils/cookie'
import pageUtil from '../../utils/page'
/* 导出actions方法 */
import {showLoading, hideLoading, showFullscreenImg, hideFullscreenImg} from './widgetUi'
import {initNimSDK} from './initNimSDK'
import {initChatroomSDK, resetChatroomSDK} from './initChatroomSDK'
import {updateBlack} from './blacks'
import {updateFriend, addFriend, deleteFriend} from './friends'
import {resetSearchResult, searchUsers} from './search'
import {deleteSession, setCurrSession, resetCurrSession} from './session'
import {sendMsg, sendTip, sendFileMsg, sendMsgReceipt, sendRobotMsg, revocateMsg, getHistoryMsgs, resetNoMoreHistoryMsgs, continueRobotMsg, sendDataUrlMsg} from './msgs'
import {markSysMsgRead, resetSysMsgs, markCustomSysMsgRead} from './sysMsgs'
import {sendChatroomMsg, sendChatroomRobotMsg, sendChatroomFileMsg, getChatroomHistoryMsgs} from './chatroomMsgs'
import {initChatroomInfos, getChatroomInfo, getChatroomMembers, clearChatroomMembers} from './chatroomInfos'
import {delegateTeamFunction, onTeamNotificationMsg, enterSettingPage, getTeamMembers, checkTeamMsgReceipt, getTeamMsgReads,getTeam} from './team'
import {createTeam} from './team'
function connectNim ({state, commit, dispatch}, obj) {
let _storage=JSON.parse(window.localStorage.userInfo);
let {force} = Object.assign({}, obj)
// 操作为内容页刷新页面,此时无nim实例
if (!state.nim || force) {
let loginInfo = {
// uid: '15281055345',
// uid: '18380464246',
uid: _storage.ImAccount,
sdktoken: _storage.ImToken
}
if (!loginInfo.uid) {
// 无cookie,直接跳转登录页
pageUtil.turnPage('无历史登录记录,请重新登录', 'login')
} else {
// 有cookie,重新登录
dispatch('initNimSDK', loginInfo)
}
}
}
function connectChatroom ({state, commit, dispatch}, obj) {
let {chatroomId} = Object.assign({}, obj)
const nim = state.nim
if (nim) {
dispatch('showLoading')
nim.getChatroomAddress({
chatroomId,
done: function getChatroomAddressDone (error, obj) {
if (error) {
alert(error.message)
location.href = '#/room'
return
}
dispatch('initChatroomSDK', obj)
}
})
}
}
export default {
updateRefreshState ({commit}) {
commit('updateRefreshState')
},
// UI 及页面状态变更
showLoading,
hideLoading,
showFullscreenImg,
hideFullscreenImg,
continueRobotMsg,
// 连接sdk请求,false表示强制重连
connect (store, obj) {
let {type} = Object.assign({}, obj)
// type 可为 nim chatroom
type = type || 'nim'
switch (type) {
case 'nim':
connectNim(store, obj)
break
case 'chatroom':
connectChatroom(store, obj)
break
}
},
// 用户触发的登出逻辑
logout ({ state, commit }) {
cookie.delCookie('uid')
cookie.delCookie('sdktoken')
if (state.nim) {
state.nim.disconnect()
}
},
// 初始化 重新连接SDK
initNimSDK,
// 清空所有搜索历史纪录
resetSearchResult,
// 搜索用户信息
searchUsers,
// 更新黑名单
updateBlack,
// 更新好友
addFriend,
deleteFriend,
updateFriend,
// 删除会话
deleteSession,
// 设置当前会话
setCurrSession,
// 重置当前会话
resetCurrSession,
// 发送消息
sendMsg,
sendTip,
sendFileMsg,
sendDataUrlMsg,
sendRobotMsg,
// 发送消息已读回执
sendMsgReceipt,
// 消息撤回
revocateMsg,
getHistoryMsgs,
// 重置历史消息状态
resetNoMoreHistoryMsgs,
// 标记系统消息已读
markSysMsgRead,
markCustomSysMsgRead,
resetSysMsgs,
initChatroomSDK,
initChatroomInfos,
resetChatroomSDK,
sendChatroomMsg,
sendChatroomRobotMsg,
sendChatroomFileMsg,
getChatroomHistoryMsgs,
getChatroomInfo,
getChatroomMembers,
clearChatroomMembers,
// 代理sdk中的群方法
delegateTeamFunction,
// 处理群消息回调
onTeamNotificationMsg,
// 进入群信息设置页
enterSettingPage,
// 获取群成员
getTeamMembers,
getTeam,
// 群消息回执检查
checkTeamMsgReceipt,
// 查询群消息回执已读列表
getTeamMsgReads,
createTeam
}
/*
* 聊天室SDK,依赖于nim sdk
*/
import config from '../../configs'
import pageUtil from '../../utils/page'
import util from '../../utils'
import store from '../'
import {onChatroomMsgs} from './chatroomMsgs'
// let sdkPath = '@/sdk/' + config.sdk
// const SDK = require(sdkPath)
// 切换聊天室之前需要断开连接,原因是移动端不断累积连接实例,消息并发较大时会有性能问题
// 重新初始化 NIM SDK
export function initChatroomSDK ({ state, commit, dispatch }, obj) {
let {chatroomId, address} = obj
if (chatroomId && address) {
if (state.chatroomInsts[chatroomId]) {
state.chatroomInsts[chatroomId].connect()
} else {
state.chatroomInsts[chatroomId] = SDK.Chatroom.getInstance({
appKey: config.appkey,
account: state.userUID,
token: state.sdktoken,
chatroomId,
chatroomAddresses: address,
onconnect: function onChatroomConnect (chatroom) {
dispatch('hideLoading')
commit('setCurrChatroom', chatroomId)
},
onerror: function onChatroomError (error, obj) {
dispatch('hideLoading')
if (error) {
location.href = '#/room'
}
},
onwillreconnect: function onChatroomWillReconnect (obj) {
// 此时说明 `SDK` 已经断开连接, 请开发者在界面上提示用户连接已断开, 而且正在重新建立连接
},
ondisconnect: function onChatroomDisconnect (error) {
// 此时说明 `SDK` 处于断开状态, 切换聊天室也会触发次回调
dispatch('hideLoading')
if (error) {
switch (error.code) {
// 账号或者密码错误, 请跳转到登录页面并提示错误
case 302:
// 此逻辑与nim sdk错误逻辑相同,复用nim sdk的
// 如果单用聊天室功能需要在此做处理
break
case 13003:
alert('抱歉,你已被主播拉入了黑名单')
location.href = '#/room'
break
// 被踢, 请提示错误后跳转到登录页面
case 'kicked':
if (error.reason === 'managerKick') {
alert('你已被管理员移出聊天室')
location.href = '#/room'
} else if (error.reason === 'blacked') {
alert('你已被管理员拉入黑名单,不能再进入')
location.href = '#/room'
}
break
default:
break
}
}
},
// 聊天室消息
onmsgs: onChatroomMsgs
})
}
} else {
alert('没有聊天室地址')
}
}
export function resetChatroomSDK ({state, commit, dispatch}, chatroomId) {
if (chatroomId) {
state.chatroomInsts[chatroomId].disconnect()
} else {
for (let tempRoomId in state.chatroomInsts) {
state.chatroomInsts[tempRoomId].disconnect()
}
}
commit('resetCurrChatroom')
}
/*
* SDK连接相关
*/
import config from '../../configs'
import pageUtil from '../../utils/page'
import util from '../../utils'
import store from '../'
import {onFriends, onSyncFriendAction} from './friends'
import {onRobots} from './robots'
import {onBlacklist, onMarkInBlacklist} from './blacks'
import {onMyInfo, onUserInfo} from './userInfo'
import {onSessions, onUpdateSession} from './session'
import {onRoamingMsgs, onOfflineMsgs, onMsg} from './msgs'
import {onSysMsgs, onSysMsg, onSysMsgUnread, onCustomSysMsgs} from './sysMsgs'
import { onTeams, onSynCreateTeam, onCreateTeam, onUpdateTeam, onTeamMembers, onUpdateTeamMember, onAddTeamMembers, onRemoveTeamMembers, onUpdateTeamManagers, onDismissTeam, onUpdateTeamMembersMute, onTeamMsgReceipt} from './team'
const SDK = require('../../../static/sdk/NIM_Web_SDK_v5.0.0.js')
// 重新初始化 NIM SDK
export function initNimSDK ({ state, commit, dispatch }, loginInfo) {
if (state.nim) {
state.nim.disconnect()
}
dispatch('showLoading')
// 初始化SDK
window.nim = state.nim = SDK.NIM.getInstance({
// debug: true && { api: 'info', style: 'font-size:12px;color:blue;background-color:rgba(0,0,0,0.1)' },
appKey: config.appkey,
account: loginInfo.uid,
token: loginInfo.sdktoken,//(process.env.NODE_ENV === 'development'?'1':loginInfo.sdktoken),
db: false,
syncSessionUnread: true,
syncRobots: true,
autoMarkRead: true, // 默认为true
onconnect: function onConnect (event) {
if (loginInfo) {
// 连接上以后更新uid
commit('updateUserUID', loginInfo)
}
},
onerror: function onError (event) {
},
onwillreconnect: function onWillReconnect () {
},
ondisconnect: function onDisconnect (error) {
switch (error.code) {
// 账号或者密码错误, 请跳转到登录页面并提示错误
case 302:
// pageUtil.turnPage('帐号或密码错误', 'login')
break
// 被踢, 请提示错误后跳转到登录页面
case 'kicked':
let map = {
PC: '电脑版',
Web: '网页版',
Android: '手机版',
iOS: '手机版',
WindowsPhone: '手机版'
}
let str = error.from
let errorMsg = '你的帐号已在其他地方登录'// `你的帐号于${util.formatDate(new Date())}被${(map[str] || '其他端')}踢出下线,请确定帐号信息安全!`
// pageUtil.turnPage(errorMsg, 'login')
// ipc.send('signOut')
break
default:
break
}
},
// // 多端登录
// onloginportschange: onLoginPortsChange,
// 用户关系及好友关系
onblacklist: onBlacklist,
onsyncmarkinblacklist: onMarkInBlacklist,
// onmutelist: onMutelist,
// onsyncmarkinmutelist: onMarkInMutelist,
onfriends: onFriends,
onsyncfriendaction: onSyncFriendAction,
// 机器人
onrobots: onRobots,
// 用户名片 - actions/userInfo
onmyinfo: onMyInfo,
onupdatemyinfo: onMyInfo,
onusers: onUserInfo,
onupdateuser: onUserInfo,
// // 群组
onteams: onTeams,
onsynccreateteam: onCreateTeam,
onteammembers: onTeamMembers,
// // 会话
onsessions: onSessions,
onupdatesession: onUpdateSession,
// // 消息
onroamingmsgs: onRoamingMsgs,
onofflinemsgs: onOfflineMsgs,
onmsg: onMsg,
// // 系统通知
onsysmsg: onSysMsg,
onofflinesysmsgs: onSysMsgs,
onupdatesysmsg: onSysMsg, // 通过、拒绝好友申请会收到此回调
onsysmsgunread: onSysMsgUnread,
onupdatesysmsgunread: onSysMsgUnread,
onofflinecustomsysmsgs: onCustomSysMsgs,
oncustomsysmsg: onCustomSysMsgs,
// // 同步完成
onsyncdone: function onSyncDone () {
dispatch('hideLoading')
// 说明在聊天列表页
if (store.state.currSessionId) {
dispatch('setCurrSession', store.state.currSessionId)
}
}
})
}
import store from '../'
import config from '../../configs'
import util from '../../utils'
export function formatMsg(msg) {
const nim = store.state.nim
if (msg.type === 'robot') {
if (msg.content && msg.content.flag === 'bot') {
if (msg.content.message) {
msg.content.message = msg.content.message.map(item => {
switch (item.type) {
case 'template':
item.content = nim.parseRobotTemplate(item.content)
break
case 'text':
case 'image':
case 'answer':
break
}
return item
})
}
}
}
return msg
}
export function onRoamingMsgs(obj) {
let msgs = obj.msgs.map(msg => {
return formatMsg(msg)
})
store.commit('updateMsgs', msgs)
}
export function onOfflineMsgs(obj) {
let msgs = obj.msgs.map(msg => {
return formatMsg(msg)
})
store.commit('updateMsgs', msgs)
}
export function onMsg(msg) {
msg = formatMsg(msg)
store.commit('putMsg', msg)
if (msg.sessionId === store.state.currSessionId) {
store.commit('updateCurrSessionMsgs', {
type: 'put',
msg
})
// 发送已读回执
store.dispatch('sendMsgReceipt')
}
}
function onSendMsgDone(error, msg) {
store.dispatch('hideLoading')
if (error) {
// 被拉黑
if (error.code === 7101) {
msg.status = 'success'
alert(error.message)
} else {
alert(error.message)
}
}
onMsg(msg)
}
// 消息撤回
export function onRevocateMsg(error, msg) {
const nim = store.state.nim
if (error) {
if (error.code === 508) {
alert('发送时间超过2分钟的消息,不能被撤回')
} else {
alert(error)
}
return
}
let tip = ''
if (msg.from === store.state.userUID) {
tip = '你撤回了一条消息'
} else {
let userInfo = store.state.userInfos[msg.from]
if (userInfo) {
tip = `${util.getFriendAlias(userInfo)}撤回了一条消息`
} else {
tip = '对方撤回了一条消息'
}
}
nim.sendTipMsg({
isLocal: true,
scene: msg.scene,
to: msg.to,
tip,
time: msg.time,
done: function sendTipMsgDone(error, tipMsg) {
let idClient = msg.deletedIdClient || msg.idClient
store.commit('replaceMsg', {
sessionId: msg.sessionId,
idClient,
msg: tipMsg
})
if (msg.sessionId === store.state.currSessionId) {
store.commit('updateCurrSessionMsgs', {
type: 'replace',
idClient,
msg: tipMsg
})
}
}
})
}
export function revocateMsg({
state,
commit
}, msg) {
const nim = state.nim
let {
idClient
} = msg
msg = Object.assign(msg, state.msgsMap[idClient])
nim.deleteMsg({
msg,
done: function deleteMsgDone(error) {
onRevocateMsg(error, msg)
}
})
}
// 发送普通消息
export function sendMsg({
state,
commit
}, obj) {
const nim = state.nim
obj = obj || {}
let type = obj.type || ''
store.dispatch('showLoading')
switch (type) {
case 'text':
nim.sendText({
scene: obj.scene,
to: obj.to,
text: obj.text,
custom: JSON.stringify(obj.custom),
done: onSendMsgDone
})
break
case 'custom':
nim.sendCustomMsg({
scene: obj.scene,
to: obj.to,
pushContent: obj.pushContent,
content: JSON.stringify(obj.content),
done: onSendMsgDone,
custom: JSON.stringify(obj.custom)
})
}
}
export function sendTip({
state,
commit
}, obj) {
const nim = store.state.nim
nim.sendTipMsg({
scene: obj.scene,
to: obj.to,
tip: obj.tip,
done: function sendTipMsgDone(error, msg) {
// 超哥 do something
onSendMsgDone(error, msg)
}
})
}
// 发送文件消息
export function sendFileMsg({
state,
commit
}, obj) {
const nim = state.nim
let {
scene,
to,
fileInput
} = obj
let type = 'file'
if (/\.(png|jpg|bmp|jpeg|gif)$/i.test(fileInput.value)) {
type = 'image'
} else if (/\.(mov|mp4|ogg|webm)$/i.test(fileInput.value)) {
type = 'video'
}
store.dispatch('showLoading')
nim.sendFile({
scene,
to,
type,
fileInput,
uploadprogress: function (data) {
},
uploaderror: function () {
},
uploaddone: function (error, file) {
},
beforesend: function (msg) {
},
done: function (error, msg) {
onSendMsgDone(error, msg)
}
})
}
export function sendDataUrlMsg({
state,
commit
}, obj) {
const nim = state.nim
let {
scene,
to,
dataURL,
name
} = obj
let type = 'file'
if (/(png|jpg|bmp|jpeg|gif)$/i.test(name)) {
type = 'image'
} else if (/(mov|mp4|ogg|webm)$/i.test(name)) {
type = 'video'
}
let otherMsg = {
'fileName': name
}
store.dispatch('showLoading')
nim.sendFile({
scene: scene,
to: to,
type: type,
dataURL: dataURL,
custom: JSON.stringify(otherMsg),
uploadprogress: function (data) {
},
uploaderror: function () {
},
uploaddone: function (error, file) {
},
beforesend: function (msg) {
},
done: function (error, msg) {
onSendMsgDone(error, msg)
}
})
}
// 发送机器人消息
export function sendRobotMsg({
state,
commit
}, obj) {
const nim = state.nim
let {
type,
scene,
to,
robotAccid,
content,
params,
target,
body
} = obj
scene = scene || 'p2p'
if (type === 'text') {
nim.sendRobotMsg({
scene,
to,
robotAccid: robotAccid || to,
content: {
type: 'text',
content
},
body,
done: onSendMsgDone
})
} else if (type === 'welcome') {
nim.sendRobotMsg({
scene,
to,
robotAccid: robotAccid || to,
content: {
type: 'welcome'
},
body,
done: onSendMsgDone
})
} else if (type === 'link') {
nim.sendRobotMsg({
scene,
to,
robotAccid: robotAccid || to,
content: {
type: 'link',
params,
target
},
body,
done: onSendMsgDone
})
}
}
// 发送消息已读回执
export function sendMsgReceipt({
state,
commit
}) {
// 如果有当前会话
let currSessionId = store.state.currSessionId
if (currSessionId) {
// 只有点对点消息才发已读回执
if (util.parseSession(currSessionId).scene === 'p2p') {
let msgs = store.state.currSessionMsgs
const nim = state.nim
if (state.sessionMap[currSessionId]) {
nim.sendMsgReceipt({
msg: state.sessionMap[currSessionId].lastMsg,
done: function sendMsgReceiptDone(error, obj) {
// do something
}
})
}
}
}
}
function sendMsgReceiptDone(error, obj) {
}
export function getHistoryMsgs({
state,
commit
}, obj) {
const nim = state.nim
if (nim) {
let {
scene,
to
} = obj
let options = {
scene,
to,
reverse: false,
asc: true,
limit: config.localMsglimit || 20,
done: function getHistoryMsgsDone(error, obj) {
if (obj.msgs) {
if (obj.msgs.length === 0) {
commit('setNoMoreHistoryMsgs')
} else {
let msgs = obj.msgs.map(msg => {
return formatMsg(msg)
})
commit('updateCurrSessionMsgs', {
type: 'concat',
msgs: msgs
})
}
}
store.dispatch('hideLoading')
}
}
if (state.currSessionLastMsg) {
options = Object.assign(options, {
lastMsgId: state.currSessionLastMsg.idServer,
endTime: state.currSessionLastMsg.time
})
}
store.dispatch('showLoading')
nim.getHistoryMsgs(options)
}
}
export function resetNoMoreHistoryMsgs({
commit
}) {
commit('resetNoMoreHistoryMsgs')
}
// 继续与机器人会话交互
export function continueRobotMsg({
commit
}, robotAccid) {
commit('continueRobotMsg', robotAccid)
}
import store from '../'
export function onRobots (robots) {
store.commit('updateRobots', robots)
}
import {formatUserInfo} from './userInfo'
export function resetSearchResult ({state, commit}) {
commit('updateSearchlist', {
type: 'user',
list: []
})
commit('updateSearchlist', {
type: 'team',
list: []
})
}
export function searchUsers ({state, commit}, obj) {
let {accounts, done} = obj
const nim = state.nim
if (!Array.isArray(accounts)) {
accounts = [accounts]
}
nim.getUsers({
accounts,
done: function searchUsersDone (error, users) {
if (error) {
alert(error)
return
}
commit('updateSearchlist', {
type: 'user',
list: users
})
let updateUsers = users.filter(item => {
let account = item.account
if (item.account === state.userUID) {
return false
}
let userInfo = state.userInfos[account] || {}
if (userInfo.isFriend) {
return false
}
return true
})
updateUsers = updateUsers.map(item => {
return formatUserInfo(item)
})
commit('updateUserInfo', updateUsers)
if (done instanceof Function) {
done(users)
}
}
})
}
/*
* 会话列表
*/
import store from '../'
// 如果会话对象不是好友,需要更新好友名片
function updateSessionAccount (sessions) {
let accountsNeedSearch = []
sessions.forEach(item => {
if (item.scene === 'p2p') {
// 如果不存在缓存资料
if (!store.state.userInfos[item.to]) {
accountsNeedSearch.push(item.to)
}
}
})
if (accountsNeedSearch.length > 0) {
store.dispatch('searchUsers', {
accounts: accountsNeedSearch
})
}
}
// onSessions只在初始化完成后回调
export function onSessions (sessions) {
updateSessionAccount(sessions)
store.commit('updateSessions', sessions)
}
export function onUpdateSession (session) {
let sessions = [session]
updateSessionAccount(sessions)
store.commit('updateSessions', sessions)
}
export function deleteSession ({state, commit}, sessionId) {
const nim = state.nim
sessionId = sessionId || ''
let scene = null
let account = null
if (/^p2p-/.test(sessionId)) {
scene = 'p2p'
account = sessionId.replace(/^p2p-/, '')
} else if (/^team-/.test(sessionId)) {
scene = 'team'
account = sessionId.replace(/^team-/, '')
}
if (account && scene) {
nim.deleteSession({
scene,
to: account,
done: function deleteServerSessionDone (error, obj) {
if (error) {
alert(error)
return
}
nim.deleteLocalSession({
id: sessionId,
done: function deleteLocalSessionDone (error, obj) {
if (error) {
alert(error)
return
}
commit('deleteSessions', [sessionId])
}
})
}
})
}
}
export function setCurrSession ({state, commit, dispatch}, sessionId) {
const nim = state.nim
if (sessionId) {
commit('updateCurrSessionId', {
type: 'init',
sessionId
})
if (nim) {
// 如果在聊天页面刷新,此时还没有nim实例,需要在onSessions里同步
nim.setCurrSession(sessionId)
commit('updateCurrSessionMsgs', {
type: 'init',
sessionId
})
// 发送已读回执
dispatch('sendMsgReceipt')
}
}
}
export function resetCurrSession ({state, commit}) {
const nim = state.nim
if(!nim){
return;
}
nim.resetCurrSession()
commit('updateCurrSessionMsgs', {
type: 'destroy'
})
}
import store from '../'
import {onUpdateFriend, onDeleteFriend} from './friends'
import {onRevocateMsg} from './msgs'
export function onSysMsgs (sysMsgs) {
store.commit('updateSysMsgs', sysMsgs)
}
export function onSysMsg (sysMsg) {
switch (sysMsg.type) {
// 在其他端添加或删除好友
case 'addFriend':
onUpdateFriend(null, {
account: sysMsg.from
})
store.commit('updateSysMsgs', [sysMsg])
break
case 'deleteFriend':
onDeleteFriend(null, {
account: sysMsg.from
})
break
// 对方消息撤回
case 'deleteMsg':
sysMsg.sessionId = `${sysMsg.scene}-${sysMsg.from}`
onRevocateMsg(null, sysMsg)
break
}
}
export function onSysMsgUnread (obj) {
store.commit('updateSysMsgUnread', obj)
}
export function onCustomSysMsgs (customSysMsgs) {
if (!Array.isArray(customSysMsgs)) {
customSysMsgs = [customSysMsgs]
}
customSysMsgs = customSysMsgs.filter(msg => {
if (msg.type === 'custom') {
if (msg.content) {
try {
let content = JSON.parse(msg.content)
// 消息正在输入中
if ((content.id + '') === '1') {
return false
}
} catch (e) {}
}
}
return true
})
if (customSysMsgs.length > 0) {
store.commit('updateCustomSysMsgs', customSysMsgs)
}
}
// 不传obj则全部重置
export function markSysMsgRead ({state, commit}, obj) {
const nim = state.nim
let sysMsgs = []
if (obj && obj.sysMsgs) {
sysMsgs = obj.sysMsgs
} else {
sysMsgs = state.sysMsgs
}
if (Array.isArray(sysMsgs) && sysMsgs.length > 0) {
nim.markSysMsgRead({
sysMsgs,
done: function (error, obj) {
}
})
}
}
export function markCustomSysMsgRead ({state, commit}) {
commit('updateCustomSysMsgUnread', {
type: 'reset'
})
}
export function resetSysMsgs ({state, commit}, obj) {
commit('resetSysMsgs', obj)
}
import store from '../'
// 收到群列表及更新群列表接口
export function onTeams(teams) {
if (!Array.isArray(teams)) {
teams = [teams]
}
teams.forEach(team=>{
if (team.validToCurrentUser === undefined) {
team.validToCurrentUser = true
}
if (team.avatar && team.avatar.indexOf('nim.nosdn.127') >0 && team.avatar.indexOf('?imageView')===-1) {
team.avatar = team.avatar + '?imageView&thumbnail=300y300'
}
})
store.commit('updateTeamList', teams)
}
// 收到群成员及更新群成员接口
export function onTeamMembers(obj) {
store.commit('updateTeamMembers', obj)
}
export function onCreateTeam({team, owner}) {
onTeams(team)
onTeamMembers({
teamId: team.teamId,
members: [owner]
})
}
export function createTeam({state, commit},obj) {
onTeams(obj.team)
onTeamMembers({
teamId: obj.team.teamId,
members: [obj.owner]
})
}
export function onSynCreateTeam(team){
onTeams(team)
}
export function onDismissTeam(obj) {
store.commit('updateTeamList', {
invalid: { teamId: obj.teamId }
})
}
export function onUpdateTeam(team) {
onTeams(team)
}
export function onTeamNotificationMsg({state, commit}, msg) {
if (msg.attach.type === 'updateTeam' && msg.attach.team) {
store.commit('updateTeamInfo', msg.attach.team)
}
if (msg.attach.type === 'transferTeam') {
onTeamMembers({
teamId: msg.attach.team.teamId,
members: msg.attach.members
})
}
}
export function onAddTeamMembers(obj) {
obj.accounts.forEach(account=>{
// 自己被拉入群时更新群列表
if (account === store.state.userUID) {
let team = [obj.team]
onTeams(team)
}
})
onTeamMembers({
teamId: obj.team.teamId,
members: obj.members
})
}
export function onRemoveTeamMembers(obj) {
obj.accounts.forEach(account => {
// 自己被移出群时,更新群列表
if (account === store.state.userUID) {
obj.team.validToCurrentUser = false
let team = [obj.team]
onTeams(team)
}
})
store.commit('removeTeamMembersByAccounts', {
teamId: obj.team.teamId,
accounts: obj.accounts
})
}
export function onUpdateTeamMember(teamMember) {
onTeamMembers({
teamId: teamMember.teamId,
members: teamMember
})
}
export function onUpdateTeamMembersMute(obj) {
onTeamMembers({
teamId: obj.team.teamId,
members: obj.members
})
}
export function onUpdateTeamManagers(obj) {
onTeamMembers({
teamId: obj.team.teamId,
members: obj.members
})
}
export function onTeamMsgReceipt(obj) {
//群消息回执通知
obj.teamMsgReceipts.forEach(item => {
if (item.teamId === store.state.currReceiptQueryTeamId) {
store.commit('updateSingleTeamMsgReads', item)
}
})
}
// 进入可配置的群信息设置页,进入前改变state中的配置信息,进入页面后读取配置信息更新视图
export function enterSettingPage({commit}, obj) {
commit('updateTeamSettingConfig', obj)
setTimeout(() => {
location.href = `#/teamsetting`
}, 20)
}
/*
* 代理nim sdk中对群组的操作方法
* @functionName nim sdk中的方法名
* @options 传递给sdk方法的参数
*/
export function delegateTeamFunction({state}, {functionName, options}) {
const nim = state.nim
if (functionName && nim[functionName] && typeof nim[functionName] === 'function') {
nim[functionName](options)
} else {
throw(`There is not property of '${functionName}' in nim or '${functionName}' is not a function`)
}
}
export function getTeamMembers({ state }, teamId) {
const nim = state.nim
if (!nim) {
// 防止nim未初始化
setTimeout(() => {
getTeamMembers(store, teamId)
}, 200);
return
}
nim.getTeamMembers({
teamId: teamId,
done: (err, obj) => {
if (obj.members && obj.members!="") {
onTeamMembers({
teamId: obj.teamId,
members: obj.members
})
} else {
setTimeout(() => {
getTeamMembers(store, teamId)
}, 200);
}
}
})
}
export function getTeam({ state }, teamId) {
const nim = state.nim
if (!nim) {
// 防止nim未初始化
setTimeout(() => {
getTeamMembers(store, teamId)
}, 200);
return
}
nim.getTeam({
teamId: teamId,
done: (error, teams) => {
if (!error) {
onTeams(teams);
}
}
})
}
export function addTeamMembers({ state }, teamId, accounts) {
const nim = state.nim
if (!nim) {
// 防止nim未初始化
setTimeout(() => {
addTeamMembers(store, teamId, accounts)
}, 200);
return
}
nim.addTeamMembers({
teamId: teamId,
accounts:accounts,
done: (err, obj) => {
}
})
}
export function removeTeamMembers({ state }, teamId, accounts) {
const nim = state.nim
if (!nim) {
// 防止nim未初始化
setTimeout(() => {
removeTeamMembers(store, teamId, accounts)
}, 200);
return
}
nim.removeTeamMembers({
teamId: teamId,
accounts:accounts,
done: (err, obj) => {
}
})
}
export function getTeamMembersByList({ state }, teamId) {
const nim = state.nim
if (!nim) {
// 防止nim未初始化
setTimeout(() => {
getTeamMembers(store, teamId)
}, 200);
return
}
nim.getTeamMembers({
teamId: teamId,
done: (err, obj) => {
if (obj.members && obj.members!="") {
} else {
setTimeout(() => {
getTeamMembers(store, teamId)
}, 200);
}
}
})
}
export function checkTeamMsgReceipt({state}, msgs) {
var result = /team-(\d+)/.exec(state.currSessionId)
if (!result) {
return null
}
var teamId = result[1]
var needToPeceiptList= getMsgNeedToReceipt(state, teamId, msgs)
if (needToPeceiptList && needToPeceiptList.length>0) {
nim.sendTeamMsgReceipt({
teamMsgReceipts: needToPeceiptList,
done: (err, obj, content) => {
if (!err) {
store.commit('updateSentReceipedMap', needToPeceiptList)
}
}
})
}
store.commit('updateReceiptQueryList', {
teamId: teamId,
msgs: msgs
})
}
// 查询需要发送回执的消息
function getMsgNeedToReceipt(state, teamId, msgs) {
var sentReceipedList = state.sentReceipedMap[teamId] || []
var needToReceipt = msgs.filter(msg => {
// 需要回执,且未发送过
return msg.needMsgReceipt && msg.from !== state.myInfo.account && !sentReceipedList.find(id => id === msg.idServer)
}).map(msg => {
return {
teamId: teamId,
idServer: msg.idServer
}
})
return needToReceipt
}
export function getTeamMsgReads({ state }, needQuery) {
nim.getTeamMsgReads({
teamMsgReceipts: needQuery,
done: (error, obj, content) => {
if (error) {
}else {
store.commit('updateTeamMsgReads', content)
}
}
})
}
/*
* 用户账号信息
*/
import store from '../'
import config from '../../configs'
import util from '../../utils'
export function formatUserInfo (obj) {
const nim = store.state.nim
let gender = ''
switch (obj.gender) {
case 'male':
gender = '男'
break
case 'female':
gender = '女'
break
case 'unknown':
gender = ''
break
}
let custom = obj.custom || ''
try {
custom = JSON.parse(custom)
} catch (e) {
custom = {
data: custom
}
}
if (obj.avatar) {
obj.avatar = nim.viewImageSync({
url: obj.avatar, // 必填
thumbnail: { // 生成缩略图, 可选填
width: 40,
height: 40,
mode: 'cover'
}
})
// obj.avatar += '?imageView&thumbnail=40x40&quality=85'
} else {
obj.avatar = config.defaultUserIcon
}
let result = Object.assign(obj, {
account: obj.account,
nick: obj.nick || '',
avatar: obj.avatar || config.defaultUserIcon,
birth: obj.birth || '',
email: obj.email || '',
tel: obj.tel || '',
gender,
sign: obj.sign || '',
custom,
createTime: obj.createTime || (new Date()).getTime(),
updateTime: obj.updateTime || (new Date()).getTime()
})
return result
}
export function onMyInfo (obj) {
obj = util.mergeObject(store.state.myInfo, obj)
let myInfo = formatUserInfo(obj)
store.commit('updateMyInfo', myInfo)
}
export function onUserInfo (users) {
if (!Array.isArray(users)) {
users = [users]
}
users = users.map(formatUserInfo)
store.commit('updateUserInfo', users)
}
import pageUtil from '../../utils/page'
// 显示加载中进度条
export function showLoading ({state, commit}) {
commit('updateLoading', true)
}
// 隐藏加载中进度条
export function hideLoading ({state, commit}) {
commit('updateLoading', false)
}
// 显示原图片
export function showFullscreenImg ({state, commit}, obj) {
if (obj) {
obj.type = 'show'
commit('updateFullscreenImage', obj)
}
}
// 隐藏原图片
export function hideFullscreenImg ({state, commit}) {
commit('updateFullscreenImage', {
type: 'hide'
})
}
/* 获取数据 */
export default {
getGuestInfo(state) {
return state.guestInfo;
}
}
import Vue from 'vue' import Vue from 'vue'
import Vuex from 'vuex' import Vuex from 'vuex'
import modules from './modules' // import modules from './modules'
import mutations from './mutations' // import mutations from './mutations'
import actions from './actions' // import actions from './actions'
import state from './state' // import state from './state'
import getters from './getters' // import getters from './getters'
Vue.use(Vuex) // Vue.use(Vuex)
export default new Vuex.Store({ // export default new Vuex.Store({
modules, // modules,
// 内存数据状态,UI可通过this.$store.state.* 获得数据 // // 内存数据状态,UI可通过this.$store.state.* 获得数据
state, // state,
// 唯一拥有更改内存数据的接口,不可进行异步操作 // // 唯一拥有更改内存数据的接口,不可进行异步操作
mutations, // mutations,
// 与mutation通讯,ui层写入内存数据的接口,可异步操作 // // 与mutation通讯,ui层写入内存数据的接口,可异步操作
actions, // actions,
// 获取数据 // // 获取数据
getters, // getters,
plugins: [], // plugins: [],
strict: false // strict: false
}) // })
const state = {
main: 0
}
const mutations = {
DECREMENT_MAIN_COUNTER (state) {
state.main--
},
INCREMENT_MAIN_COUNTER (state) {
state.main++
}
}
const actions = {
someAsyncTask ({ commit }) {
// do something async
commit('INCREMENT_MAIN_COUNTER')
}
}
export default {
state,
mutations,
actions
}
/**
* The file enables `@/store/index.js` to import all vuex modules
* in a one-shot manner. There should not be any reason to edit this file.
*/
const files = require.context('.', false, /\.js$/)
const modules = {}
files.keys().forEach(key => {
if (key === './index.js' || key === './NIM_Web_SDK_v4.2.0.js') return
modules[key.replace(/(\.\/|\.js)/g, '')] = files(key).default
})
export default modules
This diff is collapsed.
/* 内存数据状态 */
export default {
// 正在加载中
isLoading: true,
// 操作是否是刷新页面,刷新初始没有nim实例,会导致时序问题
isRefresh: true,
// 全屏显示的原图
isFullscreenImgShow: false,
fullscreenImgSrc: '',
// 切页动画 forward,backward
transitionName: 'forward',
openNewMsgSession: [],
TipsNewMsgSessions: [],
// IM相关
// NIM SDK 实例
nim: null,
// 登录账户ID
userUID: null,
// 用户名片
myInfo: {},
// 好友/黑名单/陌生人名片, 数据结构如:{cid: {attr: ...}, ...}
userInfos: {},
// 用户订阅的事件同步, 数据结构如:{cid: {typeid: {...}, ...}, ...}
userSubscribes: {},
// 好友列表
friendslist: [],
// 机器人列表
robotslist: [],
// 用于判定帐号是否是robots
robotInfos: {},
robotInfosByNick: {},
// 黑名单列表
blacklist: [],
// 禁言列表
// mutelist: [],
teamlist: [],
// 群自身的属性,数据结构如:{tid: {attr: ...}, ...}
teamAttrs: {},
// 群对象的成员列表,数据结构如:{tid: {members: [...], ...}, ...}
teamMembers: {},
// 群设置传递数据
teamSettingConfig: {},
// 消息列表
msgs: {}, // 以sessionId作为key
msgsMap: {}, // 以idClient作为key,诸如消息撤回等的消息查找
// 会话列表
sessionlist: [],
sessionMap: {},
// 当前会话ID(即当前聊天列表,只有单聊群聊采用,可用于判别)
currSessionId: null,
currSessionMsgs: [],
// 是否有更多历史消息,用于上拉加载更多
noMoreHistoryMsgs: false,
// 继续对话的机器人id
continueRobotAccid: '',
// 系统消息
sysMsgs: [],
customSysMsgs: [],
sysMsgUnread: {
total: 0
},
customSysMsgUnread: 0,
// 临时变量
// 缓存需要获取的用户信息账号,如searchUser
searchedUsers: [],
// 缓存需要获取的群组账号
searchedTeams: [],
// 聊天室相关
// 聊天室sdk实例
chatroomInsts: {},
chatroomInfos: {},
// 聊天室分房间消息集合
chatroomMsgs: {},
// 当前聊天室实例及id
currChatroom: null,
currChatroomId: null,
currChatroomMsgs: [],
currChatroomInfo: {},
// 聊天室成员列表
currChatroomMembers: [],
// 页面数据暂存
pageCondition: null,
// 客户信息
guestInfo: []
}
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment