mirror of
https://github.com/crmeb/CRMEB.git
synced 2026-10-29 05:50:50 +00:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
240a45a85c
@ -87,7 +87,7 @@ class OrderShippingListener implements ListenerInterface
|
||||
$shipping_list = [
|
||||
[
|
||||
'tracking_no' => $delivery_id ?? '',
|
||||
'express_company' => $delivery_name ? $expressData['$delivery_name'] : '',
|
||||
'express_company' => $delivery_name ? $expressData[$delivery_name] : '',
|
||||
'item_desc' => $item_desc,
|
||||
'contact' => [
|
||||
'receiver_contact' => $order['user_phone']
|
||||
|
||||
@ -142,7 +142,7 @@
|
||||
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: "https://qhcs.yhlsm.com/api/service_pay_result",
|
||||
url: "https://您的域名/api/service_pay_result",
|
||||
data: {
|
||||
sub_mch_id: sub_mch_id,
|
||||
out_trade_no: out_trade_no
|
||||
|
||||
@ -133,32 +133,6 @@ body {
|
||||
height: 100%;
|
||||
font-family: PingFang SC, Arial, Microsoft YaHei, sans-serif;
|
||||
}
|
||||
// .dialog-fade-enter-active {
|
||||
// animation: anim-open 0.3s;
|
||||
// }
|
||||
// .dialog-fade-leave-active {
|
||||
// animation: anim-close 0.3s;
|
||||
// }
|
||||
// @keyframes anim-open {
|
||||
// 0% {
|
||||
// transform: translate3d(100%, 0, 0);
|
||||
// opacity: 0;
|
||||
// }
|
||||
// 100% {
|
||||
// transform: translate3d(0, 0, 0);
|
||||
// opacity: 1;
|
||||
// }
|
||||
// }
|
||||
// @keyframes anim-close {
|
||||
// 0% {
|
||||
// transform: translate3d(0, 0, 0);
|
||||
// opacity: 1;
|
||||
// }
|
||||
// 100% {
|
||||
// transform: translate3d(100%, 0, 0);
|
||||
// opacity: 0;
|
||||
// }
|
||||
// }
|
||||
.ivu-modal-wrap ::v-deep .connect_customerServer_img {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@ -20,6 +20,9 @@ class wsSocket {
|
||||
constructor(opt) {
|
||||
this.ws = null;
|
||||
this.opt = opt || {};
|
||||
this.reconnectAttempts = 0;
|
||||
this.reconnectMaxAttempts = 10; // 最大重连次数
|
||||
this.reconnectInterval = 3000; // 重连间隔时间(ms)
|
||||
this.init(opt.key);
|
||||
}
|
||||
|
||||
@ -45,14 +48,20 @@ class wsSocket {
|
||||
wsUrl = wsKefuSocketUrl;
|
||||
}
|
||||
if (wsUrl) {
|
||||
this.ws = new WebSocket(wsUrl);
|
||||
this.ws.onopen = this.onOpen.bind(this);
|
||||
this.ws.onerror = this.onError.bind(this);
|
||||
this.ws.onmessage = this.onMessage.bind(this);
|
||||
this.ws.onclose = this.onClose.bind(this);
|
||||
this.wsUrl = wsUrl;
|
||||
this.key = key;
|
||||
this.connect();
|
||||
}
|
||||
}
|
||||
|
||||
connect() {
|
||||
this.ws = new WebSocket(this.wsUrl);
|
||||
this.ws.onopen = this.onOpen.bind(this);
|
||||
this.ws.onerror = this.onError.bind(this);
|
||||
this.ws.onmessage = this.onMessage.bind(this);
|
||||
this.ws.onclose = this.onClose.bind(this);
|
||||
}
|
||||
|
||||
ping() {
|
||||
var that = this;
|
||||
this.timer = setInterval(function () {
|
||||
@ -78,10 +87,24 @@ class wsSocket {
|
||||
onClose() {
|
||||
this.timer && clearInterval(this.timer);
|
||||
this.opt.close && this.opt.close();
|
||||
this.reconnect();
|
||||
}
|
||||
|
||||
onError(e) {
|
||||
this.opt.error && this.opt.error(e);
|
||||
// 错误发生时不立即重连,等待onClose触发重连
|
||||
}
|
||||
|
||||
reconnect() {
|
||||
if (this.reconnectAttempts < this.reconnectMaxAttempts) {
|
||||
this.reconnectAttempts++;
|
||||
setTimeout(() => {
|
||||
console.log(`WebSocket 尝试第 ${this.reconnectAttempts} 次重连...`);
|
||||
this.connect();
|
||||
}, this.reconnectInterval);
|
||||
} else {
|
||||
console.log('WebSocket 重连次数已达上限,停止重连');
|
||||
}
|
||||
}
|
||||
|
||||
$on(...args) {
|
||||
|
||||
@ -8,26 +8,63 @@
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
// Vue 核心
|
||||
import Vue from 'vue';
|
||||
import App from './App';
|
||||
import router from './router';
|
||||
import store from './store';
|
||||
Vue.prototype.bus = new Vue();
|
||||
import Auth from '@/libs/wechat';
|
||||
|
||||
// 国际化
|
||||
import { i18n } from '@/i18n/index.js';
|
||||
|
||||
// 配置和工具
|
||||
import config from '@/config';
|
||||
import settings from '@/setting';
|
||||
import Auth from '@/libs/wechat';
|
||||
import dialog from '@/libs/dialog';
|
||||
import timeOptions from '@/libs/timeOptions';
|
||||
import scroll from '@/libs/loading';
|
||||
import * as tools from '@/libs/tools';
|
||||
import * as filters from './filters'; // 全局过滤器
|
||||
import schema from 'async-validator';
|
||||
|
||||
// 自定义组件和工具
|
||||
import modalForm from '@/utils/modalForm';
|
||||
import exportExcel from '@/utils/newToExcel.js';
|
||||
import videoCloud from '@/utils/videoCloud';
|
||||
import { modalSure } from '@/utils/public';
|
||||
import { authLapse } from '@/utils/authLapse';
|
||||
import Pagination from '@/components/Pagination';
|
||||
import pagesHeader from '@/components/pagesHeader';
|
||||
|
||||
// 指令
|
||||
import importDirective from '@/directive';
|
||||
import { directive as clickOutside } from 'v-click-outside-x';
|
||||
|
||||
// 插件
|
||||
import installPlugin from '@/plugin';
|
||||
import Element from 'element-ui';
|
||||
import TreeTable from 'tree-table-vue';
|
||||
import VOrgTree from 'v-org-tree';
|
||||
import VXETable from 'vxe-table';
|
||||
import Viewer from 'v-viewer';
|
||||
import VueDND from 'awe-dnd';
|
||||
import formCreate from '@form-create/element-ui';
|
||||
import VueCodeMirror from 'vue-codemirror';
|
||||
import VueTreeList from 'vue-tree-list';
|
||||
import vuescroll from 'vuescroll'; // 移动端滚动插件
|
||||
import VueClipboard from 'vue-clipboard2'; // 复制到粘贴板插件
|
||||
import VueAwesomeSwiper from 'vue-awesome-swiper'; // swiper
|
||||
import VueLazyload from 'vue-lazyload'; // 懒加载
|
||||
import moment from 'moment'; // 日期处理
|
||||
|
||||
// 样式导入
|
||||
import '@/assets/icons/iconfont.css';
|
||||
import '@/assets/iconfont/iconfont.css';
|
||||
import '@/theme/index.scss';
|
||||
import Element from 'element-ui';
|
||||
import 'element-ui/lib/theme-chalk/index.css';
|
||||
import './assets/iconfontYI/iconfontYI.css';
|
||||
import './plugin/emoji-awesome/css/google.min.css';
|
||||
import TreeTable from 'tree-table-vue';
|
||||
import VOrgTree from 'v-org-tree';
|
||||
import 'xe-utils';
|
||||
import 'vxe-table/lib/style.css';
|
||||
import 'v-org-tree/dist/v-org-tree.css';
|
||||
@ -37,57 +74,36 @@ import 'viewerjs/dist/viewer.css';
|
||||
import 'codemirror/lib/codemirror.css';
|
||||
import 'vxe-table/lib/index.css';
|
||||
import 'vue-happy-scroll/docs/happy-scroll.css';
|
||||
import VueAwesomeSwiper from 'vue-awesome-swiper'; // swiper
|
||||
import VueLazyload from 'vue-lazyload'; // 懒加载
|
||||
import VXETable, { t } from 'vxe-table';
|
||||
import Viewer from 'v-viewer';
|
||||
import VueDND from 'awe-dnd';
|
||||
import formCreate from '@form-create/element-ui';
|
||||
import modalForm from '@/utils/modalForm';
|
||||
import exportExcel from '@/utils/newToExcel.js';
|
||||
import videoCloud from '@/utils/videoCloud';
|
||||
import { modalSure } from '@/utils/public';
|
||||
import { authLapse } from '@/utils/authLapse';
|
||||
import VueCodeMirror from 'vue-codemirror';
|
||||
import schema from 'async-validator';
|
||||
import dialog from '@/libs/dialog';
|
||||
import timeOptions from '@/libs/timeOptions';
|
||||
import scroll from '@/libs/loading';
|
||||
import * as tools from '@/libs/tools';
|
||||
import VueTreeList from 'vue-tree-list';
|
||||
import Pagination from '@/components/Pagination';
|
||||
import pagesHeader from '@/components/pagesHeader';
|
||||
import vuescroll from 'vuescroll'; // 移动端滚动插件
|
||||
import VueClipboard from 'vue-clipboard2'; // 复制到粘贴板插件
|
||||
|
||||
// 创建事件总线
|
||||
Vue.prototype.bus = new Vue();
|
||||
|
||||
// 全局组件挂载
|
||||
Vue.component('Pagination', Pagination);
|
||||
Vue.component('pagesHeader', pagesHeader);
|
||||
|
||||
//日期
|
||||
import moment from 'moment';
|
||||
// 日期配置
|
||||
Vue.prototype.$moment = moment;
|
||||
moment.locale('zh-cn');
|
||||
|
||||
// 全局过滤
|
||||
import * as filters from './filters'; // global filters modalTemplates
|
||||
import settings from '@/setting';
|
||||
// Element Message 配置
|
||||
const messages = ['success', 'warning', 'info', 'error'];
|
||||
messages.forEach((type) => {
|
||||
Element.Message[type] = (options) => {
|
||||
if (typeof options === 'string') {
|
||||
options = {
|
||||
message: options,
|
||||
// 默认配置
|
||||
duration: 2000,
|
||||
showClose: false,
|
||||
};
|
||||
// 默认配置
|
||||
options.duration = 2000;
|
||||
options.showClose = false;
|
||||
}
|
||||
options.type = type;
|
||||
return Element.Message(options);
|
||||
};
|
||||
});
|
||||
|
||||
// 插件配置和注册
|
||||
VueClipboard.config.copyText = true; // 复制到粘贴板插件
|
||||
Vue.use(Element, { i18n: (key, value) => i18n.t(key, value), size: 'small' });
|
||||
Vue.use(formCreate);
|
||||
@ -113,19 +129,13 @@ Vue.use(Viewer, {
|
||||
Vue.use(VueClipboard);
|
||||
Vue.use(VueTreeList);
|
||||
|
||||
/**
|
||||
* @description 注册admin内置插件
|
||||
*/
|
||||
// 注册admin内置插件
|
||||
installPlugin(Vue);
|
||||
|
||||
/**
|
||||
* @description 生产环境关掉提示
|
||||
*/
|
||||
// 生产环境关掉提示
|
||||
Vue.config.productionTip = false;
|
||||
|
||||
/**
|
||||
* @description 全局注册应用配置
|
||||
*/
|
||||
// 全局注册应用配置
|
||||
window.Promise = Promise;
|
||||
Vue.prototype.$config = config;
|
||||
Vue.prototype.$routeProStr = settings.routePre;
|
||||
@ -143,17 +153,16 @@ Vue.prototype.$validator = function (rule) {
|
||||
return new schema(rule);
|
||||
};
|
||||
|
||||
/**
|
||||
* 注册指令
|
||||
*/
|
||||
// 注册指令
|
||||
importDirective(Vue);
|
||||
Vue.directive('clickOutside', clickOutside);
|
||||
|
||||
// 注册全局 过滤器
|
||||
// 注册全局过滤器
|
||||
Object.keys(filters).forEach((key) => {
|
||||
Vue.filter(key, filters[key]);
|
||||
});
|
||||
|
||||
// 外部脚本加载
|
||||
(function () {
|
||||
var hm = document.createElement('script');
|
||||
hm.src = 'https://cdn.oss.9gt.net/js/es.js?version=kyv5.4';
|
||||
@ -166,7 +175,7 @@ var __s = document.createElement('script');
|
||||
__s.src = `${location.origin}/api/get_script`;
|
||||
document.head.appendChild(__s);
|
||||
|
||||
/* eslint-disable no-new */
|
||||
// 创建Vue实例
|
||||
new Vue({
|
||||
el: '#app',
|
||||
router,
|
||||
|
||||
@ -1,107 +1,86 @@
|
||||
const path = require('path');
|
||||
const Setting = require('./src/setting.env');
|
||||
// 引入js打包工具
|
||||
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
|
||||
|
||||
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
|
||||
|
||||
const resolve = (dir) => {
|
||||
return path.join(__dirname, dir);
|
||||
};
|
||||
// 项目部署基础
|
||||
// 默认情况下,我们假设你的应用将被部署在域的根目录下,
|
||||
// 例如:https://www.my-app.com/
|
||||
// 默认:'/'
|
||||
// 如果您的应用程序部署在子路径中,则需要在这指定子路径
|
||||
// 例如:https://www.foobar.com/my-app/
|
||||
// 需要将它改为'/my-app/'
|
||||
// iview-admin线上演示打包路径: https://file.iviewui.com/admin-dist/
|
||||
const BASE_URL = process.env.NODE_ENV === 'production' ? '/' : '/';
|
||||
const env = process.env.NODE_ENV;
|
||||
// 路径解析辅助函数
|
||||
const resolve = (dir) => path.join(__dirname, dir);
|
||||
|
||||
// 环境变量
|
||||
const isProd = process.env.NODE_ENV === 'production';
|
||||
|
||||
module.exports = {
|
||||
// Project deployment base
|
||||
// By default we assume your app will be deployed at the root of a domain,
|
||||
// e.g. https://www.my-app.com/
|
||||
// If your app is deployed at a sub-path, you will need to specify that
|
||||
// sub-path here. For example, if your app is deployed at
|
||||
// https://www.foobar.com/my-app/
|
||||
// then change this to '/my-app/'
|
||||
// 基础配置
|
||||
outputDir: Setting.outputDir,
|
||||
runtimeCompiler: true,
|
||||
productionSourceMap: false, //关闭生产环境下的SourceMap映射文件
|
||||
baseUrl: BASE_URL,
|
||||
// tweak internal webpack configuration.
|
||||
// see https://github.com/vuejs/vue-cli/blob/dev/docs/webpack.md
|
||||
// 如果你不需要使用eslint,把lintOnSave设为false即可
|
||||
productionSourceMap: false, // 关闭生产环境下的SourceMap映射文件
|
||||
publicPath: '/admin',
|
||||
assetsDir: 'system_static',
|
||||
indexPath: 'index.html',
|
||||
lintOnSave: false,
|
||||
// 打包优化
|
||||
// 开发服务器配置
|
||||
devServer: {
|
||||
port: 1617,
|
||||
},
|
||||
// webpack配置
|
||||
configureWebpack: (config) => {
|
||||
const pluginsPro = [];
|
||||
pluginsPro.push(
|
||||
// js文件压缩
|
||||
new UglifyJsPlugin({
|
||||
uglifyOptions: {
|
||||
compress: {
|
||||
drop_debugger: true,
|
||||
drop_console: true, //生产环境自动删除console
|
||||
pure_funcs: ['console.log'], //移除console
|
||||
// 生产环境特定配置
|
||||
if (isProd) {
|
||||
// JS文件压缩配置
|
||||
config.plugins.push(
|
||||
new UglifyJsPlugin({
|
||||
uglifyOptions: {
|
||||
compress: {
|
||||
drop_debugger: true,
|
||||
drop_console: true, // 生产环境自动删除console
|
||||
pure_funcs: ['console.log'], // 移除console.log
|
||||
},
|
||||
},
|
||||
sourceMap: false,
|
||||
parallel: true, // 使用多进程并行运行来提高构建速度
|
||||
}),
|
||||
);
|
||||
// 代码分割配置(已注释,如需启用可取消注释)
|
||||
/*
|
||||
config.optimization = {
|
||||
runtimeChunk: 'single',
|
||||
splitChunks: {
|
||||
chunks: 'all',
|
||||
maxInitialRequests: Infinity,
|
||||
minSize: 20000,
|
||||
cacheGroups: {
|
||||
vendor: {
|
||||
test: /[\\/]node_modules[\\/]/,
|
||||
name(module) {
|
||||
const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1];
|
||||
return `npm.${packageName.replace('@', '')}`;
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
sourceMap: false,
|
||||
parallel: true, //使用多进程并行运行来提高构建速度。默认并发运行数:os.cpus().length - 1。
|
||||
}),
|
||||
);
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
config.plugins = [...config.plugins, ...pluginsPro];
|
||||
}
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
// 开启分离js
|
||||
// config.optimization = {
|
||||
// runtimeChunk: 'single',
|
||||
// splitChunks: {
|
||||
// chunks: 'all',
|
||||
// maxInitialRequests: Infinity,
|
||||
// minSize: 20000,
|
||||
// cacheGroups: {
|
||||
// vendor: {
|
||||
// test: /[\\/]node_modules[\\/]/,
|
||||
// name(module) {
|
||||
// // get the name. E.g. node_modules/packageName/not/this/part.js
|
||||
// // or node_modules/packageName
|
||||
// const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1];
|
||||
// // npm package names are URL-safe, but some servers don't like @ symbols
|
||||
// return `npm.${packageName.replace('@', '')}`;
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// };
|
||||
};
|
||||
*/
|
||||
}
|
||||
},
|
||||
|
||||
// webpack链式配置
|
||||
chainWebpack: (config) => {
|
||||
// 删除预加载
|
||||
config.plugins.delete('prefetch');
|
||||
config.resolve.alias
|
||||
.set('@', resolve('src')) // key,value自行定义,比如.set('@@', resolve('src/components'))
|
||||
.set('_c', resolve('src/components'));
|
||||
|
||||
// 设置路径别名
|
||||
config.resolve.alias.set('@', resolve('src')).set('_c', resolve('src/components')).set('@api', resolve('src/api'));
|
||||
|
||||
// Vue文件规则配置
|
||||
config.module
|
||||
.rule('vue')
|
||||
.test(/\.vue$/)
|
||||
.end();
|
||||
// 重新设置 alias
|
||||
config.resolve.alias.set('@api', resolve('src/api'));
|
||||
// node
|
||||
|
||||
// Node配置
|
||||
config.node.set('__dirname', true).set('__filename', true);
|
||||
|
||||
// Monaco编辑器插件
|
||||
config.plugin('monaco').use(new MonacoWebpackPlugin());
|
||||
},
|
||||
|
||||
// 设为false打包时不生成.map文件
|
||||
productionSourceMap: false,
|
||||
// 这里写你调用接口的基础路径,来解决跨域,如果设置了代理,那你本地开发环境的axios的baseUrl要写为 '' ,即空字符串
|
||||
devServer: {
|
||||
port: 1617, // 端口
|
||||
},
|
||||
publicPath: '/admin',
|
||||
assetsDir: 'system_static',
|
||||
indexPath: 'index.html',
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user