Procházet zdrojové kódy

添加期刊管理 目录管理(未完成)

asd123a20 před 3 roky
rodič
revize
1dcdeb1402
54 změnil soubory, kde provedl 26337 přidání a 24 odebrání
  1. 2 2
      admin-code/vue.config.js
  2. 2 2
      admin-column/vue.config.js
  3. 2 2
      admin-content/vue.config.js
  4. 12 0
      admin-frame/lib/apps.js
  5. 4 3
      admin-frame/vue.config.js
  6. 2 2
      admin-img-news/vue.config.js
  7. 3 0
      admin-journal-catalogue/.browserslistrc
  8. 5 0
      admin-journal-catalogue/.editorconfig
  9. 2 0
      admin-journal-catalogue/.env
  10. 1 0
      admin-journal-catalogue/.eslintignore
  11. 23 0
      admin-journal-catalogue/.eslintrc.js
  12. 23 0
      admin-journal-catalogue/.gitignore
  13. 24 0
      admin-journal-catalogue/README.md
  14. 5 0
      admin-journal-catalogue/babel.config.js
  15. 12565 0
      admin-journal-catalogue/package-lock.json
  16. 35 0
      admin-journal-catalogue/package.json
  17. binární
      admin-journal-catalogue/public/favicon.ico
  18. 17 0
      admin-journal-catalogue/public/index.html
  19. 24 0
      admin-journal-catalogue/src/App.vue
  20. binární
      admin-journal-catalogue/src/assets/logo.png
  21. 48 0
      admin-journal-catalogue/src/main.js
  22. 3 0
      admin-journal-catalogue/src/public-path.js
  23. 10 0
      admin-journal-catalogue/src/router/index.js
  24. 65 0
      admin-journal-catalogue/src/store/index.js
  25. 248 0
      admin-journal-catalogue/src/views/home.vue
  26. 33 0
      admin-journal-catalogue/vue.config.js
  27. 3 0
      admin-journal-intact/.browserslistrc
  28. 5 0
      admin-journal-intact/.editorconfig
  29. 3 0
      admin-journal-intact/.env
  30. 1 0
      admin-journal-intact/.eslintignore
  31. 24 0
      admin-journal-intact/.eslintrc.js
  32. 23 0
      admin-journal-intact/.gitignore
  33. 24 0
      admin-journal-intact/README.md
  34. 5 0
      admin-journal-intact/babel.config.js
  35. 12565 0
      admin-journal-intact/package-lock.json
  36. 35 0
      admin-journal-intact/package.json
  37. binární
      admin-journal-intact/public/favicon.ico
  38. 17 0
      admin-journal-intact/public/index.html
  39. 24 0
      admin-journal-intact/src/App.vue
  40. binární
      admin-journal-intact/src/assets/logo.png
  41. 48 0
      admin-journal-intact/src/main.js
  42. 3 0
      admin-journal-intact/src/public-path.js
  43. 10 0
      admin-journal-intact/src/router/index.js
  44. 80 0
      admin-journal-intact/src/store/index.js
  45. 257 0
      admin-journal-intact/src/views/home.vue
  46. 33 0
      admin-journal-intact/vue.config.js
  47. 1 1
      admin-log/src/store/index.js
  48. 2 2
      admin-log/vue.config.js
  49. 2 2
      admin-menu/vue.config.js
  50. 2 2
      admin-page/vue.config.js
  51. 2 2
      admin-role/vue.config.js
  52. 2 2
      admin-toconfig/vue.config.js
  53. 2 2
      admin-user/vue.config.js
  54. 6 0
      xms.code-workspace

+ 2 - 2
admin-code/vue.config.js

@@ -11,8 +11,8 @@ module.exports = {
     },
     proxy: {
       '/api/': {
-        target: 'http://192.168.0.45:18090'
-        // target: 'http://127.0.0.1:18090'
+        // target: 'http://192.168.0.45:18090'
+        target: 'http://192.168.3.45:18090'
       }
     }
   },

+ 2 - 2
admin-column/vue.config.js

@@ -11,8 +11,8 @@ module.exports = {
     },
     proxy: {
       '/api/': {
-        target: 'http://192.168.0.45:18090'
-        // target: 'http://127.0.0.1:18090'
+        // target: 'http://192.168.0.45:18090'
+        target: 'http://192.168.3.45:18090'
       }
     }
   },

+ 2 - 2
admin-content/vue.config.js

@@ -11,8 +11,8 @@ module.exports = {
     },
     proxy: {
       '/api/': {
-        target: 'http://192.168.0.45:18090'
-        // target: 'http://127.0.0.1:18090'
+        // target: 'http://192.168.0.45:18090'
+        target: 'http://192.168.3.45:18090'
       }
     }
   },

+ 12 - 0
admin-frame/lib/apps.js

@@ -74,5 +74,17 @@ export default [
     entry: config.dev ? '//localhost:3011/admin-log/' : 'admin-log',
     container: config.tabs ? '#log' : '#content',
     activeRule: '/admin/log'
+  },
+  {
+    name: 'admin-journal-intact',
+    entry: config.dev ? '//localhost:3012/admin-journal-intact/' : 'admin-journal-intact',
+    container: config.tabs ? '#intact' : '#content',
+    activeRule: '/admin/intact'
+  },
+  {
+    name: 'admin-journal-catalogue',
+    entry: config.dev ? '//localhost:3013/admin-journal-catalogue/' : 'admin-journal-catalogue',
+    container: config.tabs ? '#catalogue' : '#content',
+    activeRule: '/admin/catalogue'
   }
 ];

+ 4 - 3
admin-frame/vue.config.js

