lsw 10 months ago
parent
commit
e22a2cf86d
25 changed files with 830 additions and 1554 deletions
  1. 304 318
      admin-ui/src/views/system/user/index.vue
  2. 89 0
      admin-ui/src/views/work/news/edit.vue
  3. 115 0
      admin-ui/src/views/work/news/index.vue
  4. 2 2
      admin-ui/src/views/work/project/index.vue
  5. 2 2
      admin-ui/src/views/work/project/packages/index.vue
  6. 2 2
      admin-ui/vue.config.js
  7. 0 149
      app/pages/auth/index.vue
  8. 0 191
      app/pages/company/index.vue
  9. 0 107
      app/pages/company/search.vue
  10. 0 264
      app/pages/index/index.vue
  11. 0 256
      app/pages/index/index2.vue
  12. 0 184
      app/pages/packages/index.vue
  13. 0 73
      ruoyi-admin/src/main/java/com/ruoyi/web/work/controller/FeedbackController.java
  14. 66 0
      ruoyi-admin/src/main/java/com/ruoyi/web/work/controller/NewsController.java
  15. 11 2
      ruoyi-admin/src/main/java/com/ruoyi/web/work/controller/ProjectController.java
  16. 62 0
      ruoyi-admin/src/main/java/com/ruoyi/web/work/domain/News.java
  17. 25 0
      ruoyi-admin/src/main/java/com/ruoyi/web/work/domain/dto/ProjectChangeDto.java
  18. 46 0
      ruoyi-admin/src/main/java/com/ruoyi/web/work/domain/dto/ProjectDto.java
  19. 13 0
      ruoyi-admin/src/main/java/com/ruoyi/web/work/mapper/NewsMapper.java
  20. 13 0
      ruoyi-admin/src/main/java/com/ruoyi/web/work/service/INewsService.java
  21. 6 0
      ruoyi-admin/src/main/java/com/ruoyi/web/work/service/IProjectService.java
  22. 24 0
      ruoyi-admin/src/main/java/com/ruoyi/web/work/service/impl/NewsServiceImpl.java
  23. 30 4
      ruoyi-admin/src/main/java/com/ruoyi/web/work/service/impl/ProjectServiceImpl.java
  24. 5 0
      ruoyi-admin/src/main/java/com/ruoyi/web/work/service/impl/StatementServiceImpl.java
  25. 15 0
      ruoyi-admin/src/main/resources/mapper/work/NewsMapper.xml

+ 304 - 318
admin-ui/src/views/system/user/index.vue

@@ -72,6 +72,7 @@
               <div v-if="user.companyId">
                 <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:user:edit']" v-if="scope.row.createBy">修改</el-button>
                 <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" v-hasPermi="['system:user:remove']" v-if="scope.row.createBy">删除</el-button>
+                <el-button size="mini" type="text" icon="el-icon-key" @click="handleResetPwd(scope.row)" v-hasPermi="['system:user:resetPwd']" v-if="scope.row.createBy">重置密码</el-button>
               </div>
               <div v-else>
                 <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:user:edit']">修改</el-button>
@@ -173,18 +174,7 @@
 
     <!-- 用户导入对话框 -->
     <el-dialog :title="upload.title" :visible.sync="upload.open" :close-on-click-modal="false" width="400px" append-to-body>
-      <el-upload
-        ref="upload"
-        :limit="1"
-        accept=".xlsx, .xls"
-        :headers="upload.headers"
-        :action="upload.url + '?updateSupport=' + upload.updateSupport"
-        :disabled="upload.isUploading"
-        :on-progress="handleFileUploadProgress"
-        :on-success="handleFileSuccess"
-        :auto-upload="false"
-        drag
-      >
+      <el-upload ref="upload" :limit="1" accept=".xlsx, .xls" :headers="upload.headers" :action="upload.url + '?updateSupport=' + upload.updateSupport" :disabled="upload.isUploading" :on-progress="handleFileUploadProgress" :on-success="handleFileSuccess" :auto-upload="false" drag>
         <i class="el-icon-upload"></i>
         <div class="el-upload__text">
           将文件拖到此处,或
@@ -208,202 +198,199 @@
 </template>
 
 <script>
