Compare commits

...

30 Commits

Author SHA1 Message Date
A0066811 eecfde90e5 hgwms-2099 fix 路由 2025-11-13 10:56:19 +08:00
A0066811 26efca11f8 hgwms-2099 fix 提示展示逻辑修改 2025-11-10 11:00:31 +08:00
A0066811 8beb440874 hgwms-2099 fix 提示展示逻辑修改 2025-11-10 10:46:10 +08:00
齐慧慧 0ad90ebf0e 列表 2025-11-10 10:12:00 +08:00
齐慧慧 1f43402454 列表优化 2025-11-10 09:25:47 +08:00
齐慧慧 161a2a3e9a Merge branch 'hwork-master' of http://47.104.191.123:8090/RRSWithSmartHome/wms_vue into hwork-master
# Conflicts:
#	src/view/log/auth.vue
#	src/view/log/oper.vue
#	src/view/wms/baseInfo/request/index.vue
2025-11-07 16:45:53 +08:00
齐慧慧 b602266648 列表优化 2025-11-07 16:34:20 +08:00
A0066811 67d68d29a8 hgwms-2098 fix alert修改 2025-11-07 15:21:59 +08:00
A0066811 e0d6edfd58 hgwms-2098 fix 租户管理弹窗修改 2025-11-07 14:58:09 +08:00
A0066811 126586f663 hgwms-2098 fix 租户管理弹窗修改 2025-11-07 14:55:26 +08:00
A0066811 f907724c24 hgwms-2098 fix 角色管理弹窗修改 2025-11-07 14:48:53 +08:00
A0066811 84633099a9 hgwms-2098 fix 用户管理弹窗修改 2025-11-07 14:40:27 +08:00
A0066811 dda045dde0 hgwms-2098 fix 部门管理弹窗修改 2025-11-07 14:32:00 +08:00
A0066811 82a5263854 hgwms-2098 fix 岗位管理弹窗修改 2025-11-07 14:26:24 +08:00
A0066811 d7c8e2758b hgwms-2098 fix 策略参数弹窗修改 2025-11-07 14:21:38 +08:00
A0066811 65b8f5d368 hgwms-2098 fix 货拉管理弹窗修改 2025-11-07 14:10:35 +08:00
A0066811 087b9aa7b3 hgwms-2098 fix 搬运类型弹窗修改 2025-11-07 13:55:26 +08:00
A0066811 0e204f5cee hgwms-2098 fix 任务路径弹窗修改 2025-11-07 13:26:59 +08:00
A0066811 f5751c70d9 hgwms-2098 fix 数据字典弹窗修改 2025-11-07 13:22:40 +08:00
A0066811 f264d03008 hgwms-2098 fix 系统权限弹窗修改 2025-11-07 11:19:50 +08:00
A0066811 ff3740b150 hgwms-2098 fix 自增序列弹窗修改 2025-11-07 11:10:19 +08:00
A0066811 1893cd7734 hgwms-2098 fix 执行记录弹窗修改 2025-11-07 11:06:38 +08:00
A0066811 cf2d0c8d00 hgwms-2098 fix 定时设置弹窗修改 2025-11-07 10:59:24 +08:00
A0066811 4efee0ebad hgwms-2098 fix 托盘信息管理弹窗修改 2025-11-07 10:16:12 +08:00
A0066811 87e3bdf933 hgwms-2098 fix 物料分类弹窗修改 2025-11-07 09:56:41 +08:00
A0066811 ce4105b45c hgwms-2098 fix 物料主档弹窗修改 2025-11-07 09:52:25 +08:00
zhangkaiios d92a44e67f table 优化 2025-11-06 14:25:31 +08:00
zhangkaiios d1c6668f59 UI及bug修改 2025-11-04 15:15:46 +08:00
zhangkaiios eec9baf4b1 UI 优化 2025-11-04 14:04:50 +08:00
zhangkaiios b8fb480511 升级组件库 2025-11-03 16:40:10 +08:00
313 changed files with 14169 additions and 48276 deletions

View File

@ -1,3 +1,3 @@
NODE_ENV = development
# VUE_APP_API_BASE_URL = 'http://10.180.218.86:9292'
VUE_APP_API_BASE_URL = 'http://127.0.0.1:9292'
VITE_API_BASE_URL = 'http://10.180.218.86:9292'
# VITE_API_BASE_URL = 'http://127.0.0.1:9292'

View File

@ -1,2 +1,2 @@
NODE_ENV = 'production'
VUE_APP_API_BASE_URL = 'http://api.pro.pearadmin.com'
VITE_API_BASE_URL = 'http://api.pro.pearladmin.com'

View File

