Parcourir la source

feature(优化): 公告功能优化,新建项目自动关联销售

ZZH-wl il y a 2 ans
Parent
commit
c7007a5a5d

+ 2 - 2
.env.production

@@ -2,7 +2,7 @@
 VUE_APP_TENANT=8b9ec443
 
 # websocket地址
-VUE_APP_WEBSOCKET_URL=ws://1.15.100.104:8899/ws
+VUE_APP_WEBSOCKET_URL=wss://oms.dashoo.cn/ws
 
 # GateWay地址
 VUE_APP_MicroSrvProxy_API=https://oms.dashoo.cn/api/
@@ -12,4 +12,4 @@ VUE_APP_AdminPath=dashoo.opms.admin-0.0.1
 VUE_APP_ParentPath=dashoo.opms.parent-0.0.1
 
 # 文件上传
-VUE_APP_UPLOAD_WEED='http://1.15.100.104:9333/dir/assign'
+VUE_APP_UPLOAD_WEED='https://oms.dashoo.cn/dir/assign'

+ 3 - 0
src/api/system/message.js

@@ -6,6 +6,9 @@ export default {
   getList(query) {
     return micro_request.postRequest(basePath, 'Message', 'GetList', query)
   },
+  getUserHistory(query) {
+    return micro_request.postRequest(basePath, 'Message', 'GetUserHistory', query)
+  },
   getEntityById(query) {
     return micro_request.postRequest(basePath, 'Message', 'GetEntityById', query)
   },

+ 8 - 1
src/store/modules/user.js

@@ -18,6 +18,7 @@ const state = () => ({
   phone: '',
   avatar: require('@/assets/login_images/user_avatar.png'),
   isFirstLogin: false,
+  roleKeys: [],
 })
 const getters = {
   id: (state) => state.id,
@@ -27,6 +28,7 @@ const getters = {
   phone: (state) => state.phone,
   avatar: (state) => state.avatar,
   isFirstLogin: (state) => state.isFirstLogin,
+  roleKeys: (state) => state.roleKeys,
 }
 const mutations = {
   /**
@@ -67,6 +69,9 @@ const mutations = {
   setAvatar(state, avatar) {
     state.avatar = avatar
   },
+  setRoleKeys(state, roleKeys) {
+    state.roleKeys = roleKeys
+  },
 }
 const actions = {
   /**
@@ -113,7 +118,7 @@ const actions = {
 
     const res = await userApi.getUserInfo()
     const { id, userName, nickName, phone, avatar } = res.data.entity
-    const { roleIds, permissions } = res.data
+    const { roleIds, roleKeys, permissions } = res.data
     /**
      * 检验返回数据是否正常,无对应参数,将使用默认用户名,头像,Roles和Permissions
      * username {String}
@@ -126,6 +131,7 @@ const actions = {
       (avatar && !isString(avatar)) ||
       (nickName && !isString(nickName)) ||
       (phone && !isString(phone)) ||
+      (roleKeys && !isArray(roleKeys)) ||
       (roleIds && !isArray(roleIds)) ||
       (permissions && !isArray(permissions))
     ) {
@@ -143,6 +149,7 @@ const actions = {
       if (avatar) commit('setAvatar', avatar)
       // 如不使用roles权限控制,可删除以下代码
       if (roleIds) dispatch('acl/setRole', roleIds, { root: true })
+      if (roleKeys) commit('setRoleKeys', roleKeys)
       // 如不使用permissions权限控制,可删除以下代码
       if (permissions) dispatch('acl/setPermission', permissions, { root: true })
 

+ 2 - 2
src/views/contract/components/Transfer.vue

@@ -12,11 +12,11 @@
       <el-row :gutter="20">
         <el-col :span="24">
           <el-form-item label="销售工程师" prop="inchargeName">
-            <el-select
+            <el-input
               v-model="userForm.inchargeName"
               placeholder="请选择销售工程师"
               readonly
-              style="width: 100%"
+              suffix-icon="el-icon-search"
               @focus="openUser(false, 'inchargeId', 'inchargeName')" />
           </el-form-item>
         </el-col>

+ 13 - 12
src/views/index/index.vue

@@ -132,7 +132,7 @@
         <div slot="header" class="card-title">
           <span>公告</span>
           <div class="buttons">
-            <el-button size="mini">
+            <el-button size="mini" @click="handleHistoryNotice">
               更多
               <i class="el-icon-arrow-right el-icon--right"></i>
             </el-button>
@@ -189,10 +189,14 @@
         <el-button type="primary" @click="save">确 定</el-button>
       </template>
     </el-dialog>
+
+    <!--通知公告详情-->
+    <notice-details ref="notice-details" />
   </div>
 </template>
 
 <script>
+  import NoticeDetails from '@/views/system/notice/details.vue'
   import * as echarts from 'echarts'
   import VueDragger from 'vuedraggable'
   import VueGridLayout from 'vue-grid-layout'
@@ -203,6 +207,7 @@
   export default {
     name: 'Index',
     components: {
+      NoticeDetails,
       VueDragger,
       GridLayout: VueGridLayout.GridLayout,
       GridItem: VueGridLayout.GridItem,
@@ -574,21 +579,17 @@
       msgTypeFormat(row) {
         return this.selectDictLabel(this.msgTypeOptions, row.msgType)
       },
+      handleHistoryNotice() {
+        this.$router.push({
+          name: 'NoticeHistory',
+        })
+      },
       async handleNoticeList() {
         const { data } = await messageApi.getList({ msgType: '10' })
         this.messageList = data.list
       },
-      getNoticeInfo(msg) {
-        messageApi.getEntityById({ id: msg.id }).then((res) => {
-          this.$notify({
-            title: res.msgTitle,
-            position: 'top-right',
-            type: 'info',
-            duration: 1000 * 60 * 5,
-            dangerouslyUseHTMLString: true,
-            message: msg.msgContent,
-          })
-        })
+      getNoticeInfo(row) {
+        this.$refs['notice-details'].open(row.id)
       },
     },
   }

+ 12 - 0
src/views/proj/business/components/BusinessEdit.vue

@@ -204,6 +204,7 @@
 <script>
   import businessApi from '@/api/proj/business'
   import AmountInput from '@/components/currency'
+  import { mapGetters } from 'vuex'
   import ProductTable from './ProductTable'
   import SelectContact from '@/components/select/SelectCustomerContact'
   import SelectCustomer from '@/components/select/SelectCustomer'
@@ -307,6 +308,13 @@
         this.customerInfo = val
       },
     },
+    computed: {
+      ...mapGetters({
+        userId: 'user/id',
+        nickName: 'user/nickName',
+        roleKeys: 'user/roleKeys',
+      }),
+    },
     created() {},
     mounted() {
       this.getOptions()
@@ -459,6 +467,10 @@
           this.getProductData(row.id)
         }
         this.dialogFormVisible = true
+        if (this.roleKeys.includes('SalesEngineer')) {
+          this.form.saleId = this.id
+          this.form.saleName = this.nickName
+        }
       },
       close() {
         this.$refs['form'].resetFields()

+ 4 - 5
src/views/system/notice/components/NoticeEdit.vue

@@ -16,7 +16,7 @@
         </el-col>
         <el-col :span="24">
           <el-form-item label="接收用户" prop="recvUser">
-            <el-input v-model="form.recvUser" readonly @focus="handleSelectSale" />
+            <el-input v-model="form.recvUser" readonly suffix-icon="el-icon-search" @focus="handleSelectUsers" />
           </el-form-item>
         </el-col>
         <el-col :span="24">
@@ -70,8 +70,7 @@
       <el-button type="primary" @click="save">确 定</el-button>
     </div>
 
-    <!-- 选择销售工程师弹窗 -->
-    <select-user ref="selectSales" multiple @save="selectSales" />
+    <select-user ref="selectUsers" multiple @save="selectUsers" />
   </el-dialog>
 </template>
 
@@ -122,10 +121,10 @@
       onCreated(editor) {
         this.editor = Object.seal(editor) // 一定要用 Object.seal() ,否则会报错
       },
-      handleSelectSale() {
+      handleSelectUsers() {
         this.$refs.selectSales.open()
       },
-      selectSales(val) {
+      selectUsers(val) {
         if (val && val.length > 0) {
           this.form.recvUserIds = val.map((item) => item.id).join()
           this.form.recvUser = val.map((item) => item.nickName).join()

+ 48 - 0
src/views/system/notice/details.vue

@@ -0,0 +1,48 @@
+<template>
+  <el-dialog :title="title" :visible.sync="dialogFormVisible" width="80%" @close="close">
+    <div style="text-align: center">
+      <h1>{{ details.msgTitle }}</h1>
+      <p>{{ details.createdTime }}</p>
+      <div v-html="details.msgContent"></div>
+    </div>
+    <div slot="footer" class="dialog-footer"></div>
+  </el-dialog>
+</template>
+
+<script>
+  import messageApi from '@/api/system/message'
+
+  export default {
+    name: 'NoticeDetails',
+    data() {
+      return {
+        details: {},
+        title: '通知公告',
+        dialogFormVisible: false,
+        msgTypeOptions: [],
+        msgStatusOptions: [],
+      }
+    },
+    created() {},
+    methods: {
+      getOptions() {
+        this.getDicts('sys_msg_type').then((response) => {
+          this.msgTypeOptions = response.data.values || []
+        })
+        this.getDicts('sys_msg_status').then((response) => {
+          this.msgStatusOptions = response.data.values || []
+        })
+      },
+      close() {
+        this.dialogFormVisible = false
+      },
+      open(id) {
+        messageApi.getEntityById({ id: id }).then((res) => {
+          this.details = res.data
+          this.dialogFormVisible = true
+        })
+      },
+    },
+  }
+</script>
+<style src="@wangeditor/editor/dist/css/style.css"></style>

+ 196 - 0
src/views/system/notice/history.vue

@@ -0,0 +1,196 @@
+<template>
+  <div class="app-container">
+    <vab-query-form>
+      <vab-query-form-top-panel>
+        <el-form ref="queryForm" :inline="true" label-width="68px" :model="queryForm" size="small">
+          <el-form-item prop="msgTitle">
+            <el-input
+              v-model="queryForm.msgTitle"
+              clearable
+              placeholder="请输入消息标题"
+              @keyup.enter.native="queryData" />
+          </el-form-item>
+          <el-form-item prop="msgType">
+            <el-select v-model="queryForm.msgType" clearable placeholder="消息类别">
+              <el-option v-for="dict in msgTypeOptions" :key="dict.key" :label="dict.value" :value="dict.key" />
+            </el-select>
+          </el-form-item>
+          <el-form-item>
+            <el-button icon="el-icon-search" type="primary" @click="queryData">搜索</el-button>
+            <el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
+          </el-form-item>
+        </el-form>
+      </vab-query-form-top-panel>
+    </vab-query-form>
+    <el-table
+      :key="uuid"
+      v-loading="listLoading"
+      :data="list"
+      :height="$baseTableHeight(1)"
+      @selection-change="setSelectRows">
+      <el-table-column
+        v-for="(item, index) in columns"
+        :key="index"
+        align="center"
+        :formatter="item.formatter"
+        :label="item.label"
+        :prop="item.prop"
+        :sortable="item.sortable"
+        :width="item.width" />
+      <el-table-column align="center" label="操作" width="85">
+        <template #default="{ row }">
+          <el-button type="text" @click="handleLook(row)">查看</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <el-pagination
+      background
+      :current-page="queryForm.pageNum"
+      :layout="layout"
+      :page-size="queryForm.pageSize"
+      :total="total"
+      @current-change="handleCurrentChange"
+      @size-change="handleSizeChange" />
+
+    <notice-details ref="notice-details" />
+  </div>
+</template>
+
+<script>
+  import messageApi from '@/api/system/message'
+  import NoticeDetails from './details.vue'
+
+  export default {
+    name: 'NoticeHistory',
+    components: { NoticeDetails },
+    data() {
+      return {
+        uuid: '',
+        checkList: [],
+        columns: [
+          {
+            prop: 'msgType',
+            label: '消息类别',
+            width: 'auto',
+            disableCheck: true,
+            formatter: this.msgTypeFormat,
+          },
+          {
+            prop: 'msgTitle',
+            label: '消息标题',
+            width: 'auto',
+            disableCheck: true,
+          },
+          {
+            prop: 'isRead',
+            label: '已读',
+            width: 'auto',
+            formatter: this.yesOrNoFormat,
+          },
+          {
+            prop: 'readTime',
+            label: '读取时间',
+            width: 'auto',
+          },
+        ],
+        list: [],
+        listLoading: false,
+        layout: 'total, sizes, prev, pager, next, jumper',
+        total: 0,
+        selectRows: '',
+        queryForm: {
+          pageNum: 1,
+          pageSize: 10,
+          configName: '',
+          configKey: '',
+          configType: '',
+        },
+        msgTypeOptions: [],
+        msgStatusOptions: [],
+        yesOrNoOptions: [],
+      }
+    },
+    computed: {
+      finallyColumns() {
+        return this.columns.filter((item) => this.checkList.includes(item.label))
+      },
+    },
+    created() {
+      this.getOptions()
+    },
+    mounted() {
+      this.fetchData()
+    },
+    methods: {
+      getOptions() {
+        this.getDicts('sys_msg_type').then((response) => {
+          this.msgTypeOptions = response.data.values || []
+        })
+      },
+      // 参数系统内置字典翻译
+      msgTypeFormat(row) {
+        return this.selectDictLabel(this.msgTypeOptions, row.msgType)
+      },
+      msgStatusFormat(row) {
+        return this.selectDictLabel(this.msgStatusOptions, row.msgStatus)
+      },
+      yesOrNoFormat(row) {
+        return row.isRead === '20' ? '是' : '否'
+      },
+      setSelectRows(val) {
+        this.selectRows = val
+      },
+      handleLook(row) {
+        this.$refs['notice-details'].open(row.id)
+      },
+      handleDelete(row) {
+        if (row.id) {
+          this.$baseConfirm('你确定要删除当前项吗', null, async () => {
+            const { msg } = await messageApi.doDelete({ ids: [row.id] })
+            this.$baseMessage(msg, 'success')
+            await this.fetchData()
+          })
+        } else {
+          if (this.selectRows.length > 0) {
+            const ids = this.selectRows.map((item) => item.id)
+            this.$baseConfirm('你确定要删除选中项吗', null, async () => {
+              const { msg } = await messageApi.doDelete({ ids })
+              this.$baseMessage(msg, 'success')
+              await this.fetchData()
+            })
+          } else {
+            this.$baseMessage('未选中任何行', 'error')
+            return false
+          }
+        }
+      },
+      handleSizeChange(val) {
+        this.queryForm.pageSize = val
+        this.fetchData()
+      },
+      handleCurrentChange(val) {
+        this.queryForm.pageNum = val
+        this.fetchData()
+      },
+      queryData() {
+        this.queryForm.pageNum = 1
+        this.fetchData()
+      },
+      /** 重置按钮操作 */
+      resetQuery() {
+        this.resetForm('queryForm')
+        this.fetchData()
+      },
+      async fetchData() {
+        this.listLoading = true
+        const {
+          data: { list, total },
+        } = await messageApi.getUserHistory(this.queryForm)
+        this.list = list
+        this.total = total
+        this.listLoading = false
+      },
+    },
+  }
+</script>