diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..403adbc
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,23 @@
+.DS_Store
+node_modules
+/dist
+
+
+# local env files
+.env.local
+.env.*.local
+
+# Log files
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+
+# Editor directories and files
+.idea
+.vscode
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
diff --git a/vue/.gitignore b/vue/.gitignore
new file mode 100644
index 0000000..403adbc
--- /dev/null
+++ b/vue/.gitignore
@@ -0,0 +1,23 @@
+.DS_Store
+node_modules
+/dist
+
+
+# local env files
+.env.local
+.env.*.local
+
+# Log files
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+
+# Editor directories and files
+.idea
+.vscode
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
diff --git a/vue/README.md b/vue/README.md
new file mode 100644
index 0000000..f462a9b
--- /dev/null
+++ b/vue/README.md
@@ -0,0 +1,24 @@
+# vue2_element
+
+## Project setup
+```
+npm install
+```
+
+### Compiles and hot-reloads for development
+```
+npm run serve
+```
+
+### Compiles and minifies for production
+```
+npm run build
+```
+
+### Lints and fixes files
+```
+npm run lint
+```
+
+### Customize configuration
+See [Configuration Reference](https://cli.vuejs.org/config/).
diff --git a/vue/babel.config.js b/vue/babel.config.js
new file mode 100644
index 0000000..162a3ea
--- /dev/null
+++ b/vue/babel.config.js
@@ -0,0 +1,3 @@
+module.exports = {
+ presets: ["@vue/cli-plugin-babel/preset"],
+};
diff --git a/vue/jsconfig.json b/vue/jsconfig.json
new file mode 100644
index 0000000..4aafc5f
--- /dev/null
+++ b/vue/jsconfig.json
@@ -0,0 +1,19 @@
+{
+ "compilerOptions": {
+ "target": "es5",
+ "module": "esnext",
+ "baseUrl": "./",
+ "moduleResolution": "node",
+ "paths": {
+ "@/*": [
+ "src/*"
+ ]
+ },
+ "lib": [
+ "esnext",
+ "dom",
+ "dom.iterable",
+ "scripthost"
+ ]
+ }
+}
diff --git a/vue/package.json b/vue/package.json
new file mode 100644
index 0000000..ef5645c
--- /dev/null
+++ b/vue/package.json
@@ -0,0 +1,35 @@
+{
+ "name": "vue2_element",
+ "version": "0.1.0",
+ "private": true,
+ "scripts": {
+ "serve": "vue-cli-service serve",
+ "build": "vue-cli-service build",
+ "lint": "vue-cli-service lint"
+ },
+ "dependencies": {
+ "axios": "^1.4.0",
+ "core-js": "^3.8.3",
+ "element-ui": "^2.15.13",
+ "js-cookie": "^3.0.5",
+ "vue": "^2.6.14",
+ "vue-router": "^3.5.1",
+ "vuex": "^3.6.2"
+ },
+ "devDependencies": {
+ "@babel/core": "^7.12.16",
+ "@vue/cli-plugin-babel": "~5.0.0",
+ "@vue/cli-plugin-router": "~5.0.0",
+ "@vue/cli-plugin-vuex": "~5.0.0",
+ "@vue/cli-service": "~5.0.0",
+ "prettier": "^2.4.1",
+ "sass": "^1.32.7",
+ "sass-loader": "^12.0.0",
+ "vue-template-compiler": "^2.6.14"
+ },
+ "browserslist": [
+ "> 1%",
+ "last 2 versions",
+ "not dead"
+ ]
+}
diff --git a/vue/public/favicon.ico b/vue/public/favicon.ico
new file mode 100644
index 0000000..df36fcf
Binary files /dev/null and b/vue/public/favicon.ico differ
diff --git a/vue/public/index.html b/vue/public/index.html
new file mode 100644
index 0000000..3e5a139
--- /dev/null
+++ b/vue/public/index.html
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+ <%= htmlWebpackPlugin.options.title %>
+
+
+
+
+
+
+
diff --git a/vue/src/App.vue b/vue/src/App.vue
new file mode 100644
index 0000000..56cd2ce
--- /dev/null
+++ b/vue/src/App.vue
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
diff --git a/vue/src/api/login.js b/vue/src/api/login.js
new file mode 100644
index 0000000..400b61f
--- /dev/null
+++ b/vue/src/api/login.js
@@ -0,0 +1,17 @@
+import request from "@/utils/request";
+
+export function login(data) {
+ return request({
+ url: "http://127.0.0.1:9090/K3Cloud/Kingdee.BOS.WebApi.ServicesStub.AuthService.ValidateUser.common.kdsvc",
+ method: "post",
+ data,
+ });
+}
+
+export function supplierLogin(data) {
+ return request({
+ url: "http://1.14.142.111:9090/K3CLOUD/Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.ExecuteBillQuery.common.kdsvc",
+ method: "post",
+ data,
+ });
+}
diff --git a/vue/src/api/user.js b/vue/src/api/user.js
new file mode 100644
index 0000000..2f02f78
--- /dev/null
+++ b/vue/src/api/user.js
@@ -0,0 +1,9 @@
+import request from "@/utils/request";
+
+export function getTenantCodeByUser(data) {
+ return request({
+ url: "/api/account/sysuserdetail/getTenantCodeByUser",
+ method: "post",
+ params: data,
+ });
+}
diff --git a/vue/src/assets/logo.png b/vue/src/assets/logo.png
new file mode 100644
index 0000000..f3d2503
Binary files /dev/null and b/vue/src/assets/logo.png differ
diff --git a/vue/src/components/HelloWorld.vue b/vue/src/components/HelloWorld.vue
new file mode 100644
index 0000000..539979e
--- /dev/null
+++ b/vue/src/components/HelloWorld.vue
@@ -0,0 +1,130 @@
+
+
+
{{ msg }}
+
+ For a guide and recipes on how to configure / customize this project,
+ check out the
+ vue-cli documentation.
+
+
Installed CLI Plugins
+
+
Essential Links
+
+
Ecosystem
+
+
+
+
+
+
+
+
diff --git a/vue/src/main.js b/vue/src/main.js
new file mode 100644
index 0000000..9b3c207
--- /dev/null
+++ b/vue/src/main.js
@@ -0,0 +1,22 @@
+import Vue from "vue";
+import App from "./App.vue";
+import router from "./router";
+import store from "./store";
+import Cookies from "js-cookie";
+import Element from "element-ui";
+import "./styles/element-variables.scss";
+
+import axios from "axios";
+
+Vue.prototype.$axios = axios;
+Vue.config.productionTip = false;
+Vue.use(Element, {
+ size: Cookies.get("size") || "small", // set element-ui default size
+});
+Element.Dialog.props.closeOnClickModal.default = false; // 全局关闭,点击遮罩层关闭弹窗
+
+new Vue({
+ router,
+ store,
+ render: (h) => h(App),
+}).$mount("#app");
diff --git a/vue/src/router/index.js b/vue/src/router/index.js
new file mode 100644
index 0000000..a672e86
--- /dev/null
+++ b/vue/src/router/index.js
@@ -0,0 +1,31 @@
+import Vue from "vue";
+import VueRouter from "vue-router";
+
+Vue.use(VueRouter);
+
+const routes = [
+ {
+ path: "/",
+ component: () => import("@/views/login/login"),
+ name: "SysUrl",
+ meta: { title: "sysurl", icon: "el-icon-set-up" },
+ },
+ {
+ path: "/about",
+ component: () => import("@/views/AboutView"),
+ name: "SysRole",
+ meta: { icon: "el-icon-postcard" },
+ },
+ {
+ path: "/master",
+ component: () => import("@/views/master/master"),
+ name: "master",
+ meta: { icon: "el-icon-postcard" },
+ },
+];
+
+const router = new VueRouter({
+ routes,
+});
+
+export default router;
diff --git a/vue/src/store/getters.js b/vue/src/store/getters.js
new file mode 100644
index 0000000..768046b
--- /dev/null
+++ b/vue/src/store/getters.js
@@ -0,0 +1,5 @@
+const getters = {
+ token: (state) => state.user.token,
+ cookie: (state) => state.user.cookie,
+};
+export default getters;
diff --git a/vue/src/store/index.js b/vue/src/store/index.js
new file mode 100644
index 0000000..875e753
--- /dev/null
+++ b/vue/src/store/index.js
@@ -0,0 +1,25 @@
+import Vue from "vue";
+
+import Vuex from "vuex";
+import getters from "./getters";
+Vue.use(Vuex);
+
+// https://webpack.js.org/guides/dependency-management/#requirecontext
+const modulesFiles = require.context("./modules", true, /\.js$/);
+
+// you do not need `import app from './modules/app'`
+// it will auto require all vuex module from modules file
+const modules = modulesFiles.keys().reduce((modules, modulePath) => {
+ // set './app.js' => 'app'
+ const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, "$1");
+ const value = modulesFiles(modulePath);
+ modules[moduleName] = value.default;
+ return modules;
+}, {});
+
+const store = new Vuex.Store({
+ modules,
+ getters,
+});
+
+export default store;
diff --git a/vue/src/store/modules/user.js b/vue/src/store/modules/user.js
new file mode 100644
index 0000000..9add4e9
--- /dev/null
+++ b/vue/src/store/modules/user.js
@@ -0,0 +1,17 @@
+import { getToken, setToken, removeToken, getCookie } from "@/utils/auth";
+
+const state = {
+ token: getToken(),
+ cookie: getCookie(),
+};
+
+const mutations = {};
+
+const actions = {};
+
+export default {
+ namespaced: true,
+ state,
+ mutations,
+ actions,
+};
diff --git a/vue/src/styles/btn.scss b/vue/src/styles/btn.scss
new file mode 100644
index 0000000..373c6c5
--- /dev/null
+++ b/vue/src/styles/btn.scss
@@ -0,0 +1,106 @@
+@import './variables.scss';
+
+@mixin colorBtn($color) {
+ background: $color;
+
+ &:hover {
+ color: $color;
+
+ &:before,
+ &:after {
+ background: $color;
+ }
+ }
+}
+
+.blue-btn {
+ @include colorBtn($blue)
+}
+
+.light-blue-btn {
+ @include colorBtn($light-blue)
+}
+
+.red-btn {
+ @include colorBtn($red)
+}
+
+.pink-btn {
+ @include colorBtn($pink)
+}
+
+.green-btn {
+ @include colorBtn($green)
+}
+
+.tiffany-btn {
+ @include colorBtn($tiffany)
+}
+
+.yellow-btn {
+ @include colorBtn($yellow)
+}
+
+.pan-btn {
+ font-size: 14px;
+ color: #fff;
+ padding: 14px 36px;
+ border-radius: 8px;
+ border: none;
+ outline: none;
+ transition: 600ms ease all;
+ position: relative;
+ display: inline-block;
+
+ &:hover {
+ background: #fff;
+
+ &:before,
+ &:after {
+ width: 100%;
+ transition: 600ms ease all;
+ }
+ }
+
+ &:before,
+ &:after {
+ content: '';
+ position: absolute;
+ top: 0;
+ right: 0;
+ height: 2px;
+ width: 0;
+ transition: 400ms ease all;
+ }
+
+ &::after {
+ right: inherit;
+ top: inherit;
+ left: 0;
+ bottom: 0;
+ }
+}
+
+.custom-button {
+ display: inline-block;
+ line-height: 1;
+ white-space: nowrap;
+ cursor: pointer;
+ background: #fff;
+ color: #fff;
+ -webkit-appearance: none;
+ text-align: center;
+ box-sizing: border-box;
+ outline: 0;
+ margin: 0;
+ padding: 10px 15px;
+ font-size: 14px;
+ border-radius: 4px;
+}
+
+.svg-icon-arrow {
+ cursor: pointer;
+ color: #1890ff;
+ padding-left: 10px;
+ font-size: 20px;
+}
diff --git a/vue/src/styles/element-ui.scss b/vue/src/styles/element-ui.scss
new file mode 100644
index 0000000..219bc47
--- /dev/null
+++ b/vue/src/styles/element-ui.scss
@@ -0,0 +1,83 @@
+// cover some element-ui styles
+
+.el-breadcrumb__inner,
+.el-breadcrumb__inner a {
+ font-weight: 400 !important;
+}
+
+.el-upload {
+ input[type="file"] {
+ display: none !important;
+ }
+}
+
+.el-upload__input {
+ display: none;
+}
+
+.cell {
+ .el-tag {
+ margin-right: 0px;
+ }
+}
+
+.small-padding {
+ .cell {
+ padding-left: 5px;
+ padding-right: 5px;
+ }
+}
+
+.fixed-width {
+ .el-button--mini {
+ padding: 7px 10px;
+ min-width: 60px;
+ }
+}
+
+.status-col {
+ .cell {
+ padding: 0 10px;
+ text-align: center;
+
+ .el-tag {
+ margin-right: 0px;
+ }
+ }
+}
+
+.el-dialog {
+ transform: none;
+ left: 0;
+ position: relative;
+ margin: 0 auto;
+}
+
+// refine element ui upload
+.upload-container {
+ .el-upload {
+ width: 100%;
+
+ .el-upload-dragger {
+ width: 100%;
+ height: 200px;
+ }
+ }
+}
+
+// dropdown
+.el-dropdown-menu {
+ a {
+ display: block
+ }
+}
+
+// fix date-picker ui bug in filter-item
+.el-range-editor.el-input__inner {
+ display: inline-flex !important;
+}
+
+// to fix el-date-picker css style
+.el-range-separator {
+ box-sizing: content-box;
+}
diff --git a/vue/src/styles/element-variables.scss b/vue/src/styles/element-variables.scss
new file mode 100644
index 0000000..5bdc4da
--- /dev/null
+++ b/vue/src/styles/element-variables.scss
@@ -0,0 +1,31 @@
+/**
+* I think element-ui's default theme color is too light for long-term use.
+* So I modified the default color and you can modify it to your liking.
+**/
+
+/* theme color */
+$--color-primary: #1890ff;
+$--color-success: #13ce66;
+$--color-warning: #ffba00;
+$--color-danger: #ff4949;
+// $--color-info: #1E1E1E;
+
+$--button-font-weight: 400;
+
+// $--color-text-regular: #1f2d3d;
+
+$--border-color-light: #dfe4ed;
+$--border-color-lighter: #e6ebf5;
+
+$--table-border: 1px solid #dfe6ec;
+
+/* icon font path, required */
+$--font-path: "~element-ui/lib/theme-chalk/fonts";
+
+@import "~element-ui/packages/theme-chalk/src/index";
+
+// the :export directive is the magic sauce for webpack
+// https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass
+:export {
+ theme: $--color-primary;
+}
diff --git a/vue/src/styles/formgeneratorhome.scss b/vue/src/styles/formgeneratorhome.scss
new file mode 100644
index 0000000..b9110e0
--- /dev/null
+++ b/vue/src/styles/formgeneratorhome.scss
@@ -0,0 +1,271 @@
+$selectedColor: #f6f7ff;
+$lighterBlue: #409EFF;
+
+.container {
+ position: relative;
+ width: 100%;
+ height: 100%;
+}
+
+.components-list {
+ padding: 8px;
+ box-sizing: border-box;
+ height: 100%;
+ .components-item {
+ display: inline-block;
+ width: 48%;
+ margin: 1%;
+ transition: transform 0ms !important;
+ }
+}
+.components-draggable {
+ padding-bottom: 20px;
+}
+.components-title {
+ font-size: 14px;
+ color: #222;
+ margin: 6px 2px;
+ .svg-icon {
+ color: #666;
+ font-size: 18px;
+ }
+}
+
+.components-body {
+ padding: 8px 10px;
+ background: $selectedColor;
+ font-size: 12px;
+ cursor: move;
+ border: 1px dashed $selectedColor;
+ border-radius: 3px;
+ .svg-icon {
+ color: #777;
+ font-size: 15px;
+ }
+ &:hover {
+ border: 1px dashed #787be8;
+ color: #787be8;
+ .svg-icon {
+ color: #787be8;
+ }
+ }
+}
+
+.left-board {
+ width: 260px;
+ position: absolute;
+ left: 0;
+ top: 0;
+ height: 100vh;
+}
+.left-scrollbar{
+ height: calc(100vh - 42px);
+ overflow: hidden;
+}
+.center-scrollbar {
+ height: calc(100vh - 42px);
+ overflow: hidden;
+ border-left: 1px solid #f1e8e8;
+ border-right: 1px solid #f1e8e8;
+ box-sizing: border-box;
+}
+.center-board {
+ height: 100vh;
+ width: auto;
+ margin: 0 350px 0 260px;
+ box-sizing: border-box;
+}
+.empty-info {
+ position: absolute;
+ top: 46%;
+ left: 0;
+ right: 0;
+ text-align: center;
+ font-size: 18px;
+ color: #ccb1ea;
+ letter-spacing: 4px;
+}
+.action-bar {
+ position: relative;
+ height: 42px;
+ text-align: right;
+ padding: 0 15px;
+ box-sizing: border-box;;
+ border: 1px solid #f1e8e8;
+ border-top: none;
+ border-left: none;
+ .delete-btn {
+ color: #F56C6C;
+ }
+}
+.logo-wrapper {
+ position: relative;
+ height: 42px;
+ background: #fff;
+ border-bottom: 1px solid #f1e8e8;
+ box-sizing: border-box;
+}
+.logo {
+ position: absolute;
+ left: 12px;
+ top: 6px;
+ line-height: 30px;
+ color: #00afff;
+ font-weight: 600;
+ font-size: 17px;
+ white-space: nowrap;
+ > img {
+ width: 30px;
+ height: 30px;
+ vertical-align: top;
+ }
+ .github {
+ display: inline-block;
+ vertical-align: sub;
+ margin-left: 15px;
+ > img {
+ height: 22px;
+ }
+ }
+}
+
+.center-board-row {
+ padding: 12px 12px 15px 12px;
+ box-sizing: border-box;
+ & > .el-form {
+ // 69 = 12+15+42
+ height: calc(100vh - 69px);
+ }
+}
+.drawing-board {
+ height: 100%;
+ position: relative;
+ .components-body {
+ padding: 0;
+ margin: 0;
+ font-size: 0;
+ }
+ .sortable-ghost {
+ position: relative;
+ display: block;
+ overflow: hidden;
+ &::before {
+ content: " ";
+ position: absolute;
+ left: 0;
+ right: 0;
+ top: 0;
+ height: 3px;
+ background: rgb(89, 89, 223);
+ z-index: 2;
+ }
+ }
+ .components-item.sortable-ghost {
+ width: 100%;
+ height: 60px;
+ background-color: $selectedColor;
+ }
+ .active-from-item {
+ & > .el-form-item {
+ background: $selectedColor;
+ border-radius: 6px;
+ }
+ & > .drawing-item-copy, & > .drawing-item-delete {
+ display: initial;
+ }
+ & > .component-name {
+ color: $lighterBlue;
+ }
+ }
+ .el-form-item {
+ margin-bottom: 15px;
+ }
+}
+.drawing-item {
+ position: relative;
+ cursor: move;
+ &.unfocus-bordered:not(.active-from-item) > div:first-child {
+ border: 1px dashed #ccc;
+ }
+ .el-form-item {
+ padding: 12px 10px;
+ }
+}
+.drawing-row-item {
+ position: relative;
+ cursor: move;
+ box-sizing: border-box;
+ border: 1px dashed #ccc;
+ border-radius: 3px;
+ padding: 0 2px;
+ margin-bottom: 15px;
+ .drawing-row-item {
+ margin-bottom: 2px;
+ }
+ .el-col {
+ margin-top: 22px;
+ }
+ .el-form-item {
+ margin-bottom: 0;
+ }
+ .drag-wrapper {
+ min-height: 80px;
+ }
+ &.active-from-item {
+ border: 1px dashed $lighterBlue;
+ }
+ .component-name {
+ position: absolute;
+ top: 0;
+ left: 0;
+ font-size: 12px;
+ color: #bbb;
+ display: inline-block;
+ padding: 0 6px;
+ }
+}
+.drawing-item, .drawing-row-item {
+ &:hover {
+ & > .el-form-item {
+ background: $selectedColor;
+ border-radius: 6px;
+ }
+ & > .drawing-item-copy, & > .drawing-item-delete {
+ display: initial;
+ }
+ }
+ & > .drawing-item-copy, & > .drawing-item-delete {
+ display: none;
+ position: absolute;
+ top: -10px;
+ width: 22px;
+ height: 22px;
+ line-height: 22px;
+ text-align: center;
+ border-radius: 50%;
+ font-size: 12px;
+ border: 1px solid;
+ cursor: pointer;
+ z-index: 1;
+ }
+ & > .drawing-item-copy {
+ right: 56px;
+ border-color: $lighterBlue;
+ color: $lighterBlue;
+ background: #fff;
+ &:hover {
+ background: $lighterBlue;
+ color: #fff;
+ }
+ }
+ & > .drawing-item-delete {
+ right: 24px;
+ border-color: #F56C6C;
+ color: #F56C6C;
+ background: #fff;
+ &:hover {
+ background: #F56C6C;
+ color: #fff;
+ }
+ }
+}
diff --git a/vue/src/styles/index.scss b/vue/src/styles/index.scss
new file mode 100644
index 0000000..8054265
--- /dev/null
+++ b/vue/src/styles/index.scss
@@ -0,0 +1,527 @@
+@import './variables.scss';
+@import './mixin.scss';
+@import './transition.scss';
+@import './element-ui.scss';
+@import './sidebar.scss';
+@import './btn.scss';
+
+body {
+ height: 100%;
+ -moz-osx-font-smoothing: grayscale;
+ -webkit-font-smoothing: antialiased;
+ text-rendering: optimizeLegibility;
+ font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;
+}
+
+label {
+ font-weight: 700;
+}
+
+html {
+ height: 100%;
+ box-sizing: border-box;
+}
+
+#app {
+ height: 100%;
+}
+
+*,
+*:before,
+*:after {
+ box-sizing: inherit;
+}
+
+.no-padding {
+ padding: 0px !important;
+}
+
+.padding-content {
+ padding: 4px 0;
+}
+
+a:focus,
+a:active {
+ outline: none;
+}
+
+a,
+a:focus,
+a:hover {
+ cursor: pointer;
+ color: inherit;
+ text-decoration: none;
+}
+
+div:focus {
+ outline: none;
+}
+
+.fr {
+ float: right;
+}
+
+.fl {
+ float: left;
+}
+
+.pr-5 {
+ padding-right: 5px;
+}
+
+.pl-5 {
+ padding-left: 5px;
+}
+
+.block {
+ display: block;
+}
+
+.pointer {
+ cursor: pointer;
+}
+
+.inlineBlock {
+ display: block;
+}
+
+.clearfix {
+ &:after {
+ visibility: hidden;
+ display: block;
+ font-size: 0;
+ content: " ";
+ clear: both;
+ height: 0;
+ }
+}
+
+aside {
+ background: #eef1f6;
+ padding: 8px 24px;
+ margin-bottom: 20px;
+ border-radius: 2px;
+ display: block;
+ line-height: 32px;
+ font-size: 16px;
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
+ color: #2c3e50;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+
+ a {
+ color: #337ab7;
+ cursor: pointer;
+
+ &:hover {
+ color: rgb(32, 160, 255);
+ }
+ }
+}
+
+//main-container全局样式
+.app-container {
+ padding: 20px;
+ width: 100%;
+ height: 100%;
+ overflow-y: auto;
+ box-sizing: border-box;
+}
+
+.components-container {
+ margin: 30px 50px;
+ position: relative;
+}
+
+.pagination-container {
+ margin-top: 30px;
+}
+
+.text-center {
+ text-align: center
+}
+
+.sub-navbar {
+ height: 50px;
+ line-height: 50px;
+ position: relative;
+ width: 100%;
+ text-align: right;
+ padding-right: 20px;
+ transition: 600ms ease position;
+ background: linear-gradient(90deg, rgba(32, 182, 249, 1) 0%, rgba(32, 182, 249, 1) 0%, rgba(33, 120, 241, 1) 100%, rgba(33, 120, 241, 1) 100%);
+
+ .subtitle {
+ font-size: 20px;
+ color: #fff;
+ }
+
+ &.draft {
+ background: #d0d0d0;
+ }
+
+ &.deleted {
+ background: #d0d0d0;
+ }
+}
+
+.link-type,
+.link-type:focus {
+ color: #337ab7;
+ cursor: pointer;
+
+ &:hover {
+ color: rgb(32, 160, 255);
+ }
+}
+
+.filter-container {
+ padding-bottom: 10px;
+
+ .filter-input {
+ width: 150px;
+ margin-right: 10px;
+ }
+
+ .filter-item {
+ display: inline-block;
+ vertical-align: middle;
+ margin-bottom: 10px;
+ }
+}
+
+//refine vue-multiselect plugin
+.multiselect {
+ line-height: 16px;
+}
+
+.multiselect--active {
+ z-index: 1000 !important;
+}
+
+.center-tabs {
+ .el-tabs__header {
+ margin-bottom: 0!important;
+ }
+ .el-tabs__item {
+ width: 50%;
+ text-align: center;
+ }
+ .el-tabs__nav {
+ width: 100%;
+ }
+}
+
+::-webkit-scrollbar {
+ width: 8px;
+ height: 8px;
+}
+::-webkit-scrollbar-thumb {
+ background-color: #C0D4F0;
+ border-radius: 3px;
+}
+
+// formgenerator
+$editorTabsborderColor: #121315;
+.editor-tabs {
+ background: $editorTabsborderColor;
+ .el-tabs__header {
+ margin: 0;
+ border-bottom-color: $editorTabsborderColor;
+ .el-tabs__nav {
+ border-color: $editorTabsborderColor;
+ }
+ }
+ .el-tabs__item {
+ height: 32px;
+ line-height: 32px;
+ color: #888a8e;
+ border-left: 1px solid $editorTabsborderColor!important;
+ background: #363636;
+ margin-right: 5px;
+ user-select: none;
+ }
+ .el-tabs__item.is-active {
+ background: #1e1e1e;
+ border-bottom-color: #1e1e1e!important;
+ color: #fff;
+ }
+ .el-icon-edit {
+ color: #f1fa8c;
+ }
+ .el-icon-document {
+ color: #a95812;
+ }
+ :focus.is-active.is-focus:not(:active) {
+ box-shadow: none;
+ border-radius: 0;
+ }
+}
+
+.right-scrollbar {
+ .el-scrollbar__view {
+ padding: 12px 18px 15px 15px;
+ }
+}
+
+.reg-item {
+ padding: 12px 6px;
+ background: #f8f8f8;
+ position: relative;
+ border-radius: 4px;
+ .close-btn {
+ position: absolute;
+ right: -6px;
+ top: -6px;
+ display: block;
+ width: 16px;
+ height: 16px;
+ line-height: 16px;
+ background: rgba(0, 0, 0, 0.2);
+ border-radius: 50%;
+ color: #fff;
+ text-align: center;
+ z-index: 1;
+ cursor: pointer;
+ font-size: 12px;
+ &:hover {
+ background: rgba(210, 23, 23, 0.5)
+ }
+ }
+ & + .reg-item {
+ margin-top: 18px;
+ }
+}
+
+.action-bar {
+ & .el-button+.el-button {
+ margin-left: 15px;
+ }
+ & i {
+ font-size: 20px;
+ vertical-align: middle;
+ position: relative;
+ top: -1px;
+ }
+}
+
+.custom-tree-node {
+ width: 100%;
+ font-size: 14px;
+ .node-operation {
+ float: right;
+ }
+ i[class*="el-icon"] + i[class*="el-icon"] {
+ margin-left: 6px;
+ }
+ .el-icon-plus {
+ color: #409EFF;
+ }
+ .el-icon-delete {
+ color: #157a0c;
+ }
+}
+
+//
+.popoverTo {
+ .el-popover__title {
+
+ font-size: 14px;
+ }
+}
+
+// 弹窗和内弹窗
+.pop-up,
+.inner-pop-up,
+.pop-up-height {
+ display: flex;
+
+ // 弹窗内边据
+ .el-dialog__body {
+ padding: 0px 20px;
+ }
+ .dataForm {
+ border-top: 1px solid #ccc;
+ padding: 20px 0;
+ }
+ // 弹窗里面的表单的外边距设置 el-dialog-bottom
+ .el-dialog-bottom {
+ margin-bottom: 10px;
+ margin-top: 5px;
+ }
+ // 弹窗标题加粗 title 粘性定位固定在顶部
+ .el-dialog__header {
+ position: sticky;
+ top: 0;
+ background-color: #FFFFFF;
+ box-shadow: 0 1px 2px 1px #f0f0f0;
+ z-index: 9999;
+ .el-dialog__title {
+ font-weight: bold;
+ }
+ }
+ // 限制弹窗的高度
+ .el-dialog {
+ max-height: calc(100% - 10vh ) !important;
+ // min-height: 20vh;
+ margin: auto !important;
+ overflow: auto;
+ position: relative;
+ // 个性化-固定在容器顶部
+ .content-fixed-top {
+ position: fixed;
+ padding-top: 10px;
+ margin-top: 2px;
+ z-index: 9999;
+ background-color: #fff;
+ }
+ // 个性化-中部
+ .content-fixed-conter {
+ padding-top: 50px;
+ }
+ // 个性化-固定底部
+ .content-fixed-bottom {
+ position: sticky;
+ bottom: 0;
+ z-index: 9999;
+ background-color: #fff;
+ .pagination-container {
+ margin-top: 0;
+ padding: 25px 0;
+ }
+
+ }
+ .filter-container {
+
+ padding-bottom: 0px;
+ }
+ }
+
+}
+.pop-up-height {
+ .el-dialog {
+ height: calc(100% - 10vh ) !important;
+ }
+}
+
+
+// 表单里面的input框 手动添加icon 图标
+.icon_style {
+
+ .el-form-item__content{
+ position: relative;
+ }
+ .icon {
+ width: calc(100% - 47px);
+ height: calc(100% - 2px);
+ color: #C0C4CC;
+ transform: translateY(-50%);
+ display: flex;
+ align-content: center;
+ justify-content: flex-end;
+ position: absolute ;
+ top: 50%;
+ left: 0;
+ .el-icon-circle-close{
+ line-height: inherit;
+ background-color: #fff;
+ padding: 0 8px;
+ &:hover {
+ color: #1890FF;
+ cursor: pointer;
+ }
+ }
+ }
+ .el-input__suffix {
+ display: none;
+ }
+}
+
+.app-sticky {
+ width: 100%;
+ height: calc(100vh - 84px);
+ overflow-y: auto;
+ box-sizing: border-box;
+ padding: 0 20px;
+ // 表格的导航栏 粘性定位国定
+ .positionStl {
+ position: sticky;
+ top: 0;
+ z-index: 20;
+ background-color: #fff;
+ padding-top: 10px;
+ box-sizing: border-box;
+
+ .filter-container {
+ padding-bottom: 0;
+ }
+ }
+ .pagination-container {
+ margin-top: 0;
+ padding: 10px 16px !important;
+ position: sticky;
+ bottom: 0;
+ z-index: 20;
+ }
+
+ #screenfull-container {
+ height: calc( 100% - 94px - 52px );
+ .mainHeight {
+ height: calc( 100% - 23px )
+ }
+ #tableData {
+ tr td .cell {
+ line-height: initial !important;
+ // 超出两行 以省略号显示
+ overflow : hidden;
+ text-overflow: ellipsis;
+ display: -webkit-box;
+ -webkit-line-clamp: 2; // 控制几行
+ -webkit-box-orient: vertical;
+ }
+
+
+ .el-button--small {
+ padding: 0px;
+ }
+ }
+ }
+
+}
+
+// 黑色字体
+.el-input.is-disabled .el-input__inner {
+ color: #000;
+
+}
+
+// 让input number类型的标签不产生上下加减的按钮
+input::-webkit-outer-spin-button,
+input::-webkit-inner-spin-button {
+ -webkit-appearance: none !important;
+ margin: 0;
+}
+
+// 自定义加载
+ .daoru .el-loading-mask .el-loading-spinner {
+ font-size: 50px;
+ .el-loading-text {
+ font-size: 20px;
+ }
+}
+
+// el-divider 组件的修改样式
+.divider {
+ margin: 30px 0 !important;
+ .el-divider__text {
+ font-weight: bold;
+ font-size: 17px;
+
+ }
+}
+
+// 加载中 .el-loading-spinner .circular
+.el-loading-spinner .circular {
+ width: 70px;
+ height: 70px;
+}
diff --git a/vue/src/styles/mixin.scss b/vue/src/styles/mixin.scss
new file mode 100644
index 0000000..fe53bc7
--- /dev/null
+++ b/vue/src/styles/mixin.scss
@@ -0,0 +1,100 @@
+@mixin clearfix {
+ &:after {
+ content: "";
+ display: table;
+ clear: both;
+ }
+}
+
+@mixin scrollBar {
+ &::-webkit-scrollbar-track-piece {
+ background: #d3dce6;
+ }
+
+ &::-webkit-scrollbar {
+ width: 6px;
+ }
+
+ &::-webkit-scrollbar-thumb {
+ background: #99a9bf;
+ border-radius: 20px;
+ }
+}
+
+@mixin relative {
+ position: relative;
+ width: 100%;
+ height: 100%;
+}
+
+@mixin pct($pct) {
+ width: #{$pct};
+ position: relative;
+ margin: 0 auto;
+}
+
+@mixin triangle($width, $height, $color, $direction) {
+ $width: $width/2;
+ $color-border-style: $height solid $color;
+ $transparent-border-style: $width solid transparent;
+ height: 0;
+ width: 0;
+
+ @if $direction==up {
+ border-bottom: $color-border-style;
+ border-left: $transparent-border-style;
+ border-right: $transparent-border-style;
+ }
+
+ @else if $direction==right {
+ border-left: $color-border-style;
+ border-top: $transparent-border-style;
+ border-bottom: $transparent-border-style;
+ }
+
+ @else if $direction==down {
+ border-top: $color-border-style;
+ border-left: $transparent-border-style;
+ border-right: $transparent-border-style;
+ }
+
+ @else if $direction==left {
+ border-right: $color-border-style;
+ border-top: $transparent-border-style;
+ border-bottom: $transparent-border-style;
+ }
+}
+
+@mixin action-bar {
+ .action-bar {
+ height: 33px;
+ background: #f2fafb;
+ padding: 0 15px;
+ box-sizing: border-box;
+
+ .bar-btn {
+ display: inline-block;
+ padding: 0 6px;
+ line-height: 32px;
+ color: #8285f5;
+ cursor: pointer;
+ font-size: 14px;
+ user-select: none;
+ & i {
+ font-size: 20px;
+ }
+ &:hover {
+ color: #4348d4;
+ }
+ }
+ .bar-btn + .bar-btn {
+ margin-left: 8px;
+ }
+ .delete-btn {
+ color: #f56c6c;
+ &:hover {
+ color: #ea0b30;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/vue/src/styles/sidebar.scss b/vue/src/styles/sidebar.scss
new file mode 100644
index 0000000..94760cc
--- /dev/null
+++ b/vue/src/styles/sidebar.scss
@@ -0,0 +1,226 @@
+#app {
+
+ .main-container {
+ min-height: 100%;
+ transition: margin-left .28s;
+ margin-left: $sideBarWidth;
+ position: relative;
+ }
+
+ .sidebar-container {
+ transition: width 0.28s;
+ width: $sideBarWidth !important;
+ background-color: $menuBg;
+ height: 100%;
+ position: fixed;
+ font-size: 0px;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 1001;
+ overflow: hidden;
+
+ // reset element-ui css
+ .horizontal-collapse-transition {
+ transition: 0s width ease-in-out, 0s padding-left ease-in-out, 0s padding-right ease-in-out;
+ }
+
+ .scrollbar-wrapper {
+ overflow-x: hidden !important;
+ }
+
+ .el-scrollbar__bar.is-vertical {
+ right: 0px;
+ }
+
+ .el-scrollbar {
+ height: 100%;
+ }
+
+ &.has-logo {
+ .el-scrollbar {
+ height: calc(100% - 50px);
+ }
+ }
+
+ .is-horizontal {
+ display: none;
+ }
+
+ a {
+ display: inline-block;
+ width: 100%;
+ overflow: hidden;
+ }
+
+ .svg-icon {
+ margin-right: 16px;
+ }
+
+ .sub-el-icon {
+ margin-right: 12px;
+ margin-left: -2px;
+ }
+
+ .el-menu {
+ border: none;
+ height: 100%;
+ width: 100% !important;
+ }
+
+ // menu hover
+ .submenu-title-noDropdown,
+ .el-submenu__title {
+ &:hover {
+ background-color: $menuHover !important;
+ }
+ }
+
+ .is-active>.el-submenu__title {
+ color: $subMenuActiveText !important;
+ }
+
+ & .nest-menu .el-submenu>.el-submenu__title,
+ & .el-submenu .el-menu-item {
+ min-width: $sideBarWidth !important;
+ background-color: $subMenuBg !important;
+
+ &:hover {
+ background-color: $subMenuHover !important;
+ }
+ }
+ }
+
+ .hideSidebar {
+ .sidebar-container {
+ width: 54px !important;
+ }
+
+ .main-container {
+ margin-left: 54px;
+ }
+
+ .submenu-title-noDropdown {
+ padding: 0 !important;
+ position: relative;
+
+ .el-tooltip {
+ padding: 0 !important;
+
+ .svg-icon {
+ margin-left: 20px;
+ }
+
+ .sub-el-icon {
+ margin-left: 19px;
+ }
+ }
+ }
+
+ .el-submenu {
+ overflow: hidden;
+
+ &>.el-submenu__title {
+ padding: 0 !important;
+
+ .svg-icon {
+ margin-left: 20px;
+ }
+
+ .sub-el-icon {
+ margin-left: 19px;
+ }
+
+ .el-submenu__icon-arrow {
+ display: none;
+ }
+ }
+ }
+
+ .el-menu--collapse {
+ .el-submenu {
+ &>.el-submenu__title {
+ &>span {
+ height: 0;
+ width: 0;
+ overflow: hidden;
+ visibility: hidden;
+ display: inline-block;
+ }
+ }
+ }
+ }
+ }
+
+ .el-menu--collapse .el-menu .el-submenu {
+ min-width: $sideBarWidth !important;
+ }
+
+ // mobile responsive
+ .mobile {
+ .main-container {
+ margin-left: 0px;
+ }
+
+ .sidebar-container {
+ transition: transform .28s;
+ width: $sideBarWidth !important;
+ }
+
+ &.hideSidebar {
+ .sidebar-container {
+ pointer-events: none;
+ transition-duration: 0.3s;
+ transform: translate3d(-$sideBarWidth, 0, 0);
+ }
+ }
+ }
+
+ .withoutAnimation {
+
+ .main-container,
+ .sidebar-container {
+ transition: none;
+ }
+ }
+}
+
+// when menu collapsed
+.el-menu--vertical {
+ &>.el-menu {
+ .svg-icon {
+ margin-right: 16px;
+ }
+ .sub-el-icon {
+ margin-right: 12px;
+ margin-left: -2px;
+ }
+ }
+
+ .nest-menu .el-submenu>.el-submenu__title,
+ .el-menu-item {
+ &:hover {
+ // you can use $subMenuHover
+ background-color: $menuHover !important;
+ }
+ }
+
+ // the scroll bar appears when the subMenu is too long
+ >.el-menu--popup {
+ max-height: 100vh;
+ overflow-y: auto;
+
+ &::-webkit-scrollbar-track-piece {
+ background: #d3dce6;
+ }
+
+ &::-webkit-scrollbar {
+ width: 6px;
+ }
+
+ &::-webkit-scrollbar-thumb {
+ background: #99a9bf;
+ border-radius: 20px;
+ }
+ }
+}
diff --git a/vue/src/styles/transition.scss b/vue/src/styles/transition.scss
new file mode 100644
index 0000000..4cb27cc
--- /dev/null
+++ b/vue/src/styles/transition.scss
@@ -0,0 +1,48 @@
+// global transition css
+
+/* fade */
+.fade-enter-active,
+.fade-leave-active {
+ transition: opacity 0.28s;
+}
+
+.fade-enter,
+.fade-leave-active {
+ opacity: 0;
+}
+
+/* fade-transform */
+.fade-transform-leave-active,
+.fade-transform-enter-active {
+ transition: all .5s;
+}
+
+.fade-transform-enter {
+ opacity: 0;
+ transform: translateX(-30px);
+}
+
+.fade-transform-leave-to {
+ opacity: 0;
+ transform: translateX(30px);
+}
+
+/* breadcrumb transition */
+.breadcrumb-enter-active,
+.breadcrumb-leave-active {
+ transition: all .5s;
+}
+
+.breadcrumb-enter,
+.breadcrumb-leave-active {
+ opacity: 0;
+ transform: translateX(20px);
+}
+
+.breadcrumb-move {
+ transition: all .5s;
+}
+
+.breadcrumb-leave-active {
+ position: absolute;
+}
diff --git a/vue/src/styles/variables.scss b/vue/src/styles/variables.scss
new file mode 100644
index 0000000..5350ff2
--- /dev/null
+++ b/vue/src/styles/variables.scss
@@ -0,0 +1,35 @@
+// base color
+$blue:#324157;
+$light-blue:#3A71A8;
+$red:#C03639;
+$pink: #E65D6E;
+$green: #30B08F;
+$tiffany: #4AB7BD;
+$yellow:#FEC171;
+$panGreen: #30B08F;
+
+// sidebar
+$menuText:#bfcbd9;
+$menuActiveText:#409EFF;
+$subMenuActiveText:#f4f4f5;
+
+$menuBg:#304156;
+$menuHover:#263445;
+
+$subMenuBg:#1f2d3d;
+$subMenuHover:#001528;
+
+$sideBarWidth: 210px;
+
+// the :export directive is the magic sauce for webpack
+// https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass
+:export {
+ menuText: $menuText;
+ menuActiveText: $menuActiveText;
+ subMenuActiveText: $subMenuActiveText;
+ menuBg: $menuBg;
+ menuHover: $menuHover;
+ subMenuBg: $subMenuBg;
+ subMenuHover: $subMenuHover;
+ sideBarWidth: $sideBarWidth;
+}
diff --git a/vue/src/utils/auth.js b/vue/src/utils/auth.js
new file mode 100644
index 0000000..58b8c45
--- /dev/null
+++ b/vue/src/utils/auth.js
@@ -0,0 +1,31 @@
+import Cookies from "js-cookie";
+
+const TokenKey = "kdservice-sessionid";
+
+export function getToken() {
+ // console.log('取出to'+Cookies.get(TokenKey))
+ return Cookies.get(TokenKey);
+}
+
+export function setToken(token) {
+ // console.log('设置传入to'+token)
+ return Cookies.set(TokenKey, token);
+}
+
+export function removeToken() {
+ return Cookies.remove(TokenKey);
+}
+
+const CookieKey = "cookie";
+
+export function getCookie() {
+ return Cookies.get(CookieKey);
+}
+
+export function setCookie(cookie) {
+ return Cookies.set(CookieKey, cookie);
+}
+
+export function removeCookie() {
+ return Cookies.remove(CookieKey);
+}
diff --git a/vue/src/utils/request.js b/vue/src/utils/request.js
new file mode 100644
index 0000000..eaeb8ad
--- /dev/null
+++ b/vue/src/utils/request.js
@@ -0,0 +1,61 @@
+import axios from "axios";
+import { Message } from "element-ui";
+import store from "@/store";
+import { getCookie, getToken } from "@/utils/auth";
+
+// create an axios instance
+const service = axios.create({
+ // baseURL: "http://1.14.142.111:9090", // url = base url + request url
+ // withCredentials: true, // send cookies when cross-domain requests
+ timeout: 5000, // request timeout
+});
+
+// request interceptor
+service.interceptors.request.use(
+ (config) => {
+ // do something before request is sent
+ if (store.getters.token) {
+ // config.headers['Cookie'] = 'kdservice-sessionid=' + getToken()
+ // config.headers['kdservice'] = getToken()
+ }
+ config.headers["Cookie"] = "kdservice-sessionid=" + getToken();
+ config.headers["Content-Type"] = "application/json";
+
+ return config;
+ },
+ (error) => {
+ // do something with request error
+ console.log(error); // for debug
+ return Promise.reject(error);
+ }
+);
+
+// response interceptor
+service.interceptors.response.use(
+ /**
+ * If you want to get http information such as headers or status
+ * Please return response => response
+ */
+
+ /**
+ * Determine the request status by custom code
+ * Here is just an example
+ * You can also judge the status by HTTP Status Code
+ */
+ (response) => {
+ const res = response.data;
+ // if the custom code is not 200, it is judged as an error.
+ if (res.code && res.code !== 200) {
+ Message({
+ message: res.message || "Error",
+ type: "error",
+ duration: 5 * 1000,
+ });
+ return Promise.reject(new Error(res.message || "Error"));
+ } else {
+ return res;
+ }
+ }
+);
+
+export default service;
diff --git a/vue/src/views/AboutView.vue b/vue/src/views/AboutView.vue
new file mode 100644
index 0000000..3fa2807
--- /dev/null
+++ b/vue/src/views/AboutView.vue
@@ -0,0 +1,5 @@
+
+
+
This is an about page
+
+
diff --git a/vue/src/views/HomeView.vue b/vue/src/views/HomeView.vue
new file mode 100644
index 0000000..e8d96d7
--- /dev/null
+++ b/vue/src/views/HomeView.vue
@@ -0,0 +1,18 @@
+
+
+

+
+
+
+
+
diff --git a/vue/src/views/login/login.vue b/vue/src/views/login/login.vue
new file mode 100644
index 0000000..a22c797
--- /dev/null
+++ b/vue/src/views/login/login.vue
@@ -0,0 +1,341 @@
+
+
+
+
+
+
+
+
+
diff --git a/vue/src/views/master/master.vue b/vue/src/views/master/master.vue
new file mode 100644
index 0000000..2fe1529
--- /dev/null
+++ b/vue/src/views/master/master.vue
@@ -0,0 +1,704 @@
+
+
+
+
+ {{ '保存' }}
+
+
+ {{ '提交' }}
+
+
+
+
+
+
+ 基本信息
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ scop.row.FPrice }}
+
+
+
+
+
+
+
+ {{ scop.row.FTaxPrice }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/vue/vue.config.js b/vue/vue.config.js
new file mode 100644
index 0000000..0aed899
--- /dev/null
+++ b/vue/vue.config.js
@@ -0,0 +1,4 @@
+const { defineConfig } = require("@vue/cli-service");
+module.exports = defineConfig({
+ transpileDependencies: true,
+});