@@ -22,11 +22,12 @@ module.exports = {
     port: 3000,
     proxy: {
       '/api/': {
-        target: 'http://192.168.0.45:18090'
-        // target: 'http://127.0.0.1:18090'
+        target: 'http://192.168.3.45:18090'
+        // target: 'http://192.168.0.45:18090'
       },
       '/upload/': {
-        target: 'http://192.168.0.45:9002'
+        target: 'http://192.168.3.45:9002'
+        // target: 'http://192.168.0.45:18090'
       }
     }
   }

+ 2 - 2
admin-img-news/vue.config.js

@@ -11,8 +11,8 @@ module.exports = {
     },
     proxy: {
       '/api/': {
-        target: 'http://192.168.0.45:18090'
-        // target: 'http://127.0.0.1:18090'
+        // target: 'http://192.168.0.45:18090'
+        target: 'http://192.168.3.45:18090'
       }
     }
   },

+ 3 - 0
admin-journal-catalogue/.browserslistrc

@@ -0,0 +1,3 @@
+> 1%
+last 2 versions
+not dead

+ 5 - 0
admin-journal-catalogue/.editorconfig

@@ -0,0 +1,5 @@
+[*.{js,jsx,ts,tsx,vue}]
+indent_style = space
+indent_size = 2
+trim_trailing_whitespace = true
+insert_final_newline = true

+ 2 - 0
admin-journal-catalogue/.env

@@ -0,0 +1,2 @@
+# 窗口使用弹出还是抽屉 (dialog And drawer)
+VUE_APP_WINDOW=dialog

+ 1 - 0
admin-journal-catalogue/.eslintignore

@@ -0,0 +1 @@
+public-path.js

+ 23 - 0
admin-journal-catalogue/.eslintrc.js

@@ -0,0 +1,23 @@
+module.exports = {
+  root: true,
+  env: {
+    node: true
+  },
+  extends: [
+    'plugin:vue/essential',
+    '@vue/standard'
+  ],
+  parserOptions: {
+    parser: 'babel-eslint'
+  },
+  rules: {
+    'no-console': 0,
+    'no-debugger': 0,
+    'comma-dangle': [2, 'never'],
+    'no-extra-parens': 2,
+    'no-extra-semi': 2,
+    semi: [2, 'always'],
+    'space-before-function-paren': [0, 'always'],
+    eqeqeq: 0
+  }
+};

+ 23 - 0
admin-journal-catalogue/.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?

+ 24 - 0
admin-journal-catalogue/README.md

@@ -0,0 +1,24 @@
+# admin-role
+
+## 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/).

+ 5 - 0
admin-journal-catalogue/babel.config.js

@@ -0,0 +1,5 @@
+module.exports = {
+  presets: [
+    '@vue/cli-plugin-babel/preset'
+  ]
+};

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 12565 - 0
admin-journal-catalogue/package-lock.json


+ 35 - 0
admin-journal-catalogue/package.json

@@ -0,0 +1,35 @@
+{
+  "name": "admin-journal-catalogue",
+  "version": "0.1.0",
+  "private": true,
+  "scripts": {
+    "serve": "vue-cli-service serve",
+    "build": "vue-cli-service build",
+    "lint": "vue-cli-service lint"
+  },
+  "dependencies": {
+    "core-js": "^3.6.5",
+    "element-ui": "^2.15.6",
+    "sass": "^1.48.0",
+    "sass-loader": "^10.0.0",
+    "vue": "^2.6.11",
+    "vue-router": "^3.2.0",
+    "vuex": "^3.4.0"
+  },
+  "devDependencies": {
+    "@vue/cli-plugin-babel": "~4.5.0",
+    "@vue/cli-plugin-eslint": "~4.5.0",
+    "@vue/cli-plugin-router": "~4.5.0",
+    "@vue/cli-plugin-vuex": "~4.5.0",
+    "@vue/cli-service": "~4.5.0",
+    "@vue/eslint-config-standard": "^5.1.2",
+    "babel-eslint": "^10.1.0",
+    "eslint": "^6.7.2",
+    "eslint-plugin-import": "^2.20.2",
+    "eslint-plugin-node": "^11.1.0",
+    "eslint-plugin-promise": "^4.2.1",
+    "eslint-plugin-standard": "^4.0.0",
+    "eslint-plugin-vue": "^6.2.2",
+    "vue-template-compiler": "^2.6.11"
+  }
+}

binární
admin-journal-catalogue/public/favicon.ico


+ 17 - 0
admin-journal-catalogue/public/index.html

@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html lang="">
+  <head>
+    <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 %>favicon.ico">
+    <title><%= htmlWebpackPlugin.options.title %></title>
+  </head>
+  <body>
+    <noscript>
+      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
+    </noscript>
+    <div id="app"></div>
+    <!-- built files will be auto injected -->
+  </body>
+</html>

+ 24 - 0
admin-journal-catalogue/src/App.vue

@@ -0,0 +1,24 @@
+<template>
+  <div id="app">
+    <router-view></router-view>
+  </div>
+</template>
+
+<script>
+export default {
+  components: {},
+  computed: {},
+  data() {
+    return {};
+  },
+  mounted() {},
+  methods: {}
+};
+</script>
+
+<style lang="scss" scoped>
+#app {
+  width: 100%;
+  height: 100%;
+}
+</style>

binární
admin-journal-catalogue/src/assets/logo.png


+ 48 - 0
admin-journal-catalogue/src/main.js