-import { listUser, getUser, delUser, addUser, updateUser, resetUserPwd, changeUserStatus, deptTreeSelect } from '@/api/system/user';
-import { getToken } from '@/utils/auth';
-import Treeselect from '@riophae/vue-treeselect';
-import '@riophae/vue-treeselect/dist/vue-treeselect.css';
-
-export default {
-  name: 'User',
-  dicts: ['sys_normal_disable'],
-  components: { Treeselect },
-  data() {
-    return {
-      user: this.$store.state.user,
-      // 选中数组
-      ids: [],
-      // 非单个禁用
-      single: true,
-      // 非多个禁用
-      multiple: true,
-      // 显示搜索条件
-      showSearch: true,
-      // 总条数
-      total: 0,
-      // 用户表格数据
-      userList: null,
-      // 弹出层标题
-      title: '',
-      // 部门树选项
-      deptOptions: undefined,
-      // 是否显示弹出层
-      open: false,
-      // 部门名称
-      deptName: undefined,
-      // 默认密码
-      initPassword: undefined,
-      // 日期范围
-      dateRange: [],
-      // 岗位选项
-      postOptions: [],
-      // 角色选项
-      roleOptions: [],
-      // 表单参数
-      form: {},
-      defaultProps: {
-        children: 'children',
-        label: 'label'
-      },
-      // 用户导入参数
-      upload: {
-        // 是否显示弹出层(用户导入)
-        open: false,
-        // 弹出层标题(用户导入)
+  import { listUser, getUser, delUser, addUser, updateUser, resetUserPwd, changeUserStatus, deptTreeSelect } from '@/api/system/user';
+  import { getToken } from '@/utils/auth';
+  import Treeselect from '@riophae/vue-treeselect';
+  import '@riophae/vue-treeselect/dist/vue-treeselect.css';
+  export default {
+    name: 'User',
+    dicts: ['sys_normal_disable'],
+    components: { Treeselect },
+    data() {
+      return {
+        user: this.$store.state.user,
+        // 选中数组
+        ids: [],
+        // 非单个禁用
+        single: true,
+        // 非多个禁用
+        multiple: true,
+        // 显示搜索条件
+        showSearch: true,
+        // 总条数
+        total: 0,
+        // 用户表格数据
+        userList: null,
+        // 弹出层标题
         title: '',
-        // 是否禁用上传
-        isUploading: false,
-        // 是否更新已经存在的用户数据
-        updateSupport: 0,
-        // 设置上传的请求头部
-        headers: { Authorization: 'Bearer ' + getToken() },
-        // 上传的地址
-        url: process.env.VUE_APP_BASE_API + '/system/user/importData'
-      },
-      // 查询参数
-      queryParams: {
-        pageNum: 1,
-        pageSize: 10,
-        userName: undefined,
-        phonenumber: undefined,
-        status: undefined,
-        deptId: undefined,
-        orderByColumn: 'create_time',
-        isAsc: 'desc'
-      },
-      // 表单校验
-      rules: {
-        userName: [
-          { required: true, message: '账号不能为空', trigger: 'blur' },
-          { min: 2, max: 20, message: '账号长度必须介于 2 和 20 之间', trigger: 'blur' }
-        ],
-        nickName: [{ required: true, message: '姓名不能为空', trigger: 'blur' }],
-        password: [
-          { required: true, message: '密码不能为空', trigger: 'blur' },
-          { min: 5, max: 20, message: '用户密码长度必须介于 5 和 20 之间', trigger: 'blur' }
-        ],
-        email: [
-          {
+        // 部门树选项
+        deptOptions: undefined,
+        // 是否显示弹出层
+        open: false,
+        // 部门名称
+        deptName: undefined,
+        // 默认密码
+        initPassword: undefined,
+        // 日期范围
+        dateRange: [],
+        // 岗位选项
+        postOptions: [],
+        // 角色选项
+        roleOptions: [],
+        // 表单参数
+        form: {},
+        defaultProps: {
+          children: 'children',
+          label: 'label'
+        },
+        // 用户导入参数
+        upload: {
+          // 是否显示弹出层(用户导入)
+          open: false,
+          // 弹出层标题(用户导入)
+          title: '',
+          // 是否禁用上传
+          isUploading: false,
+          // 是否更新已经存在的用户数据
+          updateSupport: 0,
+          // 设置上传的请求头部
+          headers: { Authorization: 'Bearer ' + getToken() },
+          // 上传的地址
+          url: process.env.VUE_APP_BASE_API + '/system/user/importData'
+        },
+        // 查询参数
+        queryParams: {
+          pageNum: 1,
+          pageSize: 10,
+          userName: undefined,
+          phonenumber: undefined,
+          status: undefined,
+          deptId: undefined,
+          orderByColumn: 'create_time',
+          isAsc: 'desc'
+        },
+        // 表单校验
+        rules: {
+          userName: [
+            { required: true, message: '账号不能为空', trigger: 'blur' },
+            { min: 2, max: 20, message: '账号长度必须介于 2 和 20 之间', trigger: 'blur' }
+          ],
+          nickName: [{ required: true, message: '姓名不能为空', trigger: 'blur' }],
+          password: [
+            { required: true, message: '密码不能为空', trigger: 'blur' },
+            { min: 5, max: 20, message: '用户密码长度必须介于 5 和 20 之间', trigger: 'blur' }
+          ],
+          email: [{
             type: 'email',
             message: '请输入正确的邮箱地址',
             trigger: ['blur', 'change']
-          }
-        ],
-        phonenumber: [
-          { required: true, message: '手机号不能为空', trigger: 'blur' },
-          {
-            pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
-            message: '请输入正确的手机号码',
-            trigger: 'blur'
-          }
-        ]
+          }],
+          phonenumber: [
+            { required: true, message: '手机号不能为空', trigger: 'blur' },
+            {
+              pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
+              message: '请输入正确的手机号码',
+              trigger: 'blur'
+            }
+          ]
+        }
+      };
+    },
+    watch: {
+      // 根据名称筛选部门树
+      deptName(val) {
+        this.$refs.tree.filter(val);
       }
-    };
-  },
-  watch: {
-    // 根据名称筛选部门树
-    deptName(val) {
-      this.$refs.tree.filter(val);
-    }
-  },
-  created() {
-    this.getList();
-    this.getDeptTree();
-    this.getConfigKey('sys.user.initPassword').then((response) => {
-      this.initPassword = response.msg;
-    });
-  },
-  methods: {
-    /** 查询用户列表 */
-    getList() {
-      listUser(this.addDateRange(this.queryParams, this.dateRange)).then((response) => {
-        this.userList = response.rows;
-        this.total = response.total;
-      });
     },
-    /** 查询部门下拉树结构 */
-    getDeptTree() {
-      deptTreeSelect().then((response) => {
-        this.deptOptions = response.data;
+    created() {
+      this.getList();
+      this.getDeptTree();
+      this.getConfigKey('sys.user.initPassword').then((response) => {
+        this.initPassword = response.msg;
       });
     },
-    // 筛选节点
-    filterNode(value, data) {
-      if (!value) return true;
-      return data.label.indexOf(value) !== -1;
-    },
-    // 节点单击事件
-    handleNodeClick(data) {
-      this.queryParams.deptId = data.id;
-      this.handleQuery();
-    },
-    // 用户状态修改
-    handleStatusChange(row) {
-      let text = row.status === '0' ? '启用' : '停用';
-      this.$modal
-        .confirm('确认要' + text + '"' + row.userName + '"用户吗?')
-        .then(function () {
-          return changeUserStatus(row.userId, row.status);
-        })
-        .then(() => {
-          this.$modal.msgSuccess(text + '成功');
-        })
-        .catch(function () {
-          row.status = row.status === '0' ? '1' : '0';
+    methods: {
+      /** 查询用户列表 */
+      getList() {
+        listUser(this.addDateRange(this.queryParams, this.dateRange)).then((response) => {
+          this.userList = response.rows;
+          this.total = response.total;
         });
-    },
-    // 取消按钮
-    cancel() {
-      this.open = false;
-      this.reset();
-    },
-    // 表单重置
-    reset() {
-      this.form = {
-        userId: undefined,
-        deptId: undefined,
-        userName: undefined,
-        nickName: undefined,
-        password: undefined,
-        phonenumber: undefined,
-        email: undefined,
-        sex: undefined,
-        status: '0',
-        remark: undefined,
-        postIds: [],
-        roleIds: []
-      };
-      this.resetForm('form');
-    },
-    /** 搜索按钮操作 */
-    handleQuery() {
-      this.queryParams.pageNum = 1;
-      this.getList();
-    },
-    /** 重置按钮操作 */
-    resetQuery() {
-      this.dateRange = [];
-      this.resetForm('queryForm');
-      this.handleQuery();
-    },
-    // 多选框选中数据
-    handleSelectionChange(selection) {
-      this.ids = selection.map((item) => item.userId);
-      this.single = selection.length != 1;
-      this.multiple = !selection.length;
-    },
-    // 更多操作触发
-    handleCommand(command, row) {
-      switch (command) {
+      },
+      /** 查询部门下拉树结构 */
+      getDeptTree() {
+        deptTreeSelect().then((response) => {
+          this.deptOptions = response.data;
+        });
+      },
+      // 筛选节点
+      filterNode(value, data) {
+        if (!value) return true;
+        return data.label.indexOf(value) !== -1;
+      },
+      // 节点单击事件
+      handleNodeClick(data) {
+        this.queryParams.deptId = data.id;
+        this.handleQuery();
+      },
+      // 用户状态修改
+      handleStatusChange(row) {
+        let text = row.status === '0' ? '启用' : '停用';
+        this.$modal
+          .confirm('确认要' + text + '"' + row.userName + '"用户吗?')
+          .then(function () {
+            return changeUserStatus(row.userId, row.status);
+          })
+          .then(() => {
+            this.$modal.msgSuccess(text + '成功');
+          })
+          .catch(function () {
+            row.status = row.status === '0' ? '1' : '0';
+          });
+      },
+      // 取消按钮
+      cancel() {
+        this.open = false;
+        this.reset();
+      },
+      // 表单重置
+      reset() {
+        this.form = {
+          userId: undefined,
+          deptId: undefined,
+          userName: undefined,
+          nickName: undefined,
+          password: undefined,
+          phonenumber: undefined,
+          email: undefined,
+          sex: undefined,
+          status: '0',
+          remark: undefined,
+          postIds: [],
+          roleIds: []
+        };
+        this.resetForm('form');
+      },
+      /** 搜索按钮操作 */
+      handleQuery() {
+        this.queryParams.pageNum = 1;
+        this.getList();
+      },
+      /** 重置按钮操作 */
+      resetQuery() {
+        this.dateRange = [];
+        this.resetForm('queryForm');
+        this.handleQuery();
+      },
+      // 多选框选中数据
+      handleSelectionChange(selection) {
+        this.ids = selection.map((item) => item.userId);
+        this.single = selection.length != 1;
+        this.multiple = !selection.length;
+      },
+      // 更多操作触发
+      handleCommand(command, row) {
+        switch (command) {
         case 'handleResetPwd':
           this.handleResetPwd(row);
           break;
@@ -412,126 +399,125 @@ export default {
           break;
         default:
           break;
-      }
-    },
-    /** 新增按钮操作 */
-    handleAdd() {
-      this.reset();
-      this.open = true;
-      this.title = '添加用户';
-      getUser().then((response) => {
-        this.postOptions = response.posts;
-        this.roleOptions = response.roles;
-        this.form.password = this.initPassword;
-      });
-    },
-    /** 修改按钮操作 */
-    handleUpdate(row) {
-      this.reset();
-      this.open = true;
-      this.title = '修改用户';
-      const userId = row.userId || this.ids;
-      getUser(userId).then((response) => {
-        this.form = response.data;
-        this.postOptions = response.posts;
-        this.roleOptions = response.roles;
-        this.form.postIds = response.postIds;
-        this.form.roleIds = response.roleIds;
-        this.form.password = '';
-      });
-    },
-    /** 重置密码按钮操作 */
-    handleResetPwd(row) {
-      this.$prompt('请输入"' + row.userName + '"的新密码', '提示', {
-        confirmButtonText: '确定',
-        cancelButtonText: '取消',
-        closeOnClickModal: false,
-        inputPattern: /^.{5,20}$/,
-        inputErrorMessage: '用户密码长度必须介于 5 和 20 之间'
-      })
-        .then(({ value }) => {
-          resetUserPwd(row.userId, value).then((response) => {
-            this.$modal.msgSuccess('修改成功,新密码是:' + value);
-          });
-        })
-        .catch(() => {});
-    },
-    /** 分配角色操作 */
-    handleAuthRole: function (row) {
-      const userId = row.userId;
-      this.$router.push('/system/user-auth/role/' + userId);
-    },
-    /** 提交按钮 */
-    submitForm: function () {
-      this.$refs['form'].validate((valid) => {
-        if (valid) {
-          if (this.form.userId != undefined) {
-            updateUser(this.form).then((response) => {
-              this.$modal.msgSuccess('修改成功');
-              this.open = false;
-              this.getList();
-            });
-          } else {
-            addUser(this.form).then((response) => {
-              this.$modal.msgSuccess('新增成功');
-              this.open = false;
-              this.getList();
+        }
+      },
+      /** 新增按钮操作 */
+      handleAdd() {
+        this.reset();
+        this.open = true;
+        this.title = '添加用户';
+        getUser().then((response) => {
+          this.postOptions = response.posts;
+          this.roleOptions = response.roles;
+          this.form.password = this.initPassword;
+        });
+      },
+      /** 修改按钮操作 */
+      handleUpdate(row) {
+        this.reset();
+        this.open = true;
+        this.title = '修改用户';
+        const userId = row.userId || this.ids;
+        getUser(userId).then((response) => {
+          this.form = response.data;
+          this.postOptions = response.posts;
+          this.roleOptions = response.roles;
+          this.form.postIds = response.postIds;
+          this.form.roleIds = response.roleIds;
+          this.form.password = '';
+        });
+      },
+      /** 重置密码按钮操作 */
+      handleResetPwd(row) {
+        this.$prompt('请输入"' + row.userName + '"的新密码', '提示', {
+            confirmButtonText: '确定',
+            cancelButtonText: '取消',
+            closeOnClickModal: false,
+            inputPattern: /^.{5,20}$/,
+            inputErrorMessage: '用户密码长度必须介于 5 和 20 之间'
+          })
+          .then(({ value }) => {
+            resetUserPwd(row.userId, value).then((response) => {
+              this.$modal.msgSuccess('修改成功,新密码是:' + value);
             });
+          })
+          .catch(() => {});
+      },
+      /** 分配角色操作 */
+      handleAuthRole: function (row) {
+        const userId = row.userId;
+        this.$router.push('/system/user-auth/role/' + userId);
+      },
+      /** 提交按钮 */
+      submitForm: function () {
+        this.$refs['form'].validate((valid) => {
+          if (valid) {
+            if (this.form.userId != undefined) {
+              updateUser(this.form).then((response) => {
+                this.$modal.msgSuccess('修改成功');
+                this.open = false;
+                this.getList();
+              });
+            } else {
+              addUser(this.form).then((response) => {
+                this.$modal.msgSuccess('新增成功');
+                this.open = false;
+                this.getList();
+              });
+            }
           }
-        }
-      });
-    },
-    /** 删除按钮操作 */
-    handleDelete(row) {
-      const userIds = row.userId || this.ids;
-      this.$modal
-        .confirm('是否确认删除?')
-        .then(function () {
-          return delUser(userIds);
-        })
-        .then(() => {
-          this.getList();
-          this.$modal.msgSuccess('删除成功');
-        })
-        .catch(() => {});
-    },
-    /** 导出按钮操作 */
-    handleExport() {
-      this.download(
-        'system/user/export',
-        {
-          ...this.queryParams
-        },
-        `user_${new Date().getTime()}.xlsx`
-      );
-    },
-    /** 导入按钮操作 */
-    handleImport() {
-      this.upload.title = '用户导入';
-      this.upload.open = true;
-    },
-    /** 下载模板操作 */
-    importTemplate() {
-      this.download('system/user/importTemplate', {}, `user_template_${new Date().getTime()}.xlsx`);
-    },
-    // 文件上传中处理
-    handleFileUploadProgress(event, file, fileList) {
-      this.upload.isUploading = true;
-    },
-    // 文件上传成功处理
-    handleFileSuccess(response, file, fileList) {
-      this.upload.open = false;
-      this.upload.isUploading = false;
-      this.$refs.upload.clearFiles();
-      this.$alert("<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" + response.msg + '</div>', '导入结果', {
-        dangerouslyUseHTMLString: true
-      });
-      this.getList();
-    },
-    // 提交上传文件
-    submitFileForm() {
-      this.$refs.upload.submit();
+        });
+      },
+      /** 删除按钮操作 */
+      handleDelete(row) {
+        const userIds = row.userId || this.ids;
+        this.$modal
+          .confirm('是否确认删除?')
+          .then(function () {
+            return delUser(userIds);
+          })
+          .then(() => {
+            this.getList();
+            this.$modal.msgSuccess('删除成功');
+          })
+          .catch(() => {});
+      },
+      /** 导出按钮操作 */
+      handleExport() {
+        this.download(
+          'system/user/export', {
+            ...this.queryParams
+          },
+          `user_${new Date().getTime()}.xlsx`
+        );
+      },
+      /** 导入按钮操作 */
+      handleImport() {
+        this.upload.title = '用户导入';
+        this.upload.open = true;
+      },
+      /** 下载模板操作 */
+      importTemplate() {
+        this.download('system/user/importTemplate', {}, `user_template_${new Date().getTime()}.xlsx`);
+      },
+      // 文件上传中处理
+      handleFileUploadProgress(event, file, fileList) {
+        this.upload.isUploading = true;
+      },
+      // 文件上传成功处理
+      handleFileSuccess(response, file, fileList) {
+        this.upload.open = false;
+        this.upload.isUploading = false;
+        this.$refs.upload.clearFiles();
+        this.$alert("<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" + response.msg + '</div>', '导入结果', {
+          dangerouslyUseHTMLString: true
+        });
+        this.getList();
+      },
+      // 提交上传文件
+      submitFileForm() {
+        this.$refs.upload.submit();
+      }
     }
-  }
-};
+  };
 </script>

+ 89 - 0
admin-ui/src/views/work/news/edit.vue

@@ -0,0 +1,89 @@
+<template>
+  <div class="cmain">
+    <el-form ref="form" :model="form" :rules="rules" label-width="100px">
+      <el-row>
+        <el-col :span="16">
+          <el-form-item label="标题" prop="title">
+            <el-input v-model="form.title" placeholder="请输入标题" clearable maxlength="30" show-word-limit />
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="类型" prop="type">
+            <el-select v-model="form.type" placeholder="请选择" clearable>
+              <el-option v-for="dict in dict.type.news_type" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-form-item label="内容" prop="contents">
+        <editor v-model="form.contents" placeholder="请输入内容"></editor>
+      </el-form-item>
+      <el-form-item label="状态" prop="state">
+        <el-select v-model="form.state" placeholder="请选择">
+          <el-option label="正常" :value="0"></el-option>
+          <el-option label="停用" :value="1"></el-option>
+        </el-select>
+      </el-form-item>
+    </el-form>
+    <div class="mfooter">
+      <el-button type="primary" @click="submitForm">确 定</el-button>
+      <el-button @click="$layer.close(layerid)">取 消</el-button>
+    </div>
+  </div>
+</template>
+
+<script>
+  export default {
+    dicts: ['news_type'],
+    data() {
+      return {
+        form: { state: 0 },
+        rules: {
+          title: [{ required: true, message: "标题不能为空", trigger: "blur" }],
+          type: [{ required: true, message: "类型不能为空", trigger: "blur" }],
+          contents: [{ required: true, message: "内容不能为空", trigger: "blur" }],
+          state: [{ required: true, message: "状态不能为空", trigger: "blur" }],
+        }
+      };
+    },
+    props: {
+      param: {
+        type: Object,
+        default: () => {
+          return {};
+        }
+      },
+      layerid: {
+        type: String
+      }
+    },
+    mounted() {
+      if (this.param.id) {
+        this.ajax({ url: '/work/news/detail/' + this.param.id }).then(response => {
+          this.form = response.data;
+        });
+      }
+    },
+    methods: {
+      submitForm() {
+        this.$refs["form"].validate(valid => {
+          if (valid) {
+            if (this.form.id) {
+              this.ajax({ method: 'post', url: '/work/news/edit', data: this.form }).then(response => {
+                this.$modal.msgSuccess("修改成功");
+                this.$layer.close(this.layerid);
+                this.$parent.getList();
+              });
+            } else {
+              this.ajax({ method: 'post', url: '/work/news/add', data: this.form }).then(response => {
+                this.$modal.msgSuccess("新增成功");
+                this.$layer.close(this.layerid);
+                this.$parent.getList();
+              });
+            }
+          }
+        });
+      }
+    }
+  };
+</script>

+ 115 - 0
admin-ui/src/views/work/news/index.vue

@@ -0,0 +1,115 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" @submit.native.prevent v-show="showSearch">
+      <el-form-item label="标题" prop="title">
+        <el-input v-model="queryParams.title" placeholder="请输入标题" @keyup.enter.native="handleQuery" clearable />
+      </el-form-item>
+      <el-form-item label="类型" prop="type">
+        <el-select v-model="queryParams.type" placeholder="请选择" class="se" clearable>
+          <el-option v-for="dict in dict.type.news_type" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="状态" prop="state">
+        <el-select v-model="queryParams.state" placeholder="状态" class="se" clearable>
+          <el-option value="0" label="启用"></el-option>
+          <el-option value="1" label="禁用"></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+    <el-row :gutter="10" class="mb8">
+      <el-button type="primary" icon="el-icon-plus" :disabled="ids.length > 0" @click="op('add')" v-hasPermi="['work:news:add']">新增</el-button>
+      <el-button type="success" icon="el-icon-edit" :disabled="ids.length != 1" @click="op('edit',ids)" v-hasPermi="['work:news:edit']">修改</el-button>
+      <el-button type="danger" icon="el-icon-delete" :disabled="ids.length == 0" @click="del" v-hasPermi="['work:news:remove']">删除{{ids.length>0?'('+ids.length+')':''}}</el-button>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table :data="response.rows" border @selection-change="selects" height="calc(100vh - 270px)">
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="标题" align="left" prop="title" />
+      <el-table-column label="类型" align="center" prop="type" width="150" />
+      <el-table-column label="状态" align="center" prop="state" width="140">
+        <template slot-scope="scope">
+          <el-tag type="success" v-if="scope.row.state == 0">启用</el-tag>
+          <el-tag type="danger" v-if="scope.row.state == 1">停用</el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="创建时间" align="center" prop="createTime" width="200" />
+      <el-table-column label="操作" align="center" width="200">
+        <template slot-scope="scope">
+          <el-button size="mini" type="text" icon="el-icon-edit" @click="op('edit',scope.row)" v-hasPermi="['work:news:edit']">修改</el-button>
+          <el-button size="mini" type="text" icon="el-icon-delete" @click="del(scope.row)" v-hasPermi="['work:news:remove']">删除</el-button>
+        </template>
+      </el-table-column>
+      <template slot="empty">
+        <el-empty></el-empty>
+      </template>
+    </el-table>
+    <pagination v-if="response.total>0" :total="response.total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" />
+  </div>
+</template>
+
+<script>
+  import edit from './edit'
+  export default {
+    name: "News",
+    dicts: ['news_type'],
+    data() {
+      return {
+        ids: [],
+        showSearch: true,
+        response: {},
+        queryParams: {
+          pageNum: 1,
+          pageSize: 10,
+          title: null,
+          type: null,
+          state: null,
+          orderByColumn: 'id',
+          isAsc: 'desc'
+        }
+      };
+    },
+    created() {
+      this.getList();
+    },
+    methods: {
+      getList() {
+        this.ajax({ url: '/work/news/list', data: this.queryParams }).then(response => {
+          this.response = response;
+        });
+      },
+      handleQuery() {
+        this.queryParams.pageNum = 1;
+        this.getList();
+      },
+      resetQuery() {
+        this.resetForm("queryForm");
+        this.handleQuery();
+      },
+      selects(rows) {
+        this.ids = rows.map(item => item.id)
+      },
+      op(tag, row) {
+        if (tag == 'add') {
+          this.iframe({ obj: edit, param: {}, title: '新增', width: '58%', height: '73%' });
+        }
+        if (tag == 'edit') {
+          const id = row.id || this.ids[0];
+          this.iframe({ obj: edit, param: { id: id }, title: '编辑', width: '58%', height: '73%' });
+        }
+      },
+      del(row) {
+        this.$confirm('是否确认删除选中数据?', '警告', { type: 'warning' }).then(() => {
+          this.get({ url: '/work/news/remove/' + (row.id || this.ids) }).then(response => {
+            this.$modal.msgSuccess('删除成功');
+            this.getList();
+          });
+        });
+      }
+    }
+  };
+</script>

+ 2 - 2
admin-ui/src/views/work/project/index.vue

@@ -138,9 +138,9 @@
         //账号状态
         if (tag == 'change') {
           let text = row.state === 0 ? '发布' : '停用';
-          this.$confirm('确认要' + text + '该项目吗?', '警告', { type: 'warning' })
+          this.$confirm('确认要' + text + '该项目吗?,停用后无法再接包', '警告', { type: 'warning' })
             .then(() => {
-              this.post({ url: '/work/project/edit', data: { id: row.id, state: row.state } })
+              this.post({ url: '/work/project/change', data: { id: row.id, state: row.state } })
                 .then((response) => {
                   this.$modal.msgSuccess(text + '成功');
                 })

+ 2 - 2
admin-ui/src/views/work/project/packages/index.vue

@@ -24,7 +24,8 @@
       <el-table-column label="开户行" align="center" prop="bankName" width="150" />
       <el-table-column label="银行卡号" align="center" prop="bankAccount" width="200" />
       <el-table-column label="支付宝账号" align="center" prop="alipay" width="120" />
-      <el-table-column label="接包凭证" align="center" width="130">
+      <el-table-column label="接包日期" align="center" prop="createTime" width="160" />
+      <el-table-column label="接包凭证" align="center" width="130" fixed="right">
         <template slot-scope="scope">
           <el-tag type="danger" v-if="scope.row.audit == 0">待上传</el-tag>
           <el-tag type="info" v-if="scope.row.audit == 1">待审核</el-tag>
@@ -39,7 +40,6 @@
           </el-popover>
         </template>
       </el-table-column>
-      <el-table-column label="接包日期" align="center" prop="createTime" width="160" />
       <el-table-column label="操作" align="center" width="250" fixed="right">
         <template slot-scope="scope">
           <el-button size="mini" type="text" icon="el-icon-document" @click="op('contract', scope.row)">查看合同</el-button>

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

@@ -35,8 +35,8 @@ module.exports = {
     proxy: {
       // detail: https://cli.vuejs.org/config/#devserver-proxy
       [process.env.VUE_APP_BASE_API]: {
-        //target: `http://localhost:9191`,
-        target: `http://47.104.228.216/prod-api`,
+        target: `http://localhost:9191`,
+        //target: `http://47.104.228.216/prod-api`,
         changeOrigin: true,
         pathRewrite: {
           ['^' + process.env.VUE_APP_BASE_API]: ''

+ 0 - 149
app/pages/auth/index.vue

@@ -1,149 +0,0 @@
-<template>
-	<view>
-		<view class="tips" v-if="item.isAuthentication === 1">
-			<text class="icon">&#xe600;</text>
-			<text>实名认证成功</text>
-		</view>
-		<view class="tips" v-else>
-			<text class="icon">&#xe634;</text>
-			<text>为保障资金安全,用户需进行实名认证,请务必认真填写</text>
-		</view>
-		<view class="main">
-			<view v-if="step === 1">
-				<u-divider text="本人二代身份证"></u-divider>
-				<view class="r">
-					<view class="r50">
-						<card v-model="item.p1" text="点击拍摄/上传人像面" icon="&#xe690;" :read="item.isAuthentication === 1" side="face" @success="success"></card>
-					</view>
-					<view class="r50">
-						<card v-model="item.p2" text="点击拍摄/上传国徽面" icon="&#xe61e;" :read="item.isAuthentication === 1" side="back" @success="success"></card>
-					</view>
-				</view>
-			</view>
-			<view v-else>
-				<view class="form">
-					<view class="form_group">
-						<view class="lable re">姓名</view>
-						<input type="text" placeholder="请输入姓名" v-model="item.name" :disabled="true" />
-					</view>
-					<view class="form_group">
-						<view class="lable re">身份证</view>
-						<input type="text" placeholder="请输入身份证" v-model="item.idCard" :disabled="true" />
-					</view>
-				</view>
-				<view class="form" style="margin-top: 15px">
-					<view class="form_group">
-						<view class="lable re">手机号</view>
-						<input type="text" placeholder="请输入手机号" v-model="item.phone" />
-					</view>
-					<view class="form_group">
-						<view class="lable re">支付宝</view>
-						<input type="text" placeholder="请输入支付宝账号" v-model="item.alipay" />
-					</view>
-				</view>
-			</view>
-			<view class="form" v-if="item.isAuthentication === 1" style="margin-top: 10px">
-				<view class="form_group">
-					<view class="lable">姓名</view>
-					<input type="text" v-model="item.name" :disabled="true" />
-				</view>
-				<view class="form_group">
-					<view class="lable">身份证</view>
-					<input type="text" v-model="item.idCard" :disabled="true" />
-				</view>
-				<view class="form_group">
-					<view class="lable">有效期</view>
-					<input type="text" v-model="item.endDate" :disabled="true" />
-				</view>
-			</view>
-			<button class="btn" @click="next()" v-if="step === 1 && item.isAuthentication != 1">下一步</button>
-			<button class="btn" @click="save()" v-if="step === 2 && item.isAuthentication != 1">确定</button>
-		</view>
-	</view>
-</template>
-
-<script>
-export default {
-	data() {
-		return {
-			step: 1,
-			item: {}
-		};
-	},
-	onLoad() {
-		this.getData();
-	},
-	methods: {
-		getData() {
-			this.http.request({
-				url: '/app/user/info',
-				data: this.item,
-				success: (res) => {
-					this.item = res.data.data;
-					if (this.item.isAuthentication === 1) {
-						uni.setNavigationBarTitle({ title: '我的认证' });
-					}
-				}
-			});
-		},
-		success(res) {
-			if (res.side == 'face') {
-				this.item.name = res.data.name;
-				this.item.idCard = res.data.num;
-				this.item.sex = res.data.sex;
-				this.item.address = res.data.address;
-				this.item.nationality = res.data.nationality;
-				this.item.birth = res.data.birth;
-			} else {
-				this.item.endDate = res.data.end_date;
-			}
-		},
-		next() {
-			if (!this.item.name) {
-				uni.showModal({ content: '请上传身份证人像面', showCancel: false });
-				return;
-			}
-			if (!this.item.endDate) {
-				uni.showModal({ content: '请上传身份证国徽面', showCancel: false });
-				return;
-			}
-			this.step = 2;
-		},
-		save() {
-			let rule = [
-				{ name: 'name', checkType: 'notnull', errorMsg: '请输入姓名' },
-				{ name: 'idCard', checkType: 'notnull', errorMsg: '请输入身份证' },
-				{ name: 'p1', checkType: 'notnull', errorMsg: '请上传身份证人面像' },
-				{ name: 'p2', checkType: 'notnull', errorMsg: '请上传身份证人徽面' },
-				{ name: 'phone', checkType: 'phone', errorMsg: '请请输入手机号' },
-				{ name: 'alipay', checkType: 'notnull', errorMsg: '请输入支付宝账号' }
-			];
-			if (!this.verify.check(this.item, rule)) {
-				uni.showModal({ content: this.verify.error, showCancel: false });
-				return false;
-			}
-			this.http.request({
-				url: '/app/user/auth',
-				data: this.item,
-				method: 'POST',
-				success: (res) => {
-					uni.showModal({
-						title: '提示',
-						content: '实名认证成功。',
-						showCancel: false,
-						success: (res) => {
-							uni.navigateBack();
-						}
-					});
-				}
-			});
-		}
-	}
-};
-</script>
-
-<style lang="scss">
-.btn {
-	margin-top: 30px;
-}
-</style>

+ 0 - 191
app/pages/company/index.vue

@@ -1,191 +0,0 @@
-<template>
-	<view>
-		<view class="tab">
-			<u-tabs :list="tab" :current="current" @click="click"></u-tabs>
-		</view>
-		<view class="list">
-			<view class="item" v-for="(item, index) in list" :key="index">
-				<view class="title">{{ item.companyName }}</view>
-				<view class="op">
-					<text>{{ item.createTime }}</text>
-					<text class="add" @click="del(item)" v-if="current == 0">点击关联</text>
-					<text class="del" @click="del(item)" v-else>解除</text>
-				</view>
-			</view>
-			<view class="loading" v-if="loadMore"><u-loadmore :status="loadMore ? 'loading' : 'nomore'" /></view>
-			<u-empty v-if="!loadMore && list.length == 0" text="尚未关联公司"></u-empty>
-		</view>
-		<view class="footer">
-			<view class="db"><button class="btn" @click="show = true">手动关联</button></view>
-		</view>
-		<u-action-sheet round="20" :actions="actions" @select="selectClick" cancelText="取消" :show="show" @close="show = false"></u-action-sheet>
-	</view>
-</template>
-
-<script>
-export default {
-	data() {
-		return {
-			tab: [{ name: '企业大厅' }, { name: '我的关联' }],
-			show: false,
-			current: 0,
-			actions: [{ name: '扫码关联' }, { name: '搜索企业' }],
-			list: [],
-			param: { pageNum: 1, pageSize: 10 },
-			loadMore: true
-		};
-	},
-	onLoad(e) {
-		this.getData();
-		uni.$on('company', (res) => {
-			this.refresh();
-		});
-	},
-	methods: {
-		getData() {
-			this.http.request({
-				url: this.current == 0 ? '/app/company/list' : '/app/relate/list',
-				data: this.param,
-				loading: 'false',
-				success: (res) => {
-					this.loadMore = res.data.pages > this.param.pageNum ? true : false;
-					res.data.rows.forEach((item) => {
-						item.createTime = uni.$u.timeFrom(Date.parse(item.createTime));
-						this.list.push(item);
-					});
-				}
-			});
-		},
-		click(e) {
-			this.current = e.index;
-			this.param.state = e.index === 1 ? 0 : 1;
-			this.refresh();
-		},
-		selectClick(e) {
-			if (e.name == '搜索企业') {
-				uni.navigateTo({ url: '/pages/company/search' });
-			} else {
-				uni.scanCode({
-					success: (res) => {
-						this.http.request({
-							url: '/app/relate/add',
-							data: { companyId: res.result, way: '扫码关联' },
-							method: 'POST',
-							success: (res) => {
-								uni.showModal({
-									title: '提示',
-									content: '关联成功',
-									showCancel: false,
-									success: (res) => {
-										this.refresh();
-									}
-								});
-							}
-						});
-					},
-					fail: (res) => {}
-				});
-			}
-		},
-		del(item) {
-			uni.showModal({
-				title: '提示',
-				content: this.current == 0 ? '确定关联该企业?' : '确定解除该企业关联?',
-				success: (res) => {
-					if (res.confirm) {
-						if (this.current == 0) {
-							this.http.request({
-								url: '/app/relate/add',
-								data: { companyId: item.id, way: '手动关联' },
-								method: 'POST',
-								success: (res) => {
-									uni.showModal({
-										title: '提示',
-										content: '关联成功',
-										showCancel: false,
-										success: (res) => {
-											this.current = 1;
-											this.refresh();
-										}
-									});
-								}
-							});
-						} else {
-							this.http.request({
-								url: '/app/relate/remove',
-								data: { companyId: item.companyId },
-								method: 'POST',
-								success: (res) => {
-									uni.showToast({ title: '解除成功' });
-									this.list.splice(this.list.indexOf(item), 1);
-								}
-							});
-						}
-					}
-				}
-			});
-		},
-		//刷新数据
-		refresh() {
-			this.loadMore = true;
-			this.param.pageNum = 1;
-			this.list = [];
-			this.getData();
-		}
-	},
-	//下拉刷新
-	onPullDownRefresh() {
-		setTimeout(() => {
-			this.refresh();
-			uni.stopPullDownRefresh();
-		}, 1000);
-	},
-	//上拉加载
-	onReachBottom() {
-		if (this.loadMore) {
-			this.param.pageNum++;
-			this.getData();
-		}
-	}
-};
-</script>
-
-<style lang="scss">
-.list {
-	padding: 10px 10px 90px 10px;
-	.item {
-		background-color: white;
-		padding: 15px;
-		border-radius: 5px;
-		margin-bottom: 10px;
-		.title {
-			padding-bottom: 10px;
-		}
-		.op {
-			border-top: 1px solid $line;
-			padding-top: 10px;
-			color: #676767;
-			font-size: 14px;
-			.del {
-				float: right;
-				color: #f44336;
-			}
-			.add {
-				float: right;
-				color: $main-color;
-			}
-		}
-	}
-}
-.footer {
-	position: fixed;
-	width: 100%;
-	bottom: 0px;
-	padding-bottom: 13px;
-	background-color: white;
-	border-top: 1px solid $line;
-	.db {
-		padding: 15px 35px 10px 35px;
-	}
-}
-</style>

+ 0 - 107
app/pages/company/search.vue

@@ -1,107 +0,0 @@
-<template>
-	<view>
-		<view class="search"><u-search placeholder="企业名称" v-model="companyName" :showAction="false" @search="getData()" @clear="clear()"></u-search></view>
-		<view class="list">
-			<view class="item" v-for="(item, index) in list" :key="index" @click="detail(item)">
-				<text>{{ item.companyName }}</text>
-				<text class="icon">&#xe62b;</text>
-			</view>
-			<view class="loading" v-if="loadMore"><u-loadmore :status="loadMore ? 'loading' : 'nomore'" /></view>
-			<u-empty v-if="!loadMore && list.length == 0"></u-empty>
-		</view>
-	</view>
-</template>
-
-<script>
-export default {
-	data() {
-		return {
-			list: [],
-			companyName: '',
-			param: { pageNum: 1, pageSize: 10 },
-			loadMore: false
-		};
-	},
-	watch: {
-		companyName(val) {
-			if (val.length > 3) {
-				this.refresh();
-			}
-		}
-	},
-	methods: {
-		getData() {
-			this.http.request({
-				url: '/app/company/list',
-				data: { companyName: this.companyName },
-				success: (res) => {
-					this.loadMore = res.data.pages > this.param.pageNum ? true : false;
-					res.data.rows.forEach((item) => {
-						this.list.push(item);
-					});
-				}
-			});
-		},
-		detail(item) {
-			uni.showModal({
-				title: '提示',
-				content: '确定关联该企业?',
-				success: (res) => {
-					if (res.confirm) {
-						this.http.request({
-							url: '/app/relate/add',
-							data: { companyId: item.id, way: '手动关联' },
-							method: 'POST',
-							success: (res) => {
-								uni.showModal({
-									title: '提示',
-									content: '关联成功',
-									showCancel: false,
-									success: (res) => {
-										uni.$emit('company');
-										uni.navigateBack();
-									}
-								});
-							}
-						});
-					}
-				}
-			});
-		},
-		clear() {
-			this.list = [];
-		},
-		//刷新数据
-		refresh() {
-			this.loadMore = true;
-			this.param.pageNum = 1;
-			this.list = [];
-			this.getData();
-		}
-	},
-	//上拉加载
-	onReachBottom() {
-		if (this.loadMore) {
-			this.param.pageNum++;
-			this.getData();
-		}
-	}
-};
-</script>
-
-<style lang="scss">
-.search {
-	padding: 12px 20px 12px 20px;
-	background-color: white;
-}
-.list {
-	.item {
-		padding: 17px;
-		background-color: white;
-		margin-top: 10px;
-		.icon {
-			float: right;
-		}
-	}
-}
-</style>

+ 0 - 264
app/pages/index/index.vue

@@ -1,264 +0,0 @@
-<template>
-	<view class="main">
-		<!--轮播图-->
-		<view class="banner">
-			<u-swiper circular :radius="5" :indicator="true" keyName="pic" :list="bannerList" :height="150" class="uni-swiper" @click="click"></u-swiper>
-		</view>
-		<!--通知公告-->
-		<view class="notice">
-			<u-notice-bar color="#848484" :text="noticeList" :step="true" direction="column" mode="link" bgColor="white" speed="300" url="/pages/notice/index"></u-notice-bar>
-		</view>
-		<view class="flow">
-			<!--实名认证-->
-			<view class="item" @click="go('auth')">
-				<view class="out">
-					<view class="int">
-						<view class="icon tb" style="color: rgb(72, 154, 253)">&#xe600;</view>
-						<view class="con">
-							<view class="bt">实名认证</view>
-							<view class="zt">{{ !user.isAuthentication || user.isAuthentication == 0 ? '尚未提交资料' : '已认证' }}</view>
-						</view>
-						<view class="state" v-if="!user.isAuthentication || user.isAuthentication === 0">
-							<view class="go">去认证</view>
-						</view>
-					</view>
-				</view>
-			</view>
-			<!--关联企业-->
-			<view class="item" @click="go('company')">
-				<view class="out">
-					<view class="int">
-						<view class="icon tb" style="color: rgb(250, 178, 46)">&#xe623;</view>
-						<view class="con">
-							<view class="bt">关联企业</view>
-							<view class="zt">{{ !user.isCompany || user.isCompany == 0 ? '尚未关联企业' : '已关联' }} {{ user.isCompany > 0 ? user.isCompany + '家' : '' }}</view>
-						</view>
-						<view class="state" v-if="!user.isCompany || user.isCompany == 0">
-							<view class="go" :style="{ backgroundColor: user.isAuthentication === 1 ? '#5a7afc' : '#d6d6d6' }">去关联</view>
-						</view>
-					</view>
-				</view>
-			</view>
-			<!--电子签约-->
-			<view class="item" @click="go('contract')">
-				<view class="out">
-					<view class="int">
-						<view class="icon tb" style="color: rgb(255, 87, 34)">&#xe6ed;</view>
-						<view class="con">
-							<view class="bt">电子签约</view>
-							<view class="zt">{{ !user.isContract || user.isContract == 0 ? '尚未签约' : '已签约' }}</view>
-						</view>
-						<view class="state">
-							<view class="go" :style="{ backgroundColor: user.isCompany > 0 ? '#5a7afc' : '#d6d6d6' }" v-if="!user.isContract || user.isContract == 0">去签约</view>
-						</view>
-					</view>
-				</view>
-			</view>
-			<!--开始接包-->
-			<view class="item" @click="go('packages')">
-				<view class="out">
-					<view class="int">
-						<view class="icon tb" style="color: rgb(250, 83, 118)">&#xe604;</view>
-						<view class="con">
-							<view class="bt">进入结算</view>
-							<view class="zt">{{ !user.isCompany || user.isCompany == 0 ? '请先签约' : '开始' }}</view>
-						</view>
-						<view class="state">
-							<view class="go" :style="{ backgroundColor: user.isCompany > 0 && user.isContract == 1 ? '#5a7afc' : '#d6d6d6' }" v-if="!user.isCompany || user.isCompany == 0 || user.isContract == 0">进入</view>
-						</view>
-					</view>
-				</view>
-			</view>
-		</view>
-		<u-action-sheet round="20" :actions="actions" @select="selectClick" cancelText="取消" :show="show" @close="show = false"></u-action-sheet>
-		<signature ref="sig" @sign="sign"></signature>
-	</view>
-</template>
-<script>
-	export default {
-		data() {
-			return {
-				ip: this.http.ip,
-				user: {},
-				bannerList: [],
-				noticeList: [],
-				contract: {},
-				show: false,
-				actions: [{ name: '查看合同' }, { name: '去签字' }]
-			};
-		},
-		onShow() {
-			if (this.hasLogin()) {
-				this.getUserInfo();
-			}
-		},
-		onLoad() {
-			this.getData();
-		},
-		methods: {
-			getUserInfo() {
-				this.http.request({
-					url: '/app/user/info',
-					success: (res) => {
-						this.user = res.data.data;
-					}
-				});
-			},
-			getData() {
-				this.http.request({
-					url: '/app/home/index',
-					success: (res) => {
-						this.contract = res.data.data.contract;
-						this.bannerList = res.data.data.bannerList;
-						res.data.data.noticeList.forEach((item) => {
-							this.noticeList.push(item.title);
-						});
-					}
-				});
-			},
-			go(url) {
-				if (this.hasLogin()) {
-					if (url == 'auth') {
-						uni.navigateTo({ url: '/pages/auth/index' });
-					}
-					if (url == 'company' && this.user.isAuthentication === 1) {
-						uni.navigateTo({ url: '/pages/company/index' });
-					}
-					if (url == 'packages' && this.user.isCompany > 0 && this.user.isContract == 1) {
-						uni.navigateTo({ url: '/pages/packages/index' });
-					}
-					if (url == 'contract' && this.user.isContract == 1) {
-						this.look();
-					}
-					if (url == 'contract' && this.user.isContract == 0) {
-						this.show = true;
-					}
-				} else {
-					uni.navigateTo({ url: '/pages/user/login' });
-				}
-			},
-			selectClick(e) {
-				if (e.name == '查看合同') {
-					this.look();
-				} else {
-					this.$refs.sig.getSyncSignature();
-				}
-			},
-			//查看合同
-			look() {
-				uni.showLoading({ title: '正在打开合同...', mask: true });
-				uni.downloadFile({
-					url: this.user.isContract == 0 ? this.ip + this.contract.url : this.ip + '/app/contract/look',
-					header: { Authorization: this.getUser().token },
-					success: (res) => {
-						uni.openDocument({
-							filePath: res.tempFilePath,
-							showMenu: true,
-							success: (res) => {
-								uni.hideLoading();
-							},
-							fail: (res) => {
-								uni.hideLoading();
-								uni.showModal({ title: '提示', content: '打开合同失败', showCancel: false });
-							}
-						});
-					},
-					fail: (res) => {
-						uni.hideLoading();
-					}
-				});
-			},
-			//电子签名
-			sign(val) {
-				this.http.request({
-					url: '/app/contract/add',
-					data: { contractId: this.contract.id, url: val },
-					method: 'POST',
-					success: (res) => {
-						uni.showModal({
-							title: '提示',
-							content: '签约成功',
-							showCancel: false,
-							success: (res) => {
-								this.getUserInfo();
-							}
-						});
-					}
-				});
-			}
-		}
-	};
-</script>
-
-<style lang="scss">
-	.main {
-		padding: 5px 15px 15px 15px;
-	}
-	.banner {}
-	.notice {
-		margin-top: 10px;
-		margin-bottom: -10px;
-	}
-	.flow {
-		padding-top: 20px;
-		.title {
-			font-size: 15px;
-			margin-bottom: 10px;
-		}
-		.item {
-			border-radius: 10px;
-			overflow: hidden;
-			float: left;
-			width: 50%;
-			.out {
-				padding: 5px;
-				.int {
-					padding: 15px;
-					background-color: white;
-					overflow: hidden;
-					border-radius: 9px;
-					text-align: center;
-					.tb {
-						margin: 0 auto;
-						width: 40px;
-						height: 40px;
-						padding: 10px;
-						line-height: 39px;
-						color: $main-color;
-						box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
-						border-radius: 50%;
-						font-size: 27px;
-					}
-					.con {
-						padding-top: 8px;
-						.bt {
-							font-size: 18px;
-						}
-						.zt {
-							font-size: 13px;
-							padding-top: 5px;
-							color: #909090;
-						}
-					}
-					.state {
-						padding-top: 11px;
-						.zt {
-							font-size: 13px;
-							color: $main-color;
-						}
-						.icon {
-							color: #909090;
-						}
-						.go {
-							padding: 5px 12px;
-							font-size: 14px;
-							background-color: #5a7afc;
-							color: white;
-							border-radius: 20px;
-						}
-					}
-				}
-			}
-		}
-	}
-</style>

+ 0 - 256
app/pages/index/index2.vue

@@ -1,256 +0,0 @@
-<template>
-	<view class="main">
-		<!--轮播图-->
-		<view class="banner">
-			<u-swiper circular :radius="5" :indicator="true" keyName="pic" :list="bannerList" :height="150" class="uni-swiper" @click="click"></u-swiper>
-		</view>
-		<!--通知公告-->
-		<view class="notice">
-			<u-notice-bar color="#848484" :text="noticeList" :step="true" direction="column" mode="link" bgColor="white" speed="300" url="/pages/notice/index"></u-notice-bar>
-		</view>
-		<view class="flow">
-			<view class="title">操作流程</view>
-			<!--实名认证-->
-			<view class="item" @click="go('auth')">
-				<view class="icon tb">&#xe600;</view>
-				<view class="con">
-					<view class="bt">实名认证</view>
-					<view class="bor" style="background: linear-gradient(to right, rgb(198 187 250), rgb(251 251 251))"></view>
-					<view class="zt">{{ !user.isAuthentication || user.isAuthentication == 0 ? '尚未提交资料' : '已提交资料' }}</view>
-				</view>
-				<view class="state" v-if="user.isAuthentication === 1">
-					<text class="zt">已认证</text>
-					<text class="icon">&#xe62b;</text>
-				</view>
-				<view class="state" v-else>
-					<view class="go">去认证</view>
-				</view>
-			</view>
-			<!--关联企业-->
-			<view class="item" @click="go('company')">
-				<view class="icon tb">&#xe623;</view>
-				<view class="con">
-					<view class="bt">关联企业</view>
-					<view class="bor" style="background: linear-gradient(to right, #eecce0, rgb(253 253 253))"></view>
-					<view class="zt">{{ !user.isCompany || user.isCompany == 0 ? '尚未关联企业' : '已完成' }}</view>
-				</view>
-				<view class="state" v-if="user.isCompany > 0">
-					<text class="zt">{{ user.isCompany }}家</text>
-					<text class="icon">&#xe62b;</text>
-				</view>
-				<view class="state" v-else>
-					<view class="go" :style="{ backgroundColor: user.isAuthentication === 1 ? '#5a7afc' : '#d6d6d6' }">去关联</view>
-				</view>
-			</view>
-			<!--电子签约-->
-			<view class="item" @click="go('contract')">
-				<view class="icon tb">&#xe6ed;</view>
-				<view class="con">
-					<view class="bt">电子签约</view>
-					<view class="bor" style="background: linear-gradient(to right, #f6f6bf, rgb(246 246 246))"></view>
-					<view class="zt">{{ !user.isContract || user.isContract == 0 ? '尚未签约' : '已签约' }}</view>
-				</view>
-				<view class="state">
-					<view class="go" :style="{ backgroundColor: user.isCompany > 0 ? '#5a7afc' : '#d6d6d6' }" v-if="!user.isContract || user.isContract == 0">去签约</view>
-					<text class="icon" v-if="user.isContract == 1">&#xe62b;</text>
-				</view>
-			</view>
-			<!--开始接包-->
-			<view class="item" @click="go('packages')">
-				<view class="icon tb">&#xe604;</view>
-				<view class="con">
-					<view class="bt">开始接包</view>
-					<view class="bor" style="background: linear-gradient(to right, #c9f1d4, rgb(250 255 252))"></view>
-					<view class="zt">{{ !user.isCompany || user.isCompany == 0 ? '请先完成上一步' : '去接包' }}</view>
-				</view>
-				<view class="state">
-					<view class="go" :style="{ backgroundColor: user.isCompany > 0 && user.isContract == 1 ? '#5a7afc' : '#d6d6d6' }">去接包</view>
-				</view>
-			</view>
-		</view>
-		<u-action-sheet round="20" :actions="actions" @select="selectClick" cancelText="取消" :show="show" @close="show = false"></u-action-sheet>
-		<signature ref="sig" @sign="sign" v-if=""></signature>
-	</view>
-</template>
-<script>
-export default {
-	data() {
-		return {
-			ip: this.http.ip,
-			user: {},
-			bannerList: [],
-			noticeList: [],
-			contract: {},
-			show: false,
-			actions: [{ name: '查看合同' }, { name: '去签字' }]
-		};
-	},
-	onShow() {
-		if (this.hasLogin()) {
-			this.getUserInfo();
-		}
-	},
-	onLoad() {
-		this.getData();
-	},
-	methods: {
-		getUserInfo() {
-			this.http.request({
-				url: '/app/user/info',
-				success: (res) => {
-					this.user = res.data.data;
-				}
-			});
-		},
-		getData() {
-			this.http.request({
-				url: '/app/home/index',
-				success: (res) => {
-					this.contract = res.data.data.contract;
-					this.bannerList = res.data.data.bannerList;
-					res.data.data.noticeList.forEach((item) => {
-						this.noticeList.push(item.title);
-					});
-				}
-			});
-		},
-		go(url) {
-			if (this.hasLogin()) {
-				if (url == 'auth') {
-					uni.navigateTo({ url: '/pages/auth/index' });
-				}
-				if (url == 'company' && this.user.isAuthentication === 1) {
-					uni.navigateTo({ url: '/pages/company/index' });
-				}
-				if (url == 'packages' && this.user.isCompany > 0 && this.user.isContract == 1) {
-					uni.switchTab({ url: '/pages/packages/index' });
-				}
-				if (url == 'contract' && this.user.isContract == 1) {
-					this.look();
-				}
-				if (url == 'contract' && this.user.isContract == 0) {
-					this.show = true;
-				}
-			} else {
-				uni.navigateTo({ url: '/pages/user/login' });
-			}
-		},
-		selectClick(e) {
-			if (e.name == '查看合同') {
-				this.look();
-			} else {
-				this.$refs.sig.getSyncSignature();
-			}
-		},
-		//查看合同
-		look() {
-			uni.showLoading({ title: '正在打开合同...', mask: true });
-			uni.downloadFile({
-				url: this.user.isContract == 0 ? this.ip + this.contract.url : this.ip + '/app/contract/look',
-				header: { Authorization: this.getUser().token },
-				success: (res) => {
-					uni.openDocument({
-						filePath: res.tempFilePath,
-						showMenu: true,
-						success: (res) => {
-							uni.hideLoading();
-						}
-					});
-				},
-				fail: (res) => {
-					uni.hideLoading();
-				}
-			});
-		},
-		//电子签名
-		sign(val) {
-			this.http.request({
-				url: '/app/contract/add',
-				data: { contractId: this.contract.id, url: val },
-				method: 'POST',
-				success: (res) => {
-					uni.showModal({
-						title: '提示',
-						content: '签约成功',
-						showCancel: false,
-						success: (res) => {
-							this.getUserInfo();
-						}
-					});
-				}
-			});
-		}
-	}
-};
-</script>
-
-<style lang="scss">
-.main {
-	padding: 5px 15px 15px 15px;
-}
-.banner {
-}
-.notice {
-	margin-top: 10px;
-}
-.flow {
-	padding-top: 20px;
-	.title {
-		font-size: 15px;
-	}
-	.item {
-		background-color: white;
-		border-radius: 10px;
-		padding: 18px;
-		overflow: hidden;
-		margin-top: 12px;
-		.tb {
-			float: left;
-			padding: 13px;
-			border: 1px solid $main-color;
-			color: $main-color;
-			border-radius: 50%;
-			font-size: 23px;
-		}
-		.con {
-			float: left;
-			padding-left: 20px;
-
-			.bt {
-				font-size: 18px;
-			}
-			.bor {
-				background-color: red;
-				border-radius: 20px;
-				height: 9px;
-				margin-top: -9px;
-				width: 105px;
-				margin-left: -5px;
-			}
-			.zt {
-				font-size: 13px;
-				padding-top: 5px;
-				color: #909090;
-			}
-		}
-		.state {
-			float: right;
-			padding-top: 11px;
-			.zt {
-				font-size: 13px;
-				color: $main-color;
-			}
-			.icon {
-				color: #909090;
-			}
-			.go {
-				padding: 5px 12px;
-				font-size: 14px;
-				background-color: #5a7afc;
-				color: white;
-				border-radius: 20px;
-			}
-		}
-	}
-}
-</style>

+ 0 - 184
app/pages/packages/index.vue

@@ -1,184 +0,0 @@
-<template>
-	<view class="main">
-		<view class="tab">
-			<u-tabs :list="tab" :current="current" @click="click"></u-tabs>
-		</view>
-		<view class="list">
-			<view class="item" v-for="(item, index) in list" :key="index">
-				<view class="it">
-					<view class="lable">项目名称</view>
-					<view class="desc">{{ item.projectName }}</view>
-				</view>
-				<view class="it">
-					<view class="lable">发包公司</view>
-					<view class="desc">{{ item.companyName }}</view>
-				</view>
-				<view class="it">
-					<view class="lable">项目周期</view>
-					<view class="desc">{{ item.startDate }} 至 {{ item.finishDate }}</view>
-				</view>
-				<view class="it">
-					<view class="lable">结算日期</view>
-					<view class="desc">{{ item.balanceDate }}</view>
-				</view>
-				<view class="op">
-					<text>{{ item.createTime }}</text>
-					<text class="add" @click="add(item)" v-if="current == 0">接任务</text>
-					<text class="add" @click="voucher(item)" v-if="current == 1 && item.audit == 0">上传凭证</text>
-					<text class="add" @click="voucher(item)" v-if="current == 1 && item.audit == 1">已上传凭证</text>
-					<text class="add" @click="voucher(item)" v-if="current == 1 && item.audit == 3" style="background-color: #f44336">凭证驳回,请重新上传</text>
-					<text v-if="current == 2" class="state">已完成</text>
-				</view>
-			</view>
-			<view class="loading" v-if="loadMore"><u-loadmore :status="loadMore ? 'loading' : 'nomore'" /></view>
-			<u-empty v-if="!loadMore && list.length == 0"></u-empty>
-		</view>
-		<voucher ref="voucher" @success="success()"></voucher>
-	</view>
-</template>
-
-<script>
-export default {
-	data() {
-		return {
-			show: false,
-			current: 0,
-			tab: [{ name: '待接任务' }, { name: '已接任务' }, { name: '完成任务' }],
-			list: [],
-			param: { pageNum: 1, pageSize: 10, state: 0 },
-			loadMore: true
-		};
-	},
-	onLoad() {
-		this.getData();
-	},
-	methods: {
-		getData() {
-			this.http.request({
-				url: this.current === 0 ? '/app/project/list' : '/app/packages/list',
-				data: this.param,
-				loading: 'false',
-				success: (res) => {
-					this.loadMore = res.data.pages > this.param.pageNum ? true : false;
-					res.data.rows.forEach((item) => {
-						item.createTime = uni.$u.timeFrom(Date.parse(item.createTime));
-						this.list.push(item);
-					});
-				}
-			});
-		},
-		click(e) {
-			this.current = e.index;
-			this.param.state = e.index === 1 ? 0 : 1;
-			this.refresh();
-		},
-		add(item) {
-			uni.showModal({
-				title: '提示',
-				content: '确定接包?',
-				success: (res) => {
-					if (res.confirm) {
-						this.http.request({
-							url: '/app/packages/add',
-							data: { projectId: item.id, companyId: item.companyId },
-							method: 'POST',
-							success: (res) => {
-								uni.showModal({
-									title: '提示',
-									content: '接包成功',
-									showCancel: false,
-									success: (res) => {
-										this.refresh();
-									}
-								});
-							}
-						});
-					}
-				}
-			});
-		},
-		//上传凭证
-		voucher(item) {
-			this.$refs.voucher.init(JSON.parse(JSON.stringify(item)));
-		},
-		success() {
-			this.refresh();
-		},
-		//刷新数据
-		refresh() {
-			this.loadMore = true;
-			this.param.pageNum = 1;
-			this.list = [];
-			this.getData();
-		}
-	},
-	//下拉刷新
-	onPullDownRefresh() {
-		setTimeout(() => {
-			this.refresh();
-			uni.stopPullDownRefresh();
-		}, 1000);
-	},
-	//上拉加载
-	onReachBottom() {
-		if (this.loadMore) {
-			this.param.pageNum++;
-			this.getData();
-		}
-	}
-};
-</script>
-
-<style lang="scss">
-.main {
-	padding: 0px 15px 10px 15px;
-}
-.tab {
-	background-color: white;
-	border-radius: 7px;
-	padding-bottom: 10px;
-}
-.list {
-	padding-top: 13px;
-	.item {
-		background-color: white;
-		padding: 15px;
-		border-radius: 5px;
-		margin-bottom: 10px;
-		.it {
-			overflow: hidden;
-			padding: 7px 0px 7px 0px;
-			.lable {
-				float: left;
-				font-size: 14px;
-				color: #787878;
-			}
-			.desc {
-				float: right;
-				font-size: 14px;
-				width: 60%;
-				text-align: right;
-			}
-		}
-		.op {
-			border-top: 1px solid $line;
-			padding-top: 10px;
-			color: #676767;
-			font-size: 14px;
-			.add {
-				float: right;
-				color: white;
-				background-color: $main-color;
-				padding: 3px 20px;
-				border-radius: 20px;
-			}
-			.state {
-				float: right;
-			}
-		}
-		.cz {
-			float: right;
-		}
-	}
-}
-</style>

+ 0 - 73
ruoyi-admin/src/main/java/com/ruoyi/web/work/controller/FeedbackController.java

@@ -1,73 +0,0 @@
-package com.ruoyi.web.work.controller;
-
-import com.ruoyi.common.annotation.Log;
-import com.ruoyi.common.core.controller.BaseController;
-import com.ruoyi.common.core.domain.AjaxResult;
-import com.ruoyi.common.core.page.TableDataInfo;
-import com.ruoyi.common.enums.BusinessType;
-import com.ruoyi.web.work.domain.Feedback;
-import com.ruoyi.web.work.service.IFeedbackService;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
-
-import java.rmi.ServerException;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * 问题反馈
- *
- * @author lsw
- * @date 2024-04-24
- */
-@RestController
-@RequestMapping("/work/feedback")
-public class FeedbackController extends BaseController {
-    @Autowired
-    private IFeedbackService feedbackService;
-
-    @GetMapping("/list")
-    public TableDataInfo list(Feedback feedback) {
-        feedback.setCompanyId(getLoginUser().getUser().getCompanyId());
-        if (getLoginUser().getUser().getType() == 1) {
-            feedback.setUserId(getUserId());
-        }
-        startPage();
-        List<Feedback> list = feedbackService.selectList(feedback);
-        return getDataTable(list);
-    }
-
-    @GetMapping(value = "/detail/{id}")
-    public AjaxResult detail(@PathVariable("id") Long id) {
-        return AjaxResult.success(feedbackService.getById(id));
-    }
-
-    @Log(title = "提交问题反馈", businessType = BusinessType.INSERT)
-    @PostMapping("/add")
-    public AjaxResult add(@Validated @RequestBody Feedback feedback) throws ServerException {
-        return feedbackService.add(feedback);
-    }
-
-    @PreAuthorize("@ss.hasPermi('work:feedback:edit')")
-    @Log(title = "问题反馈", businessType = BusinessType.UPDATE)
-    @PostMapping("/edit")
-    public AjaxResult edit(@RequestBody Feedback feedback) {
-        feedback.setState(1);
-        return toAjax(feedbackService.updateById(feedback));
-    }
-
-    @PreAuthorize("@ss.hasPermi('work:feedback:remove')")
-    @Log(title = "删除问题反馈", businessType = BusinessType.DELETE)
-    @GetMapping("/remove/{ids}")
-    public AjaxResult remove(@PathVariable Long[] ids) {
-        return toAjax(feedbackService.removeByIds(Arrays.asList(ids)));
-    }
-
-    @Log(title = "删除问题反馈", businessType = BusinessType.DELETE)
-    @GetMapping("/delByUser/{id}")
-    public AjaxResult delByUser(@PathVariable Long id) {
-        return toAjax(feedbackService.delByUser(id));
-    }
-}

+ 66 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/work/controller/NewsController.java

@@ -0,0 +1,66 @@
+package com.ruoyi.web.work.controller;
+
+import com.ruoyi.common.annotation.Log;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.core.page.TableDataInfo;
+import com.ruoyi.common.enums.BusinessType;
+import com.ruoyi.web.work.domain.News;
+import com.ruoyi.web.work.service.INewsService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * 新闻资讯
+ *
+ * @author lsw
+ * @date 2024-05-31
+ */
+@RestController
+@RequestMapping("/work/news")
+public class NewsController extends BaseController {
+    @Autowired
+    private INewsService newsService;
+
+    @PreAuthorize("@ss.hasPermi('work:news:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(News news) {
+        startPage();
+        List<News> list = newsService.selectList(news);
+        return getDataTable(list);
+    }
+
+    @PreAuthorize("@ss.hasPermi('work:news:query')")
+    @GetMapping(value = "/detail/{id}")
+    public AjaxResult detail(@PathVariable("id") String id) {
+        return AjaxResult.success(newsService.getById(id));
+    }
+
+    @PreAuthorize("@ss.hasPermi('work:news:add')")
+    @Log(title = "新闻资讯", businessType = BusinessType.INSERT)
+    @PostMapping("/add")
+    public AjaxResult add(@Validated @RequestBody News news) {
+        news.setContents(news.getContents().replace("/dev-api", "").replace("/prod-api", ""));
+        return toAjax(newsService.save(news));
+    }
+
+    @PreAuthorize("@ss.hasPermi('work:news:edit')")
+    @Log(title = "新闻资讯", businessType = BusinessType.UPDATE)
+    @PostMapping("/edit")
+    public AjaxResult edit(@Validated @RequestBody News news) {
+        news.setContents(news.getContents().replace("/dev-api", "").replace("/prod-api", ""));
+        return toAjax(newsService.updateById(news));
+    }
+
+    @PreAuthorize("@ss.hasPermi('work:news:remove')")
+    @Log(title = "新闻资讯", businessType = BusinessType.DELETE)
+    @GetMapping("/remove/{ids}")
+    public AjaxResult remove(@PathVariable String[] ids) {
+        return toAjax(newsService.removeByIds(Arrays.asList(ids)));
+    }
+}

+ 11 - 2
ruoyi-admin/src/main/java/com/ruoyi/web/work/controller/ProjectController.java

@@ -6,6 +6,8 @@ import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.common.core.page.TableDataInfo;
 import com.ruoyi.common.enums.BusinessType;
 import com.ruoyi.web.work.domain.Project;
+import com.ruoyi.web.work.domain.dto.ProjectChangeDto;
+import com.ruoyi.web.work.domain.dto.ProjectDto;
 import com.ruoyi.web.work.service.IProjectService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
@@ -61,8 +63,15 @@ public class ProjectController extends BaseController {
     @PreAuthorize("@ss.hasPermi('work:project:edit')")
     @Log(title = "编辑项目", businessType = BusinessType.UPDATE)
     @PostMapping("/edit")
-    public AjaxResult edit(@Validated @RequestBody Project project) {
-        return toAjax(projectService.updateById(project));
+    public AjaxResult edit(@Validated @RequestBody ProjectDto project) throws ServerException {
+        return projectService.edit(project);
+    }
+
+    @PreAuthorize("@ss.hasPermi('work:project:edit')")
+    @Log(title = "停用或启用项目", businessType = BusinessType.UPDATE)
+    @PostMapping("/change")
+    public AjaxResult change(@Validated @RequestBody ProjectChangeDto dto) throws ServerException {
+        return projectService.change(dto);
     }
 
     @PreAuthorize("@ss.hasPermi('work:project:remove')")

+ 62 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/work/domain/News.java

@@ -0,0 +1,62 @@
+package com.ruoyi.web.work.domain;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.Size;
+import java.util.Date;
+/**
+ * @author lsw
+ * @date 2024-05-31
+ */
+@Data
+@TableName(value = "tb_news")
+@Accessors(chain = true)
+public class News{
+    private static final long serialVersionUID = 1L;
+
+    private Long id;
+
+    @NotBlank(message = "标题不能为空")
+    @Size(max = 30, message = "标题长度不能超过30个字符")
+    @ApiModelProperty(value = "标题")
+    private String title;
+
+    @ApiModelProperty(value = "封面图")
+    private String pic;
+
+    @NotBlank(message = "新闻类型不能为空")
+    @ApiModelProperty(value = "新闻类型")
+    private String type;
+
+    @ApiModelProperty(value = "简介")
+    private String brief;
+
+    @ApiModelProperty(value = "内容")
+    private String contents;
+
+    @ApiModelProperty(value = "状态:0=正常,1=停用")
+    private Integer state;
+
+    @TableField(fill = FieldFill.INSERT)
+    private String createBy;
+
+    @TableField(fill = FieldFill.INSERT)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createTime;
+
+    @TableField(fill = FieldFill.UPDATE)
+    private String updateBy;
+
+    @TableField(fill = FieldFill.UPDATE)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date updateTime;
+
+
+}

+ 25 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/work/domain/dto/ProjectChangeDto.java

@@ -0,0 +1,25 @@
+package com.ruoyi.web.work.domain.dto;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+
+/**
+ * @author lsw
+ * @date 2024-04-15
+ */
+@Data
+@Accessors(chain = true)
+public class ProjectChangeDto {
+
+    @NotNull(message = "参数错误")
+    private Long id;
+
+    @NotNull(message = "状态不能为空")
+    @Min(value = 0, message = "state 只能是 0 或者 1")
+    @Max(value = 1, message = "state 只能是 1 或者 0")
+    private Integer state;
+}

+ 46 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/work/domain/dto/ProjectDto.java

@@ -0,0 +1,46 @@
+package com.ruoyi.web.work.domain.dto;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.ruoyi.web.work.domain.base.BaseData;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.util.Date;
+
+/**
+ * @author lsw
+ * @date 2024-04-15
+ */
+@Data
+@Accessors(chain = true)
+public class ProjectDto extends BaseData {
+
+    @NotNull(message = "参数错误")
+    private Long id;
+
+    @NotBlank(message = "项目名称不能为空")
+    @ApiModelProperty(value = "项目名称")
+    private String projectName;
+
+    @ApiModelProperty(value = "项目内容")
+    private String contents;
+
+    @NotNull(message = "项目周期不能为空")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @ApiModelProperty(value = "开始时间")
+    private Date startDate;
+
+    @NotNull(message = "项目周期不能为空")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @ApiModelProperty(value = "结束时间")
+    private Date finishDate;
+
+    @NotNull(message = "项目周期不能为空")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @ApiModelProperty(value = "结算日")
+    private Date balanceDate;
+
+}

+ 13 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/work/mapper/NewsMapper.java

@@ -0,0 +1,13 @@
+package com.ruoyi.web.work.mapper;
+
+import java.util.List;
+import com.ruoyi.web.work.domain.News;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * @author lsw
+ * @date 2024-05-31
+ */
+public interface NewsMapper extends BaseMapper<News> {
+    List<News> selectList(News news);
+}

+ 13 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/work/service/INewsService.java

@@ -0,0 +1,13 @@
+package com.ruoyi.web.work.service;
+
+import java.util.List;
+import com.ruoyi.web.work.domain.News;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * @author lsw
+ * @date 2024-05-31
+ */
+public interface INewsService extends IService<News>{
+    List<News> selectList(News news);
+}

+ 6 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/work/service/IProjectService.java

@@ -3,6 +3,8 @@ package com.ruoyi.web.work.service;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.web.work.domain.Project;
+import com.ruoyi.web.work.domain.dto.ProjectChangeDto;
+import com.ruoyi.web.work.domain.dto.ProjectDto;
 import com.ruoyi.web.work.domain.vo.ProjectListVo;
 
 import java.rmi.ServerException;
@@ -18,4 +20,8 @@ public interface IProjectService extends IService<Project>{
     List<ProjectListVo> selectProjectList(Project project);
 
     AjaxResult add(Project project) throws ServerException;
+
+    AjaxResult edit(ProjectDto dto) throws ServerException;
+
+    AjaxResult change(ProjectChangeDto dto) throws ServerException;
 }

+ 24 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/work/service/impl/NewsServiceImpl.java

@@ -0,0 +1,24 @@
+package com.ruoyi.web.work.service.impl;
+
+import java.util.List;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.ruoyi.web.work.mapper.NewsMapper;
+import com.ruoyi.web.work.domain.News;
+import com.ruoyi.web.work.service.INewsService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+
+/**
+ * @author lsw
+ * @date 2024-05-31
+ */
+@Service
+public class NewsServiceImpl extends ServiceImpl<NewsMapper, News> implements INewsService {
+    @Autowired
+    private NewsMapper newsMapper;
+
+    @Override
+    public List<News> selectList(News news) {
+        return newsMapper.selectList(news);
+    }
+}

+ 30 - 4
ruoyi-admin/src/main/java/com/ruoyi/web/work/service/impl/ProjectServiceImpl.java

@@ -6,11 +6,11 @@ import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.common.core.redis.RedisCache;
 import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.common.utils.bean.BeanUtils;
 import com.ruoyi.web.work.api.util.AppUtil;
-import com.ruoyi.web.work.domain.Packages;
-import com.ruoyi.web.work.domain.Platform;
-import com.ruoyi.web.work.domain.Project;
-import com.ruoyi.web.work.domain.Relate;
+import com.ruoyi.web.work.domain.*;
+import com.ruoyi.web.work.domain.dto.ProjectChangeDto;
+import com.ruoyi.web.work.domain.dto.ProjectDto;
 import com.ruoyi.web.work.domain.vo.ProjectListVo;
 import com.ruoyi.web.work.domain.vo.RelateCompanyListVo;
 import com.ruoyi.web.work.mapper.ProjectMapper;
@@ -72,4 +72,30 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
         }
         return AjaxResult.success();
     }
+
+    @Override
+    public AjaxResult edit(ProjectDto dto) throws ServerException {
+        Project project = getById(dto.getId());
+        if (project == null || !project.getCompanyId().equals(SecurityUtils.getLoginUser().getUser().getCompanyId())) {
+            return AjaxResult.error("项目不存在或非法操作");
+        }
+        BeanUtils.copyProperties(dto, project);
+        if (!updateById(project)) {
+            throw new ServerException("编辑项目失败,请联系管理员");
+        }
+        return AjaxResult.success();
+    }
+
+    @Override
+    public AjaxResult change(ProjectChangeDto dto) throws ServerException {
+        Project project = getById(dto.getId());
+        if (project == null || !project.getCompanyId().equals(SecurityUtils.getLoginUser().getUser().getCompanyId())) {
+            return AjaxResult.error("项目不存在或非法操作");
+        }
+        project.setState(dto.getState());
+        if (!updateById(project)) {
+            throw new ServerException("停用或启用项目失败,请联系管理员");
+        }
+        return AjaxResult.success();
+    }
 }

+ 5 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/work/service/impl/StatementServiceImpl.java

@@ -164,6 +164,11 @@ public class StatementServiceImpl extends ServiceImpl<StatementMapper, Statement
         if (packagesList.isEmpty() || packagesList.size() == 0) {
             return AjaxResult.error("该项目暂无人接包,无法生成结算单");
         }
+        packagesList.forEach(e -> {
+            if (e.getAudit() != 2) {
+                throw new ServiceException("接包凭证未审核或者审核不通过,请全部审核通过后再生成");
+            }
+        });
         Platform platform = redisCache.getCacheObject(CacheConstants.APP_PLATFORM);
         Statement statement = new Statement();
         statement.setFileName("自动生成");

+ 15 - 0
ruoyi-admin/src/main/resources/mapper/work/NewsMapper.xml

@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.web.work.mapper.NewsMapper">
+    <select id="selectList" resultType="com.ruoyi.web.work.domain.News">
+        select * from tb_news
+        <where>
+            <if test="title != null  and title != ''"> and title like concat('%', #{title}, '%')</if>
+            <if test="type != null  and type != ''"> and type = #{type}</if>
+            <if test="state != null "> and state = #{state}</if>
+        </where>
+    </select>
+
+</mapper>