@ -13,7 +13,7 @@ module.exports = {
[
"import",
{
libraryName: "ant-design-vue",
libraryName: "@hwork/ant-design-vue",
libraryDirectory: "es",
style: true // `style: true` 会加载 less 文件
}

View File

@ -1,27 +0,0 @@
const path = require('path');
const { generateTheme } = require('antd-theme-generator');
generateTheme({
antDir: path.join(__dirname, './node_modules/ant-design-vue'), //node_modules中antd的路径
stylesDir: path.join(__dirname, './src/assets/css'), //styles对应的目录路径
varFile: path.join(__dirname, './src/assets/css/color.less'), //less变量的入口文件
themeVariables: [
'@primary-color',
'@secondary-color',
'@text-color',
'@text-color-secondary',
'@heading-color',
'@layout-body-background',
'@btn-primary-bg',
'@layout-header-background',
],
outputFilePath: path.join(__dirname, './public/theme.less'), //生成的color.less文件的位置
customColorRegexArray: [/^color\(.*\)$/],
})
.then(res => {
console.log('generate theme success');
})
.catch(res => {
console.log('generate theme failure');
});

View File

@ -5,10 +5,8 @@
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>superMan.ico">
<title>
<%= htmlWebpackPlugin.options.title %>
</title>
<link rel="icon" href="/public/superMan.ico">
<title>WMS Admin</title>
<style>.first-loading-wrp{display:flex;justify-content:center;align-items:center;flex-direction:column;min-height:420px;height:100%}.first-loading-wrp>h1{font-size:120px}.first-loading-wrp .loading-wrp{padding:98px;display:flex;justify-content:center;align-items:center}.dot{animation:antRotate 1.2s infinite linear;transform:rotate(45deg);position:relative;display:inline-block;font-size:32px;width:42px;height:42px;box-sizing:border-box}.dot i{width:18px;height:18px;position:absolute;display:block;background-color:#1890ff !important;border-radius:100%;transform:scale(.75);transform-origin:50% 50%;opacity:.3;animation:antSpinMove 1s infinite linear alternate}.dot i:nth-child(1){top:0;left:0}.dot i:nth-child(2){top:0;right:0;-webkit-animation-delay:.4s;animation-delay:.4s}.dot i:nth-child(3){right:0;bottom:0;-webkit-animation-delay:.8s;animation-delay:.8s}.dot i:nth-child(4){bottom:0;left:0;-webkit-animation-delay:1.2s;animation-delay:1.2s}@keyframes antRotate{to{-webkit-transform:rotate(405deg);transform:rotate(405deg)}}@-webkit-keyframes antRotate{to{-webkit-transform:rotate(405deg);transform:rotate(405deg)}}@keyframes antSpinMove{to{opacity:1}}@-webkit-keyframes antSpinMove{to{opacity:1}}</style>
</head>
<body>
@ -21,14 +19,6 @@
<div style="display: flex; justify-content: center; align-items: center;">WMS</div>
</div>
</div>
<link rel="stylesheet/less" type="text/css" href="/theme.less" />
<script>
window.less = {
async: false,
env:"production"
};
</script>
<!-- src="https://cdn.bootcdn.net/ajax/libs/less.js/2.7.2/less.min.js" -->
<script type="text/javascript" href="/less.min2.7.2.js"></script>
<script type="module" src="/src/main.js"></script>
</body>
</html>

36978
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -3,20 +3,19 @@
"version": "1.0.0-RELEASE",
"private": true,
"scripts": {
"serve-dev": "node generate && vue-cli-service serve --mode development",
"serve": "set NODE_OPTIONS=--openssl-legacy-provider && node generate && vue-cli-service serve --mode development",
"serve-pro": "node generate && vue-cli-service serve --mode production",
"build-dev": "node generate && vue-cli-service build --mode development",
"build-pro": "node generate && vue-cli-service build --mode production",
"report": "vue-cli-service build --report"
"dev": "vite --mode development",
"prod": "vite --mode production",
"build": "vite build",
"build-dev": "vite build --mode development",
"build-pro": "vite build --mode production",
"preview": "vite preview"
},
"dependencies": {
"@ant-design-vue/use": "^0.0.1-alpha.10",
"@ant-design/icons-vue": "^6.0.1",
"@antv/g2": "^4.1.20",
"@hwork/ant-design-vue": "4.1.24",
"@hwork/icon": "^1.0.0",
"@tinymce/tinymce-vue": "^4.0.4",
"ant-design-vue": "^2.2.2",
"antd-theme-generator": "^1.2.8",
"axios": "^0.21.1",
"core-js": "^3.6.5",
"dayjs": "^1.11.7",
@ -37,21 +36,12 @@
"devDependencies": {
"@types/node": "^14.14.6",
"@types/webpack-env": "^1.15.3",
"@vue/cli-plugin-babel": "~4.5.8",
"@vue/cli-plugin-eslint": "~4.5.8",
"@vue/cli-service": "~4.5.8",
"@vue/compiler-sfc": "^3.2.19",
"antd-theme-webpack-plugin": "^1.3.9",
"babel-eslint": "^10.1.0",
"babel-plugin-import": "^1.13.3",
"compression-webpack-plugin": "^6.1.1",
"eslint": "^6.7.2",
"eslint-plugin-vue": "^7.0.0-0",
"less": "^3.13.1",
"less-loader": "^7.1.0",
"@vitejs/plugin-vue": "^4.0.0",
"eslint": "^8.0.0",
"eslint-plugin-vue": "^9.0.0",
"less": "^4.1.3",
"mockjs2": "^1.0.8",
"webpack": "^5.64.4",
"webpackbar": "^5.0.0-3"
"vite": "^4.0.0"
},
"eslintConfig": {
"root": true,
@ -63,7 +53,8 @@
"eslint:recommended"
],
"parserOptions": {
"parser": "babel-eslint"
"ecmaVersion": 2020,
"sourceType": "module"
},
"rules": {
"no-unused-vars": "off",

File diff suppressed because it is too large Load Diff

View File

@ -6,8 +6,8 @@
<script>
import {useStore} from "vuex";
import {computed, defineComponent, ref} from "vue";
import zhCN from 'ant-design-vue/es/locale/zh_CN';
import enUS from 'ant-design-vue/es/locale/en_US';
import zhCN from '@hwork/ant-design-vue/es/locale/zh_CN';
import enUS from '@hwork/ant-design-vue/es/locale/en_US';
import dayjs from "dayjs";
import "dayjs/locale/zh-cn";
@ -35,12 +35,6 @@
})
)
setTimeout(function(){
window.less.modifyVars({
"primary-color": color.value,
})
},10)
return {
antdLocal,
dayjs

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
/** 接口管理 */
const Api = {

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
// 接口
const Api = {

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
const Api = {
page: '/api/sys/config/page',

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
/** 接口列表 */
const Api = {

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
const Api = {
tree: '/api/sys/dept/tree',

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
const Api = {
page: '/api/sys/dict/page',

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
const Api = {
list: '/api/sys/dict/data/list',

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
/** 接口管理 */
const Api = {

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
const Api = {
page: '/api/sys/job/page',

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
const Api = {
page: '/api/sys/job/log/page',

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
const Api = {
page: '/api/sys/log/page',

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
const Api = {
send: '/api/sys/mail/send'

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
const Api = {
list: '/api/sys/online/list',

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
const Api = {
page: '/api/sys/oss/page',

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
const Api = {
page: '/api/sys/post/page',

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
const Api = {
tree: '/api/sys/power/tree',

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
const Api = {
info: '/api/sys/redis/info',

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
/** 接口管理 */
const Api = {

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
const Api = {
info: '/api/sys/server/info',

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
const Api = {
send: '/api/sys/sms/send'

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
const Api = {
page: '/api/sys/tenant/page',

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
/** 接口 */
const Api = {

View File

@ -1,8 +1,8 @@
import axios from "axios";
import {
message as antdMessage
} from "ant-design-vue";
import store from "../store";
} from "@hwork/ant-design-vue";
import store from '../store/index.js';
import qs from 'qs';
import router from '@/route/index'
@ -12,7 +12,7 @@ class Request {
this.config = config || {
timeout: 8000,
withCredentials: true,
baseURL: process.env.VUE_APP_API_BASE_URL,
baseURL: import.meta.env.VITE_API_BASE_URL,
headers: {
"Content-Type": "application/json; charset=utf-8"
}
@ -81,7 +81,7 @@ class Request {
);
}
errorHandle = function(error) {
errorHandle(error) {
var response = error.response
var message = error.message
if (response) {

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
/** 接口管理 */
const Api = {

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
const Api = {
page: '/api/wms/check/page',

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
const Api = {
page: '/api/wms/checkDetail/page',

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
const Api = {
page: '/api/wms/checkPlt/page',

View File

@ -1,4 +1,4 @@
import request from '../../request'
import request from '../../request.js';
/** 接口管理 */
const Api = {

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
/** 接口管理 */
const Api = {

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
const Api = {
page: '/api/wms/deliver/page',

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
const Api = {
page: '/api/wms/inBill/page',

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
const Api = {
page: '/api/wms/InBillDetail/page',

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
/** 接口管理 */
const Api = {

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
/** 接口管理 */
const Api = {

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
/** 接口管理 */
const Api = {

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
/** 接口管理 */
const Api = {

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
/** 接口管理 */
const Api = {

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
const Api = {
page: '/api/wms/outBill/page',

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
const Api = {
page: '/api/wms/outBillDetail/page',

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
/** 接口管理 */
const Api = {

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
/** 接口管理 */
const Api = {

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
/** 接口管理 */
const Api = {

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
/** 接口管理 */
const Api = {

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
const Api = {
page: '/api/wms/pick/page',

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
/** 接口管理 */
const Api = {

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
/** 接口管理 */
const Api = {

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
/** 接口管理 */
const Api = {

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
/** 接口管理 */
const Api = {

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
const Api = {
page: '/api/wms/sku/page',

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
const Api = {
page: '/api/wms/skuCategory/page',

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
/** 接口管理 */
const Api = {

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
/** 接口管理 */
const Api = {

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
/** 接口管理 */
const Api = {

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
/** 接口管理 */
const Api = {

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
/** 接口管理 */
const Api = {

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
/** 接口管理 */
const Api = {

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
/** 接口管理 */
const Api = {

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
/** 接口管理 */
const Api = {

View File

@ -1,4 +1,4 @@
import request from '../request'
import request from '../request.js';
/** 接口管理 */
const Api = {

View File

@ -1,2 +1 @@
@import './layout.less';
@import './theme.less';
@import './layout.less';

View File

@ -341,7 +341,7 @@ html {
.fixedHeader.muiltTab {
z-index: 600;
#content {
height: calc(~"(100% - 51px)");
height: calc(~"(100% - 42px)");
-ms-overflow-style: none;
overflow: -moz-scrollbars-none;
}
@ -422,4 +422,18 @@ html {
text-align: center;
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.15);
line-height: 30px;
}
.ant-list-layout {
height: 100% !important;
}
.ant-list-layout-content {
height: 100%;
display: flex;
flex-direction: column;
}
#pro-table {
flex: 1;
overflow: hidden;
display: flex;
flex-direction: column;
}

View File

@ -1,284 +0,0 @@
@primary-color: #2d8cf0;
#nprogress .bar {
background: @primary-color!important;
}
#nprogress .peg {
box-shadow: @primary-color!important;
}
.pear-dot-tab {
height: 45.5px;
line-height: 45.5px;
}
.pear-dot-tab .ant-tabs-tab-active::before{
background-color: @primary-color!important;
}
.pear-dot-tab .tab {
width: calc(~"(100% - 40px)");
display: inline-block;
}
.pear-dot-tab .ant-tabs-tab-prev {
border-right: 1px solid #f0f2f5;
background-color: #f0f2f5;
height: 34px !important;
line-height: 34px !important;
text-align: center;
}
.pear-dot-tab .ant-tabs-tab-next {
border-left: 1px solid #f0f2f5;
background-color: #f0f2f5;
height: 34px !important;
line-height: 34px !important;
text-align: center;
}
.pear-dot-tab .tab-tool {
float: right;
top: 6px;
right: 6px;
border: none;
}
.pear-dot-tab .ant-tabs-bar {
margin: 0px !important;
border: none;
margin-top: 6px !important;
margin-bottom: 6px !important;
}
.pear-dot-tab .ant-tabs.ant-tabs-card .ant-tabs-card-bar .ant-tabs-tab {
border-radius: 3px;
border: none;
margin-right: 4px;
margin-left: 4px;
height: 34px !important;
line-height: 34px !important;
color: #808695;
background-color: white;
}
.pear-dot-tab
.ant-tabs.ant-tabs-card
.ant-tabs-card-bar
.ant-tabs-tab:first-child {
margin-left: 6px;
}
.pear-dot-tab
.ant-tabs.ant-tabs-card
.ant-tabs-card-bar
.ant-tabs-tab:last-child {
margin-right: 6px;
}
.pear-dot-tab .ant-tabs-nav-container {
height: 34px;
}
.pear-dot-tab .ant-tabs-nav .ant-tabs-tab::before {
background-color: whitesmoke;
height: 7.6px;
width: 7.6px;
border-radius: 500px;
position: absolute;
margin-top: 14.5px;
margin-left: 13px;
}
.pear-dot-tab .ant-tabs-nav .ant-tabs-tab > div {
margin-left: 13.5px;
color: #808695;
}
.pear-card-tab {
height: 40.5px;
line-height: 40.5px;
z-index: 200;
background-color: white !important;
border-top: 1px solid whitesmoke;
border-bottom: 1px solid whitesmoke;
}
.pear-card-tab .ant-tabs-tab-active::before{
background-color: @primary-color!important;
}
.pear-card-tab .tab {
width: calc(~"(100% - 40px)");
display: inline-block;
}
.pear-card-tab .ant-tabs-nav-container {
padding-left: 40px;
padding-right: 40px;
}
.pear-card-tab .ant-tabs-tab-prev {
border-right: 1px solid whitesmoke;
width: 40px !important;
height: 40px !important;
line-height: 39px !important;
text-align: center;
opacity: 1;
pointer-events: auto;
color: rgba(0, 0, 0, 0.65);
}
.pear-card-tab .ant-tabs-tab-next {
border-left: 1px solid whitesmoke;
width: 40px !important;
height: 40px !important;
line-height: 39px !important;
text-align: center;
opacity: 1;
pointer-events: auto;
color: rgba(0, 0, 0, 0.65);
}
.pear-card-tab .tab-tool {
float: right;
border: none !important;
border-left: 1px solid whitesmoke !important;
width: 40px !important;
height: 39px !important;
line-height: 39px !important;
}
.pear-card-tab .ant-tabs-bar {
margin: 0px !important;
border: none;
}
.pear-card-tab .ant-tabs.ant-tabs-card .ant-tabs-card-bar .ant-tabs-tab {
border-radius: 0px;
border: none;
height: 40px !important;
line-height: 40px !important;
color: #808695;
background-color: white;
margin-right: 0px;
border-right: whitesmoke 1px solid;
}
.pear-card-tab .ant-tabs-nav-container {
height: 40px;
}
.pear-card-tab .ant-tabs-nav .ant-tabs-tab::before {
background-color: whitesmoke;
height: 8px;
width: 8px;
border-radius: 50px;
position: absolute;
margin-top: 17px;
margin-left: 13px;
}
.pear-card-tab .ant-tabs-nav .ant-tabs-tab > div {
margin-left: 13.5px;
color: #808695;
}
// tab 标 签 样 式
.pear-label-tab {
height: 45.5px;
line-height: 45.5px;
}
.pear-label-tab .tab {
width: calc(~"(100% - 40px)");
display: inline-block;
}
.pear-label-tab .ant-tabs-tab-prev {
border-right: 1px solid whitesmoke;
height: 34px !important;
line-height: 34px !important;
text-align: center;
}
.pear-label-tab .ant-tabs-tab-active{
background-color: @primary-color!important;
}
.pear-label-tab .ant-tabs-tab-active *{
color:white!important;
}
.pear-label-tab .ant-tabs-tab-next {
border-left: 1px solid whitesmoke;
height: 34px !important;
line-height: 34px !important;
text-align: center;
}
.pear-label-tab .tab-tool {
float: right;
top: 6px;
right: 6px;
border: none;
}
.pear-label-tab .ant-tabs-bar {
margin: 0px !important;
border: none;
margin-top: 6px !important;
margin-bottom: 6px !important;
}
.pear-label-tab .ant-tabs.ant-tabs-card .ant-tabs-card-bar .ant-tabs-tab {
border-radius: 3px;
border: none;
margin-right: 4px;
margin-left: 4px;
height: 34px !important;
line-height: 34px !important;
color: #808695;
background-color: white;
}
.pear-label-tab
.ant-tabs.ant-tabs-card
.ant-tabs-card-bar
.ant-tabs-tab:first-child {
margin-left: 6px;
}
.pear-label-tab
.ant-tabs.ant-tabs-card
.ant-tabs-card-bar
.ant-tabs-tab:last-child {
margin-right: 6px;
}
.pear-label-tab .ant-tabs-nav-container {
height: 34px;
}
.pear-label-tab .ant-tabs-nav .ant-tabs-tab::before {
display: none;
}
.pear-label-tab .ant-tabs-nav .ant-tabs-tab > div {
color: #808695;
}
// 路由动画
.fade-right-enter-active {
transition: all .90s;
}
.fade-right-leave-active{
transition: all .90s;
}
.fade-right-enter-from {
opacity: 0;
transform: translateX(-35px);
}
.fade-right-leave-to {
opacity: 0;
transform: translateX(35px);
display: none;
}
.fade-top-enter-active {
transition: all .90s;
}
.fade-top-leave-active{
transition: all .90s;
}
.fade-top-enter-from {
opacity: 0;
transform: translateY(35px);
}
.fade-top-leave-to {
opacity: 0;
transform: translateY(-35px);
display: none;
}
/** Antd 的 通 用 美 化 */
.ant-card {
border-radius: 4px !important;
}
.ant-card-bordered {
border: none !important;
}
.ant-divider {
background-color: whitesmoke !important;
}
.ant-layout-content {
flex: 1 !important;
}
.ant-table-title {
padding: 0 !important;
}

View File

@ -1,4 +1,4 @@
import Component from './src'
import Component from './src/index.vue'
Component.install = function (Vue) {
Vue.component(Component.name, Component)

View File

@ -1,4 +1,4 @@
import Component from './src'
import Component from './src/index.vue'
Component.install = function (Vue) {
Vue.component(Component.name, Component)

View File

@ -1,4 +1,4 @@
import Component from './src'
import Component from './src/index.vue'
Component.install = function (Vue) {
Vue.component(Component.name, Component)

View File

@ -1,4 +1,4 @@
import Component from './src'
import Component from './src/index.vue'
Component.install = function (Vue) {
Vue.component(Component.name, Component)

View File

@ -46,7 +46,7 @@
} from "vue";
import {
list
} from "../../../api/module/dictData";
} from '../../../api/module/dictData.js';
import {
useStore
} from 'vuex';

View File

@ -1,4 +1,4 @@
import Component from './src'
import Component from './src/index.vue'
Component.install = function (Vue) {
Vue.component(Component.name, Component)

View File

@ -1,4 +1,4 @@
import Component from './src'
import Component from './src/index.vue'
Component.install = function (Vue) {
Vue.component(Component.name, Component)

View File

@ -1,4 +1,4 @@
import Component from './src'
import Component from './src/index.vue'
Component.install = function (Vue) {
Vue.component(Component.name, Component)

View File

@ -1,16 +1,16 @@
/*头部组件*/
import Header from "./header";
import Layout from "./layout";
import Footer from "./footer";
import CardBase from "./cardBase";
import Count from "./count";
import Table from './table';
import Query from './query';
import Authority from './authority';
import iconPicker from './iconPicker';
import icon from './icon';
import Dictionary from './dictionary';
import Modal from './proModal';
import Header from './header/index.js';
import Layout from './layout/index.js';
import Footer from './footer/index.js';
import CardBase from './cardBase/index.js';
import Count from './count/index.js';
import Table from './table/index.js';
import Query from './query/index.js';
import Authority from './authority/index.js';
import iconPicker from './iconPicker/index.js';
import icon from './icon/index.js';
import Dictionary from './dictionary/index.js';
import Modal from './proModal/index.js';
const components = [
Footer,Header,Layout,CardBase,Count,Table,Query,Authority,iconPicker,icon,Dictionary,Modal

View File

@ -1,4 +1,4 @@
import Component from './src'
import Component from './src/index.vue'
Component.install = function (Vue) {
Vue.component(Component.name, Component)

View File

@ -0,0 +1,25 @@
import { h, defineComponent } from 'vue';
import { Table } from '@hwork/ant-design-vue';
function patchColumns(cols) {
if (!Array.isArray(cols)) return cols;
return cols.map((col) => {
if (!col) return col;
const next = { ...col };
if (next.ellipsis === undefined) next.ellipsis = true;
if (Array.isArray(next.children)) next.children = patchColumns(next.children);
return next;
});
}
export default defineComponent({
name: 'ATable',
inheritAttrs: false,
setup(_, { attrs, slots }) {
// 每次渲染时基于最新的 columns 重新打补丁,确保列显示/隐藏等变更能够生效
return () => {
const patchedColumns = patchColumns(attrs.columns);
return h(Table, { ...attrs, columns: patchedColumns }, slots);
};
},
});

View File

@ -1,4 +1,4 @@
import Component from './src'
import Component from './src/index.vue'
Component.install = function (Vue) {
Vue.component(Component.name, Component)

View File

@ -1,14 +1,13 @@
.pro-table-prev {
display: inline-block;
.ant-btn {
margin: 4px;
margin-right: 12px;
margin-bottom: 8px;
}
}
.pro-table-next {
float: right;
.ant-btn {
margin: 4px;
margin-bottom: 8px;
}
}

View File

@ -1,5 +1,5 @@
<template>
<a-modal :visible="visible" :title="title" :cancelText="cancelText" :okText="okText" @ok="submit" @cancel="cancel">
<a-modal :open="visible" :title="title" :cancelText="cancelText" :okText="okText" @ok="submit" @cancel="cancel">
<a-form ref="formRef" :model="formState" :rules="formRules" :label-col="labelCol" :wrapper-col="wrapperCol">
<template v-if="formState.columns===false">
@ -61,14 +61,14 @@
</a-modal>
</template>
<script>
import {
import {
message
} from "ant-design-vue";
} from "@hwork/ant-design-vue";
import {
save
} from "@/api/module/config";
import "./index.less";
import M from "ant-design-vue/es/modal/Modal";
import { Modal as M } from "@hwork/ant-design-vue";
import {
defineComponent,
reactive,

View File

@ -1,4 +1,4 @@
import Component from './src'
import Component from './src/index.vue'
Component.install = function (Vue) {
Vue.component(Component.name, Component)

View File

@ -1,12 +0,0 @@
.pro-query {
.pro-query-select {
width: 180px;
}
.pro-query-button {
margin-left: 3px;
margin-right: 3px;
}
.pro-query-hidden {
margin-left: 10px;
}
}

View File

@ -1,62 +1,45 @@
<template>
<div class="pro-query">
<!-- 表单内容 -->
<a-form
layout="inline"
:model="formState"
:label-col="labelCol"
:wrapper-col="wrapperCol">
<a-form-item v-show="!param.hidden || !hidden" :label="param.label" :key="index" v-for="(param, index) in searchParam">
<!-- 输入框 -->
<a-input v-model:value="formState[param.key]"
v-show="!param.hidden || !hidden"
v-if="param.type == 'input'" type="text"
:disabled=" param.disabled === undefined ? false : param.disabled">
</a-input>
<!--多行文本框-->
<a-textarea v-model:value="formState[param.key]"
v-show="!param.hidden || !hidden"
v-if="param.type == 'textarea'"
placeholder="Info" :rows="4"
:disabled=" param.disabled === undefined ? false : param.disabled"/>
<!-- 数值输入框 -->
<a-input-number v-model:value="formState[param.key]" :min="1" :max="100" v-show="!param.hidden || !hidden"
v-if="param.type == 'number'" :disabled=" param.disabled === undefined ? false : param.disabled"/>
<!-- 选择框 -->
<a-select v-if="param.type == 'select'"
v-model:value="formState[param.key]"
style="width: 160px" class="pro-query-select"
<a-search ref="formRef" @search="search" @reset="reset">
<a-search-item v-show="!param.hidden || !hidden" :label="param.label" :key="index" v-for="(param, index) in searchParam" :span="param.type == 'rangePicker' ? 2 : 1">
<!-- 输入框 -->
<a-input v-model:value="formState[param.key]"
v-show="!param.hidden || !hidden"
v-if="param.type == 'input'" type="text"
:disabled=" param.disabled === undefined ? false : param.disabled">
<a-select-option :key="index" v-for="(option,index) in param.options" :value="option.value" >{{option.text}}</a-select-option>
</a-select>
<!-- 连级选择器change-on-select 允许只选父节点 -->
<a-cascader v-if="param.type == 'cascader'" v-model:value="formState[param.key]" :options="param.options" change-on-select placeholder="Please select" />
<!-- 日期选择 -->
<a-time-picker v-if="param.type == 'timePicker'" v-model:value="formState[param.key]" :valueFormat="param.format ? param.format:'YYYY-MM-DD HH:mm:ss'" />
<a-date-picker v-if="param.type == 'datePicker'" v-model:value="formState[param.key]" :valueFormat="param.format ? param.format:'YYYY-MM-DD HH:mm:ss'"/>
<a-range-picker v-if="param.type == 'rangePicker'" v-model:value="formState[param.key]" :valueFormat="param.format ? param.format:'YYYY-MM-DD HH:mm:ss'"
:format="param.format ? param.format:'YYYY-MM-DD HH:mm:ss'"/>
<a-week-picker v-if="param.type == 'weekPicker'" v-model:value="formState[param.key]" :valueFormat="param.format ? param.format:'YYYY-MM-DD HH:mm:ss'"/>
<!-- 内容插槽 -->
<template v-if="param.type == 'custom'">
<slot :name="param.customRender" :data="formState"></slot>
</template>
</a-form-item>
<!-- 按钮组 -->
<a-button type="primary" class="pro-query-button" @click="search"> </a-button>
<a-button html-type="submit" class="pro-query-button" @click="reset"> </a-button>
<!-- 收起 隐藏 -->
<a class="pro-query-hidden" @click="hiddenHandle" v-show="hidden && more"> &nbsp;<DownOutlined/></a>
<a class="pro-query-hidden" @click="hiddenHandle" v-show="!hidden && more"> &nbsp;<UpOutlined/></a>
</a-form>
</div>
</a-input>
<!--多行文本框-->
<a-textarea v-model:value="formState[param.key]"
v-show="!param.hidden || !hidden"
v-if="param.type == 'textarea'"
placeholder="Info" :rows="4"
:disabled=" param.disabled === undefined ? false : param.disabled"/>
<!-- 数值输入框 -->
<a-input-number v-model:value="formState[param.key]" :min="1" :max="100" v-show="!param.hidden || !hidden"
v-if="param.type == 'number'" :disabled=" param.disabled === undefined ? false : param.disabled"/>
<!-- 选择框 -->
<a-select v-if="param.type == 'select'"
v-model:value="formState[param.key]"
:disabled=" param.disabled === undefined ? false : param.disabled">
<a-select-option :key="index" v-for="(option,index) in param.options" :value="option.value" >{{option.text}}</a-select-option>
</a-select>
<!-- 连级选择器change-on-select 允许只选父节点 -->
<a-cascader v-if="param.type == 'cascader'" v-model:value="formState[param.key]" :options="param.options" change-on-select placeholder="Please select" />
<!-- 日期选择 -->
<a-time-picker v-if="param.type == 'timePicker'" v-model:value="formState[param.key]" :valueFormat="param.format ? param.format:'YYYY-MM-DD HH:mm:ss'" />
<a-date-picker v-if="param.type == 'datePicker'" v-model:value="formState[param.key]" :valueFormat="param.format ? param.format:'YYYY-MM-DD HH:mm:ss'"/>
<a-range-picker v-if="param.type == 'rangePicker'" v-model:value="formState[param.key]" :valueFormat="param.format ? param.format:'YYYY-MM-DD HH:mm:ss'"
:format="param.format ? param.format:'YYYY-MM-DD HH:mm:ss'"/>
<a-week-picker v-if="param.type == 'weekPicker'" v-model:value="formState[param.key]" :valueFormat="param.format ? param.format:'YYYY-MM-DD HH:mm:ss'"/>
<!-- 内容插槽 -->
<template v-if="param.type == 'custom'">
<slot :name="param.customRender" :data="formState"></slot>
</template>
</a-search-item>
</a-search>
</template>
<script>
import "./index.less";
import { defineComponent, reactive, ref,watch } from "vue";
import { DownOutlined , UpOutlined } from "@ant-design/icons-vue"
import { useForm } from "@ant-design-vue/use";
export default defineComponent({
name: "pro-query",
props: {
@ -73,8 +56,7 @@ export default defineComponent({
}
},
components: {
DownOutlined,
UpOutlined
},
emits: [
'on-search',
@ -82,16 +64,14 @@ export default defineComponent({
],
setup(props, {emit}) {
const hidden = ref(true);
const more = ref(false);
const formRef = ref();
const formState = reactive({})
const formRules = reactive({})
///
const generateFormState = array => {
array.length > 0 && array.forEach(it => {
const {key, rules = [], value,defaultValue} = it
formState[key] = defaultValue || (value === undefined ? "" : value);
formState[key] = defaultValue || (it.type !== 'select' && value === undefined ? "" : value);
formRules[key] = rules
})
}
@ -100,29 +80,21 @@ export default defineComponent({
})
generateFormState(props.searchParam);
const { validate, resetFields } = useForm(formState, formRules)
///
props.searchParam.forEach(element => {
if(element.hidden){
return more.value = true;
}
});
///
const hiddenHandle = function() {
hidden.value = !hidden.value;
}
///
const search = async function(){
var o = await validate();
emit('on-search',o)
try {
emit('on-search', {...formState})
} catch (error) {
console.log('表单验证失败:', error);
}
}
///
const reset = function(){
resetFields();
generateFormState(props.searchParam);
search();
emit('on-reset')
}
@ -132,14 +104,10 @@ export default defineComponent({
}
return {
more: more,
hidden: hidden,
hiddenHandle: hiddenHandle,
formRef,
/// EMIT
search: search,
reset: reset,
///
formState,
formRules,

View File

@ -1,4 +1,4 @@
import Component from './src'
import Component from './src/index.vue'
Component.install = function (Vue) {
Vue.component(Component.name, Component)

View File

@ -1,45 +0,0 @@
.pro-table-prev {
display: inline-block;
.ant-btn {
margin: 4px;
margin-bottom: 8px;
}
}
.pro-table-next {
float: right;
.ant-btn {
margin: 4px;
margin-bottom: 8px;
}
}
.filtration {
width: 130px;
.ant-checkbox-wrapper {
margin-left: 14px;
margin-top: 4px;
}
}
/*//点击行的样式*/
.clickRowStyl {
background-color: #a5a5e0 !important;
}
/*//偶数行的样式*/
.evenRowStyl {
background-color: #FFFFFF !important;
}
.ant-table-tbody>tr:hover:not(.ant-table-expanded-row)>td {
background: #bbbbff;
}
/*//鼠标移入样式*/
.ant-table-tbody>tr:hover>td {
background: #a5a5e0 !important
}
.ant-table-tbody > tr > td , .ant-table-tbody > tr > th{
padding: 3px 12px !important
}

View File

@ -1,14 +1,22 @@
<template>
<div id="pro-table">
<!-- 表格工具栏 -->
<div class="pro-table-tool">
<div class="pro-table-tool" :style="proTableToolStyle">
<!-- 自定义工具栏 -->
<div class="pro-table-prev">
<template :key="index" v-for="(item, index) in toolbar">
<div class="pro-table-prev" >
<!-- 将工具栏改为合并后的 mergedToolbar包含外部传入与内置的 打印/导出 按钮 -->
<template :key="index" v-for="(item, index) in mergedToolbar">
<!-- 更多按钮 -->
<pro-authority :value="item.code ? item.code : false" v-if="item.children && item.children.length > 0">
<a-dropdown>
<a-button @click="item.event(selectedRowKeys)">{{ item.label }}</a-button>
<!-- 支持 danger icon 插槽 -->
<a-button :danger="item.danger === true || item.type === 'danger'"
@click="item.event(selectedRowKeys)">
<template v-if="item.icon" #icon>
<component :is="item.icon" />
</template>
{{ item.label }}
</a-button>
<template #overlay>
<a-menu>
<!-- 遍历子集 -->
@ -22,69 +30,26 @@
</a-dropdown>
</pro-authority>
<pro-authority :value="item.code ? item.code : false" v-else>
<a-button
:type="item.type&&['primary','ghost','dashed','link','text','default'].includes(item.type) ? item.type : index == 0 ? 'primary' : 'default'"
<a-button size="small"
:type="item.type&&['primary','ghost','dashed','link','text','default',].includes(item.type) ? item.type : 'default'"
:danger="item.danger === true || item.type === 'danger'"
@click="item.event(selectedRowKeys)" :style="item.style ?? ''">
<template v-if="item.icon" #icon>
<component :is="item.icon" />
</template>
{{ item.label }}
</a-button>
</pro-authority>
</template>
</div>
<!-- 默认工具栏 -->
<!-- 默认工具栏使用 Antd a-table-settings 呈现列设置 + 行高并保留刷新按钮 -->
<div class="pro-table-next" v-if="defaultToolbar">
<!-- 刷新工具栏 -->
<a-button @click="reload">
<a-table-settings v-model:columns="columnsModel" :sizeOptions="[]" size="small"/>
<!-- <a-button @click="reload" style="margin-left: 8px">
<template #icon>
<SyncOutlined />
</template>
</a-button>
<!-- 过滤工具栏 -->
<a-dropdown>
<a-button>
<template #icon>
<AppstoreOutlined />
</template>
</a-button>
<template #overlay>
<a-menu class="filtration">
<a-checkbox-group v-model:value="filtrationColumnKeys" @change="filtration">
<a-row>
<!-- 遍历字段 -->
<a-col :span="24" :key="index" v-for="(filtrationColumn, index) in filtrationColumns">
<a-checkbox :value="filtrationColumn.value">
{{ filtrationColumn.label }}
</a-checkbox>
</a-col>
</a-row>
</a-checkbox-group>
</a-menu>
</template>
</a-dropdown>
<!-- 过滤工具栏 -->
<a-dropdown>
<a-button><template #icon>
<ColumnHeightOutlined />
</template></a-button>
<template #overlay>
<a-menu :selectedKeys="[size]">
<a-menu-item @click="changeSize('default')" key="default">默认尺寸</a-menu-item>
<a-menu-item @click="changeSize('middle')" key="middle">中等尺寸</a-menu-item>
<a-menu-item @click="changeSize('small')" key="small">最小尺寸</a-menu-item>
</a-menu>
</template>
</a-dropdown>
<!--打印按钮-->
<a-button @click="print">
<template #icon>
<ExportOutlined />
</template>
</a-button>
<!--excel导出按钮-->
<a-button @click="ExportExcel">
<template #icon>
<CloudDownloadOutlined />
</template>
</a-button>
</a-button> -->
</div>
</div>
<!--数据导出栏-->
@ -94,14 +59,14 @@
:pagination="exportExcelPagination" style="display: none">
</a-table>
<!-- 表格组件 -->
<a-table id="table" :rowKey="rowKey" @change="fetch" :columns="columns" :loading="loading" :pagination="pagination"
:dataSource="datasource" :row-selection="rowSelection" :size="size" :scroll="{ x: 1200, y: 900 }"
<a-table id="table" :rowKey="rowKey" @change="fetch" :columns="columnsModel" :loading="loading" :pagination="pagination"
:dataSource="datasource" :row-selection="rowSelection"
:row-height="100" :customRow="rowClick" :sortDirections="['descend', 'ascend', '']"
:rowClassName="setRowClassName" @resizeColumn="handleResizeColumn" bordered>
:rowClassName="setRowClassName" @resizeColumn="handleResizeColumn">
<!--列搜索组件封装-->
<template #filterDropdown="{ setSelectedKeys, selectedKeys, confirm, clearFilters, column }">
<template #customFilterDropdown="{ setSelectedKeys, selectedKeys, confirm, clearFilters, column }">
<div style="padding: 8px">
<a-input ref="searchInput" :placeholder="`Search ${column.dataIndex}`" :value="selectedKeys[0]"
<a-input ref="searchInput" :placeholder="'请输入'" :value="selectedKeys[0]"
style="width: 188px; margin-bottom: 8px; display: block"
@change="(e) => {
setSelectedKeys(e.target.value ? [e.target.value] : []);
@ -114,7 +79,7 @@
</template>
搜索
</a-button>
<a-button size="small" style="width: 90px" @click="handleReset(clearFilters)"></a-button>
<a-button size="small" style="width: 90px" @click="handleReset(clearFilters, setSelectedKeys, column.dataIndex, confirm)">重置</a-button>
</div>
</template>
<!--列过滤组件封装-->
@ -152,13 +117,23 @@
</div>
</template>
<!--列排序组件封装-->
<template #filterIcon="filtered">
<template #customFilterIcon="filtered">
<search-outlined :style="{ color: filtered ? '#108ee9' : undefined }" />
</template>
<!-- 列转换 -->
<template :key="index" v-for="(column, index) in columns" #[column.dataIndex]="{ record }">
<!-- 表格头部单元格插槽 -->
<template #headerCell="{ column }">
<span>{{ column.title }}</span>
</template>
<!-- 表格内容单元格插槽 -->
<template #bodyCell="{ column, record, index }">
<!-- 序号 -->
<template v-if="column.dataIndex === 'index'">
{{ index + 1 }}
</template>
<!-- 行操作 -->
<span v-if="column.dataIndex == 'operate'">
<template v-if="column.dataIndex === 'operate'">
<template :key="i" v-for="(item, i) in operate">
<!-- 下拉操作 -->
<a-dropdown v-if="item.children && item.children.length > 0">
@ -179,8 +154,9 @@
<!-- 单个操作 -->
<pro-authority :value="item.code ? item.code : false" v-else>
<a-popconfirm v-if="item.isDel" title="确认删除?" ok-text="" cancel-text=""
@confirm="item.delEvent(record)" @cancel="item.cancelEvent(record)">
<a href="#">删除</a>
@confirm="item.delEvent && item.delEvent(record)"
@cancel="item.cancelEvent ? item.cancelEvent(record) : null">
<a-button type="text" danger >{{ item.label || '删除' }}</a-button>
</a-popconfirm>
<div style="display: inline-block" v-else>
<a @click="item.event(record)"> {{ item.label }} </a>
@ -188,25 +164,25 @@
<a-divider type="vertical" v-if="i != operate.length - 1" />
</pro-authority>
</template>
</span>
</template>
<!-- 开关转换 -->
<span v-else-if="column.switch">
<template v-else-if="column.switch">
<a-switch @change="column.switch.event($event, record)"
:checked="record[column.dataIndex] === column.switch.yes" checked-children="启用" un-checked-children="禁用" />
</span>
</template>
<!-- 文本转换 -->
<span v-else-if="column.conver">
<template v-else-if="column.conver">
<template v-for="(data, index) in column.conver">
<span :key="index" v-if="data.value === record[column.dataIndex]">
{{ data.label }}
</span>
</template>
</span>
</template>
<!-- 头像 -->
<span v-else-if="column.avatar">
<template v-else-if="column.avatar">
<!-- 空头像 -->
<a-avatar v-if="record[column.dataIndex] == null" :size="column.avatar.size" :shape="column.avatar.shape">
<template #icon>
@ -215,23 +191,28 @@
</a-avatar>
<!-- 非头像 -->
<a-avatar v-else :src="record[column.dataIndex]" :size="column.avatar.size" :shape="column.avatar.shape" />
</span>
</template>
<!-- 数据字典 -->
<span v-else-if="column.dictionary">
<template v-else-if="column.dictionary">
<pro-dictionary :code="column.dictionary.code" :type="column.dictionary.type"
v-model="record[column.dataIndex]"></pro-dictionary>
</span>
</template>
<!-- 预览 -->
<span v-else-if="column.image">
<template v-else-if="column.image">
<a-image :width="column.image.width" :src="record[column.dataIndex]" />
</span>
</template>
<!-- 右对齐数字列千位分隔格式化显示 -->
<template v-else-if="column.align === 'right'">
{{ formatNumber(record[column.dataIndex]) }}
</template>
<!-- 原样输出 -->
<span v-else-if="record">
<template v-else>
{{ record[column.dataIndex] }}
</span>
</template>
</template>
<!-- 内容插槽 -->
@ -240,8 +221,13 @@
</template>
<!--分页插件-->
<template>
<a-pagination v-model:current="current" :page-size-options="pageSizeOptions" :total="total" show-size-changer
:page-size="pageSize" @showSizeChange="onShowSizeChange">
<a-pagination v-if="pagination"
v-model:current="pagination.current"
:page-size-options="pagination.pageSizeOptions"
:total="pagination.total"
show-size-changer
:page-size="pagination.pageSize"
@showSizeChange="onShowSizeChange">
<template #buildOptionText="props">
<span v-if="props.value !== '50'">{{ props.value }}/</span>
<span v-else></span>
@ -252,54 +238,53 @@
<!-- 页脚字段汇总模板,取datasource中的第一条数据渲染table -->
<template #footer="" v-if="showPageTotal && datasource.length>0">
<a-table id="totalTable" :rowKey="rowKey" :data-source=" datasource.slice(0, 1)" :columns="columns"
:pagination="false" :showHeader="false" :scroll="{ x: true, y: false }" :bordered=false size="small">
<template :key="index" v-for="(column, index) in columns" #[column.dataIndex]="{ record }">
:pagination="false" :showHeader="false" :bordered=false size="small">
<template #bodyCell="{ column, record }">
<!-- 开关转换 -->
<template v-if="index == 0 ">
<template v-if="column.dataIndex === 'operate'">
<span :style="{fontSize: '14px', color: '#08c'}">合计</span>
</template>
<template v-if="column.showTotal">
<template v-else-if="column.showTotal">
<span :style="{fontSize: '14px', color: '#08c'}">
{{column.title}}<br />合计{{ getSum(datasource, column.dataIndex,record) }}{{ column.totalUnit || '' }}
</span>
</template>
<template v-else>
<!-- 原样输出 -->
</template>
</template>
</a-table>
</template>
</a-table>
</div>
</template>
<script>
import "./index.less";
import FileSaver from 'file-saver';
import * as XLSX from 'xlsx/xlsx.mjs';
import T from "ant-design-vue/es/table/Table";
import T from "@hwork/ant-design-vue/es/table/Table";
//import excelExport from "../module/ExportExcel"
import {
list
} from "../../../api/module/dictData";
} from '../../../api/module/dictData.js';
import {
useStore
} from 'vuex';
import { message } from '@hwork/ant-design-vue';
import {
defineComponent,
onMounted,
reactive,
toRefs,
toRef,
watch,
ref,
nextTick,
computed
} from "vue";
import {
AppstoreOutlined,
ExportOutlined,
SyncOutlined,
UserOutlined,
ColumnHeightOutlined,
SearchOutlined,
CloudDownloadOutlined,
} from "@ant-design/icons-vue";
//table
const searchInput = ref();
@ -311,9 +296,6 @@
name: "pro-table",
currentRowI: 999,
components: {
ColumnHeightOutlined,
AppstoreOutlined,
ExportOutlined,
SyncOutlined,
UserOutlined,
SearchOutlined,
@ -336,10 +318,29 @@
type: Array,
required: true,
},
///
///
toolbar: {
type: Array,
},
/// columns index
autoIndex: {
type: Boolean,
default: false,
},
///
hasSearch: {
type: Boolean,
default: true,
},
///
showPrint: {
type: Boolean,
default: true,
},
showExport: {
type: Boolean,
default: true,
},
defaultToolbar: {
type: Boolean,
default: true,
@ -375,10 +376,10 @@
setup(props) {
const slotsData = ref([]);
const store = useStore();
// slotsData column.slots
props.columns.map((value) => {
if (value.slots) {
if (value.slots && value.slots.customRender) {
slotsData.value.push(value.slots.customRender);
//slotsData.value.push(value.slots.filterIcon);
}
});
@ -392,9 +393,9 @@
//excel
exportExcelPagination: {
pageNum: 1,
pageSize: 1000
pageSize: 2000
}, //
columns: props.columns, //
columns: props.columns, // a-table-settings v-model:columns
filtrationColumnKeys: [], //
selectedRowKeys: [], //
size: "small", //
@ -405,17 +406,104 @@
});
///
if (props.operate != false) {
let operateSize = props.operate.length * 70;
state.columns.push({
dataIndex: "operate",
key: "operate",
title: "操作",
fixed: "right",
width: operateSize,
});
// autoIndex
const hasIndexCol = (cols) => (cols || []).some(col => col && (col.dataIndex === 'index' || col.key === 'index'))
if (props.autoIndex && !hasIndexCol(state.columns)) {
state.columns.unshift({
dataIndex: 'index',
key: 'index',
title: '序号',
width: 60,
fixed: 'left',
align: 'center',
customRender: ({ index }) => {
try {
if (state.pagination !== false) {
const current = Number(state.pagination.current || state.pagination.pageNum || 1)
const pageSize = Number(state.pagination.pageSize || 20)
return (current - 1) * pageSize + index + 1
}
} catch (e) {}
return index + 1
},
})
}
if (props.operate != false) {
//
const estimateOperateWidth = () => {
const items = Array.isArray(props.operate) ? props.operate : []
// children
const powerList = (store.getters && store.getters.power) ? store.getters.power : []
const isVisible = (it) => {
if (!it) return false
if (!it.code) return true
return powerList.indexOf(it.code) !== -1
}
const visible = items.filter(it => isVisible(it))
// 使 canvas
const getTextWidth = (text) => {
try {
const canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d')
if (!ctx) return 0
ctx.font = '14px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans"'
return Math.ceil(ctx.measureText(String(text || '')).width)
} catch (e) {
return (String(text || '').length) * 14
}
}
// + 16
const itemsWidth = visible.reduce((acc, it) => acc + getTextWidth(it.label || '') + 16, 0)
// 线 12px * (n-1)
const sepWidth = visible.length > 1 ? (visible.length - 1) * 12 : 0
//
const padding = 12
const total = padding + itemsWidth + sepWidth + padding
//
return Math.min(Math.max(total, 96), 260)
}
const operateCol = {
dataIndex: 'operate',
key: 'operate',
title: '操作',
fixed: 'right',
width: estimateOperateWidth(),
}
state.columns.push(operateCol)
// /
const recompute = () => {
const idx = state.columns.findIndex(c => c.dataIndex === 'operate')
if (idx !== -1) state.columns[idx].width = estimateOperateWidth()
}
// operate
watch(() => store.getters && store.getters.power, recompute)
watch(() => props.operate, recompute, { deep: true })
}
// props.showPrint / props.showExport
const builtinPrevToolbar = () => {
const items = [];
if (props.showPrint) {
items.push({ label: "打印", event: print, icon: 'PrinterOutlined' });
}
if (props.showExport) {
items.push({ label: "导出", event: ExportExcel, icon: 'CloudDownloadOutlined' });
}
return items;
};
// toolbar
const mergedToolbar = computed(() => {
const ext = Array.isArray(props.toolbar) ? props.toolbar : [];
return [...ext, ...builtinPrevToolbar()];
});
//
const proTableToolStyle = computed(() => (props.hasSearch ? {} : { paddingTop: '16px' }));
/**
* 从服务端获取下拉字典数据并对数据进行格式化
* @param code 字典值
@ -453,7 +541,7 @@
return dict;
} catch (error) {
console.error('获取字典数据失败:', error);
throw error;
throw error;
}
};
@ -482,7 +570,7 @@
}
};
/// column customRender
/// / antdv4 APIcustomFilterDropdown/customFilterIcon column.slots
state.columns.forEach(async (column) => {
//dictionarytable
let dict = [];
@ -493,27 +581,14 @@
column.filtered = false;
if (column.dictionary) {
//
state.filterColumnsIndex.push(column.index),
column.filters = dict;
state.filterColumnsIndex.push(column.dataIndex);
column.filters = dict;
column.filterSearch = true;
column.slots = {
customRender: column.dataIndex,
filterDropdown: "columnfilter",
};
} else {
//
column.slots = {
customRender: column.dataIndex,
filterIcon: "filterIcon",
filterDropdown: "filterDropdown",
};
}
} else {
//
column.slots = {
customRender: column.dataIndex
};
// API使 customFilterDropdown 使
column.customFilterDropdown = true;
}
// showSearch / column.slots
});
///
@ -531,6 +606,11 @@
state.columns = props.columns.filter((item) => value.includes(item.key));
state.filtrationColumnKeys = value;
};
// a-table-settings v-model
const columnsModel = toRef(state, 'columns');
// visibleColumns display=false
// columnsModel a-table display
//table
const handleResizeColumn = function(w, col) {
console.log("handleResizeColumn")
@ -564,20 +644,23 @@
const handleSearch = async (selectedKeys, confirm, dataIndex) => {
confirm();
state.loading = true;
/// :
const pageInfo = await getPageInfo(undefined);
let searchParams = Object.assign({}, pageInfo, state.columnSearchParams, props.param)
console.log("查询条件", searchParams)
const {
total,
data
} = await props.fetch(searchParams);
//
if (state.pagination != false) {
state.pagination.total = total;
try {
//
const pageInfo = await getPageInfo(undefined);
let searchParams = Object.assign({}, pageInfo, state.columnSearchParams, props.param)
console.log("查询条件", searchParams)
const { total, data } = await props.fetch(searchParams);
if (state.pagination != false) {
state.pagination.total = total || 0;
}
state.datasource = data || [];
} catch (error) {
console.error('列搜索请求失败:', error);
if (state.pagination != false) state.pagination.total = 0;
state.datasource = [];
} finally {
state.loading = false;
}
state.datasource = data;
state.loading = false;
};
/**
@ -594,27 +677,32 @@
}
};
///
const handleReset = (clearFilters) => {
/// UI
const handleReset = (clearFilters, setSelectedKeys, dataIndex, confirm) => {
console.log("列搜索条件重置")
state.columnSearchParams = {};
// UI
if (typeof setSelectedKeys === 'function') setSelectedKeys([])
//
if (dataIndex) {
const { [dataIndex]: _, ...rest } = state.columnSearchParams
state.columnSearchParams = rest
} else {
state.columnSearchParams = {}
}
//
if (state.filterColumnsIndex.length > 0) {
state.filterColumnsIndex.forEach((columnIndex) => {
//
const index = state.columns.findIndex(item => item === columnIndex);
const index = state.columns.findIndex(item => item.dataIndex === columnIndex);
if (index != -1) {
state.columns[index].filtered = false;
}
});
state.filterColumnsIndex = []
}
// state.columns.forEach((value, index) => {
// if(value.filtered&&value.filtered==true){
// value.filtered = false;
// }
// });
clearFilters();
// antd
if (typeof clearFilters === 'function') clearFilters()
if (typeof confirm === 'function') confirm()
fetchData();
};
@ -628,34 +716,60 @@
return str.replace(/([a-z])([A-Z])/g, '$1_$2').toLowerCase();
}
//
const formatNumber = function(val) {
if (val === null || val === undefined || val === '') return ''
if (typeof val === 'string' && val.trim() === '-') return val
const raw = String(val).replace(/,/g, '')
if (!/^[-+]?\d*(\.\d+)?$/.test(raw)) return val
const negative = raw.startsWith('-')
const numStr = negative ? raw.slice(1) : raw
const [intPart, decPart] = numStr.split('.')
const intWithSep = intPart.replace(/\B(?=(\d{3})+(?!\d))/g, ',')
return (negative ? '-' : '') + intWithSep + (decPart ? '.' + decPart : '')
}
///
const fetchData = async (pagination, filters, sorter) => {
console.log("filters 列过滤条件", filters)
//queryTypequeryType = 'like'使
// a-table
if (state.pagination !== false) {
if (pagination && typeof pagination.current !== 'undefined') {
state.pagination.current = pagination.current;
state.pagination.pageNum = pagination.current;
state.pagination.pageSize = pagination.pageSize;
} else {
if (typeof state.pagination.current === 'undefined') {
state.pagination.current = state.pagination.pageNum || 1;
}
}
}
// queryTypequeryType = 'like'使
const pageInfo = await getPageInfo(pagination);
state.loading = true;
var sortFeild = null
if (sorter && sorter.columnKey && sorter.order) {
sortFeild = {
sortColumn: toUnderline(sorter.columnKey),
sortType: sorter.order ? (sorter.order === "ascend" ? "ASC" : sorter.order === "descend" ?
"DESC" : "") : ""
try {
let sortFeild = null
if (sorter && sorter.columnKey && sorter.order) {
sortFeild = {
sortColumn: toUnderline(sorter.columnKey),
sortType: sorter.order ? (sorter.order === 'ascend' ? 'ASC' : sorter.order === 'descend' ? 'DESC' : '') : ''
}
console.log('sortFeild 列排序条件', sortFeild)
}
console.log("sortFeild 列排序条件", sortFeild)
const searchParams = Object.assign({}, pageInfo, state.columnSearchParams, props.param, sortFeild)
console.log('查询条件', searchParams)
const { total, data } = await props.fetch(searchParams)
if (state.pagination != false) state.pagination.total = total || 0
state.datasource = data || []
} catch (error) {
console.error('表格加载失败:', error)
if (state.pagination != false) state.pagination.total = 0
state.datasource = []
//
// message.error('')
} finally {
state.loading = false
}
let searchParams = Object.assign({}, pageInfo, state.columnSearchParams, props.param, sortFeild)
console.log("查询条件", searchParams)
///
const {
total,
data
} = await props.fetch(searchParams);
///
if (state.pagination != false) {
state.pagination.total = total;
}
state.datasource = data;
state.loading = false;
};
///
@ -677,6 +791,16 @@
return pageInfo;
};
//
const onShowSizeChange = (current, pageSize) => {
if (state.pagination !== false) {
state.pagination.pageSize = pageSize;
state.pagination.current = current;
state.pagination.pageNum = current;
}
fetchData({ current, pageSize });
};
///
const reload = function() {
console.log("刷新方法")
@ -725,26 +849,24 @@
let activeKey = store.getters.activeKey;
var exportFileName = panes.filter(item => item.path == activeKey)[0].title+new Date().toLocaleString().replace(/[/]/g, '_').replace(/[:]/g, '');
console.log("ExportExcel tablename", exportFileName)
state.exportExcelPagination.pageNum = 1;
state.exportExcelPagination.pageSize = state.pagination.total;
let searchParams = Object.assign({}, state.exportExcelPagination, state.columnSearchParams, props.param)
console.log("导出数据条件", searchParams)
const { total, data} = await props.fetch(searchParams);
if (data) {
//
state.datasourceExport = data;
//excelExportRef.value.excelExport()
nextTick(() => {
//table
exportDataMethod(props.tableId,exportFileName);
})
// nextTick(() => {
//
// exportExcelWithData(exportFileName,data);
// })
try {
state.exportExcelPagination.pageNum = 1;
state.exportExcelPagination.pageSize = state.pagination.total;
let searchParams = Object.assign({}, state.exportExcelPagination, state.columnSearchParams, props.param)
console.log('导出数据条件', searchParams)
const { total, data } = await props.fetch(searchParams)
if (data) {
state.datasourceExport = data;
nextTick(() => {
exportDataMethod(props.tableId, exportFileName);
})
}
} catch (error) {
console.error('导出失败:', error)
message.error('导出失败')
} finally {
state.loading = false
}
state.loading = false;
};
const exportDataMethod = function(elementId ,fileName) {
@ -812,16 +934,24 @@
onSelectChange,
///
changeSize,
///
/// /
print,
ExportExcel,
///
mergedToolbar,
proTableToolStyle,
columnsModel,
slotsData,
handleReset,
handleSearch,
setSelectedKeysOnChange,
changeFilteredStatus
changeFilteredStatus,
onShowSizeChange,
//
formatNumber
};
},

View File

@ -5,9 +5,9 @@
</template>
<script>
import Editor from "@tinymce/tinymce-vue";
require("./imp.js");
import init from "./init";
import initMini from "./init_mini";
import './imp.js';
import init from './init.js';
import initMini from './init_mini.js';
export default {
name:"tinymce",

View File

@ -8,9 +8,9 @@ const plugins = [
"print preview searchreplace autolink directionality visualblocks visualchars fullscreen link media template code codesample table charmap hr pagebreak nonbreaking anchor insertdatetime advlist lists wordcount imagetools textpattern help autosave autoresize "
];
let init = {
language_url: require("@/assets/tinymce/langs/zh_CN.js"),
language_url: "/src/assets/tinymce/langs/zh_CN.js",
language: "zh_CN",
skin_url: require("@/assets/tinymce/skins/ui/oxide/skin.css"),
skin_url: "/src/assets/tinymce/skins/ui/oxide/skin.css",
min_height: 300,
plugins: plugins,
toolbar: toolbar,

View File

@ -7,9 +7,9 @@ const plugins = [
"print preview searchreplace autolink directionality visualblocks visualchars fullscreen link media template code codesample table charmap hr pagebreak nonbreaking anchor insertdatetime advlist lists wordcount imagetools textpattern help autosave autoresize "
];
let init = {
language_url: require("@/assets/tinymce/langs/zh_CN.js"),
language_url: "/src/assets/tinymce/langs/zh_CN.js",
language: "zh_CN",
skin_url: require("@/assets/tinymce/skins/ui/oxide/skin.css"),
skin_url: "/src/assets/tinymce/skins/ui/oxide/skin.css",
min_height: 300,
plugins: plugins,
toolbar: toolbar,

View File

@ -40,4 +40,4 @@ export default {
background-color: transparent;
height: 100%;
}
</style>
</style>

View File

@ -48,7 +48,7 @@
<div class="menu-item" v-else @click="full(2)">
<CompressOutlined />
</div>
<a-dropdown class="notice-item" placement="bottomCenter">
<a-dropdown class="notice-item" placement="bottom">
<BellOutlined />
<template #overlay>
<a-menu class="notice-dropdown">
@ -69,7 +69,7 @@
</a-menu>
</template>
</a-dropdown>
<a-dropdown class="locale-item" placement="bottomCenter">
<a-dropdown class="locale-item" placement="bottom">
<GlobalOutlined />
<template #overlay>
<a-menu @click="toggleLang" :selectedKeys="selectedKeys">
@ -78,7 +78,7 @@
</a-menu>
</template>
</a-dropdown>
<a-dropdown class="avatar-item" placement="bottomCenter">
<a-dropdown class="avatar-item" placement="bottom">
<a-avatar :src="userInfo.avatar"></a-avatar>
<template #overlay>
<a-menu class="avatar-dropdown">

View File

@ -6,13 +6,15 @@
</div>
<!-- 根据侧边收缩状态决定隐显内容 -->
<!-- <span v-else><img class="image" :src="image" /></span> -->
<span v-else><img class="image" :src="require('@/assets/image/superMan.png')" /></span>
<span v-else><img class="image" :src="superManImage" /></span>
</div>
</template>
<script>
import { computed } from "vue";
import { useStore } from "vuex";
import config from '@/configure/pear.config.js';
import superManImage from '@/assets/image/superMan.png';
export default {
setup() {
@ -25,7 +27,8 @@ export default {
return {
collapsed,
image,
title
title,
superManImage
};
}
};

View File

@ -2,9 +2,9 @@
<a-drawer
placement="right"
:closable="false"
:visible="visible"
:open="visible"
width="340"
:after-visible-change="afterVisibleChange"
@afterOpenChange="afterVisibleChange"
@close="onChangeVisible()"
:class="[color]"
>
@ -424,7 +424,4 @@ export default {
float: right;
margin-right: 15px;
}
.ant-drawer-body{
padding: 10px!important;
}
</style>

View File

@ -24,9 +24,9 @@
</a-button>
<template v-slot:overlay>
<a-menu>
<a-menu-item @click="closeAll()"> </a-menu-item>
<a-menu-item @click="closeOther()"> </a-menu-item>
<a-menu-item @click="closeCurrent()"> </a-menu-item>
<a-menu-item @click="closeAll()"></a-menu-item>
<a-menu-item @click="closeOther()"></a-menu-item>
<a-menu-item @click="closeCurrent()"></a-menu-item>
</a-menu>
</template>
</a-dropdown>
@ -169,3 +169,22 @@ export default {
}
};
</script>
<style lang="less" scoped>
#tab {
display: flex;
justify-content: space-between;
align-items: flex-start;
.tab {
flex: 1;
overflow: auto;
}
.tab-tool {
margin-top: 5px;
margin-right: 16px;
margin-left: 16px;
}
:deep(.ant-tabs-top >.ant-tabs-nav) {
margin: 0 !important;
}
}
</style>

View File

@ -1,8 +1,8 @@
import { getModule } from '@/tools/common'
import antLocal from 'ant-design-vue/es/locale/en_US'
import antLocal from '@hwork/ant-design-vue/es/locale/en_US'
const requireENContext = require.context('./en-us/', false, /[\w+].(js)$/)
const enUS = getModule(requireENContext)
const moduleFiles = import.meta.glob('./en-us/*.js', { eager: true })
const enUS = getModule(moduleFiles)
export default {
...enUS,

Some files were not shown because too many files have changed in this diff Show More