@@ -0,0 +1,48 @@
+import Vue from 'vue';
+import App from './App.vue';
+import VueRouter from 'vue-router';
+import routes from './router';
+import store from './store';
+import ElementUI from 'element-ui';
+import 'element-ui/lib/theme-chalk/index.css';
+import './public-path.js';
+import dict from '@lib/dict.js';
+import tree from '@lib/tree.js';
+import resChange from '@lib/resChange.js';
+Vue.config.productionTip = false;
+Vue.use(VueRouter);
+Vue.use(ElementUI);
+Vue.use(dict);
+Vue.use(tree);
+Vue.use(resChange);
+let router = null;
+let instance = null;
+function render (props = {}) {
+  const { container } = props;
+  router = new VueRouter({
+    base: window.__POWERED_BY_QIANKUN__ ? '/admin/catalogue/' : '/',
+    mode: 'history',
+    routes
+  });
+  instance = new Vue({
+    router,
+    store,
+    render: (h) => h(App)
+  }).$mount(container ? container.querySelector('#app') : '#app');
+}
+
+// 独立运行时
+if (!window.__POWERED_BY_QIANKUN__) {
+  render();
+}
+
+export async function bootstrap () {}
+export async function mount (props) {
+  render(props);
+}
+export async function unmount () {
+  instance.$destroy();
+  instance.$el.innerHTML = '';
+  instance = null;
+  router = null;
+}

+ 3 - 0
admin-journal-catalogue/src/public-path.js

@@ -0,0 +1,3 @@
+if (window.__POWERED_BY_QIANKUN__) {
+  __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
+}

+ 10 - 0
admin-journal-catalogue/src/router/index.js

@@ -0,0 +1,10 @@
+import home from '../views/home.vue';
+const routes = [
+  {
+    path: '/home',
+    name: 'home',
+    component: home
+  }
+];
+
+export default routes;

+ 65 - 0
admin-journal-catalogue/src/store/index.js

@@ -0,0 +1,65 @@
+import Vue from 'vue';
+import Vuex from 'vuex';
+import $axios from '@lib/axios.js';
+const api = {
+  contentsCreate: '/api/journal/contents/create',
+  contentsUpdate: '/api/journal/contents/update',
+  contentsDelete: '/api/journal/contents/delete',
+  contentsQuery: '/api/journal/contents/query',
+  contentsFetch: '/api/journal/contents/fetch',
+  columnQuery: '/api/journal/column/query'
+};
+Vue.use(Vuex);
+const state = () => ({
+  Total: 0,
+  contentsList: [],
+  columnList: [],
+  dict: {}
+});
+
+const actions = {
+  async contentsCreate ({ commit }, payload) {
+    const res = await $axios.post(api.contentsCreate, payload);
+    return res;
+  },
+  async contentsUpdate ({ commit }, payload) {
+    const res = await $axios.post(api.contentsUpdate, { ...payload, id: payload._id });
+    return res;
+  },
+  async contentsDelete ({ commit }, { id }) {
+    const res = await $axios.delete(`${api.contentsDelete}/${id}`);
+    return res;
+  },
+  async contentsQuery ({ commit }, { filter, paging } = {}) {
+    const res = await $axios.get(api.contentsQuery, { ...filter, skip: paging.page, limit: paging.size });
+    commit('contentsQuery', res);
+    return res;
+  },
+  async contentsFetch ({ commit }, payload) {
+    const res = await $axios.get(api.contentsFetch, payload);
+    return res;
+  },
+  async columnQuery ({ commit }) {
+    const res = await $axios.get(api.columnQuery);
+    commit('columnQuery', res);
+    return res;
+  }
+};
+
+const mutations = {
+  contentsQuery(state, payload) {
+    state.contentsList = payload.data;
+    state.Total = payload.total;
+  },
+  columnQuery(state, payload) {
+    state.columnList = payload.data;
+    state.dict.column = payload.data;
+  }
+};
+
+export default new Vuex.Store({
+  state,
+  actions,
+  mutations,
+  modules: {}
+});

+ 248 - 0
admin-journal-catalogue/src/views/home.vue

