Ver código fonte

Merge branch 'pre' of http://git.dgtis.com/sunlupeng/pointsMall-admin

sunlupeng 1 ano atrás
pai
commit
cd447b517a

+ 2 - 1
build/utils.js

@@ -47,7 +47,8 @@ exports.cssLoaders = function (options) {
     if (options.extract) {
       return ExtractTextPlugin.extract({
         use: loaders,
-        fallback: 'vue-style-loader'
+        fallback: 'vue-style-loader',
+        publicPath: '../../'
       })
     } else {
       return ['vue-style-loader'].concat(loaders)

+ 1 - 1
config/index.js

@@ -14,7 +14,7 @@ module.exports = {
 
     // Various Dev Server settings
     // host: 'localhost', // can be overwritten by process.env.HOST
-    host: '192.168.100.205', // can be overwritten by process.env.HOST
+    host: '192.168.100.104', // can be overwritten by process.env.HOST
     port: 8081, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
     autoOpenBrowser: true,
     errorOverlay: true,

+ 2 - 1
package.json

@@ -12,10 +12,11 @@
     "test": "npm run lint"
   },
   "dependencies": {
+    "@riophae/vue-treeselect": "0.4.0",
     "axios": "0.17.1",
     "clipboard": "1.7.1",
     "echarts": "3.8.5",
-    "element-ui": "2.0.8",
+    "element-ui": "2.15.13",
     "file-saver": "1.3.3",
     "font-awesome": "4.7.0",
     "js-cookie": "2.2.0",

+ 54 - 0
src/api/certManage.js

@@ -1,5 +1,59 @@
 import request from '@/utils/request'
 
+// 查询证书列表
+export function listDept(query) {
+  return request({
+    url: '/mall-certificat/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询证书列表(排除节点)
+export function listDeptExcludeChild(query) {
+  return request({
+    url: '/mall-certificat/list/excludeChild',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询证书详细
+export function getDept(query) {
+  return request({
+    url: '/mall-certificat/getInfo',
+    method: 'get',
+    params: query
+  })
+}
+
+// 新增证书
+export function addDept(data) {
+  return request({
+    url: '/mall-certificat/add',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改证书
+export function updateDept(data) {
+  return request({
+    url: '/mall-certificat/edit',
+    method: 'post',
+    data: data
+  })
+}
+
+// 删除证书
+export function delDept(query) {
+  return request({
+    url: '/mall-certificat/remove',
+    method: 'post',
+    params: query
+  })
+}
+
 export function list(query) {
   return request({
     url: '/mall-integral-obtain/certificate/sys/page',

+ 1 - 1
src/api/postManage.js

@@ -34,7 +34,7 @@ export function changeState(query) {
 
 export function approvalList(query) {
   return request({
-    url: '/mall-post/complete/list',
+    url: 'mall-post/comment/list',
     method: 'get',
     params:query
   })

+ 17 - 0
src/api/trainManage.js

@@ -1,5 +1,22 @@
 import request from '@/utils/request'
 
+//获取材料备注详情
+export function fileRulesDetail(query) {
+  return request({
+    url: '/news/mall/getNotice',
+    method: 'get',
+    params: query
+  })
+}
+//修改材料备注
+export function updateFileRules(query) {
+  return request({
+    url: '/news/update',
+    method: 'post',
+    data: query
+  })
+}
+
 
 // 培训列表
 export function trainList(query) {

+ 104 - 0
src/components/RightToolbar/index.vue

@@ -0,0 +1,104 @@
+<template>
+  <div class="top-right-btn" :style="style">
+    <el-row>
+      <el-tooltip class="item" effect="dark" :content="showSearch ? '隐藏搜索' : '显示搜索'" placement="top" v-if="search">
+        <el-button size="mini" circle icon="el-icon-search" @click="toggleSearch()" />
+      </el-tooltip>
+      <el-tooltip class="item" effect="dark" content="刷新" placement="top">
+        <el-button size="mini" circle icon="el-icon-refresh" @click="refresh()" />
+      </el-tooltip>
+      <el-tooltip class="item" effect="dark" content="显隐列" placement="top" v-if="columns">
+        <el-button size="mini" circle icon="el-icon-menu" @click="showColumn()" />
+      </el-tooltip>
+    </el-row>
+    <el-dialog :title="title" :visible.sync="open" append-to-body>
+      <el-transfer
+        :titles="['显示', '隐藏']"
+        v-model="value"
+        :data="columns"
+        @change="dataChange"
+      ></el-transfer>
+    </el-dialog>
+  </div>
+</template>
+<script>
+export default {
+  name: "RightToolbar",
+  data() {
+    return {
+      // 显隐数据
+      value: [],
+      // 弹出层标题
+      title: "显示/隐藏",
+      // 是否显示弹出层
+      open: false,
+    };
+  },
+  props: {
+    showSearch: {
+      type: Boolean,
+      default: true,
+    },
+    columns: {
+      type: Array,
+    },
+    search: {
+      type: Boolean,
+      default: true,
+    },
+    gutter: {
+      type: Number,
+      default: 10,
+    },
+  },
+  computed: {
+    style() {
+      const ret = {};
+      if (this.gutter) {
+        ret.marginRight = `${this.gutter / 2}px`;
+      }
+      return ret;
+    }
+  },
+  created() {
+    // 显隐列初始默认隐藏列
+    for (let item in this.columns) {
+      if (this.columns[item].visible === false) {
+        this.value.push(parseInt(item));
+      }
+    }
+  },
+  methods: {
+    // 搜索
+    toggleSearch() {
+      this.$emit("update:showSearch", !this.showSearch);
+    },
+    // 刷新
+    refresh() {
+      this.$emit("queryTable");
+    },
+    // 右侧列表元素变化
+    dataChange(data) {
+      for (let item in this.columns) {
+        const key = this.columns[item].key;
+        this.columns[item].visible = !data.includes(key);
+      }
+    },
+    // 打开显隐列dialog
+    showColumn() {
+      this.open = true;
+    },
+  },
+};
+</script>
+<style lang="scss" scoped>
+::v-deep .el-transfer__button {
+  border-radius: 50%;
+  padding: 12px;
+  display: block;
+  margin-left: 0px;
+}
+::v-deep .el-transfer__button:first-child {
+  margin-bottom: 10px;
+}
+</style>

+ 9 - 1
src/main.js

@@ -13,6 +13,9 @@ import store from './store'
 import './icons' // icon
 import './permission' // permission control
 // import './mock' // simulation data
+import { handleTree,resetForm } from "@/utils/index";
+// 自定义表格工具组件
+import RightToolbar from "@/components/RightToolbar"
 
 Vue.use(Element, {
   size: 'medium' // set element-ui default size
@@ -24,8 +27,13 @@ const prodUrl = 'https://xiaoyou.dgtis.com/admin/storage/create';//正式地址
 const devUrl = 'http://47.103.79.143:9085/admin/storage/create';//本地测试地址
 
 const baseUrl = process.env.NODE_ENV === 'production' ? prodUrl : devUrl;
+// 全局方法挂载
 Vue.prototype.upLoadUrl = baseUrl;
-Vue.config.productionTip = false
+Vue.config.productionTip = false;
+Vue.prototype.handleTree = handleTree;
+Vue.prototype.resetForm = resetForm;
+// 全局组件挂载
+Vue.component('RightToolbar', RightToolbar);
 
 new Vue({
   el: '#app',

+ 3 - 1
src/permission.js

@@ -75,6 +75,7 @@ const myRoles = [
   'ceoCiteList',
 
   'trainManage', 
+  'upLoadFileRules',
   'trainList',
   'operateTrainList',
   'ceoTrainList',
@@ -82,7 +83,8 @@ const myRoles = [
   'festivalManage', 
   'festivalList', 
 
-  'certManage', 
+  'certManage',
+  'certSetList', 
   'certRules',
   'certList', 
 

+ 2 - 0
src/router/index.js

@@ -251,6 +251,7 @@ export const asyncRouterMap = [
       icon: 'xunzhang'
     },
     children: [
+      { path: 'upLoadFileRules', component: _import('trainManage/upLoadFileRules'), name: 'upLoadFileRules', meta: { title: '培训材料备注', noCache: true }},
       { path: 'trainList', component: _import('trainManage/trainList'), name: 'trainList', meta: { title: '培训列表', noCache: true }},
       { path: 'operateTrainList', component: _import('trainManage/operateTrainList'), name: 'operateTrainList', meta: { title: '培训审批列表', noCache: true }},
       { path: 'ceoTrainList', component: _import('trainManage/ceoTrainList'), name: 'ceoTrainList', meta: { title: '培训确认列表', noCache: true }},
@@ -279,6 +280,7 @@ export const asyncRouterMap = [
       icon: 'zhengshu'
     },
     children: [
+      { path: 'certSetList', component: _import('certManage/certSetList'), name: 'certSetList', meta: { title: '证书配置列表', noCache: true }},
       { path: 'certRules', component: _import('certManage/certRules'), name: 'certRules', meta: { title: '积分获取规则', noCache: true }},
       { path: 'certList', component: _import('certManage/certList'), name: 'certList', meta: { title: '证书列表', noCache: true }},
       

+ 7 - 0
src/utils/index.js

@@ -53,6 +53,13 @@ export function handleTree(data, id, parentId, children) {
   return tree;
 }
 
+// 表单重置
+export function resetForm(refName) {
+  if (this.$refs[refName]) {
+    this.$refs[refName].resetFields();
+  }
+}
+
 export function parseTime(time, cFormat) {
   if (arguments.length === 0) {
     return null

+ 299 - 0
src/views/certManage/certSetList.vue

@@ -0,0 +1,299 @@
+<template>
+    <div class="app-container">
+      <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch">
+        <el-form-item label="证书类型" prop="typeName">
+          <el-input
+            v-model="queryParams.typeName"
+            placeholder="请输入证书类型"
+            clearable
+            @keyup.enter.native="handleQuery"
+          />
+        </el-form-item>
+        <el-form-item>
+          <el-button class="filter-item" type="primary" icon="el-icon-search" @click="handleQuery">查找</el-button>
+          <el-button class="filter-item" type="primary" icon="el-icon-refresh" @click="resetQuery">重置</el-button>
+          <el-button class="filter-item" type="primary" icon="el-icon-edit" @click="handleAdd">添加</el-button>
+          <el-button class="filter-item" type="info" icon="el-icon-sort" @click="toggleExpandAll">展开/折叠</el-button>
+        </el-form-item>
+      </el-form>
+      <!-- <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> -->
+      <el-table
+        v-if="refreshTable"
+        v-loading="loading"
+        :data="deptList"
+        row-key="id"
+        border
+        :default-expand-all="isExpandAll"
+        :tree-props="{children: 'children', hasChildren: 'hasChildren'}"
+      >
+        <el-table-column prop="typeName" label="证书类型" min-width="180px"></el-table-column>
+        <el-table-column prop="orderNum" label="排序" align="center"></el-table-column>
+        <el-table-column prop="integral" label="积分" align="center"></el-table-column>
+        <el-table-column label="创建时间" align="center" prop="createTime">
+        </el-table-column>
+        <el-table-column label="操作" align="center" min-width="110px">
+          <template slot-scope="scope">
+            <el-button
+              size="mini"
+              type="primary"
+              @click="handleUpdate(scope.row)"
+            >修改</el-button>
+            <el-button
+              size="mini"
+              type="success"
+              @click="handleAdd(scope.row)"
+            >添加</el-button>
+            <el-button
+              v-if="scope.row.parentId != 0"
+              size="mini"
+              type="danger"
+              @click="handleDelete(scope.row)"
+            >删除</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+  
+      <!-- 添加或修改证书对话框 -->
+      <el-dialog :title="title" :visible.sync="open" width="600px" append-to-body>
+        <el-form ref="form" :model="form" :rules="rules" label-width="80px">
+          <el-row>
+            <el-col :span="24" v-if="form.parentId !== 0">
+              <el-form-item label="上级类型" prop="parentId">
+                <treeselect default-expand-all v-model="form.parentId" :options="deptOptions" :normalizer="normalizer" placeholder="选择上级类型" />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row>
+            <el-col :span="24">
+              <el-form-item label="证书类型" prop="typeName">
+                <el-input v-model="form.typeName" placeholder="请输入证书类型" />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row>
+            <el-col :span="24">
+              <el-form-item label="积分" prop="integral">
+                <el-input-number v-model="form.integral" controls-position="right" :min="0" />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row>
+            <el-col :span="24">
+              <el-form-item label="显示排序" prop="orderNum">
+                <el-input-number v-model="form.orderNum" controls-position="right" :min="0" />
+              </el-form-item>
+            </el-col>
+          </el-row>
+        </el-form>
+        <div slot="footer" class="dialog-footer">
+          <el-button type="primary" @click="submitForm">确 定</el-button>
+          <el-button @click="cancel">取 消</el-button>
+        </div>
+      </el-dialog>
+    </div>
+  </template>
+  
+  <script>
+  import { listDept, getDept, delDept, addDept, updateDept, listDeptExcludeChild } from "@/api/certManage";
+  import Treeselect from "@riophae/vue-treeselect";
+  import "@riophae/vue-treeselect/dist/vue-treeselect.css";
+  
+  export default {
+    components: { Treeselect },
+    data() {
+      return {
+        // 遮罩层
+        loading: true,
+        // 显示搜索条件
+        showSearch: true,
+        // 表格树数据
+        deptList: [],
+        // 证书树选项
+        deptOptions: [],
+        // 弹出层标题
+        title: "",
+        // 是否显示弹出层
+        open: false,
+        // 是否展开,默认全部展开
+        isExpandAll: true,
+        // 重新渲染表格状态
+        refreshTable: true,
+        // 查询参数
+        queryParams: {
+          typeName: undefined,
+        },
+        // 表单参数
+        form: {},
+        // 表单校验
+        rules: {
+          parentId: [
+            { required: true, message: "上级类型不能为空", trigger: "blur" }
+          ],
+          typeName: [
+            { required: true, message: "证书类型不能为空", trigger: "blur" }
+          ],
+          orderNum: [
+            { required: true, message: "显示排序不能为空", trigger: "blur" }
+          ],
+          integral: [
+            { required: true, message: "积分不能为空", trigger: "blur" }
+          ],
+          email: [
+            {
+              type: "email",
+              message: "请输入正确的邮箱地址",
+              trigger: ["blur", "change"]
+            }
+          ],
+          phone: [
+            {
+              pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
+              message: "请输入正确的手机号码",
+              trigger: "blur"
+            }
+          ]
+        }
+      };
+    },
+    created() {
+      this.getList();
+    },
+    methods: {
+      /** 查询证书列表 */
+      getList() {
+        this.loading = true;
+        listDept(this.queryParams).then(response => {
+          this.deptList = this.handleTree(response.data.data,'id');
+          console.log(this.deptList);
+          this.loading = false;
+        });
+      },
+      /** 转换证书数据结构 */
+      normalizer(node) {
+        if (node.children && !node.children.length) {
+          delete node.children;
+        }
+        return {
+          id: node.id,
+          label: node.typeName,
+          children: node.children
+        };
+      },
+      // 取消按钮
+      cancel() {
+        this.open = false;
+        this.reset();
+      },
+      // 表单重置
+      reset() {
+        this.form = {
+          id: undefined,
+          parentId: undefined,
+          typeName: undefined,
+          orderNum: undefined,
+          integral:undefined,
+          leader: undefined,
+          phone: undefined,
+          email: undefined,
+          status: "0"
+        };
+        this.resetForm("form");
+      },
+      /** 搜索按钮操作 */
+      handleQuery() {
+        this.getList();
+      },
+      /** 重置按钮操作 */
+      resetQuery() {
+        this.resetForm("queryForm");
+        this.handleQuery();
+      },
+      /** 新增按钮操作 */
+      handleAdd(row) {
+        this.reset();
+        if (row != undefined) {
+          this.form.parentId = row.id;
+        }
+        this.open = true;
+        this.title = "添加证书";
+        listDept().then(response => {
+          this.deptOptions = this.handleTree(response.data.data, "id");
+        });
+      },
+      /** 展开/折叠操作 */
+      toggleExpandAll() {
+        this.refreshTable = false;
+        this.isExpandAll = !this.isExpandAll;
+        this.$nextTick(() => {
+          this.refreshTable = true;
+        });
+      },
+      /** 修改按钮操作 */
+      handleUpdate(row) {
+        this.reset();
+        getDept({id:row.id}).then(response => {
+          this.form = response.data.data;
+          this.open = true;
+          this.title = "修改证书";
+          listDeptExcludeChild({id:row.id}).then(response => {
+            this.deptOptions = this.handleTree(response.data.data, "id");
+            if (this.deptOptions.length == 0) {
+              const noResultsOptions = { id: this.form.parentId, typeName: this.form.parentName, children: [] };
+              this.deptOptions.push(noResultsOptions);
+            }
+          });
+        });
+      },
+      /** 提交按钮 */
+      submitForm: function() {
+        this.$refs["form"].validate(valid => {
+          if (valid) {
+            if (this.form.id != undefined) {
+              updateDept(this.form).then(response => {
+                this.$notify({
+                            title: '成功',
+                            message: '修改成功',
+                            type: 'success',
+                            duration: 2000
+                        })
+                this.open = false;
+                this.getList();
+              });
+            } else {
+              addDept(this.form).then(response => {
+                this.$notify({
+                            title: '成功',
+                            message: '新增成功',
+                            type: 'success',
+                            duration: 2000
+                        })
+                this.open = false;
+                this.getList();
+              });
+            }
+          }
+        });
+      },
+      /** 删除按钮操作 */
+      handleDelete(row) {
+        this.$confirm('是否确认删除名称为"' + row.typeName + '"的数据项?', "提示", {
+                confirmButtonText: "确定",
+                cancelButtonText: "取消",
+                type: "warning",
+            })
+        .then(function() {
+          return delDept({id:row.id});
+        }).then(() => {
+          this.getList();
+          this.$notify({
+                            title: '成功',
+                            message: '删除成功',
+                            type: 'success',
+                            duration: 2000
+                        })
+        }).catch(() => {});
+      }
+    }
+  };
+  </script>
+  

+ 54 - 88
src/views/postManage/postApprovalList.vue

@@ -4,7 +4,7 @@
     <!-- 查询和其他操作 -->
     <div class="filter-container">
       <el-input clearable class="filter-item" style="width: 200px;" placeholder="请输入帖子Id"
-        v-model="listQuery.topicId"></el-input>
+        v-model="listQuery.postId"></el-input>
       <el-input clearable class="filter-item" style="width: 200px;" placeholder="请输入帖子标题"
         v-model="listQuery.title"></el-input>
       <el-input clearable class="filter-item" style="width: 200px;" placeholder="请输入姓名"
@@ -29,6 +29,8 @@
       </el-table-column>
       <el-table-column align="center" min-width="200px" label="帖子标题" prop="title">
       </el-table-column>
+      <el-table-column align="center" min-width="80px" label="积分" prop="integral">
+            </el-table-column>
       <el-table-column align="center" min-width="150px" label="回复时间" prop="createTime">
       </el-table-column>
       <el-table-column align="center" min-width="100px" label="审批状态" prop="statusName">
@@ -36,7 +38,7 @@
       <el-table-column align="center" label="操作" width="240px" class-name="small-padding fixed-width">
         <template slot-scope="scope">
           <el-button type="primary" size="small" @click="handleView(scope.row,'view')">查看</el-button>
-          <el-button type="success" size="small" @click="handleView(scope.row,'complete')">处理</el-button>
+          <el-button v-if="scope.row.status==1" type="success" size="small" @click="handleView(scope.row,'complete')">处理</el-button>
         </template>
       </el-table-column>
     </el-table>
@@ -55,26 +57,27 @@
         <div class="quesList">
           <div class="listItem" v-for="(item,index) in data" :key="index">
             <div v-if="item.type=='SCQ'">
-              <div class="itemTitle">{{ index+1 }}. {{item.description}}(单选)</div>
-              <el-radio-group v-model="item.comment">
-                <el-radio v-for="(childItem,childIndex) in item.options" :key="childIndex" :label="childItem.id" disabled>{{ childItem.name }}</el-radio>
+              <div class="itemTitle">{{ index + 1 }}. {{ item.description }}<el-tag class="elTag" size="small" type="danger">单选</el-tag></div>
+              <el-radio-group v-model="item.comment" class="flex-column">
+                <el-radio class="myRadio" v-for="(childItem,childIndex) in item.options" :key="childIndex" :label="childItem.id" disabled>{{ childItem.name }}</el-radio>
               </el-radio-group>
             </div>
 
             <div v-if="item.type=='MCQ'">
-              <div class="itemTitle">{{ index+1 }}. {{item.description}}(多选)</div>
-              <el-checkbox-group v-model="item.comment">
-                <el-checkbox v-for="(childItem,childIndex) in item.options" :key="childIndex" :label="childItem.id" disabled>{{ childItem.name }}</el-checkbox>
+              <div class="itemTitle">{{ index + 1 }}. {{ item.description }}<el-tag class="elTag" size="small" type="danger">多选</el-tag></div>
+              <el-checkbox-group v-model="item.comment" class="flex-column">
+                <el-checkbox class="myRadio" v-for="(childItem,childIndex) in item.options" :key="childIndex" :label="childItem.id" disabled>{{ childItem.name }}</el-checkbox>
               </el-checkbox-group>
             </div>
             <div v-if="item.type=='SAQ'">
-              <div class="itemTitle">{{ index+1 }}. {{item.description}}(问答)</div>
-              <el-input disabled type="textarea" :rows="4" placeholder="请输入内容" v-model="item.comment"></el-input>
+              <div class="itemTitle">{{ index + 1 }}. {{ item.description }}<el-tag class="elTag" size="small" type="danger">问答</el-tag></div>
+              <div class="myText">{{ item.comment }}</div>
+              <!-- <el-input disabled type="textarea" :rows="6" maxlength="200" show-word-limit placeholder="请输入内容" v-model="item.comment"></el-input> -->
             </div>
           </div>
           <div v-if="dialogStatus=='complete'" class="listItem">
               <div class="itemTitle">审批意见</div>
-              <el-input type="textarea" :rows="4" placeholder="请输入审批意见" v-model="comment"></el-input>
+              <el-input type="textarea" :rows="6" maxlength="200" show-word-limit placeholder="请输入审批意见" v-model="comment"></el-input>
           </div>
         </div>
       </div>
@@ -91,8 +94,12 @@
 .listItem{
   margin-bottom: 30px;
 }
-.itemTitle{
-  margin-bottom: 10px;
+.itemTitle {
+    margin-bottom: 10px;
+    font-weight: 700;
+}
+.elTag{
+    margin-left: 5px;
 }
 .demo-table-expand {
   font-size: 0;
@@ -211,77 +218,6 @@ export default {
         },
       ],
       list: [
-        {
-          "id": 1,
-          "loginId": "root",
-          "topicId": 0,
-          "discussId": 0,
-          "title": "谁是世界上最帅的人",
-          "content": "请评价谁是最帅的人",
-          "media": null,
-          "readCount": 0,
-          "postTop": 0,
-          "type": 4,
-          "address": null,
-          "longitude": 0,
-          "latitude": 0,
-          "status": 0,
-          "statusName": "待审批",
-          "createTime": "2023-10-31 16:35:07",
-          "modifyTime": "2023-11-02 14:32:49",
-          "deadline": null,
-          "integral": 1000,
-          "cut1": "0",
-          "cut2": "0",
-          "cut3": null,
-          "userName": "系统管理员",
-          "employeeNo": null,
-          "deptName": "神州通誉",
-          "data": [
-            {
-              "id": 1,
-              "postId": 1,
-              "description": "最帅的人,请选择以下选项",
-              "type": "SCQ",
-              "createTime": "2023-10-31 16:35:07",
-              "modifyTime": "2023-10-31 16:35:07",
-              "options": [
-                {
-                  "id": 1,
-                  "postId": 1,
-                  "questionId": 1,
-                  "name": "金城武",
-                  "num": 0
-                },
-                {
-                  "id": 2,
-                  "postId": 1,
-                  "questionId": 1,
-                  "name": "刘德华",
-                  "num": 0
-                },
-                {
-                  "id": 3,
-                  "postId": 1,
-                  "questionId": 1,
-                  "name": "张三",
-                  "num": 0
-                }
-              ],
-              "comment": "1"
-            },
-            {
-              "id": 2,
-              "postId": 1,
-              "description": "请问今年是什么年",
-              "type": "SAQ",
-              "createTime": "2023-11-02 14:34:03",
-              "modifyTime": "2023-11-02 14:34:03",
-              "options": [],
-              "comment": "兔年"
-            }
-          ]
-        },
       ],
       delarr: [],
       multipleSelection: [],
@@ -290,8 +226,9 @@ export default {
       listQuery: {
         page: 1,
         limit: 10,
-        dictName: '',
-        dictType: '',
+        postId: '',
+        title: '',
+        userName: '',
         status: '',
       },
       dialogFormVisible: false,
@@ -321,12 +258,13 @@ export default {
         },
     complete(flag) {
             const parms = {
-                postId:this.postId,
+                commentId:this.commentId,
                 comment: this.comment,
                 flag:flag,
             }
             const isChecked = this.checked(parms);
             if(isChecked){
+                this.dialogFormVisible = false;
                 complete(parms).then((response) => {
                     this.$notify({
                         title: "成功",
@@ -369,7 +307,8 @@ export default {
       this.getList()
     },
     handleView(row,val){
-      this.postId = row.postId,
+      this.postId = row.postId;
+      this.commentId = row.id;
       getDetailInfo({postId:row.postId}).then(response => {
         this.data = response.data.data.data;
         this.data.forEach(item => {
@@ -423,6 +362,33 @@ export default {
 }
 </script>
 <style>
+.myText {
+    display: block;
+    resize: vertical;
+    padding: 5px 15px;
+    line-height: 1.5;
+    box-sizing: border-box;
+    width: 100%;
+    font-size: 14px;
+    color: #606266;
+    background-color: #FFF;
+    background-image: none;
+    border: 1px solid #DCDFE6;
+    border-radius: 4px;
+    transition: border-color .2s cubic-bezier(.645,.045,.355,1);
+}
+.myRadio{
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    white-space:normal !important;
+    margin: 10px !important;
+}
+.flex-column{
+    display: flex;
+    flex-flow: column nowrap;
+    align-items: flex-start;
+}
 .ad-avatar-uploader .el-upload {
   border: 1px dashed #d9d9d9;
   border-radius: 6px;

+ 72 - 1
src/views/postManage/postList.vue

@@ -43,7 +43,7 @@
                         @click="changeState(scope.row.id, 1)">开启</el-button>
                     <el-button v-if="scope.row.status == 1" type="warning" size="small"
                         @click="changeState(scope.row.id, 0)">关闭</el-button>
-                    <el-button type="danger" size="small" @click="handleDelete(scope.row.postId, -1)">删除</el-button>
+                    <el-button type="danger" size="small" @click="handleDelete(scope.row.id, -1)">删除</el-button>
                 </template>
             </el-table-column>
         </el-table>
@@ -67,6 +67,16 @@
                         </el-option>
                     </el-select>
                 </el-form-item>
+                <el-form-item style="width: 800px" label="图片" prop="media">
+                    <el-tooltip content="建议图片宽高比120*80" placement="top-start">
+                        <el-upload :action="fileImgUrl" list-type="picture-card" :file-list="dataForm.mediaFiles" :limit="1"
+                            :on-success="handleGallerySucess" :on-exceed="handleExceed" :before-upload="uploadBannerImg"
+                            :on-remove="handleRemove">
+                            <i class="el-icon-plus"></i>
+                        </el-upload>
+                    </el-tooltip>
+                    
+                </el-form-item>
                 <el-form-item label="积分" prop="integral">
                     <el-input-number style="width: 100%" :min="1" :step="1" v-model="dataForm.integral"></el-input-number>
                 </el-form-item>
@@ -153,6 +163,7 @@ export default {
     directives: { waves },
     data() {
         return {
+            fileImgUrl: this.upLoadUrl,
             qesType:'',
             qesTypeList:[
                 {
@@ -293,6 +304,8 @@ export default {
             dataForm: {
                 title: '',
                 type: '',
+                media: '',
+                mediaFiles: [],
                 integral: '',
                 deadline: '',
                 participants: [],
@@ -308,6 +321,7 @@ export default {
             rules: {
                 title: [{ required: true, message: "请填写标题", trigger: "blur" }],
                 type: [{ required: true, message: "请选择类型", trigger: "blur" }],
+                media: [{ required: true, message: "图片不能为空", trigger: "blur" }],
                 integral: [{ required: true, message: "请填写积分", trigger: "blur" }],
                 deadline: [{ required: true, message: "请选择截止日期", trigger: "blur" }],
                 content: [{ required: true, message: "内容不能为空", trigger: "blur" }],
@@ -320,6 +334,44 @@ export default {
         this.getList();
     },
     methods: {
+        handleRemove(file, fileList) {
+            console.log(file, fileList);
+            let mediaFiles = [];
+            for (let i in fileList) {
+                let response = fileList[i].response;
+                let url = response.data.url;
+                mediaFiles.push(url);
+                this.dataForm.media = mediaFiles.join(",");
+            }
+        },
+        uploadBannerImg(file) {
+            const isJPGs = file.type === "image/jpeg";
+            console.log(isJPGs);
+        },
+        handleExceed(files, fileList) {
+            this.$message.warning(
+                `当前限制选择 1 个文件,本次选择了 ${files.length} 个文件!,共选择了 ${files.length + fileList.length
+                } 个文件`
+            );
+        },
+        handleGallerySucess(res, file, fileList) {
+            this.dataForm.media = ""; // 清空画廊图片数组
+
+            let mediaFiles = [];
+            for (let i in fileList) {
+                let response = fileList[i].response;
+                if (response.errno && response.errno != "0") {
+                    this.$message.error("该图片上传失败,已被移除,请重新上传!");
+                    // 上传失败移除该 file 对象
+                    fileList.splice(i, 1);
+                } else {
+                    let url = response.data.url;
+                    mediaFiles.push(url);
+                }
+            }
+
+            this.dataForm.media = mediaFiles.join(",");
+        },
         //改变类型
         changeType(val){
             if(val==5){
@@ -393,6 +445,8 @@ export default {
             this.dataForm = {
                 title: '',
                 type: '',
+                media: '',
+                mediaFiles: [],
                 integral: '',
                 deadline: '',
                 participants: [],
@@ -458,8 +512,25 @@ export default {
             getDetailInfo({postId:row.id}).then(response => {
                 this.dataForm = response.data.data;
                 this.dataForm.questions = response.data.data.data;
+                if (this.dataForm.media) {
+                    let mediaFiles = this.dataForm.media.split(",");
+                    this.dataForm.mediaFiles = [];
+                    for (let i in mediaFiles) {
+                        let url = mediaFiles[i];
+                        let name = "image_" + i;
+
+                        this.dataForm.mediaFiles.push({
+                            name: name,
+                            url: url,
+                            response: { error: "0", data: { url: url } },
+                        });
+                    }
+                }
                 this.dialogStatus = 'update'
                 this.dialogFormVisible = true
+                this.$nextTick(() => {
+                    this.$refs["dataForm"].clearValidate();
+                });
             }).catch(() => {})
         },
         updateData() {

+ 86 - 0
src/views/trainManage/upLoadFileRules.vue

@@ -0,0 +1,86 @@
+<template>
+    <div class="app-container calendar-list-container" style="padding-bottom: 80px;">
+        <el-form :rules="rules" ref="dataForm" :model="dataForm" status-icon label-position="left" label-width="100px" style='width: 85%; margin-left:50px;'>
+         <el-form-item  label="标题" prop="title">
+              <el-input v-model="dataForm.title"></el-input>
+            </el-form-item>
+            <el-form-item
+              style="width: 100%"
+              label="内容"
+              prop="content"
+            >
+              <tinymce v-model="dataForm.content" ref="tinymce"></tinymce>
+            </el-form-item>
+  
+        </el-form>
+        <el-button style="float: right;margin-right: 120px;" type="primary" @click="updateData">修改</el-button>
+    
+        
+    </div>
+   
+  </template>
+  
+  <style>
+    
+  </style>
+  
+  
+  <script>
+   import {fileRulesDetail, updateFileRules} from "@/api/trainManage";
+    import waves from "@/directive/waves"; // 水波纹指令
+    import Tinymce from '@/components/Tinymce'
+    export default {
+    name: 'giftExchangeRules',
+    components: { Tinymce },
+    directives: { waves },
+    data() {
+      return {
+        dataForm: {
+          type:'trainrule',
+          title: '',
+          content: "",
+        },
+        dialogFormVisible: false,
+        rules: {
+            title: [{ required: true, message: "标题不能为空", trigger: "blur" }],
+            content: [{ required: true, message: "积分规则不能为空", trigger: "blur" }],
+        },
+      }
+    },
+    created() {
+        this.getDetail();
+    },
+    methods: {
+    
+      getDetail() {
+          this.loading = true
+          fileRulesDetail({noticeType:'trainrule'}).then(response => {
+            this.dataForm.title = response.data.data.title;
+            this.dataForm.content = response.data.data.content;
+            this.dataForm.id = response.data.data.id;
+            this.loading = false;
+          }).catch(() => {})
+      },
+      updateData() {
+        this.$refs['dataForm'].validate((valid) => {
+          if (valid) {
+            this.loading = true;
+            updateFileRules(this.dataForm).then(() => {
+              this.loading = false;
+                this.$notify({
+                  title: '成功',
+                  message: '更新成功',
+                  type: 'success',
+                  duration: 2000
+                })
+                this.getDetail()
+              }) 
+          }
+        })
+      },
+  
+      
+    }
+  }
+  </script>
+  

+ 71 - 8
yarn.lock

@@ -49,6 +49,13 @@
     chalk "^2.0.0"
     js-tokens "^4.0.0"
 
+"@babel/runtime@^7.3.1":
+  version "7.23.2"
+  resolved "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.23.2.tgz#062b0ac103261d68a966c4c7baf2ae3e62ec3885"
+  integrity sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==
+  dependencies:
+    regenerator-runtime "^0.14.0"
+
 "@babel/template@7.0.0-beta.31":
   version "7.0.0-beta.31"
   resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-beta.31.tgz#577bb29389f6c497c3e7d014617e7d6713f68bda"
@@ -103,6 +110,20 @@
     mkdirp "^1.0.4"
     rimraf "^3.0.2"
 
+"@riophae/vue-treeselect@0.4.0":
+  version "0.4.0"
+  resolved "https://registry.npmmirror.com/@riophae/vue-treeselect/-/vue-treeselect-0.4.0.tgz#0baed5a794cffc580b63591f35c125e51c0df241"
+  integrity sha512-J4atYmBqXQmiPFK/0B5sXKjtnGc21mBJEiyKIDZwk0Q9XuynVFX6IJ4EpaLmUgL5Tve7HAS7wkiGGSti6Uaxcg==
+  dependencies:
+    "@babel/runtime" "^7.3.1"
+    babel-helper-vue-jsx-merge-props "^2.0.3"
+    easings-css "^1.0.0"
+    fuzzysearch "^1.0.3"
+    is-promise "^2.1.0"
+    lodash "^4.0.0"
+    material-colors "^1.2.6"
+    watch-size "^2.0.0"
+
 "@tootallnate/once@1":
   version "1.1.2"
   resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82"
@@ -732,9 +753,9 @@ babel-helper-replace-supers@^6.24.1:
     babel-traverse "^6.24.1"
     babel-types "^6.24.1"
 
-babel-helper-vue-jsx-merge-props@2.0.3, babel-helper-vue-jsx-merge-props@^2.0.0:
+babel-helper-vue-jsx-merge-props@2.0.3, babel-helper-vue-jsx-merge-props@^2.0.0, babel-helper-vue-jsx-merge-props@^2.0.3:
   version "2.0.3"
-  resolved "https://registry.yarnpkg.com/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-2.0.3.tgz#22aebd3b33902328e513293a8e4992b384f9f1b6"
+  resolved "https://registry.npmmirror.com/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-2.0.3.tgz#22aebd3b33902328e513293a8e4992b384f9f1b6"
   integrity sha512-gsLiKK7Qrb7zYJNgiXKpXblxbV5ffSwR0f5whkPAaBAR4fhi6bwRZxX9wBlIc5M/v8CCkXUbXZL4N/nSE97cqg==
 
 babel-helpers@^6.24.1:
@@ -2730,6 +2751,11 @@ duplexify@^3.4.2, duplexify@^3.6.0:
     readable-stream "^2.0.0"
     stream-shift "^1.0.0"
 
+easings-css@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.npmmirror.com/easings-css/-/easings-css-1.0.0.tgz#dde569003bb7a4a0c0b77878f5db3e0be5679c81"
+  integrity sha512-7Uq7NdazNfVtr0RNmPAys8it0zKCuaqxJStYKEl72D3j4gbvXhhaM7iWNbqhA4C94ygCye6VuyhzBRQC4szeBg==
+
 ecc-jsbn@~0.1.1:
   version "0.1.2"
   resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9"
@@ -2760,14 +2786,16 @@ electron-to-chromium@^1.2.7, electron-to-chromium@^1.3.30:
   resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.30.tgz#0f75a1dce26dffbd5a0f7212e5b87fe0b61cbc76"
   integrity sha512-609z9sIMxDHg+TcR/VB3MXwH+uwtrYyeAwWc/orhnr90ixs6WVGSrt85CDLGUdNnLqCA7liv426V20EecjvflQ==
 
-element-ui@2.0.8:
-  version "2.0.8"
-  resolved "https://registry.npmmirror.com/element-ui/-/element-ui-2.0.8.tgz#cee493530a8e7a3c69bb83dc22f252a5b9ce0a11"
-  integrity sha512-Y0eiOhJZl4lgrGaGK6z02YtLsWljochxKud6IX4q2ju/NraZfexTah3GH+6x8D0IhplVP+QxHZ1+gSqnIbnmmQ==
+element-ui@2.15.13:
+  version "2.15.13"
+  resolved "https://registry.npmmirror.com/element-ui/-/element-ui-2.15.13.tgz#380f019ee7d15b181105587b41fd5914c308a143"
+  integrity sha512-LJoatEYX6WV74FqXBss8Xfho9fh9rjDSzrDrTyREdGb1h1R3uRvmLh5jqp2JU137aj4/BgqA3K06RQpQBX33Bg==
   dependencies:
     async-validator "~1.8.1"
     babel-helper-vue-jsx-merge-props "^2.0.0"
     deepmerge "^1.2.0"
+    normalize-wheel "^1.0.1"
+    resize-observer-polyfill "^1.5.0"
     throttle-debounce "^1.0.1"
 
 elliptic@^6.5.3:
@@ -3655,6 +3683,11 @@ functional-red-black-tree@^1.0.1:
   resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327"
   integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=
 
+fuzzysearch@^1.0.3:
+  version "1.0.3"
+  resolved "https://registry.npmmirror.com/fuzzysearch/-/fuzzysearch-1.0.3.tgz#dffc80f6d6b04223f2226aa79dd194231096d008"
+  integrity sha512-s+kNWQuI3mo9OALw0HJ6YGmMbLqEufCh2nX/zzV5CrICQ/y4AwPxM+6TIiF9ItFCHXFCyM/BfCCmN57NTIJuPg==
+
 gauge@^3.0.0:
   version "3.0.2"
   resolved "https://registry.yarnpkg.com/gauge/-/gauge-3.0.2.tgz#03bf4441c044383908bcfa0656ad91803259b395"
@@ -4640,6 +4673,11 @@ is-primitive@^2.0.0:
   resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575"
   integrity sha1-IHurkWOEmcB7Kt8kCkGochADRXU=
 
+is-promise@^2.1.0:
+  version "2.2.2"
+  resolved "https://registry.npmmirror.com/is-promise/-/is-promise-2.2.2.tgz#39ab959ccbf9a774cf079f7b40c7a26f763135f1"
+  integrity sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==
+
 is-regex@^1.0.4, is-regex@^1.1.4:
   version "1.1.4"
   resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958"
@@ -5013,9 +5051,9 @@ lodash.uniq@^4.5.0:
   resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
   integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
 
-lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.2, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.3.0, lodash@~4.17.10:
+lodash@^4.0.0, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.2, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.3.0, lodash@~4.17.10:
   version "4.17.21"
-  resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
+  resolved "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
   integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
 
 log-symbols@^1.0.2:
@@ -5121,6 +5159,11 @@ map-visit@^1.0.0:
   dependencies:
     object-visit "^1.0.0"
 
+material-colors@^1.2.6:
+  version "1.2.6"
+  resolved "https://registry.npmmirror.com/material-colors/-/material-colors-1.2.6.tgz#6d1958871126992ceecc72f4bcc4d8f010865f46"
+  integrity sha512-6qE4B9deFBIa9YSpOc9O0Sgc43zTeVYbgDT5veRKSlB2+ZuHNoVVxA1L/ckMUayV9Ay9y7Z/SZCLcGteW9i7bg==
+
 math-expression-evaluator@^1.2.14:
   version "1.3.8"
   resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.3.8.tgz#320da3b2bc1512f4f50fc3020b2b1cd5c8e9d577"
@@ -5678,6 +5721,11 @@ normalize-url@^1.4.0:
     query-string "^4.1.0"
     sort-keys "^1.0.0"
 
+normalize-wheel@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.npmmirror.com/normalize-wheel/-/normalize-wheel-1.0.1.tgz#aec886affdb045070d856447df62ecf86146ec45"
+  integrity sha512-1OnlAPZ3zgrk8B91HyRj+eVv+kS5u+Z0SCsak6Xil/kmgEia50ga7zfkumayonZrImffAxPU/5WcyGhzetHNPA==
+
 normalize.css@7.0.0:
   version "7.0.0"
   resolved "https://registry.yarnpkg.com/normalize.css/-/normalize.css-7.0.0.tgz#abfb1dd82470674e0322b53ceb1aaf412938e4bf"
@@ -6962,6 +7010,11 @@ regenerator-runtime@^0.11.0:
   resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9"
   integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==
 
+regenerator-runtime@^0.14.0:
+  version "0.14.0"
+  resolved "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz#5e19d68eb12d486f797e15a3c6a918f7cec5eb45"
+  integrity sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==
+
 regenerator-transform@^0.10.0:
   version "0.10.1"
   resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd"
@@ -7107,6 +7160,11 @@ requires-port@^1.0.0:
   resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
   integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=
 
+resize-observer-polyfill@^1.5.0:
+  version "1.5.1"
+  resolved "https://registry.npmmirror.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464"
+  integrity sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==
+
 resolve-cwd@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a"
@@ -8608,6 +8666,11 @@ vuex@3.0.1:
   resolved "https://registry.yarnpkg.com/vuex/-/vuex-3.0.1.tgz#e761352ebe0af537d4bb755a9b9dc4be3df7efd2"
   integrity sha512-wLoqz0B7DSZtgbWL1ShIBBCjv22GV5U+vcBFox658g6V0s4wZV9P4YjCNyoHSyIBpj1f29JBoNQIqD82cR4O3w==
 
+watch-size@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.npmmirror.com/watch-size/-/watch-size-2.0.0.tgz#096ee28d0365bd7ea03d9c8bf1f2f50a73be1474"
+  integrity sha512-M92R89dNoTPWyCD+HuUEDdhaDnh9jxPGOwlDc0u51jAgmjUvzqaEMynXSr3BaWs+QdHYk4KzibPy1TFtjLmOZQ==
+
 watchpack-chokidar2@^2.0.1:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz#38500072ee6ece66f3769936950ea1771be1c957"