wxy 4 vuotta sitten
vanhempi
commit
049a9dc6f2

+ 82 - 73
package-lock.json

@@ -1320,8 +1320,8 @@
     },
     "@types/mini-css-extract-plugin": {
       "version": "0.9.1",
-      "resolved": "https://registry.npm.taobao.org/@types/mini-css-extract-plugin/download/@types/mini-css-extract-plugin-0.9.1.tgz",
-      "integrity": "sha1-1L3eUZcyb8oDnUGPS92gPcdNxFE=",
+      "resolved": "https://registry.npmjs.org/@types/mini-css-extract-plugin/-/mini-css-extract-plugin-0.9.1.tgz",
+      "integrity": "sha512-+mN04Oszdz9tGjUP/c1ReVwJXxSniLd7lF++sv+8dkABxVNthg6uccei+4ssKxRHGoMmPxdn7uBdJWONSJGTGQ==",
       "dev": true,
       "optional": true,
       "requires": {
@@ -1744,17 +1744,6 @@
           "integrity": "sha1-4a1IbmxUUBY0xsOXxcEh2qODYHw=",
           "dev": true
         },
-        "ansi-styles": {
-          "version": "4.2.1",
-          "resolved": "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-4.2.1.tgz",
-          "integrity": "sha1-kK51xCTQCNJiTFvynq0xd+v881k=",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "@types/color-name": "^1.1.1",
-            "color-convert": "^2.0.1"
-          }
-        },
         "cacache": {
           "version": "13.0.1",
           "resolved": "https://registry.npm.taobao.org/cacache/download/cacache-13.0.1.tgz?cache=0&sync_timestamp=1594427999421&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcacache%2Fdownload%2Fcacache-13.0.1.tgz",
@@ -1781,34 +1770,6 @@
             "unique-filename": "^1.1.1"
           }
         },
-        "chalk": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npm.taobao.org/chalk/download/chalk-3.0.0.tgz?cache=0&sync_timestamp=1591687042638&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fchalk%2Fdownload%2Fchalk-3.0.0.tgz",
-          "integrity": "sha1-P3PCv1JlkfV0zEksUeJFY0n4ROQ=",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "ansi-styles": "^4.1.0",
-            "supports-color": "^7.1.0"
-          }
-        },
-        "color-convert": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npm.taobao.org/color-convert/download/color-convert-2.0.1.tgz",
-          "integrity": "sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM=",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "color-name": "~1.1.4"
-          }
-        },
-        "color-name": {
-          "version": "1.1.4",
-          "resolved": "https://registry.npm.taobao.org/color-name/download/color-name-1.1.4.tgz",
-          "integrity": "sha1-wqCah6y95pVD3m9j+jmVyCbFNqI=",
-          "dev": true,
-          "optional": true
-        },
         "find-cache-dir": {
           "version": "3.3.1",
           "resolved": "https://registry.npm.taobao.org/find-cache-dir/download/find-cache-dir-3.3.1.tgz?cache=0&sync_timestamp=1583734954715&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffind-cache-dir%2Fdownload%2Ffind-cache-dir-3.3.1.tgz",
@@ -1830,13 +1791,6 @@
             "path-exists": "^4.0.0"
           }
         },
-        "has-flag": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npm.taobao.org/has-flag/download/has-flag-4.0.0.tgz",
-          "integrity": "sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s=",
-          "dev": true,
-          "optional": true
-        },
         "locate-path": {
           "version": "5.0.0",
           "resolved": "https://registry.npm.taobao.org/locate-path/download/locate-path-5.0.0.tgz?cache=0&sync_timestamp=1597081904643&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Flocate-path%2Fdownload%2Flocate-path-5.0.0.tgz",
@@ -1901,16 +1855,6 @@
             "minipass": "^3.1.1"
           }
         },
-        "supports-color": {
-          "version": "7.2.0",
-          "resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-7.2.0.tgz?cache=0&sync_timestamp=1598611878833&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-7.2.0.tgz",
-          "integrity": "sha1-G33NyzK4E4gBs+R4umpRyqiWSNo=",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "has-flag": "^4.0.0"
-          }
-        },
         "terser-webpack-plugin": {
           "version": "2.3.8",
           "resolved": "https://registry.npm.taobao.org/terser-webpack-plugin/download/terser-webpack-plugin-2.3.8.tgz",
@@ -1927,21 +1871,6 @@
             "terser": "^4.6.12",
             "webpack-sources": "^1.4.3"
           }
-        },
-        "vue-loader-v16": {
-          "version": "npm:vue-loader@16.0.0-beta.7",
-          "resolved": "https://registry.npm.taobao.org/vue-loader/download/vue-loader-16.0.0-beta.7.tgz?cache=0&sync_timestamp=1599639300665&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvue-loader%2Fdownload%2Fvue-loader-16.0.0-beta.7.tgz",
-          "integrity": "sha1-bycm+g4rH7rmeJXEdZO79p8rmrg=",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "@types/mini-css-extract-plugin": "^0.9.1",
-            "chalk": "^3.0.0",
-            "hash-sum": "^2.0.0",
-            "loader-utils": "^1.2.3",
-            "merge-source-map": "^1.1.0",
-            "source-map": "^0.6.1"
-          }
         }
       }
     },
@@ -11337,6 +11266,86 @@
         }
       }
     },