@@ -0,0 +1,248 @@
+<template>
+  <div class="box">
+    <el-card class="box-card">
+      <div slot="header" class="clearfix">
+        <span>期刊栏目</span>
+        <el-button style="float: right; padding: 3px 0" type="text" @click="addcontents">添加期刊</el-button>
+      </div>
+      <div class="main">
+        <filterList ref="filterList" :tableData="contents" :filed="filed" @edit="filtereEdit" @delete="filterDelete" @query="filterQuery" :total="Total">
+          <template v-slot:search="{ item, formInline }">
+            <el-select clearable v-if="item.name == 'bind'" v-model="formInline[item.name]" placeholder="请选择">
+              <el-option
+                v-for="i in columnList"
+                :key="i.value"
+                :label="i.name"
+                :value="i.code">
+              </el-option>
+            </el-select>
+          </template>
+        </filterList>
+      </div>
+    </el-card>
+    <dialogAndDrawer :width="'35%'" :title="title" :visibleSync="visibleSync" v-if="visibleSync" @close="visibleSync = false">
+      <template v-slot:windowMain>
+        <formData ref="formData" :filed="formfiled" :data="formdata" :rules="formrules" @save="formSave" v-if="visibleSync">
+          <template v-slot:formItem="{ item, formdata }">
+            <!-- 缩略图 -->
+            <el-upload
+              v-if="item.name == 'thumbnail'"
+              class="avatar-uploader"
+              action="/api/files/avatar/upload"
+              :show-file-list="false"
+              :headers="myHeaders"
+              :on-success="handleAvatarSuccess"
+              :before-upload="beforeAvatarUpload">
+              <img v-if="formdata[item.name] && formdata[item.name] !== ''" :src="formdata[item.name]" class="avatar">
+              <i v-else class="el-icon-plus avatar-uploader-icon"></i>
+            </el-upload>
+            <!-- 富文本 -->
+            <editoritem v-if="item.name == 'content'" @change="editChage" :value="formdata[item.name]"></editoritem>
+            <!-- 附件上传 -->
+            <el-upload
+              v-if="item.name == 'annex'"
+              :headers="myHeaders"
+              class="upload-demo"
+              action="/api/files/avatar/upload"
+              :on-success="handleAnnexSuccess"
+              :on-remove="handleRemove"
+              :file-list="fileList">
+              <el-button size="small" type="primary">附件上传</el-button>
+            </el-upload>
+          </template>
+        </formData>
+      </template>
+    </dialogAndDrawer>
+  </div>
+</template>
+<script>
+import filterList from '@components/filterList/index.vue';
+import dialogAndDrawer from '@components/dialogAndDrawer.vue';
+import formData from '@components/formData/index.vue';
+import editoritem from '@components/editoritem.vue';
+import { mapState, mapActions } from 'vuex';
+const token = sessionStorage.getItem('token');
+export default {
+  components: {
+    filterList,
+    dialogAndDrawer,
+    formData,
+    editoritem
+  },
+  data() {
+    return {
+      fileList: [],
+      myHeaders: { Authorization: token },
+      title: '',
+      visibleSync: false,
+      filed: [
+        { name: 'title', label: '标题', filter: true },
+        { name: 'bind', label: '绑定栏目', formater: 'slot', filter: true },
+        { name: 'visit', label: '访问量' }
+      ],
+      formdata: {},
+      formfiled: [
+        { name: 'thumbnail', label: '缩略图', formater: 'slot' },
+        { name: 'title', label: '标题' },
+        { name: 'describe', label: '描述' },
+        { name: 'bind', label: '绑定栏目', formater: 'dict:column' },
+        { name: 'date', label: '时间', formater: 'date:datetime' },
+        { name: 'content', label: '内容', formater: 'slot' },
+        { name: 'annex', label: '附件', formater: 'slot' }
+      ],
+      formrules: {
+        thumbnail: [
+          { required: true, message: '请上传缩略图', trigger: 'chage' }
+        ],
+        title: [
+          { required: true, message: '请输入标题', trigger: 'blur' }
+        ],
+        describe: [
+          { required: true, message: '请输入描述', trigger: 'blur' }
+        ],
+        bind: [
+          { required: true, message: '请绑定栏目', trigger: 'chage' }
+        ],
+        date: [
+          { required: true, message: '请输入时间', trigger: 'blur' }
+        ],
+        content: [
+          { required: true, message: '请输入内容', trigger: 'blur' }
+        ]
+      }
+    };
+  },
+  computed: {
+    ...mapState(['contentsList', 'Total', 'columnList']),
+    contents() {
+      this.contentsList.map(p => {
+        const findName = this.columnList.find(e => e.code == p.bind);
+        if (findName) p.bind = findName?.name;
+        return p;
+      });
+      return this.contentsList;
+    }
+  },
+  async mounted() {
+    await this.filterQuery();
+    await this.columnQuery();
+  },
+  methods: {
+    ...mapActions(['contentsQuery', 'contentsCreate', 'contentsUpdate', 'contentsDelete', 'contentsQuery', 'contentsFetch', 'columnQuery']),
+    // 添加
+    addcontents () {
+      this.formdata = {};
+      this.title = '添加文章';
+      this.visibleSync = true;
+    },
+    // 修改
+    async filtereEdit (e) {
+      const res = await this.contentsFetch({ id: e._id });
+      this.formdata = res.data;
+      this.title = '修改文章';
+      this.visibleSync = true;
+    },
+    // 删除
+    async filterDelete (e) {
+      const res = await this.contentsDelete({ id: e?._id });
+      this.$resChange(res, '删除成功');
+      this.filterQuery();
+    },
+    // 查询
+    async filterQuery ({ filter = {}, paging = { content: 0, size: 10 } } = {}) {
+      await this.contentsQuery({ filter, paging });
+    },
+    // 表单保存
+    async formSave (e) {
+      if (e.isRevise && e?.isRevise == false) {
+        this.$message.warning('未作修改');
+        return;
+      }
+      this.$delete(e, 'isRevise');
+      let res, msg;
+      // 修改
+      if (e._id) {
+        res = await this.contentsUpdate(e);
+        msg = '文章修改成功';
+      } else {
+        res = await this.contentsCreate(e);
+        msg = '文章修改成功';
+      }
+      this.$resChange(res, msg);
+      this.filterQuery();
+      this.visibleSync = false;
+    },
+    // 富文本改变
+    editChage (e) {
+      this.$refs.formData.setForm('content', e);
+    },
+    // 附件上传
+    handleAnnexSuccess(res, file) {
+      this.$refs.formData.setForm('annex', res.data.filePath);
+      this.fileList.push({ name: res.data.name, url: res.data.filePath });
+    },
+    // 删除附件列表
+    handleRemove(file, fileList) {
+      console.log(123);
+      this.$refs.formData.setForm('annex', null);
+      delete this.fileList[0];
+    },
+    // 缩略图上传
+    handleAvatarSuccess(res, file) {
+      this.$refs.formData.setForm('thumbnail', res.data.filePath);
+    },
+    // 缩略图上传限制
+    beforeAvatarUpload(file) {
+      const isJPG = file.type === 'image/jpeg';
+      const isLt2M = file.size / 1024 / 1024 < 2;
+
+      if (!isJPG) {
+        this.$message.error('上传头像图片只能是 JPG 格式!');
+      }
+      if (!isLt2M) {
+        this.$message.error('上传头像图片大小不能超过 2MB!');
+      }
+      return isJPG && isLt2M;
+    }
+  }
+};
+</script>
+<style lang="scss" scoped>
+.box {
+  width: 100%;
+  height: 100%;
+  .box-card {
+    height: 100%;
+    .el-card__body {
+      height: 100%;
+    }
+  }
+}
+.el-dialog {
+  .avatar-uploader-icon {
+    font-size: 28px;
+    color: #8c939d;
+    width: 120px;
+    height: 120px;
+    line-height: 120px;
+    text-align: center;
+  }
+  .avatar {
+    width: 120px;
+    height: 120px;
+    display: block;
+  }
+}
+</style>
+<style>
+.el-upload {
+  border: 1px dashed #d9d9d9;
+  border-radius: 6px;
+  cursor: pointer;
+  position: relative;
+  overflow: hidden;
+}
+.el-upload:hover {
+  border-color: #409EFF;
+}
+</style>

+ 33 - 0
admin-journal-catalogue/vue.config.js

@@ -0,0 +1,33 @@
+const path = require('path');
+const frameSrc = path.resolve(__dirname, '../admin-frame');
+const packageName = require('./package.json').name;
+module.exports = {
+  publicPath: `/${packageName}/`,
+  outputDir: path.join(frameSrc, `../../admin-web/${packageName}/`),
+  devServer: {
+    port: 3013,
+    headers: {
+      'Access-Control-Allow-Origin': '*'
+    },
+    proxy: {
+      '/api/': {
+        // target: 'http://192.168.0.45:18090'
+        target: 'http://192.168.3.45:18090'
+      }
+    }
+  },
+  configureWebpack: {
+    output: {
+      library: `${packageName}-[name]`,
+      libraryTarget: 'umd',
+      jsonpFunction: `webpackJsonp_${packageName}`
+    },
+    resolve: {
+      alias: {
+        '@components': path.join(frameSrc, '/src/components'),
+        '@style': path.join(frameSrc, '/style'),
+        '@lib': path.join(frameSrc, '/lib')
+      }
+    }
+  }
+};

+ 3 - 0
admin-journal-intact/.browserslistrc

@@ -0,0 +1,3 @@
+> 1%
+last 2 versions
+not dead

+ 5 - 0
admin-journal-intact/.editorconfig

@@ -0,0 +1,5 @@
+[*.{js,jsx,ts,tsx,vue}]
+indent_style = space
+indent_size = 2
+trim_trailing_whitespace = true
+insert_final_newline = true

+ 3 - 0
admin-journal-intact/.env

@@ -0,0 +1,3 @@
+# 窗口使用弹出还是抽屉 (dialog And drawer)
+VUE_APP_WINDOW=dialog
+VUE_APP_PDF=false

+ 1 - 0
admin-journal-intact/.eslintignore

@@ -0,0 +1 @@
+public-path.js

+ 24 - 0
admin-journal-intact/.eslintrc.js

@@ -0,0 +1,24 @@
+module.exports = {
+  root: true,
+  env: {
+    node: true
+  },
+  extends: [
+    'plugin:vue/essential',
+    '@vue/standard'
+  ],
+  parserOptions: {
+    parser: 'babel-eslint'
+  },
+  rules: {
+    'no-console': 0,
+    'no-debugger': 0,
+    'comma-dangle': [2, 'never'],
+    'no-extra-parens': 2,
+    'no-extra-semi': 2,
+    semi: [2, 'always'],
+    'space-before-function-paren': [0, 'always'],
+    eqeqeq: 0,
+    'no-eval': [0, { allowIndirect: true }]
+  }
+};

+ 23 - 0
admin-journal-intact/.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?

+ 24 - 0
admin-journal-intact/README.md

@@ -0,0 +1,24 @@
+# admin-role
+
+## 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/).

+ 5 - 0
admin-journal-intact/babel.config.js

@@ -0,0 +1,5 @@
+module.exports = {
+  presets: [
+    '@vue/cli-plugin-babel/preset'
+  ]
+};

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 12565 - 0
admin-journal-intact/package-lock.json


+ 35 - 0
admin-journal-intact/package.json

@@ -0,0 +1,35 @@
+{
+  "name": "admin-journal-intact",
+  "version": "0.1.0",
+  "private": true,
+  "scripts": {
+    "serve": "vue-cli-service serve",
+    "build": "vue-cli-service build",
+    "lint": "vue-cli-service lint"
+  },
+  "dependencies": {
+    "core-js": "^3.6.5",
+    "element-ui": "^2.15.6",
+    "sass": "^1.48.0",
+    "sass-loader": "^10.0.0",
+    "vue": "^2.6.11",
+    "vue-router": "^3.2.0",
+    "vuex": "^3.4.0"
+  },
+  "devDependencies": {
+    "@vue/cli-plugin-babel": "~4.5.0",
+    "@vue/cli-plugin-eslint": "~4.5.0",
+    "@vue/cli-plugin-router": "~4.5.0",
+    "@vue/cli-plugin-vuex": "~4.5.0",
+    "@vue/cli-service": "~4.5.0",
+    "@vue/eslint-config-standard": "^5.1.2",
+    "babel-eslint": "^10.1.0",
+    "eslint": "^6.7.2",
+    "eslint-plugin-import": "^2.20.2",
+    "eslint-plugin-node": "^11.1.0",
+    "eslint-plugin-promise": "^4.2.1",
+    "eslint-plugin-standard": "^4.0.0",
+    "eslint-plugin-vue": "^6.2.2",
+    "vue-template-compiler": "^2.6.11"
+  }
+}

binární
admin-journal-intact/public/favicon.ico


+ 17 - 0
admin-journal-intact/public/index.html

@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html lang="">
+  <head>
+    <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 %>favicon.ico">
+    <title><%= htmlWebpackPlugin.options.title %></title>
+  </head>
+  <body>
+    <noscript>
+      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
+    </noscript>
+    <div id="app"></div>
+    <!-- built files will be auto injected -->
+  </body>
+</html>

+ 24 - 0
admin-journal-intact/src/App.vue

@@ -0,0 +1,24 @@
+<template>
+  <div id="app">
+    <router-view></router-view>
+  </div>
+</template>
+
+<script>
+export default {
+  components: {},
+  computed: {},
+  data() {
+    return {};
+  },
+  mounted() {},
+  methods: {}
+};
+</script>
+
+<style lang="scss" scoped>
+#app {
+  width: 100%;
+  height: 100%;
+}
+</style>

binární
admin-journal-intact/src/assets/logo.png