+    "vue-loader-v16": {
+      "version": "npm:vue-loader@16.0.0-beta.7",
+      "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.0.0-beta.7.tgz",
+      "integrity": "sha512-xQ8/GZmRPdQ3EinnE0IXwdVoDzh7Dowo0MowoyBuScEBXrRabw6At5/IdtD3waKklKW5PGokPsm8KRN6rvQ1cw==",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "@types/mini-css-extract-plugin": "^0.9.1",
+        "chalk": "^3.0.0",
+        "hash-sum": "^2.0.0",
+        "loader-utils": "^1.2.3",
+        "merge-source-map": "^1.1.0",
+        "source-map": "^0.6.1"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "4.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
+          "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "@types/color-name": "^1.1.1",
+            "color-convert": "^2.0.1"
+          }
+        },
+        "chalk": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+          "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+          "dev": true,
+          "optional": true
+        },
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+          "dev": true,
+          "optional": true
+        },
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true,
+          "optional": true
+        },
+        "supports-color": {
+          "version": "7.2.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+          "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
+        }
+      }
+    },
     "vue-meta": {
       "version": "2.4.0",
       "resolved": "https://registry.npm.taobao.org/vue-meta/download/vue-meta-2.4.0.tgz",

+ 15 - 0
src/router/index.js

@@ -40,16 +40,31 @@ export default new Router({
           component: () => import('../views/policy/index.vue'),
           meta: { title: '科技政策' },
         },
+        {
+          path: '/policy/detail',
+          component: () => import('../views/policy/detail.vue'),
+          meta: { title: '科技政策信息管理' },
+        },
         {
           path: '/record',
           component: () => import('../views/record/index.vue'),
           meta: { title: '科技数据' },
         },
+        {
+          path: '/record/detail',
+          component: () => import('../views/record/detail.vue'),
+          meta: { title: '科技数据信息管理' },
+        },
         {
           path: '/serve',
           component: () => import('../views/serve/index.vue'),
           meta: { title: '科技服务' },
         },
+        {
+          path: '/serve/detail',
+          component: () => import('../views/serve/detail.vue'),
+          meta: { title: '科技服务信息管理' },
+        },
         {
           path: '/column',
           component: () => import('../views/column/index.vue'),

+ 15 - 0
src/store/index.js

@@ -10,6 +10,15 @@ import site from './site';
 // 科技政务
 import column from './column';
 import news from './news';
+//科技政策
+import policyColumn from './policyColumn';
+import policyNews from './policyNews';
+//科技数据
+import recordColumn from './recordColumn';
+import recordNews from './recordNews';
+//科技服务
+import serveColumn from './serveColumn';
+import serveNews from './serveNews';
 // 科技人才
 // 科技人才-栏目
 import talentColumn from './talentColumn';
@@ -29,5 +38,11 @@ export default new Vuex.Store({
     news,
     talentColumn,
     talentRecruitment,
+    policyColumn,
+    policyNews,
+    recordColumn,
+    recordNews,
+    serveColumn,
+    serveNews,
   },
 });

+ 38 - 0
src/store/policyColumn.js

@@ -0,0 +1,38 @@
+import Vue from 'vue';
+import Vuex from 'vuex';
+import _ from 'lodash';
+Vue.use(Vuex);
+const api = {
+  columnInfo: `/api/policy/column`,
+};
+const state = () => ({});
+const mutations = {};
+
+const actions = {
+  async query({ commit }, { skip = 0, limit, ...info } = {}) {
+    const res = await this.$axios.$get(`${api.columnInfo}`, { skip, limit, ...info });
+    return res;
+  },
+  async create({ commit }, payload) {
+    const res = await this.$axios.$post(`${api.columnInfo}`, payload);
+    return res;
+  },
+  async fetch({ commit }, payload) {
+    const res = await this.$axios.$get(`${api.columnInfo}/${payload}`);
+    return res;
+  },
+  async update({ commit }, { id, ...data }) {
+    const res = await this.$axios.$post(`${api.columnInfo}/update/${id}`, data);
+    return res;
+  },
+  async delete({ commit }, payload) {
+    const res = await this.$axios.$delete(`${api.columnInfo}/${payload}`);
+    return res;
+  },
+};
+export default {
+  namespaced: true,
+  state,
+  mutations,
+  actions,
+};

+ 38 - 0
src/store/policyNews.js

@@ -0,0 +1,38 @@
+import Vue from 'vue';
+import Vuex from 'vuex';
+import _ from 'lodash';
+Vue.use(Vuex);
+const api = {
+  newsInfo: `/api/policy/news`,
+};
+const state = () => ({});
+const mutations = {};
+
+const actions = {
+  async query({ commit }, { skip = 0, limit, column_id, ...info } = {}) {
+    const res = await this.$axios.$get(`${api.newsInfo}`, { skip, limit, column_id, ...info });
+    return res;
+  },
+  async create({ commit }, payload) {
+    const res = await this.$axios.$post(`${api.newsInfo}`, payload);
+    return res;
+  },
+  async fetch({ commit }, payload) {
+    const res = await this.$axios.$get(`${api.newsInfo}/${payload}`);
+    return res;
+  },
+  async update({ commit }, { id, ...data }) {
+    const res = await this.$axios.$post(`${api.newsInfo}/update/${id}`, data);
+    return res;
+  },
+  async delete({ commit }, payload) {
+    const res = await this.$axios.$delete(`${api.newsInfo}/${payload}`);
+    return res;
+  },
+};
+export default {
+  namespaced: true,
+  state,
+  mutations,
+  actions,
+};

+ 38 - 0
src/store/recordColumn.js

@@ -0,0 +1,38 @@
+import Vue from 'vue';
+import Vuex from 'vuex';
+import _ from 'lodash';
+Vue.use(Vuex);
+const api = {
+  columnInfo: `/api/record/column`,
+};
+const state = () => ({});
+const mutations = {};
+
+const actions = {
+  async query({ commit }, { skip = 0, limit, ...info } = {}) {
+    const res = await this.$axios.$get(`${api.columnInfo}`, { skip, limit, ...info });
+    return res;
+  },
+  async create({ commit }, payload) {
+    const res = await this.$axios.$post(`${api.columnInfo}`, payload);
+    return res;
+  },
+  async fetch({ commit }, payload) {
+    const res = await this.$axios.$get(`${api.columnInfo}/${payload}`);
+    return res;
+  },
+  async update({ commit }, { id, ...data }) {
+    const res = await this.$axios.$post(`${api.columnInfo}/update/${id}`, data);
+    return res;
+  },
+  async delete({ commit }, payload) {
+    const res = await this.$axios.$delete(`${api.columnInfo}/${payload}`);
+    return res;
+  },
+};
+export default {
+  namespaced: true,
+  state,
+  mutations,
+  actions,
+};

+ 38 - 0
src/store/recordNews.js

@@ -0,0 +1,38 @@
+import Vue from 'vue';
+import Vuex from 'vuex';
+import _ from 'lodash';
+Vue.use(Vuex);
+const api = {
+  newsInfo: `/api/record/news`,
+};
+const state = () => ({});
+const mutations = {};
+
+const actions = {
+  async query({ commit }, { skip = 0, limit, column_id, ...info } = {}) {
+    const res = await this.$axios.$get(`${api.newsInfo}`, { skip, limit, column_id, ...info });
+    return res;
+  },
+  async create({ commit }, payload) {
+    const res = await this.$axios.$post(`${api.newsInfo}`, payload);
+    return res;
+  },
+  async fetch({ commit }, payload) {
+    const res = await this.$axios.$get(`${api.newsInfo}/${payload}`);
+    return res;
+  },
+  async update({ commit }, { id, ...data }) {
+    const res = await this.$axios.$post(`${api.newsInfo}/update/${id}`, data);
+    return res;
+  },
+  async delete({ commit }, payload) {
+    const res = await this.$axios.$delete(`${api.newsInfo}/${payload}`);
+    return res;
+  },
+};
+export default {
+  namespaced: true,
+  state,
+  mutations,
+  actions,
+};

+ 38 - 0
src/store/serveColumn.js

@@ -0,0 +1,38 @@
+import Vue from 'vue';
+import Vuex from 'vuex';
+import _ from 'lodash';
+Vue.use(Vuex);
+const api = {
+  columnInfo: `/api/serve/column`,
+};
+const state = () => ({});
+const mutations = {};
+
+const actions = {
+  async query({ commit }, { skip = 0, limit, ...info } = {}) {
+    const res = await this.$axios.$get(`${api.columnInfo}`, { skip, limit, ...info });
+    return res;
+  },
+  async create({ commit }, payload) {
+    const res = await this.$axios.$post(`${api.columnInfo}`, payload);
+    return res;
+  },
+  async fetch({ commit }, payload) {
+    const res = await this.$axios.$get(`${api.columnInfo}/${payload}`);
+    return res;
+  },
+  async update({ commit }, { id, ...data }) {
+    const res = await this.$axios.$post(`${api.columnInfo}/update/${id}`, data);
+    return res;
+  },
+  async delete({ commit }, payload) {
+    const res = await this.$axios.$delete(`${api.columnInfo}/${payload}`);
+    return res;
+  },
+};
+export default {
+  namespaced: true,
+  state,
+  mutations,
+  actions,
+};

+ 38 - 0
src/store/serveNews.js

@@ -0,0 +1,38 @@
+import Vue from 'vue';
+import Vuex from 'vuex';
+import _ from 'lodash';
+Vue.use(Vuex);
+const api = {
+  newsInfo: `/api/serve/news`,
+};
+const state = () => ({});
+const mutations = {};
+
+const actions = {
+  async query({ commit }, { skip = 0, limit, column_id, ...info } = {}) {
+    const res = await this.$axios.$get(`${api.newsInfo}`, { skip, limit, column_id, ...info });
+    return res;
+  },
+  async create({ commit }, payload) {
+    const res = await this.$axios.$post(`${api.newsInfo}`, payload);
+    return res;
+  },
+  async fetch({ commit }, payload) {
+    const res = await this.$axios.$get(`${api.newsInfo}/${payload}`);
+    return res;
+  },
+  async update({ commit }, { id, ...data }) {
+    const res = await this.$axios.$post(`${api.newsInfo}/update/${id}`, data);
+    return res;
+  },
+  async delete({ commit }, payload) {
+    const res = await this.$axios.$delete(`${api.newsInfo}/${payload}`);
+    return res;
+  },
+};
+export default {
+  namespaced: true,
+  state,
+  mutations,
+  actions,
+};

+ 153 - 0
src/views/policy/detail.vue

@@ -0,0 +1,153 @@
+<template>
+  <div id="detail">
+    <el-row>
+      <el-col :span="24" class="main">
+        <breadcrumb :breadcrumbTitle="this.$route.meta.title"></breadcrumb>
+        <el-col :span="24" class="container">
+          <el-col :span="24" class="add">
+            <el-button type="primary" size="mini" @click="back()">返回</el-button>
+          </el-col>
+          <el-col :span="24" v-if="loading">
+            <data-form :data="form" :fields="Fields" :rules="{}" @save="turnSave">
+              <template #options="{item}">
+                <template v-if="item.model == 'column_id'">
+                  <el-option v-for="(item, index) in columnList" :key="index" :label="item.name" :value="item.id"></el-option>
+                </template>
+              </template>
+              <template #custom="{item,form}">
+                <template v-if="item.model == 'picture'">
+                  <upload :limit="1" :data="form.picture" type="picture" :url="'/files/links/upload'" @upload="uploadSuccess"></upload>
+                </template>
+                <template v-else-if="item.model == 'content'">
+                  <wang-editor v-model="form.content" placeholder="请输入信息内容"></wang-editor>
+                </template>
+              </template>
+            </data-form>
+          </el-col>
+        </el-col>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import WangEditor from '@c/frame/wang-editor.vue';
+import upload from '@c/frame/uploadone.vue';
+import breadcrumb from '@c/common/breadcrumb.vue';
+import dataForm from '@c/frame/form.vue';
+import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: policyColumn } = createNamespacedHelpers('policyColumn');
+const { mapActions: policyNews } = createNamespacedHelpers('policyNews');
+export default {
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+  name: 'detail',
+  props: {},
+  components: {
+    breadcrumb,
+    dataForm,
+    WangEditor,
+    upload,
+  },
+  data: function() {
+    return {
+      form: {},
+      Fields: [
+        { label: '信息标题', model: 'title' },
+        { label: '来源', model: 'orgin' },
+        { label: '所属栏目', model: 'column_id', type: 'select' },
+        { label: '信息图片', model: 'picture', custom: true },
+        { label: '信息内容', model: 'content', custom: true },
+      ],
+      loading: true,
+      // 栏目列表
+      columnList: [],
+    };
+  },
+  async created() {
+    await this.searchcol();
+    await this.search();
+  },
+  methods: {
+    ...policyColumn({ colquery: 'query' }),
+    ...policyNews({ newfetch: 'fetch', newcreate: 'create', newupdate: 'update' }),
+    // 查询详情
+    async search() {
+      if (this.id) {
+        this.loading = false;
+        const res = await this.newfetch(this.id);
+        if (this.$checkRes(res)) {
+          this.$set(this, `form`, res.data);
+          this.loading = true;
+        } else {
+          this.$message({
+            message: '查询失败',
+            type: 'error',
+          });
+        }
+      }
+    },
+    // 保存信息
+    async turnSave({ data }) {
+      if (data.id) {
+        const res = await this.newupdate(data);
+        if (this.$checkRes(res)) {
+          this.$message({
+            message: '修改成功',
+            type: 'success',
+          });
+          this.back();
+        } else {
+          this.$message({
+            message: '修改失败',
+            type: 'error',
+          });
+        }
+      } else {
+        const res = await this.newcreate(data);
+        if (this.$checkRes(res)) {
+          this.$message({
+            message: '添加成功',
+            type: 'success',
+          });
+          this.back();
+        } else {
+          this.$message({
+            message: '添加失败',
+            type: 'error',
+          });
+        }
+      }
+    },
+    // 返回
+    back() {
+      this.form = {};
+      this.$router.push({ path: '/policy' });
+    },
+    // 查询栏目
+    async searchcol() {
+      let res = await this.colquery();
+      if (res.errcode == 0) {
+        this.$set(this, `columnList`, res.data);
+      }
+    },
+    // 上传图片
+    uploadSuccess({ type, data }) {
+      this.$set(this.form, `${type}`, data.uri);
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+    id() {
+      return this.$route.query.id;
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.add {
+  text-align: right;
+}
+</style>

+ 276 - 7
src/views/policy/index.vue

@@ -1,31 +1,300 @@
 <template>
   <div id="index">
     <el-row>
-      <el-col :span="24">
-        <p>index</p>
+      <el-col :span="24" class="main">
+        <breadcrumb :breadcrumbTitle="this.$route.meta.title"></breadcrumb>
+        <el-col :span="24" class="container">
+          <el-col :span="6" class="column">
+            <el-col :span="6" class="txt">
+              栏目列表
+            </el-col>
+            <el-col :span="18" class="btn">
+              <el-button type="primary" size="mini" @click="coldialog = true"><i class="el-icon-plus"></i></el-button>
+            </el-col>
+            <el-col :span="24">
+              <data-table
+                :fields="columnfields"
+                :opera="columnopera"
+                :data="column"
+                @view="coltoView"
+                @edit="coltoEdit"
+                @delete="coltoDelete"
+                :usePage="false"
+              ></data-table>
+            </el-col>
+          </el-col>
+          <el-col :span="18" class="news">
+            <el-col :span="6" class="txt">
+              信息列表
+            </el-col>
+            <el-col :span="18" class="btn">
+              <el-button type="primary" size="mini" @click="addnews()"><i class="el-icon-plus"></i></el-button>
+            </el-col>
+            <el-col :span="24">
+              <data-table
+                :fields="newfields"
+                :opera="newopera"
+                :data="newslist"
+                @query="searchnews"
+                :toFormat="toFormat"
+                :total="total"
+                @edit="newtoEdit"
+                @delete="newtoDelete"
+              ></data-table>
+            </el-col>
+          </el-col>
+        </el-col>
       </el-col>
     </el-row>
+    <el-dialog :visible.sync="coldialog" title="栏目" @close="coltoClose" width="30%">
+      <data-form :data="colform" :fields="colFields" :rules="{}" @save="turnSave">
+        <template #options="{item}">
+          <template v-if="item.model === 'site'">
+            <el-option label="政策卡片" value="zckp"></el-option>
+            <el-option label="政策报告" value="zcbg"></el-option>
+            <el-option label="政策书籍" value="zcsj"></el-option>
+            <el-option label="政策解读" value="zcjd"></el-option>
+            <el-option label="创新平台园区" value="cxptyq"></el-option>
+            <el-option label="税收与金融" value="ssyjr"></el-option>
+            <el-option label="知识产权" value="zscq"></el-option>
+            <el-option label="科技人才" value="kjrc"></el-option>
+            <el-option label="科技成果转化" value="kjcgzh"></el-option>
+            <el-option label="综合政策指导" value="zhzczd"></el-option>
+          </template>
+        </template>
+      </data-form>
+    </el-dialog>
   </div>
 </template>
 
 <script>
+import breadcrumb from '@c/common/breadcrumb.vue';
+import dataTable from '@/components/frame/filter-page-table.vue';
+import dataForm from '@/components/frame/form.vue';
 import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: policyColumn } = createNamespacedHelpers('policyColumn');
+const { mapActions: policyNews } = createNamespacedHelpers('policyNews');
 export default {
   metaInfo() {
     return { title: this.$route.meta.title };
   },
   name: 'index',
   props: {},
-  components: {},
+  components: {
+    breadcrumb,
+    dataTable,
+    dataForm,
+  },
   data: function() {
-    return {};
+    return {
+      // 栏目
+      columnopera: [
+        {
+          label: '查询信息',
+          icon: 'el-icon-view',
+          method: 'view',
+        },
+        {
+          label: '修改',
+          icon: 'el-icon-edit',
+          method: 'edit',
+        },
+        {
+          label: '删除',
+          icon: 'el-icon-delete',
+          method: 'delete',
+        },
+      ],
+      columnfields: [{ label: '名称', prop: 'name' }],
+      column: [],
+      coldialog: false,
+      colform: {},
+      colFields: [
+        { label: '名称', model: 'name' },
+        { label: '所在位置', model: 'site', type: 'select' },
+      ],
+      // 信息
+      newopera: [
+        {
+          label: '修改',
+          icon: 'el-icon-edit',
+          method: 'edit',
+        },
+        {
+          label: '删除',
+          icon: 'el-icon-delete',
+          method: 'delete',
+        },
+      ],
+      newfields: [
+        { label: '名称', prop: 'title', showTip: true },
+        { label: '信息来源', prop: 'orgin' },
+        { label: '所属栏目', prop: 'column_id', format: true },
+      ],
+      newslist: [],
+      total: 0,
+      column_id: '',
+    };
+  },
+  async created() {
+    await this.searchcolumn();
+    await this.searchnews();
+  },
+  methods: {
+    ...policyColumn({ colquery: 'query', colfetch: 'fetch', coldelete: 'delete', colcreate: 'create', colupdate: 'update' }),
+    ...policyNews({ newquery: 'query', newfetch: 'fetch', newdelete: 'delete', newcreate: 'create', newupdate: 'update' }),
+    // 查询栏目
+    async searchcolumn() {
+      const res = await this.colquery();
+      if (this.$checkRes(res)) {
+        this.$set(this, `column`, res.data);
+      } else {
+        this.$message({
+          message: '查询失败',
+          type: 'error',
+        });
+      }
+    },
+    // 栏目修改
+    coltoEdit({ data }) {
+      this.coldialog = true;
+      this.$set(this, `colform`, data);
+    },
+    // 栏目删除
+    async coltoDelete({ data }) {
+      const res = await this.coldelete(data.id);
+      if (this.$checkRes(res)) {
+        this.$message({
+          message: '刪除成功',
+          type: 'success',
+        });
+        this.coltoClose();
+      } else {
+        this.$message({
+          message: '删除失败',
+          type: 'error',
+        });
+      }
+    },
+    // 栏目添加
+    async turnSave({ data }) {
+      if (data.id) {
+        const res = await this.colupdate(data);
+        if (this.$checkRes(res)) {
+          this.$message({
+            message: '修改成功',
+            type: 'success',
+          });
+          this.coltoClose();
+        } else {
+          this.$message({
+            message: '修改失败',
+            type: 'error',
+          });
+        }
+      } else {
+        const res = await this.colcreate(data);
+        if (this.$checkRes(res)) {
+          this.$message({
+            message: '添加成功',
+            type: 'success',
+          });
+          this.coltoClose();
+        } else {
+          this.$message({
+            message: '添加失败',
+            type: 'error',
+          });
+        }
+      }
+    },
+    // 栏目取消
+    coltoClose() {
+      this.form = {};
+      this.coldialog = false;
+      this.searchcolumn();
+    },
+    // 查询信息
+    coltoView({ data }) {
+      this.$set(this, `column_id`, data.id);
+      this.searchnews();
+    },
+    // 查询信息
+    async searchnews({ skip = 0, limit = 10 } = {}) {
+      let res = await this.newquery({ skip, limit, column_id: this.column_id });
+      if (this.$checkRes(res)) {
+        this.$set(this, `newslist`, res.data);
+        this.$set(this, `total`, res.total);
+      } else {
+        this.$message({
+          message: '查询失败',
+          type: 'error',
+        });
+      }
+    },
+    // 过滤栏目
+    toFormat({ model, value }) {
+      if (model == 'column_id') {
+        const res = this.column.find(f => f.id == value);
+        if (res) return res.name;
+      }
+    },
+    // 添加信息
+    addnews() {
+      this.$router.push({ path: 'policy/detail' });
+    },
+    // 修改信息
+    newtoEdit({ data }) {
+      this.$router.push({ path: 'policy/detail', query: { id: data.id } });
+    },
+    // 删除信息
+    async newtoDelete({ data }) {
+      const res = await this.newdelete(data.id);
+      if (this.$checkRes(res)) {
+        this.$message({
+          message: '刪除成功',
+          type: 'success',
+        });
+        this.searchnews();
+      } else {
+        this.$message({
+          message: '删除失败',
+          type: 'error',
+        });
+      }
+    },
   },
-  created() {},
-  methods: {},
   computed: {
     ...mapState(['user']),
   },
 };
 </script>
 
-<style lang="less" scoped></style>
+<style lang="less" scoped>
+.main {
+  .column {
+    min-height: 850px;
+    padding: 10px;
+    border: 1px solid #ccc;
+    .txt {
+      margin: 0 0 15px 0;
+    }
+    .btn {
+      text-align: right;
+      margin: 0 0 15px 0;
+    }
+  }
+  .news {
+    min-height: 850px;
+    padding: 10px;
+    border: 1px solid #ccc;
+    .txt {
+      margin: 0 0 15px 0;
+    }
+    .btn {
+      text-align: right;
+      margin: 0 0 15px 0;
+    }
+  }
+}
+</style>

+ 153 - 0
src/views/record/detail.vue

@@ -0,0 +1,153 @@
+<template>
+  <div id="detail">
+    <el-row>
+      <el-col :span="24" class="main">
+        <breadcrumb :breadcrumbTitle="this.$route.meta.title"></breadcrumb>
+        <el-col :span="24" class="container">
+          <el-col :span="24" class="add">
+            <el-button type="primary" size="mini" @click="back()">返回</el-button>
+          </el-col>
+          <el-col :span="24" v-if="loading">
+            <data-form :data="form" :fields="Fields" :rules="{}" @save="turnSave">
+              <template #options="{item}">
+                <template v-if="item.model == 'column_id'">
+                  <el-option v-for="(item, index) in columnList" :key="index" :label="item.name" :value="item.id"></el-option>
+                </template>
+              </template>
+              <template #custom="{item,form}">
+                <template v-if="item.model == 'picture'">
+                  <upload :limit="1" :data="form.picture" type="picture" :url="'/files/links/upload'" @upload="uploadSuccess"></upload>
+                </template>
+                <template v-else-if="item.model == 'content'">
+                  <wang-editor v-model="form.content" placeholder="请输入信息内容"></wang-editor>
+                </template>
+              </template>
+            </data-form>
+          </el-col>
+        </el-col>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import WangEditor from '@c/frame/wang-editor.vue';
+import upload from '@c/frame/uploadone.vue';
+import breadcrumb from '@c/common/breadcrumb.vue';
+import dataForm from '@c/frame/form.vue';
+import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: recordColumn } = createNamespacedHelpers('recordColumn');
+const { mapActions: recordNews } = createNamespacedHelpers('recordNews');
+export default {
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+  name: 'detail',
+  props: {},
+  components: {
+    breadcrumb,
+    dataForm,
+    WangEditor,
+    upload,
+  },
+  data: function() {
+    return {
+      form: {},
+      Fields: [
+        { label: '信息标题', model: 'title' },
+        { label: '来源', model: 'orgin' },
+        { label: '所属栏目', model: 'column_id', type: 'select' },
+        { label: '信息图片', model: 'picture', custom: true },
+        { label: '信息内容', model: 'content', custom: true },
+      ],
+      loading: true,
+      // 栏目列表
+      columnList: [],
+    };
+  },
+  async created() {
+    await this.searchcol();
+    await this.search();
+  },
+  methods: {
+    ...recordColumn({ colquery: 'query' }),
+    ...recordNews({ newfetch: 'fetch', newcreate: 'create', newupdate: 'update' }),
+    // 查询详情
+    async search() {
+      if (this.id) {
+        this.loading = false;
+        const res = await this.newfetch(this.id);
+        if (this.$checkRes(res)) {
+          this.$set(this, `form`, res.data);
+          this.loading = true;
+        } else {
+          this.$message({
+            message: '查询失败',
+            type: 'error',
+          });
+        }
+      }
+    },
+    // 保存信息
+    async turnSave({ data }) {
+      if (data.id) {
+        const res = await this.newupdate(data);
+        if (this.$checkRes(res)) {
+          this.$message({
+            message: '修改成功',
+            type: 'success',
+          });
+          this.back();
+        } else {
+          this.$message({
+            message: '修改失败',
+            type: 'error',
+          });
+        }
+      } else {
+        const res = await this.newcreate(data);
+        if (this.$checkRes(res)) {
+          this.$message({
+            message: '添加成功',
+            type: 'success',
+          });
+          this.back();
+        } else {
+          this.$message({
+            message: '添加失败',
+            type: 'error',
+          });
+        }
+      }
+    },
+    // 返回
+    back() {
+      this.form = {};
+      this.$router.push({ path: '/record' });
+    },
+    // 查询栏目
+    async searchcol() {
+      let res = await this.colquery();
+      if (res.errcode == 0) {
+        this.$set(this, `columnList`, res.data);
+      }
+    },
+    // 上传图片
+    uploadSuccess({ type, data }) {
+      this.$set(this.form, `${type}`, data.uri);
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+    id() {
+      return this.$route.query.id;
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.add {
+  text-align: right;
+}
+</style>

+ 272 - 7
src/views/record/index.vue

@@ -1,31 +1,296 @@
 <template>
   <div id="index">
     <el-row>
-      <el-col :span="24">
-        <p>index</p>
+      <el-col :span="24" class="main">
+        <breadcrumb :breadcrumbTitle="this.$route.meta.title"></breadcrumb>
+        <el-col :span="24" class="container">
+          <el-col :span="6" class="column">
+            <el-col :span="6" class="txt">
+              栏目列表
+            </el-col>
+            <el-col :span="18" class="btn">
+              <el-button type="primary" size="mini" @click="coldialog = true"><i class="el-icon-plus"></i></el-button>
+            </el-col>
+            <el-col :span="24">
+              <data-table
+                :fields="columnfields"
+                :opera="columnopera"
+                :data="column"
+                @view="coltoView"
+                @edit="coltoEdit"
+                @delete="coltoDelete"
+                :usePage="false"
+              ></data-table>
+            </el-col>
+          </el-col>
+          <el-col :span="18" class="news">
+            <el-col :span="6" class="txt">
+              信息列表
+            </el-col>
+            <el-col :span="18" class="btn">
+              <el-button type="primary" size="mini" @click="addnews()"><i class="el-icon-plus"></i></el-button>
+            </el-col>
+            <el-col :span="24">
+              <data-table
+                :fields="newfields"
+                :opera="newopera"
+                :data="newslist"
+                @query="searchnews"
+                :toFormat="toFormat"
+                :total="total"
+                @edit="newtoEdit"
+                @delete="newtoDelete"
+              ></data-table>
+            </el-col>
+          </el-col>
+        </el-col>
       </el-col>
     </el-row>
+    <el-dialog :visible.sync="coldialog" title="栏目" @close="coltoClose" width="30%">
+      <data-form :data="colform" :fields="colFields" :rules="{}" @save="turnSave">
+        <template #options="{item}">
+          <template v-if="item.model === 'site'">
+            <el-option label="科技交易" value="kjjy"></el-option>
+            <el-option label="科技成果" value="kjcg"></el-option>
+            <el-option label="科技智库" value="kjzk"></el-option>
+            <el-option label="科技期刊" value="kjqk"></el-option>
+            <el-option label="科技报告" value="kjbg"></el-option>
+            <el-option label="科技文献" value="kjwx"></el-option>
+          </template>
+        </template>
+      </data-form>
+    </el-dialog>
   </div>
 </template>
 
 <script>
+import breadcrumb from '@c/common/breadcrumb.vue';
+import dataTable from '@/components/frame/filter-page-table.vue';
+import dataForm from '@/components/frame/form.vue';
 import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: recordColumn } = createNamespacedHelpers('recordColumn');
+const { mapActions: recordNews } = createNamespacedHelpers('recordNews');
 export default {
   metaInfo() {
     return { title: this.$route.meta.title };
   },
   name: 'index',
   props: {},
-  components: {},
+  components: {
+    breadcrumb,
+    dataTable,
+    dataForm,
+  },
   data: function() {
-    return {};
+    return {
+      // 栏目
+      columnopera: [
+        {
+          label: '查询信息',
+          icon: 'el-icon-view',
+          method: 'view',
+        },
+        {
+          label: '修改',
+          icon: 'el-icon-edit',
+          method: 'edit',
+        },
+        {
+          label: '删除',
+          icon: 'el-icon-delete',
+          method: 'delete',
+        },
+      ],
+      columnfields: [{ label: '名称', prop: 'name' }],
+      column: [],
+      coldialog: false,
+      colform: {},
+      colFields: [
+        { label: '名称', model: 'name' },
+        { label: '所在位置', model: 'site', type: 'select' },
+      ],
+      // 信息
+      newopera: [
+        {
+          label: '修改',
+          icon: 'el-icon-edit',
+          method: 'edit',
+        },
+        {
+          label: '删除',
+          icon: 'el-icon-delete',
+          method: 'delete',
+        },
+      ],
+      newfields: [
+        { label: '名称', prop: 'title', showTip: true },
+        { label: '信息来源', prop: 'orgin' },
+        { label: '所属栏目', prop: 'column_id', format: true },
+      ],
+      newslist: [],
+      total: 0,
+      column_id: '',
+    };
+  },
+  async created() {
+    await this.searchcolumn();
+    await this.searchnews();
+  },
+  methods: {
+    ...recordColumn({ colquery: 'query', colfetch: 'fetch', coldelete: 'delete', colcreate: 'create', colupdate: 'update' }),
+    ...recordNews({ newquery: 'query', newfetch: 'fetch', newdelete: 'delete', newcreate: 'create', newupdate: 'update' }),
+    // 查询栏目
+    async searchcolumn() {
+      const res = await this.colquery();
+      if (this.$checkRes(res)) {
+        this.$set(this, `column`, res.data);
+      } else {
+        this.$message({
+          message: '查询失败',
+          type: 'error',
+        });
+      }
+    },
+    // 栏目修改
+    coltoEdit({ data }) {
+      this.coldialog = true;
+      this.$set(this, `colform`, data);
+    },
+    // 栏目删除
+    async coltoDelete({ data }) {
+      const res = await this.coldelete(data.id);
+      if (this.$checkRes(res)) {
+        this.$message({
+          message: '刪除成功',
+          type: 'success',
+        });
+        this.coltoClose();
+      } else {
+        this.$message({
+          message: '删除失败',
+          type: 'error',
+        });
+      }
+    },
+    // 栏目添加
+    async turnSave({ data }) {
+      if (data.id) {
+        const res = await this.colupdate(data);
+        if (this.$checkRes(res)) {
+          this.$message({
+            message: '修改成功',
+            type: 'success',
+          });
+          this.coltoClose();
+        } else {
+          this.$message({
+            message: '修改失败',
+            type: 'error',
+          });
+        }
+      } else {
+        const res = await this.colcreate(data);
+        if (this.$checkRes(res)) {
+          this.$message({
+            message: '添加成功',
+            type: 'success',
+          });
+          this.coltoClose();
+        } else {
+          this.$message({
+            message: '添加失败',
+            type: 'error',
+          });
+        }
+      }
+    },
+    // 栏目取消
+    coltoClose() {
+      this.form = {};
+      this.coldialog = false;
+      this.searchcolumn();
+    },
+    // 查询信息
+    coltoView({ data }) {
+      this.$set(this, `column_id`, data.id);
+      this.searchnews();
+    },
+    // 查询信息
+    async searchnews({ skip = 0, limit = 10 } = {}) {
+      let res = await this.newquery({ skip, limit, column_id: this.column_id });
+      if (this.$checkRes(res)) {
+        this.$set(this, `newslist`, res.data);
+        this.$set(this, `total`, res.total);
+      } else {
+        this.$message({
+          message: '查询失败',
+          type: 'error',
+        });
+      }
+    },
+    // 过滤栏目
+    toFormat({ model, value }) {
+      if (model == 'column_id') {
+        const res = this.column.find(f => f.id == value);
+        if (res) return res.name;
+      }
+    },
+    // 添加信息
+    addnews() {
+      this.$router.push({ path: 'record/detail' });
+    },
+    // 修改信息
+    newtoEdit({ data }) {
+      this.$router.push({ path: 'record/detail', query: { id: data.id } });
+    },
+    // 删除信息
+    async newtoDelete({ data }) {
+      const res = await this.newdelete(data.id);
+      if (this.$checkRes(res)) {
+        this.$message({
+          message: '刪除成功',
+          type: 'success',
+        });
+        this.searchnews();
+      } else {
+        this.$message({
+          message: '删除失败',
+          type: 'error',
+        });
+      }
+    },
   },
-  created() {},
-  methods: {},
   computed: {
     ...mapState(['user']),
   },
 };
 </script>
 
-<style lang="less" scoped></style>
+<style lang="less" scoped>
+.main {
+  .column {
+    min-height: 850px;
+    padding: 10px;
+    border: 1px solid #ccc;
+    .txt {
+      margin: 0 0 15px 0;
+    }
+    .btn {
+      text-align: right;
+      margin: 0 0 15px 0;
+    }
+  }
+  .news {
+    min-height: 850px;
+    padding: 10px;
+    border: 1px solid #ccc;
+    .txt {
+      margin: 0 0 15px 0;
+    }
+    .btn {
+      text-align: right;
+      margin: 0 0 15px 0;
+    }
+  }
+}
+</style>

+ 153 - 0
src/views/serve/detail.vue

@@ -0,0 +1,153 @@
+<template>
+  <div id="detail">
+    <el-row>
+      <el-col :span="24" class="main">
+        <breadcrumb :breadcrumbTitle="this.$route.meta.title"></breadcrumb>
+        <el-col :span="24" class="container">
+          <el-col :span="24" class="add">
+            <el-button type="primary" size="mini" @click="back()">返回</el-button>
+          </el-col>
+          <el-col :span="24" v-if="loading">
+            <data-form :data="form" :fields="Fields" :rules="{}" @save="turnSave">
+              <template #options="{item}">
+                <template v-if="item.model == 'column_id'">
+                  <el-option v-for="(item, index) in columnList" :key="index" :label="item.name" :value="item.id"></el-option>
+                </template>
+              </template>
+              <template #custom="{item,form}">
+                <template v-if="item.model == 'picture'">
+                  <upload :limit="1" :data="form.picture" type="picture" :url="'/files/links/upload'" @upload="uploadSuccess"></upload>
+                </template>
+                <template v-else-if="item.model == 'content'">
+                  <wang-editor v-model="form.content" placeholder="请输入信息内容"></wang-editor>
+                </template>
+              </template>
+            </data-form>
+          </el-col>
+        </el-col>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import WangEditor from '@c/frame/wang-editor.vue';
+import upload from '@c/frame/uploadone.vue';
+import breadcrumb from '@c/common/breadcrumb.vue';
+import dataForm from '@c/frame/form.vue';
+import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: serveColumn } = createNamespacedHelpers('serveColumn');
+const { mapActions: serveNews } = createNamespacedHelpers('serveNews');
+export default {
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+  name: 'detail',
+  props: {},
+  components: {
+    breadcrumb,
+    dataForm,
+    WangEditor,
+    upload,
+  },
+  data: function() {
+    return {
+      form: {},
+      Fields: [
+        { label: '信息标题', model: 'title' },
+        { label: '来源', model: 'orgin' },
+        { label: '所属栏目', model: 'column_id', type: 'select' },
+        { label: '信息图片', model: 'picture', custom: true },
+        { label: '信息内容', model: 'content', custom: true },
+      ],
+      loading: true,
+      // 栏目列表
+      columnList: [],
+    };
+  },
+  async created() {
+    await this.searchcol();
+    await this.search();
+  },
+  methods: {
+    ...serveColumn({ colquery: 'query' }),
+    ...serveNews({ newfetch: 'fetch', newcreate: 'create', newupdate: 'update' }),
+    // 查询详情
+    async search() {
+      if (this.id) {
+        this.loading = false;
+        const res = await this.newfetch(this.id);
+        if (this.$checkRes(res)) {
+          this.$set(this, `form`, res.data);
+          this.loading = true;
+        } else {
+          this.$message({
+            message: '查询失败',
+            type: 'error',
+          });
+        }
+      }
+    },
+    // 保存信息
+    async turnSave({ data }) {
+      if (data.id) {
+        const res = await this.newupdate(data);
+        if (this.$checkRes(res)) {
+          this.$message({
+            message: '修改成功',
+            type: 'success',
+          });
+          this.back();
+        } else {
+          this.$message({
+            message: '修改失败',
+            type: 'error',
+          });
+        }
+      } else {
+        const res = await this.newcreate(data);
+        if (this.$checkRes(res)) {
+          this.$message({
+            message: '添加成功',
+            type: 'success',
+          });
+          this.back();
+        } else {
+          this.$message({
+            message: '添加失败',
+            type: 'error',
+          });
+        }
+      }
+    },
+    // 返回
+    back() {
+      this.form = {};
+      this.$router.push({ path: '/serve' });
+    },
+    // 查询栏目
+    async searchcol() {
+      let res = await this.colquery();
+      if (res.errcode == 0) {
+        this.$set(this, `columnList`, res.data);
+      }
+    },
+    // 上传图片
+    uploadSuccess({ type, data }) {
+      this.$set(this.form, `${type}`, data.uri);
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+    id() {
+      return this.$route.query.id;
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.add {
+  text-align: right;
+}
+</style>

+ 271 - 7
src/views/serve/index.vue

@@ -1,31 +1,295 @@
 <template>
   <div id="index">
     <el-row>
-      <el-col :span="24">
-        <p>index</p>
+      <el-col :span="24" class="main">
+        <breadcrumb :breadcrumbTitle="this.$route.meta.title"></breadcrumb>
+        <el-col :span="24" class="container">
+          <el-col :span="6" class="column">
+            <el-col :span="6" class="txt">
+              栏目列表
+            </el-col>
+            <el-col :span="18" class="btn">
+              <el-button type="primary" size="mini" @click="coldialog = true"><i class="el-icon-plus"></i></el-button>
+            </el-col>
+            <el-col :span="24">
+              <data-table
+                :fields="columnfields"
+                :opera="columnopera"
+                :data="column"
+                @view="coltoView"
+                @edit="coltoEdit"
+                @delete="coltoDelete"
+                :usePage="false"
+              ></data-table>
+            </el-col>
+          </el-col>
+          <el-col :span="18" class="news">
+            <el-col :span="6" class="txt">
+              信息列表
+            </el-col>
+            <el-col :span="18" class="btn">
+              <el-button type="primary" size="mini" @click="addnews()"><i class="el-icon-plus"></i></el-button>
+            </el-col>
+            <el-col :span="24">
+              <data-table
+                :fields="newfields"
+                :opera="newopera"
+                :data="newslist"
+                @query="searchnews"
+                :toFormat="toFormat"
+                :total="total"
+                @edit="newtoEdit"
+                @delete="newtoDelete"
+              ></data-table>
+            </el-col>
+          </el-col>
+        </el-col>
       </el-col>
     </el-row>
+    <el-dialog :visible.sync="coldialog" title="栏目" @close="coltoClose" width="30%">
+      <data-form :data="colform" :fields="colFields" :rules="{}" @save="turnSave">
+        <template #options="{item}">
+          <template v-if="item.model === 'site'">
+            <el-option label="科技培训" value="kjpx"></el-option>
+            <el-option label="行业研究" value="hyyj"></el-option>
+            <el-option label="技术问答" value="jswd"></el-option>
+            <el-option label="专题研讨" value="ztyt"></el-option>
+            <el-option label="视频会议中心" value="sphyzx"></el-option>
+          </template>
+        </template>
+      </data-form>
+    </el-dialog>
   </div>
 </template>
 
 <script>
+import breadcrumb from '@c/common/breadcrumb.vue';
+import dataTable from '@/components/frame/filter-page-table.vue';
+import dataForm from '@/components/frame/form.vue';
 import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: serveColumn } = createNamespacedHelpers('serveColumn');
+const { mapActions: serveNews } = createNamespacedHelpers('serveNews');
 export default {
   metaInfo() {
     return { title: this.$route.meta.title };
   },
   name: 'index',
   props: {},
-  components: {},
+  components: {
+    breadcrumb,
+    dataTable,
+    dataForm,
+  },
   data: function() {
-    return {};
+    return {
+      // 栏目
+      columnopera: [
+        {
+          label: '查询信息',
+          icon: 'el-icon-view',
+          method: 'view',
+        },
+        {
+          label: '修改',
+          icon: 'el-icon-edit',
+          method: 'edit',
+        },
+        {
+          label: '删除',
+          icon: 'el-icon-delete',
+          method: 'delete',
+        },
+      ],
+      columnfields: [{ label: '名称', prop: 'name' }],
+      column: [],
+      coldialog: false,
+      colform: {},
+      colFields: [
+        { label: '名称', model: 'name' },
+        { label: '所在位置', model: 'site', type: 'select' },
+      ],
+      // 信息
+      newopera: [
+        {
+          label: '修改',
+          icon: 'el-icon-edit',
+          method: 'edit',
+        },
+        {
+          label: '删除',
+          icon: 'el-icon-delete',
+          method: 'delete',
+        },
+      ],
+      newfields: [
+        { label: '名称', prop: 'title', showTip: true },
+        { label: '信息来源', prop: 'orgin' },
+        { label: '所属栏目', prop: 'column_id', format: true },
+      ],
+      newslist: [],
+      total: 0,
+      column_id: '',
+    };
+  },
+  async created() {
+    await this.searchcolumn();
+    await this.searchnews();
+  },
+  methods: {
+    ...serveColumn({ colquery: 'query', colfetch: 'fetch', coldelete: 'delete', colcreate: 'create', colupdate: 'update' }),
+    ...serveNews({ newquery: 'query', newfetch: 'fetch', newdelete: 'delete', newcreate: 'create', newupdate: 'update' }),
+    // 查询栏目
+    async searchcolumn() {
+      const res = await this.colquery();
+      if (this.$checkRes(res)) {
+        this.$set(this, `column`, res.data);
+      } else {
+        this.$message({
+          message: '查询失败',
+          type: 'error',
+        });
+      }
+    },
+    // 栏目修改
+    coltoEdit({ data }) {
+      this.coldialog = true;
+      this.$set(this, `colform`, data);
+    },
+    // 栏目删除
+    async coltoDelete({ data }) {
+      const res = await this.coldelete(data.id);
+      if (this.$checkRes(res)) {
+        this.$message({
+          message: '刪除成功',
+          type: 'success',
+        });
+        this.coltoClose();
+      } else {
+        this.$message({
+          message: '删除失败',
+          type: 'error',
+        });
+      }
+    },
+    // 栏目添加
+    async turnSave({ data }) {
+      if (data.id) {
+        const res = await this.colupdate(data);
+        if (this.$checkRes(res)) {
+          this.$message({
+            message: '修改成功',
+            type: 'success',
+          });
+          this.coltoClose();
+        } else {
+          this.$message({
+            message: '修改失败',
+            type: 'error',
+          });
+        }
+      } else {
+        const res = await this.colcreate(data);
+        if (this.$checkRes(res)) {
+          this.$message({
+            message: '添加成功',
+            type: 'success',
+          });
+          this.coltoClose();
+        } else {
+          this.$message({
+            message: '添加失败',
+            type: 'error',
+          });
+        }
+      }
+    },
+    // 栏目取消
+    coltoClose() {
+      this.form = {};
+      this.coldialog = false;
+      this.searchcolumn();
+    },
+    // 查询信息
+    coltoView({ data }) {
+      this.$set(this, `column_id`, data.id);
+      this.searchnews();
+    },
+    // 查询信息
+    async searchnews({ skip = 0, limit = 10 } = {}) {
+      let res = await this.newquery({ skip, limit, column_id: this.column_id });
+      if (this.$checkRes(res)) {
+        this.$set(this, `newslist`, res.data);
+        this.$set(this, `total`, res.total);
+      } else {
+        this.$message({
+          message: '查询失败',
+          type: 'error',
+        });
+      }
+    },
+    // 过滤栏目
+    toFormat({ model, value }) {
+      if (model == 'column_id') {
+        const res = this.column.find(f => f.id == value);
+        if (res) return res.name;
+      }
+    },
+    // 添加信息
+    addnews() {
+      this.$router.push({ path: 'serve/detail' });
+    },
+    // 修改信息
+    newtoEdit({ data }) {
+      this.$router.push({ path: 'serve/detail', query: { id: data.id } });
+    },
+    // 删除信息
+    async newtoDelete({ data }) {
+      const res = await this.newdelete(data.id);
+      if (this.$checkRes(res)) {
+        this.$message({
+          message: '刪除成功',
+          type: 'success',
+        });
+        this.searchnews();
+      } else {
+        this.$message({
+          message: '删除失败',
+          type: 'error',
+        });
+      }
+    },
   },
-  created() {},
-  methods: {},
   computed: {
     ...mapState(['user']),
   },
 };
 </script>
 
-<style lang="less" scoped></style>
+<style lang="less" scoped>
+.main {
+  .column {
+    min-height: 850px;
+    padding: 10px;
+    border: 1px solid #ccc;
+    .txt {
+      margin: 0 0 15px 0;
+    }
+    .btn {
+      text-align: right;
+      margin: 0 0 15px 0;
+    }
+  }
+  .news {
+    min-height: 850px;
+    padding: 10px;
+    border: 1px solid #ccc;
+    .txt {
+      margin: 0 0 15px 0;
+    }
+    .btn {
+      text-align: right;
+      margin: 0 0 15px 0;
+    }
+  }
+}
+</style>