+ 48 - 0
admin-journal-intact/src/main.js

@@ -0,0 +1,48 @@
+import Vue from 'vue';
+import App from './App.vue';
+import VueRouter from 'vue-router';
+import routes from './router';
+import store from './store';
+import ElementUI from 'element-ui';
+import 'element-ui/lib/theme-chalk/index.css';
+import './public-path.js';
+import dict from '@lib/dict.js';
+import tree from '@lib/tree.js';
+import resChange from '@lib/resChange.js';
+Vue.config.productionTip = false;
+Vue.use(VueRouter);
+Vue.use(ElementUI);
+Vue.use(dict);
+Vue.use(tree);
+Vue.use(resChange);
+let router = null;
+let instance = null;
+function render (props = {}) {
+  const { container } = props;
+  router = new VueRouter({
+    base: window.__POWERED_BY_QIANKUN__ ? '/admin/intact/' : '/',
+    mode: 'history',
+    routes
+  });
+  instance = new Vue({
+    router,
+    store,
+    render: (h) => h(App)
+  }).$mount(container ? container.querySelector('#app') : '#app');
+}
+
+// 独立运行时
+if (!window.__POWERED_BY_QIANKUN__) {
+  render();
+}
+
+export async function bootstrap () {}
+export async function mount (props) {
+  render(props);
+}
+export async function unmount () {
+  instance.$destroy();
+  instance.$el.innerHTML = '';
+  instance = null;
+  router = null;
+}

+ 3 - 0
admin-journal-intact/src/public-path.js

@@ -0,0 +1,3 @@
+if (window.__POWERED_BY_QIANKUN__) {
+  __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
+}

+ 10 - 0
admin-journal-intact/src/router/index.js

@@ -0,0 +1,10 @@
+import home from '../views/home.vue';
+const routes = [
+  {
+    path: '/home',
+    name: 'home',
+    component: home
+  }
+];
+
+export default routes;

+ 80 - 0
admin-journal-intact/src/store/index.js

@@ -0,0 +1,80 @@
+import Vue from 'vue';
+import Vuex from 'vuex';
+import $axios from '@lib/axios.js';
+const api = {
+  intactCreate: '/api/journal/intact/create',
+  intactUpdate: '/api/journal/intact/update',
+  intactDelete: '/api/journal/intact/delete',
+  intactQuery: '/api/journal/intact/query',
+  intactFetch: '/api/journal/intact/fetch',
+  dictQuery: '/api/code/dictionary/query'
+};
+Vue.use(Vuex);
+const state = () => ({
+  Total: 0,
+  intactList: [],
+  columnList: [],
+  dict: {}
+});
+
+const actions = {
+  async intactCreate ({ commit }, payload) {
+    const res = await $axios.post(api.intactCreate, payload);
+    return res;
+  },
+  async intactUpdate ({ commit }, payload) {
+    const res = await $axios.post(api.intactUpdate, { ...payload, id: payload._id });
+    return res;
+  },
+  async intactDelete ({ commit }, { id }) {
+    const res = await $axios.delete(`${api.intactDelete}/${id}`);
+    return res;
+  },
+  async intactQuery ({ commit }, { filter, paging } = {}) {
+    const res = await $axios.get(api.intactQuery, { ...filter, skip: paging.page, limit: paging.size });
+    commit('intactQuery', res);
+    return res;
+  },
+  async intactFetch ({ commit }, payload) {
+    const res = await $axios.get(api.intactFetch, payload);
+    return res;
+  },
+  async statusQuery ({ commit }) {
+    const res = await $axios.get(api.dictQuery, { parentCode: 'journalStatus' });
+    commit('statusQuery', res);
+    return res;
+  },
+  async columnQuery ({ commit }) {
+    const res = await $axios.get(api.dictQuery, { parentCode: 'journalcolumn' });
+    commit('columnQuery', res);
+    return res;
+  },
+  async typeQuery ({ commit }) {
+    const res = await $axios.get(api.dictQuery, { parentCode: 'journalType' });
+    commit('typeQuery', res);
+    return res;
+  }
+};
+
+const mutations = {
+  intactQuery(state, payload) {
+    state.intactList = payload.data;
+    state.Total = payload.total;
+  },
+  statusQuery(state, payload) {
+    state.dict.journalStatus = payload.data;
+  },
+  columnQuery(state, payload) {
+    state.dict.journalcolumn = payload.data;
+  },
+  typeQuery(state, payload) {
+    state.dict.journalType = payload.data;
+  }
+};
+
+export default new Vuex.Store({
+  state,
+  actions,
+  mutations,
+  modules: {}
+});

+ 257 - 0
admin-journal-intact/src/views/home.vue

@@ -0,0 +1,257 @@
+<template>
+  <div class="box">
+    <el-card class="box-card">
+      <div slot="header" class="clearfix">
+        <span>期刊栏目</span>
+        <el-button style="float: right; padding: 3px 0" type="text" @click="addintact">添加期刊</el-button>
+      </div>
+      <div class="main">
+        <filterList ref="filterList" :tableData="intact" :filed="filed" @edit="filtereEdit" @delete="filterDelete" @query="filterQuery" :total="Total">
+          <template v-slot:search="{ item, formInline }">
+            <el-select clearable v-if="item.name == 'bind'" v-model="formInline[item.name]" placeholder="请选择">
+              <el-option
+                v-for="i in columnList"
+                :key="i.value"
+                :label="i.name"
+                :value="i.code">
+              </el-option>
+            </el-select>
+          </template>
+        </filterList>
+      </div>
+    </el-card>
+    <dialogAndDrawer :width="'35%'" :title="title" :visibleSync="visibleSync" v-if="visibleSync" @close="visibleSync = false">
+      <template v-slot:windowMain>
+        <formData ref="formData" :filed="formfiled" :data="formdata" :rules="formrules" @save="formSave" v-if="visibleSync">
+          <template v-slot:formItem="{ item, formdata }">
+            <!-- 缩略图 -->
+            <el-upload
+              v-if="item.name == 'thumbnail'"
+              class="avatar-uploader"
+              action="/api/files/avatar/upload"
+              :show-file-list="false"
+              :headers="myHeaders"
+              :on-success="handleAvatarSuccess"
+              :before-upload="beforeAvatarUpload">
+              <img v-if="formdata[item.name] && formdata[item.name] !== ''" :src="formdata[item.name]" class="avatar">
+              <i v-else class="el-icon-plus avatar-uploader-icon"></i>
+            </el-upload>
+            <!-- 附件上传 -->
+            <el-upload
+              v-if="item.name == 'url'"
+              :headers="myHeaders"
+              class="upload-demo"
+              action="/api/files/avatar/upload"
+              :on-success="handleAnnexSuccess"
+              :on-remove="handleRemove"
+              :file-list="fileList">
+              <el-button size="small" type="primary">PDF上传</el-button>
+            </el-upload>
+          </template>
+        </formData>
+      </template>
+    </dialogAndDrawer>
+  </div>
+</template>
+<script>
+import filterList from '@components/filterList/index.vue';
+import dialogAndDrawer from '@components/dialogAndDrawer.vue';
+import formData from '@components/formData/index.vue';
+import { mapState, mapActions } from 'vuex';
+const token = sessionStorage.getItem('token');
+// .env配置
+const config = {
+  pdf: eval(process.env.VUE_APP_PDF ?? false)
+};
+export default {
+  components: {
+    filterList,
+    dialogAndDrawer,
+    formData
+  },
+  data() {
+    return {
+      fileList: [],
+      myHeaders: { Authorization: token },
+      title: '',
+      visibleSync: false,
+      filed: [
+        { name: 'name', label: '标题', filter: true },
+        { name: 'status', label: '状态', filter: true },
+        { name: 'visit', label: '访问量' }
+      ],
+      formdata: {},
+      formfiled: [
+        { name: 'thumbnail', label: '缩略图', formater: 'slot' },
+        { name: 'name', label: '标题' },
+        { name: 'describe', label: '描述' },
+        { name: 'status', label: '状态', formater: 'dict:journalStatus' },
+        { name: 'date', label: '时间', formater: 'date:datetime' },
+        { name: 'column', label: '栏目', formater: 'dict:journalcolumn' },
+        { name: 'type', label: '期刊类型', formater: 'dict:journalType' },
+        ...(config.pdf ? [{ name: 'url', label: 'PDF上传', formater: 'slot' }] : [])
+      ],
+      formrules: {
+        thumbnail: [
+          { required: true, message: '请上传缩略图', trigger: 'chage' }
+        ],
+        name: [
+          { required: true, message: '请输入标题', trigger: 'blur' }
+        ],
+        describe: [
+          { required: true, message: '请输入描述', trigger: 'blur' }
+        ],
+        status: [
+          { required: true, message: '请选择状态', trigger: 'chage' }
+        ],
+        date: [
+          { required: true, message: '请输入时间', trigger: 'blur' }
+        ],
+        column: [
+          { required: true, message: '请输选择栏目', trigger: 'chage' }
+        ],
+        type: [
+          { required: true, message: '请输选择类型', trigger: 'chage' }
+        ],
+        url: [
+          { required: true, message: '请输选择PDF', trigger: 'chage' }
+        ]
+      }
+    };
+  },
+  computed: {
+    ...mapState(['intactList', 'Total', 'columnList']),
+    intact() {
+      this.intactList.map(p => {
+        const findName = this.columnList.find(e => e.code == p.bind);
+        if (findName) p.bind = findName?.name;
+        return p;
+      });
+      return this.intactList;
+    }
+  },
+  async mounted() {
+    await this.filterQuery();
+    await this.statusQuery();
+    await this.columnQuery();
+    await this.typeQuery();
+  },
+  methods: {
+    ...mapActions(['intactQuery', 'intactCreate', 'intactUpdate', 'intactDelete', 'intactQuery', 'intactFetch', 'statusQuery', 'columnQuery', 'typeQuery']),
+    // 添加
+    addintact () {
+      this.formdata = {};
+      this.title = '添加期刊';
+      this.visibleSync = true;
+    },
+    // 修改
+    async filtereEdit (e) {
+      const res = await this.intactFetch({ id: e._id });
+      this.formdata = res.data;
+      this.title = '修改期刊';
+      this.visibleSync = true;
+    },
+    // 删除
+    async filterDelete (e) {
+      const res = await this.intactDelete({ id: e?._id });
+      this.$resChange(res, '删除成功');
+      this.filterQuery();
+    },
+    // 查询
+    async filterQuery ({ filter = {}, paging = { content: 0, size: 10 } } = {}) {
+      await this.intactQuery({ filter, paging });
+    },
+    // 表单保存
+    async formSave (e) {
+      if (e.isRevise && e?.isRevise == false) {
+        this.$message.warning('未作修改');
+        return;
+      }
+      this.$delete(e, 'isRevise');
+      let res, msg;
+      // 修改
+      if (e._id) {
+        res = await this.intactUpdate(e);
+        msg = '期刊修改成功';
+      } else {
+        res = await this.intactCreate(e);
+        msg = '期刊修改成功';
+      }
+      this.$resChange(res, msg);
+      this.filterQuery();
+      this.visibleSync = false;
+    },
+    // 富文本改变
+    editChage (e) {
+      this.$refs.formData.setForm('content', e);
+    },
+    // 附件上传
+    handleAnnexSuccess(res, file) {
+      this.$refs.formData.setForm('url', res.data.filePath);
+      this.fileList.push({ name: res.data.name, url: res.data.filePath });
+    },
+    // 删除附件列表
+    handleRemove(file, fileList) {
+      console.log(123);
+      this.$refs.formData.setForm('annex', null);
+      delete this.fileList[0];
+    },
+    // 缩略图上传
+    handleAvatarSuccess(res, file) {
+      this.$refs.formData.setForm('thumbnail', res.data.filePath);
+    },
+    // 缩略图上传限制
+    beforeAvatarUpload(file) {
+      const isJPG = file.type === 'image/jpeg';
+      const isLt2M = file.size / 1024 / 1024 < 2;
+
+      if (!isJPG) {
+        this.$message.error('上传头像图片只能是 JPG 格式!');
+      }
+      if (!isLt2M) {
+        this.$message.error('上传头像图片大小不能超过 2MB!');
+      }
+      return isJPG && isLt2M;
+    }
+  }
+};
+</script>
+<style lang="scss" scoped>
+.box {
+  width: 100%;
+  height: 100%;
+  .box-card {
+    height: 100%;
+    .el-card__body {
+      height: 100%;
+    }
+  }
+}
+.el-dialog {
+  .avatar-uploader-icon {
+    font-size: 28px;
+    color: #8c939d;
+    width: 120px;
+    height: 120px;
+    line-height: 120px;
+    text-align: center;
+  }
+  .avatar {
+    width: 120px;
+    height: 120px;
+    display: block;
+  }
+}
+</style>
+<style>
+.el-upload {
+  border: 1px dashed #d9d9d9;
+  border-radius: 6px;
+  cursor: pointer;
+  position: relative;
+  overflow: hidden;
+}
+.el-upload:hover {
+  border-color: #409EFF;
+}
+</style>

+ 33 - 0
admin-journal-intact/vue.config.js

@@ -0,0 +1,33 @@
+const path = require('path');
+const frameSrc = path.resolve(__dirname, '../admin-frame');
+const packageName = require('./package.json').name;
+module.exports = {
+  publicPath: `/${packageName}/`,
+  outputDir: path.join(frameSrc, `../../admin-web/${packageName}/`),
+  devServer: {
+    port: 3012,
+    headers: {
+      'Access-Control-Allow-Origin': '*'
+    },
+    proxy: {
+      '/api/': {
+        // target: 'http://192.168.0.45:18090'
+        target: 'http://192.168.3.45:18090'
+      }
+    }
+  },
+  configureWebpack: {
+    output: {
+      library: `${packageName}-[name]`,
+      libraryTarget: 'umd',
+      jsonpFunction: `webpackJsonp_${packageName}`
+    },
+    resolve: {
+      alias: {
+        '@components': path.join(frameSrc, '/src/components'),
+        '@style': path.join(frameSrc, '/style'),
+        '@lib': path.join(frameSrc, '/lib')
+      }
+    }
+  }
+};

+ 1 - 1
admin-log/src/store/index.js

@@ -2,7 +2,7 @@ import Vue from 'vue';
 import Vuex from 'vuex';
 import $axios from '@lib/axios.js';
 const api = {
-  logQuery: '/api/log/log/query'
+  logQuery: '/api/log/adminlog/query'
 };
 Vue.use(Vuex);
 const state = () => ({

+ 2 - 2
admin-log/vue.config.js

@@ -11,8 +11,8 @@ module.exports = {
     },
     proxy: {
       '/api/': {
-        target: 'http://192.168.0.45:18090'
-        // target: 'http://127.0.0.1:18090'
+        // target: 'http://192.168.0.45:18090'
+        target: 'http://192.168.3.45:18090'
       }
     }
   },

+ 2 - 2
admin-menu/vue.config.js

@@ -11,8 +11,8 @@ module.exports = {
     },
     proxy: {
       '/api/': {
-        target: 'http://192.168.0.45:18090'
-        // target: 'http://127.0.0.1:18090'
+        // target: 'http://192.168.0.45:18090'
+        target: 'http://192.168.3.45:18090'
       }
     }
   },

+ 2 - 2
admin-page/vue.config.js

@@ -11,8 +11,8 @@ module.exports = {
     },
     proxy: {
       '/api/': {
-        target: 'http://192.168.0.45:18090'
-        // target: 'http://127.0.0.1:18090'
+        // target: 'http://192.168.0.45:18090'
+        target: 'http://192.168.3.45:18090'
       },
       '/upload/': {
         target: 'http://192.168.0.45:9002'

+ 2 - 2
admin-role/vue.config.js

@@ -11,8 +11,8 @@ module.exports = {
     },
     proxy: {
       '/api/': {
-        target: 'http://192.168.0.45:18090'
-        // target: 'http://127.0.0.1:18090'
+        // target: 'http://192.168.0.45:18090'
+        target: 'http://192.168.3.45:18090'
       }
     }
   },

+ 2 - 2
admin-toconfig/vue.config.js

@@ -11,8 +11,8 @@ module.exports = {
     },
     proxy: {
       '/api/': {
-        target: 'http://192.168.0.45:18090'
-        // target: 'http://127.0.0.1:18090'
+        // target: 'http://192.168.0.45:18090'
+        target: 'http://192.168.3.45:18090'
       }
     }
   },

+ 2 - 2
admin-user/vue.config.js

@@ -11,8 +11,8 @@ module.exports = {
     },
     proxy: {
       '/api/': {
-        target: 'http://192.168.0.45:18090'
-        // target: 'http://127.0.0.1:18090'
+        // target: 'http://192.168.0.45:18090'
+        target: 'http://192.168.3.45:18090'
       }
     }
   },

+ 6 - 0
xms.code-workspace

@@ -33,6 +33,12 @@
 		{
 			"path": "admin-log"
 		},
+		{
+			"path": "admin-journal-catalogue"
+		},
+		{
+			"path": "admin-journal-intact"
+		},
 	],
 	"settings": {}
 }