cfort 2 лет назад
Родитель
Сommit
694ea44375

+ 1 - 1
src/business/platform/form/formrender/dynamic-form/dynamic-form-table.vue

@@ -573,7 +573,7 @@ export default {
         handleRemove(button, index) {
             const position = button.position
             const selection = this.getSelection(position, index)
-            ActionUtils.removeRecord(selection, '确定删除当前数据?', true)
+            ActionUtils.removeRecord(selection, '确定删除当前数据?', true)
                 .then((ids) => {
                     for (let i = this.dataModel.length - 1; i >= 0; i--) {
                         if (ids.indexOf(i) > -1) {

+ 459 - 477
src/components/ibps-crud/index.vue

@@ -1,517 +1,499 @@
 <template>
     <div class="container-component">
-
-      <div ref="ibpsCrud" class="ibps-container-crud">
-
-        <!-- 工具栏 -->
-        <!-- 标题栏-->
-        <div v-if="displayField && displayField!='N'&& displayField!='true'&& displayField!='Y'" class="jbd-title-cont">
-           {{displayField}}
-        </div>
-        <div
-          v-if="toolbars || $slots.header"
-          ref="ibpsCrudHeader"
-          class="ibps-container-crud__header"
-        >
-          <div
-            v-if="toolbars"
-            :class="['ibps-toolbar--' +$ELEMENT.size]"
-            class="ibps-toolbar"
-          >
-      <div class="header"
-          style="overflow:scroll;
-            height: 100%;
-            background-color: #F9FFFF;
-            border-bottom: 0px;
-            border-top: 0px;
-            overflow: hidden"
+        <div ref="ibpsCrud" class="ibps-container-crud">
+            <!-- 工具栏 -->
+            <!-- 标题栏-->
+            <div v-if="displayField && displayField!='N'&& displayField!='true'&& displayField!='Y'" class="jbd-title-cont">
+                {{ displayField }}
+            </div>
+            <div
+                v-if="toolbars || $slots.header"
+                ref="ibpsCrudHeader"
+                class="ibps-container-crud__header"
             >
-  <!-- 换了位置 -->
-          <div
-            v-show="$utils.isNotEmpty(searchForm) && showToolbar"
-            ref="toolbarBox"
-            class="toolbar-box clear"
-            style="padding: 0px; border: 0px;"
-          >
-            <template v-if="$slots.searchForm" ref="searchForm">
-              <slot :loading="loading" name="searchForm" />
-            </template>
-
-            <template v-else>
-              <search-form
-                v-if="searchForm"
-                ref="searchForm"
-                :forms="searchForm.forms||[]"
-                size="mini"
-                :fuzzy="searchForm.fuzzy"
-                :inline="searchForm.inline"
-                :label-width="searchForm.labelWidth"
-                :item-width="searchForm.itemWidth"
-                @search="handleActionEvent({key:'search'}, 'toolbar')"
-              >
-                      <template v-for="item in searchFormSlot" :slot="item.slotName">
-                        <slot :name="item.slotName" :item="item" />
-                      </template>
-
-                      <template slot="jbd-buttons" v-if="searchFormSlot.length>0">
-                               <ibps-toolbar
-                                 :actions="toolbars"
-                                 :socpe="thatSocpe"
-                                 @action-event="handleActionEvent"
-                               />
-                      </template>
-
-              </search-form>
-            </template>
-
-          </div>
-
-
-              <div class="buttons"  v-if="$slots.searchForm">
-                <ibps-toolbar
-                  :actions="toolbars"
-                  :socpe="thatSocpe"
-                  @action-event="handleActionEvent"
-                />
-              </div>
-              <div class="buttons" v-else-if="searchFormSlot.length<1">
-                       <ibps-toolbar
-                         :actions="toolbars"
-                         :socpe="thatSocpe"
-                         @action-event="handleActionEvent"
-                       />
-              </div>
-        </div>
-              <!-- 下拉隐藏-->
-             <!-- <div class="tools">
-                <slot name="rightTools" />
-                <el-button v-if="displayField" icon="ibps-icon-cog" class="ibps-crud__display-field" :underline="false" @click="displayFieldVisible=true">{{ $t('components.crud.displayField') }}</el-button>
-                <el-tooltip
-                  v-if="$utils.isNotEmpty(searchForm)"
-                  :content="showToolbar?$t('components.crud.collapse'):$t('components.crud.expand')"
+                <div
+                    v-if="toolbars"
+                    :class="['ibps-toolbar--' +$ELEMENT.size]"
+                    class="ibps-toolbar"
                 >
-                  <a class="expand" @click="handleCollapseExpandToolbar">
-                    <i :class="showToolbar?'el-icon-caret-top':'el-icon-caret-bottom'" />
-                  </a>
-                </el-tooltip>
-              </div> -->
-
-
-
+                    <div
+                        class="header"
+                        style="overflow:scroll; height: 100%; background-color: #F9FFFF; border-bottom: 0px; border-top: 0px; overflow: hidden"
+                    >
+                        <!-- 换了位置 -->
+                        <div
+                            v-show="$utils.isNotEmpty(searchForm) && showToolbar"
+                            ref="toolbarBox"
+                            class="toolbar-box clear"
+                            style="padding: 0px; border: 0px;"
+                        >
+                            <template v-if="$slots.searchForm" ref="searchForm">
+                                <slot :loading="loading" name="searchForm" />
+                            </template>
+                            <template v-else>
+                                <search-form
+                                    v-if="searchForm"
+                                    ref="searchForm"
+                                    :forms="searchForm.forms||[]"
+                                    size="mini"
+                                    :fuzzy="searchForm.fuzzy"
+                                    :inline="searchForm.inline"
+                                    :label-width="searchForm.labelWidth"
+                                    :item-width="searchForm.itemWidth"
+                                    @search="handleActionEvent({key:'search'}, 'toolbar')"
+                                >
+                                    <template v-for="item in searchFormSlot" :slot="item.slotName">
+                                        <slot :name="item.slotName" :item="item" />
+                                    </template>
 
-            <slot name="header" />
-          </div>
-        </div>
+                                    <template v-if="searchFormSlot.length>0" slot="jbd-buttons">
+                                        <ibps-toolbar
+                                            :actions="toolbars"
+                                            :socpe="thatSocpe"
+                                            @action-event="handleActionEvent"
+                                        />
+                                    </template>
+                                </search-form>
+                            </template>
+                        </div>
+                        <div v-if="$slots.searchForm" class="buttons">
+                            <ibps-toolbar
+                                :actions="toolbars"
+                                :socpe="thatSocpe"
+                                @action-event="handleActionEvent"
+                            />
+                        </div>
+                        <div v-else-if="searchFormSlot.length<1" class="buttons">
+                            <ibps-toolbar
+                                :actions="toolbars"
+                                :socpe="thatSocpe"
+                                @action-event="handleActionEvent"
+                            />
+                        </div>
+                    </div>
+                    <!-- 下拉隐藏-->
+                    <!-- <div class="tools">
+                        <slot name="rightTools" />
+                        <el-button v-if="displayField" icon="ibps-icon-cog" class="ibps-crud__display-field" :underline="false" @click="displayFieldVisible=true">{{ $t('components.crud.displayField') }}</el-button>
+                        <el-tooltip
+                            v-if="$utils.isNotEmpty(searchForm)"
+                            :content="showToolbar?$t('components.crud.collapse'):$t('components.crud.expand')"
+                        >
+                            <a class="expand" @click="handleCollapseExpandToolbar">
+                                <i :class="showToolbar?'el-icon-caret-top':'el-icon-caret-bottom'" />
+                            </a>
+                        </el-tooltip>
+                    </div> -->
+                    <slot name="header" />
+                </div>
+            </div>
 
-          <!--列表--><!--   @header-dragend="handleHeaderDragend" 拖拽事件取消 -->
-          <el-table
-            ref="elTable"
-            v-loading="loading"
-            v-bind="options"
-            :row-key="pkKey"
-            :data="ibpsData"
-            :height="tableHeight"
-            :header-cell-style="{color:'#000','font-size':'14px',padding:'6px 6px'}"
-            :stripe="false"
-            :row-class-name="tableRowClassName"
-            @current-change="handleCurrentChange"
-            @select="handleSelect"
-            @select-all="handleSelectAll"
-            @selection-change="handleSelectionChange"
-            @sort-change="handleSortChange"
-            @cell-mouse-enter="handleCellMouseEnter"
-            @cell-mouse-leave="handleCellMouseLeave"
-            @cell-click="handleCellClick"
-            @cell-dblclick="handleCellDblclick"
-            @row-click="handleRowClick"
-            @row-contextmenu="handleRowContextmenu"
-            @row-dblclick="handleRowDblclick"
-            @header-click="handleHeaderClick"
-            @header-contextmenu="handleHeaderContextmenu"
-          >
-            <template slot="empty">
-              <slot v-if="$slots.empty" name="empty" />
-              <ibps-empty v-else />
-            </template>
-            <!--选择列 多选-->
-            <el-table-column
-              v-if="(selectionRow || selectionRow === '') && selectionType === 'checkbox'"
-              v-bind="typeof selectionRow === 'Object'?selectionRow:null"
-              :label="handleAttribute(selectionRow.label, '')"
-              :reserve-selection="selectionRow.reserveSelectione||false"
-              type="selection"
-              show-overflow-tooltip
-            />
-            <!--选择列 单选-->
-            <el-table-column
-              v-if="(selectionRow || selectionRow === '') && selectionType === 'radio'"
-              :label="selectionRow.label||''"
-              :width="selectionRow.width||55"
-              show-overflow-tooltip
+            <!--列表--><!--   @header-dragend="handleHeaderDragend" 拖拽事件取消 -->
+            <el-table
+                ref="elTable"
+                v-loading="loading"
+                v-bind="options"
+                :row-key="pkKey"
+                :data="ibpsData"
+                :height="tableHeight"
+                :header-cell-style="{color:'#000','font-size':'14px',padding:'6px 6px'}"
+                :stripe="false"
+                :row-class-name="tableRowClassName"
+                @current-change="handleCurrentChange"
+                @select="handleSelect"
+                @select-all="handleSelectAll"
+                @selection-change="handleSelectionChange"
+                @sort-change="handleSortChange"
+                @cell-mouse-enter="handleCellMouseEnter"
+                @cell-mouse-leave="handleCellMouseLeave"
+                @cell-click="handleCellClick"
+                @cell-dblclick="handleCellDblclick"
+                @row-click="handleRowClick"
+                @row-contextmenu="handleRowContextmenu"
+                @row-dblclick="handleRowDblclick"
+                @header-click="handleHeaderClick"
+                @header-contextmenu="handleHeaderContextmenu"
             >
-              <template slot-scope="scope">
-                <el-radio v-model="selectionRadio" :label="getPkValue(scope.row)"><span>&nbsp;</span></el-radio>
-              </template>
-            </el-table-column>
-
-            <!-- 自定义表单名称-->
-            <el-table-column :width="180"
-            show-overflow-tooltip
-            label="表单名称"
-            v-if="formName">
-              <template slot-scope="scope">
-                  {{formName}}
-              </template>
-            </el-table-column>
-
-            <!--索引列-->
-            <el-table-column
-              v-if="indexRow || indexRow === ''"
-              v-bind="typeof indexRow === 'Object'?indexRow:null"
-              :label="handleAttribute(indexRow.label, $t('components.crud.index'))"
-              :width="60"
-              type="index"
-            />
-            <slot name="prepend-column" />
-            <template v-for="(column, index) in tableColumns">
-              <el-table-column
-                v-if="showColumn(column)"
-                :key="index"
-                :prop="handleAttribute(column.prop, null)"
-                :label="handleAttribute(column.label, '')"
-                :width="handleAttribute(column.width,null)"
-                v-bind="column"
-                show-overflow-tooltip
-              >
-                <template slot="header">
-                  <slot :name="column.headerName" :column="column" />
+                <template slot="empty">
+                    <slot v-if="$slots.empty" name="empty" />
+                    <ibps-empty v-else />
                 </template>
-                <template slot-scope="scope">
-                  <!--时间格式-->
-                  <span v-if="column.dateFormat" class="ibps-table-column">
-                    {{ scope.row[column.prop] | dateFormat(column.dateFormat,column.origDateFormat) }}
-                  </span>
-                  <!--通用过滤器-->
-                  <span v-else-if="column.filter" class="ibps-table-column">
-                    {{ handleColumnFilter(column.filter,scope.row[column.prop]) }}
-                  </span>
-                  <!-- 下拉组件-->
-                  <span v-else-if="column.options" class="ibps-table-column">
-                    <!--stringArray 字符串类型的数组,逗号分隔-->
-                    <template v-if="column.dataType==='stringArray'">
-                      <span
-                        v-for="(value,i) in handleColumnDataConvert(scope.row[column.prop],column.separator)"
-                        :key="i"
-                      >
-                        {{ handleColumnOptions('label',column.options,value,column) }}<template v-if="handleColumnDataConvert(scope.row[column.prop],column.separator).length-1 !==i">,</template>
-                      </span>
-                    </template>
-                    <!--stringArray 字符串类型的数组-->
-                    <template v-else-if="column.dataType==='objectList'">
-                      <span v-for="(value,j) in scope.row[column.prop]" :key="j">
-                        {{ value[column.tagLabel] }}
-                      </span>
-                    </template>
-                    <span v-else>{{ handleColumnOptions('label',column.options,scope.row[column.prop]) }}</span>
-
-                  </span>
-                  <!-- tags组件-->
-                  <span v-else-if="column.tags" class="ibps-table-column">
-                    <span v-if="$utils.isEmpty(scope.row[column.prop]) ">{{ column.defaultLabel||'' }}</span>
-                    <!--stringArray 字符串类型的数组-->
-                    <template v-else-if="column.dataType==='stringArray'">
-                      <el-tag
-                        v-for="(value,i) in handleColumnDataConvert(scope.row[column.prop],column.separator)"
-                        :key="i"
-                        :type="handleColumnOptions('type',column.tags,value,column)"
-                      >
-                        {{ handleColumnOptions('label',column.tags,value,column) }}
-                      </el-tag>
-                    </template>
-                    <!--stringArray 字符串类型的数组-->
-                    <template v-else-if="column.dataType==='objectList'">
-                      <el-tag v-for="(value,j) in scope.row[column.prop]" :key="j">
-                        {{ value[column.tagLabel] }}
-                      </el-tag>
-                    </template>
-                    <template v-else>
-                      <el-tag :type="handleColumnOptions('type',column.tags,scope.row[column.prop],column)">{{ handleColumnOptions('label',column.tags,scope.row[column.prop],column) }}</el-tag>
+                <!--选择列 多选-->
+                <el-table-column
+                    v-if="(selectionRow || selectionRow === '') && selectionType === 'checkbox'"
+                    v-bind="typeof selectionRow === 'Object'?selectionRow:null"
+                    :label="handleAttribute(selectionRow.label, '')"
+                    :reserve-selection="selectionRow.reserveSelectione||false"
+                    type="selection"
+                    show-overflow-tooltip
+                />
+                <!--选择列 单选-->
+                <el-table-column
+                    v-if="(selectionRow || selectionRow === '') && selectionType === 'radio'"
+                    :label="selectionRow.label||''"
+                    :width="selectionRow.width||55"
+                    show-overflow-tooltip
+                >
+                    <template slot-scope="scope">
+                        <el-radio v-model="selectionRadio" :label="getPkValue(scope.row)"><span>&nbsp;</span></el-radio>
                     </template>
-                  </span>
-                  <!-- link组件-->
-                  <span v-else-if="column.link" class="ibps-table-column">
-                    <el-link :type="column.type||'primary'" :underline="column.underline||false" @click="handleColumnLink(column,scope.row)">
-                      {{ scope.row[column.prop] |removeHtmlTag }}
-                    </el-link>
-                  </span>
-
-                  <!-- 自定义slot组件############################################-->
-                 <span v-else-if="column.slotName" class="ibps-table-column">
-                    <slot  :name="column.slotName" :row="scope.row" :value="scope.row[column.prop]" :column="column" :$index="scope.$index" />
-                  </span>
+                </el-table-column>
 
-                  <!--自定义组件-->
-                  <render-custom-component
-                    v-else-if="column.component && column.component.name"
-                    v-model="scope.row[column.prop]"
-                    :component-name="column.component.name"
-                  />
-                  <!--渲染组件-->
-                  <render-component
-                    v-else-if="column.component && column.component.render"
-                    :render-function="column.component.render"
-                    :scope="scope"
-                  />
-                  <template v-else>
-                    {{ column.formatter ? column.formatter(scope.row, scope.column, _get(scope.row, column.prop), scope.$index) : _get(scope.row, column.prop) }}
-                  </template>
-                </template>
-                <!--子列 -->
-                <template v-if="column.children">
-                  <el-table-column
-                  show-overflow-tooltip
-                    v-for="(column2, index2) in column.children"
-                    :key="index2"
-                    :label="handleAttribute(column2.title, '')"
-                    :prop="handleAttribute(column2.key, null)"
-                    v-bind="column2"
-                  >
+                <!-- 自定义表单名称-->
+                <el-table-column
+                    v-if="formName"
+                    :width="180"
+                    show-overflow-tooltip
+                    label="表单名称"
+                >
                     <template slot-scope="scope">
-                      <!--过滤器-->
-                      <span v-if="column2.filter">
-                        {{ handleColumnFilter(column2.filter,scope.row[column2.prop]) }}
-                      </span>
-                      <!-- 下拉组件-->
-                      <span v-else-if="column2.options" class="table-column-options">
-                        <span>{{ handleColumnOptions('label',column2.options,scope.row[column2.prop]) }}</span>
-                      </span>
-                      <!-- tags组件-->
-                      <span v-else-if="column2.tags" class="table-column-tags">
-                        <el-tag :type="handleTags('type',column2.tags,scope.row[column2.prop])">{{ handleTags('label',column2.tags,scope.row[column2.prop]) }}</el-tag>
-                      </span>
-                      <!-- link组件-->
-                      <span v-else-if="column2.link">
-                        <a href="javascript:void(0)" class="table-column-link" @click="handleColumnLink(column2,scope.row)">{{ scope.row[column2.prop] }}</a>
-                      </span>
-                      <span v-else-if="column2.slotName">
-                        <slot :name="column2.slotName" :row="scope.row" :$index="scope.$index" />
-                      </span>
-                      <!--自定义组件-->
-                      <render-custom-component
-                        v-else-if="column2.component && column2.component.name"
-                        v-model="scope.row[column2.prop]"
-                        :component-name="column2.component.name"
-                      />
-                      <!--渲染组件-->
-                      <render-component
-                        v-else-if="column2.component && column2.component.render"
-                        :render-function="column2.component.render"
-                        :scope="scope"
-                      />
-                      <span v-if="contorlLength">
-                          <el-tooltip class="item" effect="dark" :content="column.formatter ? column.formatter(scope.row, scope.column, _get(scope.row, column.prop), scope.$index) : _get(scope.row, column.prop)" placement="bottom">
-                              <span>
-                             {{ column2.formatter ? column2.formatter(scope.row, scope.column2, _get(scope.row, column2.prop), scope.$index) : _get(scope.row, column2.prop)| ellipsis }}
-                              </span>
-                          </el-tooltip>
-                      </span>
-                      <template v-else>{{ column2.formatter ? column2.formatter(scope.row, scope.column2, _get(scope.row, column2.prop), scope.$index) : _get(scope.row, column2.prop) }}</template>
+                        {{ formName }}
                     </template>
-                  </el-table-column>
-                  <!-- end 子列-->
-                </template>
-              </el-table-column>
-            </template>
-            <!--操作列begin-->
-            <!--  $t('components.crud.manage')    handleAttribute(rowHandle.width, rowHandleDefaultWidth)     -->
-            <el-table-column
-              v-if="rowHandle"
-              v-bind="rowHandle"
-              :label=" handleAttribute(rowHandle.columnHeader,'操作') "
-              :width="handleAttribute(rowHandle.width, rowHandleDefaultWidth) <80 ?  '80' : this.rowHandle.actions.length !=0 && this.rowHandle.actions.length<=3  ? 90 + 50 * (this.rowHandle.actions.length - 1) : 90"
-              :fixed="handleAttribute(rowHandle.fixed, 'right')"
-              :align="handleAttribute(rowHandle.align, 'center')"
-            >
-
+                </el-table-column>
 
-              <template v-slot:default="scope">
+                <!--索引列-->
+                <el-table-column
+                    v-if="indexRow || indexRow === ''"
+                    v-bind="typeof indexRow === 'Object'?indexRow:null"
+                    :label="handleAttribute(indexRow.label, $t('components.crud.index'))"
+                    :width="60"
+                    type="index"
+                />
+                <slot name="prepend-column" />
+                <template v-for="(column, index) in tableColumns">
+                    <el-table-column
+                        v-if="showColumn(column)"
+                        :key="index"
+                        :prop="handleAttribute(column.prop, null)"
+                        :label="handleAttribute(column.label, '')"
+                        :width="handleAttribute(column.width,null)"
+                        v-bind="column"
+                        show-overflow-tooltip
+                    >
+                        <template slot="header">
+                            <slot :name="column.headerName" :column="column" />
+                        </template>
+                        <template slot-scope="scope">
+                            <!--时间格式-->
+                            <span v-if="column.dateFormat" class="ibps-table-column">
+                                {{ scope.row[column.prop] | dateFormat(column.dateFormat,column.origDateFormat) }}
+                            </span>
+                            <!--通用过滤器-->
+                            <span v-else-if="column.filter" class="ibps-table-column">
+                                {{ handleColumnFilter(column.filter,scope.row[column.prop]) }}
+                            </span>
+                            <!-- 下拉组件-->
+                            <span v-else-if="column.options" class="ibps-table-column">
+                                <!--stringArray 字符串类型的数组,逗号分隔-->
+                                <template v-if="column.dataType==='stringArray'">
+                                    <span
+                                        v-for="(value,i) in handleColumnDataConvert(scope.row[column.prop],column.separator)"
+                                        :key="i"
+                                    >
+                                        {{ handleColumnOptions('label',column.options,value,column) }}<template v-if="handleColumnDataConvert(scope.row[column.prop],column.separator).length-1 !==i">,</template>
+                                    </span>
+                                </template>
+                                <!--stringArray 字符串类型的数组-->
+                                <template v-else-if="column.dataType==='objectList'">
+                                    <span v-for="(value,j) in scope.row[column.prop]" :key="j">
+                                        {{ value[column.tagLabel] }}
+                                    </span>
+                                </template>
+                                <span v-else>{{ handleColumnOptions('label',column.options,scope.row[column.prop]) }}</span>
 
-                <slot name="selectCont" :row="scope.row" />
-                <template v-if="hasRowHandleActions(scope.row)">
-                  <template v-if="rowHandle.effect ==='display'">
-                    <ibps-toolbar
-                      v-if="!rowHandleMoreActions || rowHandleMoreActions.length <=1"
-                      :actions="rowHandleActions"
-                      :socpe="thatSocpe"
-                      :data="scope.row"
-                      position="manage"
-                      type="link"
-                      @action-event="handleActionEvent"
-                    />
-                  <template v-if="rowHandleMoreActions && rowHandleMoreActions.length ==1">
-                      <div class="el-divider el-divider--vertical"/>
-                          <ibps-toolbar
-                            :actions="rowHandleMoreActions"
-                            :socpe="thatSocpe"
-                            :data="scope.row"
-                            position="manage"
-                            type="link"
-                            @action-event="handleActionEvent"
-                          />
-                    </template>
+                            </span>
+                            <!-- tags组件-->
+                            <span v-else-if="column.tags" class="ibps-table-column">
+                                <span v-if="$utils.isEmpty(scope.row[column.prop]) ">{{ column.defaultLabel||'' }}</span>
+                                <!--stringArray 字符串类型的数组-->
+                                <template v-else-if="column.dataType==='stringArray'">
+                                    <el-tag
+                                        v-for="(value,i) in handleColumnDataConvert(scope.row[column.prop],column.separator)"
+                                        :key="i"
+                                        :type="handleColumnOptions('type',column.tags,value,column)"
+                                    >
+                                        {{ handleColumnOptions('label',column.tags,value,column) }}
+                                    </el-tag>
+                                </template>
+                                <!--stringArray 字符串类型的数组-->
+                                <template v-else-if="column.dataType==='objectList'">
+                                    <el-tag v-for="(value,j) in scope.row[column.prop]" :key="j">
+                                        {{ value[column.tagLabel] }}
+                                    </el-tag>
+                                </template>
+                                <template v-else>
+                                    <el-tag :type="handleColumnOptions('type',column.tags,scope.row[column.prop],column)">{{ handleColumnOptions('label',column.tags,scope.row[column.prop],column) }}</el-tag>
+                                </template>
+                            </span>
+                            <!-- link组件-->
+                            <span v-else-if="column.link" class="ibps-table-column">
+                                <el-link :type="column.type||'primary'" :underline="column.underline||false" @click="handleColumnLink(column,scope.row)">
+                                    {{ scope.row[column.prop] |removeHtmlTag }}
+                                </el-link>
+                            </span>
 
-                    <template v-if="rowHandleMoreActions && rowHandleMoreActions.length >1" >
-                      <el-dropdown>
-                        <i class="el-icon-caret-bottom el-dropdown-link" style="font-size:14px;">更多</i>
-                        <el-dropdown-menu slot="dropdown" class="ibps-table-dropdown-menu">
-                              <ibps-toolbar
-                                :actions="rowHandleMoreActions.concat(rowHandleActions)"
-                                :socpe="thatSocpe"
-                                :data="scope.row"
-                                position="manage"
-                                type="linkHide"
-                                @action-event="handleActionEvent"
-                              />
-                        </el-dropdown-menu>
-                      </el-dropdown>
-                    </template>
-
-                  </template>
-                  <!-- 下拉-->
-                  <template v-else>
-                    <el-dropdown>
-                      <i class="ibps-icon ibps-icon-chevron-circle-down" style="font-size:24px;" />
-                      <el-dropdown-menu slot="dropdown" class="ibps-table-dropdown-menu">
-                        <ibps-toolbar
-                          :actions="rowHandleActions"
-                          :socpe="thatSocpe"
-                          :data="scope.row"
-                          position="manage"
-                          @action-event="handleActionEvent"
-                        />
-                      </el-dropdown-menu>
-                    </el-dropdown>
+                            <!-- 自定义slot组件############################################-->
+                            <span v-else-if="column.slotName" class="ibps-table-column">
+                                <slot :name="column.slotName" :row="scope.row" :value="scope.row[column.prop]" :column="column" :$index="scope.$index" />
+                            </span>
 
-                    <span>&nbsp;</span>
-                  </template>
+                            <!--自定义组件-->
+                            <render-custom-component
+                                v-else-if="column.component && column.component.name"
+                                v-model="scope.row[column.prop]"
+                                :component-name="column.component.name"
+                            />
+                            <!--渲染组件-->
+                            <render-component
+                                v-else-if="column.component && column.component.render"
+                                :render-function="column.component.render"
+                                :scope="scope"
+                            />
+                            <template v-else>
+                                {{ column.formatter ? column.formatter(scope.row, scope.column, _get(scope.row, column.prop), scope.$index) : _get(scope.row, column.prop) }}
+                            </template>
+                        </template>
+                        <!--子列 -->
+                        <template v-if="column.children">
+                            <el-table-column
+                                v-for="(column2, index2) in column.children"
+                                :key="index2"
+                                show-overflow-tooltip
+                                :label="handleAttribute(column2.title, '')"
+                                :prop="handleAttribute(column2.key, null)"
+                                v-bind="column2"
+                            >
+                                <template slot-scope="scope">
+                                    <!--过滤器-->
+                                    <span v-if="column2.filter">
+                                        {{ handleColumnFilter(column2.filter,scope.row[column2.prop]) }}
+                                    </span>
+                                    <!-- 下拉组件-->
+                                    <span v-else-if="column2.options" class="table-column-options">
+                                        <span>{{ handleColumnOptions('label',column2.options,scope.row[column2.prop]) }}</span>
+                                    </span>
+                                    <!-- tags组件-->
+                                    <span v-else-if="column2.tags" class="table-column-tags">
+                                        <el-tag :type="handleTags('type',column2.tags,scope.row[column2.prop])">{{ handleTags('label',column2.tags,scope.row[column2.prop]) }}</el-tag>
+                                    </span>
+                                    <!-- link组件-->
+                                    <span v-else-if="column2.link">
+                                        <a href="javascript:void(0)" class="table-column-link" @click="handleColumnLink(column2,scope.row)">{{ scope.row[column2.prop] }}</a>
+                                    </span>
+                                    <span v-else-if="column2.slotName">
+                                        <slot :name="column2.slotName" :row="scope.row" :$index="scope.$index" />
+                                    </span>
+                                    <!--自定义组件-->
+                                    <render-custom-component
+                                        v-else-if="column2.component && column2.component.name"
+                                        v-model="scope.row[column2.prop]"
+                                        :component-name="column2.component.name"
+                                    />
+                                    <!--渲染组件-->
+                                    <render-component
+                                        v-else-if="column2.component && column2.component.render"
+                                        :render-function="column2.component.render"
+                                        :scope="scope"
+                                    />
+                                    <span v-if="contorlLength">
+                                        <el-tooltip class="item" effect="dark" :content="column.formatter ? column.formatter(scope.row, scope.column, _get(scope.row, column.prop), scope.$index) : _get(scope.row, column.prop)" placement="bottom">
+                                            <span>
+                                                {{ column2.formatter ? column2.formatter(scope.row, scope.column2, _get(scope.row, column2.prop), scope.$index) : _get(scope.row, column2.prop)| ellipsis }}
+                                            </span>
+                                        </el-tooltip>
+                                    </span>
+                                    <template v-else>{{ column2.formatter ? column2.formatter(scope.row, scope.column2, _get(scope.row, column2.prop), scope.$index) : _get(scope.row, column2.prop) }}</template>
+                                </template>
+                            </el-table-column>
+                            <!-- end 子列-->
+                        </template>
+                    </el-table-column>
                 </template>
-              </template>
-            </el-table-column>
+                <!--操作列begin-->
+                <!--  $t('components.crud.manage')    handleAttribute(rowHandle.width, rowHandleDefaultWidth)     -->
+                <el-table-column
+                    v-if="rowHandle"
+                    v-bind="rowHandle"
+                    :label=" handleAttribute(rowHandle.columnHeader,'操作') "
+                    :width="handleAttribute(rowHandle.width, rowHandleDefaultWidth) <80 ? '80' : this.rowHandle.actions.length !=0 && this.rowHandle.actions.length<=3 ? 90 + 50 * (this.rowHandle.actions.length - 1) : 90"
+                    :fixed="handleAttribute(rowHandle.fixed, 'right')"
+                    :align="handleAttribute(rowHandle.align, 'center')"
+                >
+                    <template v-slot:default="scope">
+                        <slot name="selectCont" :row="scope.row" />
+                        <template v-if="hasRowHandleActions(scope.row)">
+                            <template v-if="rowHandle.effect ==='display'">
+                                <ibps-toolbar
+                                    v-if="!rowHandleMoreActions || rowHandleMoreActions.length <=1"
+                                    :actions="rowHandleActions"
+                                    :socpe="thatSocpe"
+                                    :data="scope.row"
+                                    position="manage"
+                                    type="link"
+                                    @action-event="handleActionEvent"
+                                />
+                                <template v-if="rowHandleMoreActions && rowHandleMoreActions.length ==1">
+                                    <div class="el-divider el-divider--vertical" />
+                                    <ibps-toolbar
+                                        :actions="rowHandleMoreActions"
+                                        :socpe="thatSocpe"
+                                        :data="scope.row"
+                                        position="manage"
+                                        type="link"
+                                        @action-event="handleActionEvent"
+                                    />
+                                </template>
+                                <template v-if="rowHandleMoreActions && rowHandleMoreActions.length >1">
+                                    <el-dropdown>
+                                        <i class="el-icon-caret-bottom el-dropdown-link" style="font-size:14px;">更多</i>
+                                        <el-dropdown-menu slot="dropdown" class="ibps-table-dropdown-menu">
+                                            <ibps-toolbar
+                                                :actions="rowHandleMoreActions.concat(rowHandleActions)"
+                                                :socpe="thatSocpe"
+                                                :data="scope.row"
+                                                position="manage"
+                                                type="linkHide"
+                                                @action-event="handleActionEvent"
+                                            />
+                                        </el-dropdown-menu>
+                                    </el-dropdown>
+                                </template>
+                            </template>
+                            <!-- 下拉-->
+                            <template v-else>
+                                <el-dropdown>
+                                    <i class="ibps-icon ibps-icon-chevron-circle-down" style="font-size:24px;" />
+                                    <el-dropdown-menu slot="dropdown" class="ibps-table-dropdown-menu">
+                                        <ibps-toolbar
+                                            :actions="rowHandleActions"
+                                            :socpe="thatSocpe"
+                                            :data="scope.row"
+                                            position="manage"
+                                            @action-event="handleActionEvent"
+                                        />
+                                    </el-dropdown-menu>
+                                </el-dropdown>
+
+                                <span>&nbsp;</span>
+                            </template>
+                        </template>
+                    </template>
+                </el-table-column>
             <!--操作列end-->
-          </el-table>
-        <!--分页 或底部 自定义底部-->
-        <div
-          v-if="isShowPagination"
-          ref="ibpsCrudFooter"
-          class="ibps-container-crud__footer"
-        >
-          <template v-if="$slots.footer">
-            <slot name="footer" />
-          </template>
-          <el-pagination
-            v-else
-            :current-page="currentPage"
-            :page-size="pageSize"
-            :page-count="pagination[pageCountKey]"
-            :total="pagination[totalKey]"
-            v-bind="paginationOptions"
-            @size-change="handlePaginationSizeChange"
-            @current-change="handlePaginationCurrentChange"
-            @prev-click="handlePaginationPrevClick"
-            @next-click="handlePaginationNextClick"
-          >
-            <template>
-              <span class="el-pagination__total">{{ pageInfo }}</span>
-            </template>
-          </el-pagination>
+            </el-table>
+            <!--分页 或底部 自定义底部-->
+            <div
+                v-if="isShowPagination"
+                ref="ibpsCrudFooter"
+                class="ibps-container-crud__footer"
+            >
+                <template v-if="$slots.footer">
+                    <slot name="footer" />
+                </template>
+                <el-pagination
+                    v-else
+                    :current-page="currentPage"
+                    :page-size="pageSize"
+                    :page-count="pagination[pageCountKey]"
+                    :total="pagination[totalKey]"
+                    v-bind="paginationOptions"
+                    @size-change="handlePaginationSizeChange"
+                    @current-change="handlePaginationCurrentChange"
+                    @prev-click="handlePaginationPrevClick"
+                    @next-click="handlePaginationNextClick"
+                >
+                    <template>
+                        <span class="el-pagination__total">{{ pageInfo }}</span>
+                    </template>
+                </el-pagination>
+            </div>
         </div>
-      </div>
-      <!--显示字段-->
-      <display-field-dialog
-        :visible="displayFieldVisible"
-        :fields="columns"
-        :data="displayFields"
-        @callback="handleDisplayField"
-        @close="visible => displayFieldVisible = visible"
-      />
+        <!--显示字段-->
+        <display-field-dialog
+            :visible="displayFieldVisible"
+            :fields="columns"
+            :data="displayFields"
+            @callback="handleDisplayField"
+            @close="visible => displayFieldVisible = visible"
+        />
     </div>
-  </template>
+</template>
 
-  <script>
-  import base from './mixin/base'
-  import handleRow from './mixin/handleRow'
-  import data from './mixin/data'
-  import search from './mixin/search'
-  import column from './mixin/column'
-  import pagination from './mixin/pagination'
-  import displayField from './mixin/displayField'
-  import utils from './mixin/utils'
+<script>
+import base from './mixin/base'
+import handleRow from './mixin/handleRow'
+import data from './mixin/data'
+import search from './mixin/search'
+import column from './mixin/column'
+import pagination from './mixin/pagination'
+import displayField from './mixin/displayField'
+import utils from './mixin/utils'
 
-  import RenderComponent from './components/render-component.vue'
-  import RenderCustomComponent from './components/render-custom-component.vue'
-  import SearchForm from './components/search-form'
-  import DisplayFieldDialog from './components/display-field'
+import RenderComponent from './components/render-component.vue'
+import RenderCustomComponent from './components/render-custom-component.vue'
+import SearchForm from './components/search-form'
+import DisplayFieldDialog from './components/display-field'
 
-  export default {
-    props:['contorlLength'],
+export default {
     name: 'ibps-crud',
-    filters: { //定义过滤器
-      ellipsis(value) {
-        if (!value) return ''
-        if (value.length > 7) {
-          return value.slice(0,7) + '..'
+    filters: { // 定义过滤器
+        ellipsis (value) {
+            if (!value) return ''
+            if (value.length > 7) {
+                return value.slice(0, 7) + '..'
+            }
+            return value
         }
-        return value
-      }
     },
     components: {
-      RenderComponent,
-      RenderCustomComponent,
-      SearchForm,
-      DisplayFieldDialog
+        RenderComponent,
+        RenderCustomComponent,
+        SearchForm,
+        DisplayFieldDialog
     },
     mixins: [
-      base,
-      data,
-      search,
-      column,
-      handleRow,
-      pagination,
-      displayField,
-      utils
-    ]
-  }
-  </script>
-  <style>
+        base,
+        data,
+        search,
+        column,
+        handleRow,
+        pagination,
+        displayField,
+        utils
+    ],
+    props: ['contorlLength']
+}
+</script>
+<style>
     .el-table th{
-      background-color: #84d5cf !important;
-      font-size: 12px  !important;
-      color: #000000;
-      border: 0px;
+        background-color: #84d5cf !important;
+        font-size: 12px  !important;
+        color: #000000;
+        border: 0px;
     }
     .jbd-title-cont{
-      text-align: center;
-      font-weight: bold;
-      background-color: rgb(249, 255, 255);
-      width: 100%;
-      font-size: 18px;
-      }
+        text-align: center;
+        font-weight: bold;
+        background-color: rgb(249, 255, 255);
+        width: 100%;
+        font-size: 18px;
+    }
     .el-table .caret-wrapper{
-          top: -5px;
-      position: absolute;
-        }
+        top: -5px;
+        position: absolute;
+    }
     .el-table td{
-       padding: 4px 0 !important;
-       color: #000000;
-       font-size: 12px  !important;
-     }
+        padding: 4px 0 !important;
+        color: #000000;
+        font-size: 12px  !important;
+    }
     .el-table .warning-row {
         background: #e0f0ee;
         color: #000000;
-      }
+    }
 
-      .el-table .success-row {
+    .el-table .success-row {
         background: #F9FFFF;
         color: #000000;
-      }
-  </style>
+    }
+</style>

+ 1 - 1
src/components/ibps-crud/mixin/pagination.js

@@ -9,7 +9,7 @@ export default {
       default: () => {
         return {
           pagerCount: 5,
-          pageSizes: [10, 20, 50, 100],
+          pageSizes: [10, 15, 20, 25, 30, 50, 100],
           layout: 'prev, pager, next, jumper,sizes, ->,slot'
         }
       }

+ 1 - 1
src/components/jbd-panel/index.vue

@@ -10,7 +10,7 @@
   <div class="jbd-sys-title">
       <!--<span  class="jbd-sys-title-cont-center" style="margin-left: 40px;float: left;">金通实验室认证认可LIMS系统V2.0</span>-->
       <!-- <span  class="jbd-sys-title-cont-center" style="margin-left: 40px;float: left;">深圳市罗湖医院集团细胞质量检测实验室LIMS系统</span> -->
-      <span  class="jbd-sys-title-cont-center" style="margin-left: 40px;float: left;">金通医学实验室管理系统</span>
+      <span  class="jbd-sys-title-cont-center" style="margin-left: 40px;float: left;">医学实验室标准化智慧管理平台</span>
        <span style="float: right; " class="jbd-sys-title-contact">
          </br>
        深圳市金源信通科技有限公司开发 <i style="margin-left: 10px;" class="el-icon-phone"/> 0755-2642-4403

+ 1 - 0
src/views/platform/org/employee/change-password.vue

@@ -210,6 +210,7 @@ export default {
      */
     restoreDefault() {
       this.password.newPassword = '1'
+      this.password.repeatPassword = '1'
       this.restoreDefaultPassW = 'restoreDefault'
       this.saveData()
     },

+ 221 - 229
src/views/platform/org/employee/edit/position-info.vue

@@ -1,87 +1,79 @@
 <template>
-  <el-row :gutter="10">
-    <el-col v-if="!readonly" :span="8" border>
-      <div class="grid-content">
-        <tree
-          ref="elTree"
-          :height="height"
-          :data="treeData"
-          :check-strictly="checkStrictly"
-          :options="{
-            'default-expand-all': false,
-            'expand-on-click-node': false,
-            'default-expanded-keys':['0'],
-            lazy:true,
-            load:loadTreeNode,
-            props: {
-              children: 'children',
-              label: 'name'
-            }
-          }"
-          node-key="id"
-          @action-event="handleTreeAction"
-        />
-      </div>
-    </el-col>
-    <el-col v-if="!readonly" :span="3">
-      <el-button type="primary" icon="el-icon-d-arrow-right" class="ibps-ml-10" @click="handleBelongTo">分配</el-button>
-      <el-button type="info" icon="el-icon-d-arrow-left" class="ibps-ml-10 ibps-mt-10" @click="handleClear">清空</el-button>
-    </el-col>
-    <el-col :span="spanNumber" border>
-      <el-table
-        :data="posItemList"
-        style="width: 100%"
-        border
-      >
-        <el-table-column
-          label="部门名称"
-        >
-          <template slot-scope="scope">
-            <span style="margin-left: 10px">{{ scope.row.name }}</span>
-          </template>
-        </el-table-column>
-        <el-table-column
-          label="是否主部门"
-          width="100"
-        >
-          <template slot-scope="scope">
-            <el-radio
-              :disabled="readonly"
-              :value="check(scope.row, 'radio')"
-              :label="scope.row.id"
-              @change.native="changeMainPost(scope.$index,scope.row)"
-            >
-              <span>&nbsp;</span>
-            </el-radio>
-          </template>
-        </el-table-column>
-        <el-table-column
-          label="主负责人"
-          width="100"
-        >
-          <template slot-scope="scope">
-            <el-checkbox
-              :disabled="readonly"
-              :value="check(scope.row, 'checkbox')"
-              :label="scope.row.id"
-              @change.native="changeCharge(scope.$index,scope.row)"
+    <el-row :gutter="10">
+        <el-col v-if="!readonly" :span="8" border>
+            <div class="grid-content">
+                <tree
+                    ref="elTree"
+                    :height="height"
+                    :data="treeData"
+                    :check-strictly="checkStrictly"
+                    :options="{
+                        'default-expand-all': false,
+                        'expand-on-click-node': false,
+                        'default-expanded-keys':['0'],
+                        lazy:true,
+                        load:loadTreeNode,
+                        props: {
+                            children: 'children',
+                            label: 'name'
+                        }
+                    }"
+                    node-key="id"
+                    @action-event="handleTreeAction"
+                />
+            </div>
+        </el-col>
+        <el-col v-if="!readonly" :span="3">
+            <el-button type="primary" icon="el-icon-d-arrow-right" class="ibps-ml-10" @click="handleBelongTo">分配</el-button>
+            <el-button type="info" icon="el-icon-d-arrow-left" class="ibps-ml-10 ibps-mt-10" @click="handleClear">清空</el-button>
+        </el-col>
+        <el-col :span="spanNumber" border>
+            <el-table
+                :data="posItemList"
+                style="width: 100%"
+                border
             >
-              <span>&nbsp;</span>
-            </el-checkbox>
-          </template>
-        </el-table-column>
-        <el-table-column v-if="!readonly" label="管理" width="100">
-          <template slot-scope="scope">
-            <el-button
-              size="mini"
-              type="danger"
-              @click.native.prevent="deleteRow(scope.$index,posItemList)"
-            >删除</el-button>
-          </template>
-        </el-table-column>
-      </el-table>
-    </el-col>
-  </el-row>
+                <el-table-column label="部门名称">
+                    <template slot-scope="scope">
+                        <span style="margin-left: 10px">{{ scope.row.name }}</span>
+                    </template>
+                </el-table-column>
+                <el-table-column label="是否主部门" width="100">
+                    <template slot-scope="scope">
+                        <el-radio
+                            :disabled="readonly"
+                            :value="check(scope.row, 'radio')"
+                            :label="scope.row.id"
+                            @change.native="changeMainPost(scope.$index,scope.row)"
+                        >
+                            <span>&nbsp;</span>
+                        </el-radio>
+                    </template>
+                </el-table-column>
+                <el-table-column label="主负责人" width="100">
+                    <template slot-scope="scope">
+                        <el-checkbox
+                            :disabled="readonly"
+                            :value="check(scope.row, 'checkbox')"
+                            :label="scope.row.id"
+                            @change.native="changeCharge(scope.$index,scope.row)"
+                        >
+                            <span>&nbsp;</span>
+                        </el-checkbox>
+                    </template>
+                </el-table-column>
+                <el-table-column v-if="!readonly" label="管理" width="100">
+                    <template slot-scope="scope">
+                        <el-button
+                            size="mini"
+                            type="danger"
+                            @click.native.prevent="deleteRow(scope.$index,posItemList)"
+                        >删除</el-button>
+                    </template>
+                </el-table-column>
+            </el-table>
+        </el-col>
+    </el-row>
 </template>
 <script>
 import { findTreeData as getTreeData } from '@/api/platform/org/position'
@@ -91,161 +83,161 @@ import TreeUtils from '@/utils/tree'
 import Tree from '../../components/tree'
 
 export default {
-  components: {
-    Tree
-  },
-  props: {
-    data: Array,
-    readonly: {
-      type: Boolean,
-      default: false
+    components: {
+        Tree
     },
-    orgId: [Number, String],
-    span: [Number, String]
-  },
-  data() {
-    return {
-      parentId: '0',
-      pkKey: 'id',
-      nameKey: 'name',
-      treeData: [],
-      posItemList: [],
-      height: document.clientHeight,
-      checkStrictly: true,
-      defaultTreeData: []
-    }
-  },
-  computed: {
-    spanNumber() {
-      return this.span
-    }
-  },
-  watch: {
-    data: {
-      handler: function(val, oldVal) {
-        this.posItemList = val
-        const arr = JSON.parse(JSON.stringify(val))
-        arr.forEach(item => {
-          this.defaultTreeData.push(item.id)
-        })
-        if (this.$refs.elTree) {
-          this.$refs.elTree.setCheckedKeys(this.defaultTreeData, true)
+    props: {
+        data: Array,
+        readonly: {
+            type: Boolean,
+            default: false
+        },
+        orgId: [Number, String],
+        span: [Number, String]
+    },
+    data () {
+        return {
+            parentId: '0',
+            pkKey: 'id',
+            nameKey: 'name',
+            treeData: [],
+            posItemList: [],
+            height: document.clientHeight,
+            checkStrictly: true,
+            defaultTreeData: []
         }
-      },
-      deep: true
     },
-    posItemList: {
-      handler: function(val, oldVal) {
-        if (val !== oldVal) {
-          this.handleEmitEvent()
+    computed: {
+        spanNumber () {
+            return this.span
         }
-      },
-      deep: true
-    }
-  },
-  methods: {
-    init() {
-      if (this.$refs.elTree) {
-        this.$refs.elTree.setCheckedNodes([])
-      }
-      this.defaultTreeData = []
     },
-    // 查询
-    refreshNode() {
-      const node = this.$refs.elTree.getNode(this.parentId)
-      node.loaded = false
-      node.expand()
+    watch: {
+        data: {
+            handler: function (val, oldVal) {
+                this.posItemList = val
+                const arr = JSON.parse(JSON.stringify(val))
+                arr.forEach(item => {
+                    this.defaultTreeData.push(item.id)
+                })
+                if (this.$refs.elTree) {
+                    this.$refs.elTree.setCheckedKeys(this.defaultTreeData, true)
+                }
+            },
+            deep: true
+        },
+        posItemList: {
+            handler: function (val, oldVal) {
+                if (val !== oldVal) {
+                    this.handleEmitEvent()
+                }
+            },
+            deep: true
+        }
     },
-    // 加载岗位树
-    loadTreeNode(node, resolve) {
-      this.loading = true
-      const params = {}
-      params.type = '1'
-      params.posId = node.level === 0 ? null : node.data.id
+    methods: {
+        init () {
+            if (this.$refs.elTree) {
+                this.$refs.elTree.setCheckedNodes([])
+            }
+            this.defaultTreeData = []
+        },
+        // 查询
+        refreshNode () {
+            const node = this.$refs.elTree.getNode(this.parentId)
+            node.loaded = false
+            node.expand()
+        },
+        // 加载岗位树
+        loadTreeNode (node, resolve) {
+            this.loading = true
+            const params = {}
+            params.type = '1'
+            params.posId = node.level === 0 ? null : node.data.id
 
-      if (this.moreSearchParams) {
-        Object.assign(params, this.moreSearchParams)
-      }
-      getTreeData(params).then(res => {
-        this.loading = false
-        const arr = JSON.parse(JSON.stringify(res.data))
-        const treeData = this.toTree(arr)
-        if (treeData[0].id === '0') {
-          treeData[0].name = '部门树'
-          treeData[0].disabled = true
-        } // 根节点不能选择
-        resolve(treeData)
-      }).catch(res => {
-        this.loading = false
-        resolve([])
-      })
-    },
-    toTree(data) {
-      return TreeUtils.transformToTreeFormat(data, {
-        idKey: 'id',
-        pIdKey: 'parentId',
-        childrenKey: 'children'
-      })
-    },
-    // 树事件
-    handleTreeAction(command, position, selection, data) {
-      if (position === 'toolbar' && command === 'refresh') {
-        this.refreshNode()
-      }
-    },
-    // 属于
-    handleBelongTo() {
-      const tree = this.$refs.elTree
-      const postInfo = tree.getCheckedNodes() // 勾选
-      if (this.$utils.isEmpty(postInfo)) {
-        this.hint()
-        return
-      }
-      for (let i = 0; i < postInfo.length; i++) {
-        if (postInfo[i].id === '0') {
-          postInfo.splice(i, 1)
+            if (this.moreSearchParams) {
+                Object.assign(params, this.moreSearchParams)
+            }
+            getTreeData(params).then(res => {
+                this.loading = false
+                const arr = JSON.parse(JSON.stringify(res.data))
+                const treeData = this.toTree(arr)
+                if (treeData[0].id === '0') {
+                    treeData[0].name = '部门树'
+                    treeData[0].disabled = true
+                } // 根节点不能选择
+                resolve(treeData)
+            }).catch(res => {
+                this.loading = false
+                resolve([])
+            })
+        },
+        toTree (data) {
+            return TreeUtils.transformToTreeFormat(data, {
+                idKey: 'id',
+                pIdKey: 'parentId',
+                childrenKey: 'children'
+            })
+        },
+        // 树事件
+        handleTreeAction (command, position, selection, data) {
+            if (position === 'toolbar' && command === 'refresh') {
+                this.refreshNode()
+            }
+        },
+        // 属于
+        handleBelongTo () {
+            const tree = this.$refs.elTree
+            const postInfo = tree.getCheckedNodes() // 勾选
+            if (this.$utils.isEmpty(postInfo)) {
+                this.hint()
+                return
+            }
+            for (let i = 0; i < postInfo.length; i++) {
+                if (postInfo[i].id === '0') {
+                    postInfo.splice(i, 1)
+                }
+            }
+            this.posItemList = concat(this.posItemList, postInfo)
+        },
+        hint () {
+            this.$alert('你还没有选择任何节点!', '信息', {
+                confirmButtonText: '确定',
+                type: 'warning'
+            }).then(() => {})
+        },
+        handleClear () {
+            this.posItemList = []
+            this.init()
+        },
+        deleteRow (index, row) {
+            row.splice(index, 1)
+        },
+        changeMainPost (index, row) {
+            this.radioSelection = row
+            for (const item of this.posItemList) {
+                item.isMainPost = 'N'
+            }
+            row.isMainPost = 'Y'
+        },
+        changeCharge (index, row) {
+            this.checkBoxSelection = row
+            if (row.isPrincipal === 'Y') {
+                row.isPrincipal = 'N'
+            } else {
+                row.isPrincipal = 'Y'
+            }
+        },
+        handleEmitEvent () {
+            this.$emit('input', this.posItemList)
+        },
+        check (row, type) {
+            if (type === 'radio') {
+                return row.isMainPost === 'Y' ? row.id : false
+            } else if (type === 'checkbox') {
+                return row.isPrincipal === 'Y'
+            }
         }
-      }
-      this.posItemList = concat(this.posItemList, postInfo)
-    },
-    hint() {
-      this.$alert('你还没有选择任何节点!', '信息', {
-        confirmButtonText: '确定',
-        type: 'warning'
-      }).then(() => {})
-    },
-    handleClear() {
-      this.posItemList = []
-      this.init()
-    },
-    deleteRow(index, row) {
-      row.splice(index, 1)
-    },
-    changeMainPost(index, row) {
-      this.radioSelection = row
-      for (const item of this.posItemList) {
-        item.isMainPost = 'N'
-      }
-      row.isMainPost = 'Y'
-    },
-    changeCharge(index, row) {
-      this.checkBoxSelection = row
-      if (row.isPrincipal === 'Y') {
-        row.isPrincipal = 'N'
-      } else {
-        row.isPrincipal = 'Y'
-      }
-    },
-    handleEmitEvent() {
-      this.$emit('input', this.posItemList)
-    },
-    check(row, type) {
-      if (type === 'radio') {
-        return row.isMainPost === 'Y' ? row.id : false
-      } else if (type === 'checkbox') {
-        return row.isPrincipal === 'Y'
-      }
     }
-  }
 }
 </script>

+ 1 - 1
src/views/system/dashboard/components/new-home.vue

@@ -386,7 +386,7 @@ export default {
             // 获取任务数据
             this.getData(this.activeTab)
         },
-	        // 获取系统用户信息
+        // 获取系统用户信息
         getUserList () {
             const { userList } = this.$store.getters
             // store中有则无需请求

+ 830 - 0
src/views/system/dashboard/components/workbench.vue

@@ -0,0 +1,830 @@
+<template>
+    <div class="app-container">
+        <el-tabs v-model="activeTab" class="tabs" :before-leave="handleChange" @tab-click="changeTab">
+            <el-tab-pane v-for="item in tabList" :key="item.key" :name="item.key">
+                <span slot="label"><i :class="item.icon" /> {{ item.label }}</span>
+                <div v-if="activeTab === item.key" class="tab-container">
+                    <div class="table-container">
+                        <ibps-crud
+                            :ref="item.key"
+                            :data="dataList"
+                            :toolbars="item.key === 'save' ? listConfig.darftTool : listConfig.toolbars"
+                            :search-form="listConfig.searchForm[item.key]"
+                            :pk-key="pkKey"
+                            :columns="listConfig.columns[item.key]"
+                            :pagination="pagination"
+                            :loading="loading"
+                            :index-row="false"
+                            :selection-row="item.key === 'save'"
+                            @row-click="handleRowClick"
+                            @action-event="handleAction"
+                            @sort-change="handleSortChange"
+                            @pagination-change="handlePaginationChange"
+                        >
+                            <template slot="name" slot-scope="scope">{{ scope.row.subject | getWorkInfo('name') }}</template>
+                            <template slot="desc" slot-scope="scope">{{ scope.row.subject | getWorkInfo('desc') }}</template>
+                            <!-- 待办字段处理 -->
+                            <template slot="waitStatus" slot-scope="scope">{{ '待' + scope.row.name }}</template>
+                            <template slot="stateLabel" slot-scope="scope">
+                                <span>{{ scope.column.label }}</span>
+                                <el-tooltip effect="dark" placement="top">
+                                    <div slot="content">
+                                        普通事务:接收三天之内为待办理,三天之后为已超时
+                                        <br>
+                                        计划事务:月底前七天内为即将超时,超过接收当月月底为已超时,其余为待办理
+                                    </div>
+                                    <i class="el-icon-info" />
+                                </el-tooltip>
+                            </template>
+                            <template slot="state" slot-scope="scope">
+                                <el-tag :type="scope.row.state ? stateOption[scope.row.state].type : ''">{{ scope.row.state ? stateOption[scope.row.state].label : '待办理' }}</el-tag>
+                            </template>
+                            <template slot="submitBy" slot-scope="scope">
+                                <span>{{ scope.column.label }}</span>
+                                <el-tooltip effect="dark" placement="top">
+                                    <div slot="content">
+                                        该事务对应流程的发起人
+                                    </div>
+                                    <i class="el-icon-info" />
+                                </el-tooltip>
+                            </template>
+                            <template slot="forwardBy" slot-scope="scope">
+                                <span>上节点</span><br>
+                                <span>提交人</span>
+                                <el-tooltip effect="dark" placement="top">
+                                    <div slot="content">
+                                        该事务对应流程上一节点的提交人
+                                    </div>
+                                    <i class="el-icon-info" />
+                                </el-tooltip>
+                            </template>
+                            <!-- 已办、办结字段处理 -->
+                            <template slot="overStatus" slot-scope="scope">{{ getStatus(scope.row.status) }}</template>
+                            <template slot="overDept" slot-scope="scope">{{ getParenthesesStr(scope.row.subject)[1] }}</template>
+                            <template slot="creator" slot-scope="scope">{{ scope.row.createBy | getUserName(userList) }}</template>
+                            <template slot="updateBy" slot-scope="scope">{{ getName(scope.row) }}</template>
+                        </ibps-crud>
+                    </div>
+                </div>
+            </el-tab-pane>
+        </el-tabs>
+        <bpmn-formrender
+            :visible="dialogFormVisible"
+            :task-id="activeTab === 'wait' ? taskId : null"
+            :wai-jian="activeTab === 'wait' ? waiJian : null"
+            :instance-id="['over', 'finish'].includes(activeTab) ? instanceId : null"
+            :def-id="activeTab === 'save' ? defId : null"
+            :pro-inst-id="activeTab === 'save' ? proInstId : null"
+            :title="['wait', 'save'].includes(activeTab) ? FlowName : null"
+            @callback="getData(activeTab)"
+            @close="visible => (dialogFormVisible = visible)"
+        />
+        <news-detail
+            :id="newsId"
+            title="公告明细"
+            :visible="newsDialogVisible"
+            readonly
+            @close="visible => newsDialogVisible = visible"
+        />
+    </div>
+</template>
+
+<script>
+import { pending, handledTask } from '@/api/platform/office/bpmReceived'
+import { myDraft, removeDraft } from '@/api/platform/office/bpmInitiated'
+import { queryPageList as newsList } from '@/api/platform/system/news'
+import { queryOrgManager } from '@/api/platform/org/employee'
+import { save } from '@/api/platform/message/innerMessage'
+import BpmnFormrender from '@/business/platform/bpmn/form/dialog'
+import ActionUtils from '@/utils/action'
+import { typeOptions } from '@/views/platform/system/news/constants'
+import NewsDetail from '@/views/platform/system/news/detail'
+
+const tabList = [
+    {
+        label: '待办事宜',
+        key: 'wait',
+        icon: 'el-icon-edit'
+    },
+    {
+        label: '已办事宜',
+        key: 'over',
+        icon: 'el-icon-document-remove'
+    },
+    {
+        label: '办结事宜',
+        key: 'finish',
+        icon: 'el-icon-paperclip'
+    },
+    {
+        label: '暂存事宜',
+        key: 'save',
+        icon: 'el-icon-receiving'
+    },
+    {
+        label: '通知公告',
+        key: 'news',
+        icon: 'el-icon-message'
+    }
+]
+const taskState = {
+    running: '已发起',
+    end: '已结束',
+    manualend: '人工结束'
+}
+const paramsType = {
+    wait: 'temp.',
+    over: '',
+    finish: 'inst.',
+    save: '',
+    news: ''
+}
+const stateOption = {
+    wait: {
+        label: '待办理',
+        type: ''
+    },
+    soon: {
+        label: '即将超时',
+        type: 'warning'
+    },
+    overtime: {
+        label: '已超时',
+        type: 'danger'
+    }
+}
+const operate = {
+    wait: pending,
+    over: handledTask,
+    finish: handledTask,
+    save: myDraft,
+    news: newsList
+}
+
+export default {
+    name: 'calendar',
+    components: { BpmnFormrender, NewsDetail },
+    filters: {
+        getWorkInfo (v, type) {
+            const hasDesc = v.includes('#')
+            const res = {
+                name: {
+                    '0': v.includes('{') ? v.split('{')[0] : v.includes('(') ? v.split('(')[0] : v,
+                    '1': v.split('#')[0]
+                },
+                // 无#返回空,有#返回(左边的字符串,
+                desc: {
+                    '0': '',
+                    '1': v.split('#')[1]
+                }
+            }
+            if (!hasDesc) {
+                return res[type]['0']
+            }
+            return res[type]['1']
+        },
+        getUserName (v, list) {
+            const user = list.find(i => i.userId === v)
+            return user ? user.userName : ''
+        }
+    },
+    props: {
+        plan: {
+            type: Array,
+            default: () => []
+        }
+    },
+    data () {
+        return {
+            tabList,
+            stateOption,
+            pkKey: 'id',
+            taskId: '', // 编辑dialog需要使用
+            waiJian: '', // 编辑dialog需要使用
+            instanceId: '',
+            defId: '',
+            proInstId: '',
+            newsId: '',
+            loading: false,
+            dialogFormVisible: false,
+            newsDialogVisible: false,
+            orgName: '',
+            roleName: '',
+            FlowName: '',
+            posName: '',
+            timer: null,
+            userList: [],
+            orgInfo: {},
+            activeTab: tabList[0].key,
+            height: document.body.clientHeight,
+            selection: [],
+            defaultPagination: { page: 1, limit: 15 },
+            sorts: { CREATE_TIME_: 'DESC' },
+            dataList: [],
+            pagination: {},
+            searchParams: {
+                typeId: '',
+                subject: '',
+                createTime: ''
+            },
+            listConfig: {
+                searchForm: {
+                    wait: {
+                        forms: [
+                            { prop: 'Q^subject_^SL', name: 'Q^temp.subject_^SL', label: '事务名称', fieldType: 'input' },
+                            { prop: ['Q^temp.create_time_^DL', 'Q^temp.create_time_^DG'], label: '提交时间', fieldType: 'daterange' }
+                        ]
+                    },
+                    over: {
+                        forms: [
+                            { prop: 'Q^subject_^SL', label: '事务名称', fieldType: 'input' },
+                            { prop: ['Q^create_time_^DL', 'Q^create_time_^DG'], label: '创建时间', fieldType: 'daterange' }
+                        ]
+                    },
+                    finish: {
+                        forms: [
+                            { prop: 'Q^subject_^SL', name: 'Q^inst.subject_^SL', label: '事务名称', fieldType: 'input' },
+                            { prop: ['Q^create_time_^DL', 'Q^create_time_^DG'], name: ['Q^inst.create_time_^DL', 'Q^inst.create_time_^DG'], label: '结束时间', fieldType: 'daterange' }
+                        ]
+                    },
+                    save: {
+                        forms: [
+                            { prop: 'Q^subject_^SL', label: '事务名称', fieldType: 'input' },
+                            { prop: ['Q^create_time_^DL', 'Q^create_time_^DG'], label: '提交时间', fieldType: 'daterange' }
+                        ]
+                    },
+                    news: {
+                        forms: [
+                            { prop: 'Q^title_^SL', label: '标题', fieldType: 'input' },
+                            { prop: 'Q^user_name_^SL', label: '发布人', fieldType: 'input' },
+                            { prop: ['Q^public_date_^DL', 'Q^public_date_^DG'], label: '发布时间', fieldType: 'daterange' }
+                        ]
+                    }
+                },
+                toolbars: [
+                    {
+                        key: 'search'
+                    }
+                ],
+                darftTool: [
+                    {
+                        key: 'search'
+                    },
+                    {
+                        key: 'remove'
+                    }
+                ],
+                // 表格字段配置
+                columns: {
+                    wait: [
+                        { prop: 'scope', label: '事务名称', slotName: 'name', width: 250 },
+                        { prop: 'scope', label: '事务说明', slotName: 'desc', minWidth: 250 },
+                        { prop: 'scope', label: '事务状态', slotName: 'waitStatus', width: 120 },
+                        { prop: 'scope', label: '办理进度', headerName: 'stateLabel', slotName: 'state', width: 120 },
+                        { prop: 'startDept', label: '发起部门', width: 120 },
+                        { prop: 'submitBy', label: '发起人', headerName: 'submitBy', width: 100 },
+                        { prop: 'forwardBy', label: `上节点提交人`, headerName: 'forwardBy', width: 100 },
+                        { prop: 'createTime', label: '上节点提交时间', width: 150 }
+                    ],
+                    over: [
+                        { prop: 'scope', label: '事务名称', slotName: 'name', width: 250 },
+                        { prop: 'scope', label: '事务说明', slotName: 'desc', minWidth: 250 },
+                        { prop: 'scope', label: '事务状态', slotName: 'overStatus', width: 120 },
+                        { prop: 'scope', label: '发起部门', slotName: 'overDept', width: 120 },
+                        { prop: 'scope', label: '发起人', headerName: 'submitBy', slotName: 'creator', width: 100 },
+                        { prop: 'scope', label: `提交人`, slotName: 'updateBy', width: 100 },
+                        { prop: 'createTime', label: '创建时间', width: 150 }
+                    ],
+                    finish: [
+                        { prop: 'scope', label: '事务名称', slotName: 'name', width: 250 },
+                        { prop: 'scope', label: '事务说明', slotName: 'desc', minWidth: 250 },
+                        { prop: 'scope', label: '事务状态', slotName: 'overStatus', width: 120 },
+                        { prop: 'scope', label: '发起部门', slotName: 'overDept', width: 120 },
+                        { prop: 'scope', label: '发起人', headerName: 'submitBy', slotName: 'creator', width: 100 },
+                        { prop: 'scope', label: `提交人`, slotName: 'updateBy', width: 100 },
+                        { prop: 'createTime', label: '结束时间', width: 150 }
+                    ],
+                    save: [
+                        { prop: 'scope', label: '事务名称', slotName: 'name', width: 250 },
+                        { prop: 'scope', label: '事务说明', slotName: 'desc', minWidth: 250 },
+                        { prop: 'createTime', label: '暂存时间', width: 150 }
+                    ],
+                    news: [
+                        { prop: 'title', label: '标题', minWidth: 250 },
+                        { prop: 'userName', label: '发布人', width: 120 },
+                        { prop: 'publicDate', label: '发布时间', dateFormat: 'yyyy-MM-dd', width: 120 },
+                        { prop: 'loseDate', label: '失效时间', dateFormat: 'yyyy-MM-dd', width: 120 },
+                        { prop: 'status', label: '发布状态', tags: typeOptions, width: 100 }
+                    ]
+                }
+            }
+        }
+    },
+    mounted: function () {
+        this.getData(this.activeTab)
+        this.getUserList()
+        this.getOrgInfo()
+        if (this.timer) {
+            clearInterval(this.timer)
+        }
+        // 轮询刷新公告数据和任务数据
+        this.timer = setInterval(() => {
+            // this.getMessage()
+            this.getData(this.activeTab)
+        }, 30 * 1000)
+    },
+    beforeDestroy () {
+        clearInterval(this.timer)
+    },
+    // 路由离开时
+    beforeRouteLeave (to, from, next) {
+        clearInterval(this.timer)
+    },
+    methods: {
+        // 获取系统用户信息
+        getUserList () {
+            const { userList } = this.$store.getters
+            // store中有则无需请求
+            if (userList && userList.length) {
+                this.userList = userList
+                return
+            }
+            const sql = `select id_ as userId, name_ as userName, mobile_ as phone from ibps_party_employee where status_ = 'actived'`
+            this.$common.request('sql', sql).then(res => {
+                this.userList = res.variables && res.variables.data
+            })
+        },
+        // 获取用户部门信息
+        getOrgInfo () {
+            const { org = {}} = this.$store.getters
+            if (!org || !org.id) {
+                return
+            }
+            const params = {
+                parameters: [{ key: 'Q^MANAGER_ORG_ID_^S', value: org.id }]
+            }
+            queryOrgManager(params).then(res => {
+                this.orgInfo = {}
+                const data = res.data.dataResult
+                if (data && data.length) {
+                    const { id, name, mobile, account, gender, groupID } = data[0]
+                    this.orgInfo = { id, name, mobile, account, gender, groupID, orgName: org.name }
+                }
+            })
+        },
+        getName ({ createBy, updateBy }) {
+            const id = updateBy || createBy
+            const { name = '' } = this.$store.getters
+            if (this.activeTab === 'finish') {
+                const t = this.userList.find(i => i.userId === id)
+                return t ? t.userName : ''
+            }
+            return name
+        },
+        getStatus (val) {
+            const s = taskState[val]
+            return s || '暂停'
+        },
+        tableRowClassName ({ row, rowIndex }) {
+            if (rowIndex % 2 === 1) return 'warning-row'
+            return 'success-row'
+        },
+        // 获取表格数据
+        getData (type) {
+            this.loading = true
+            const pageParams = this.pagination.page ? this.pagination : this.defaultPagination
+            operate[this.activeTab](this.getFormatParams(null, pageParams)).then(response => {
+                const { dataResult, pageResult } = response.data
+                if (dataResult && dataResult.length) {
+                    // 待办事宜对任务发起人做额外处理
+                    if (type === 'wait') {
+                        const instList = []
+                        dataResult.forEach(item => {
+                            instList.push(item.bpmnInstId)
+                        })
+                        const sql = `select b.bpmn_inst_id_, b.create_by_, a.name_ from ibps_bpm_inst b left join ibps_party_employee a on a.id_ = b.create_by_ where b.bpmn_inst_id_ in (${instList.join(',')}) order by find_in_set(b.bpmn_inst_id_,'${instList.join(',')}')`
+                        const currentTime = Date.now()
+                        this.$common.request('sql', sql).then(res => {
+                            const data = res.variables && res.variables.data
+                            data.forEach((item, index) => {
+                                dataResult[index].submitBy = item.name_
+                                dataResult[index].workName = dataResult[index].subject.includes('#') ? dataResult[index].subject.split('#')[0] : dataResult[index].subject.split('(')[0]
+                                dataResult[index].workType = this.plan.includes(dataResult[index].procDefKey) ? 'plan' : 'normal'
+                                dataResult[index].state = this.judgeExpire(dataResult[index].createTime, currentTime, dataResult[index].workType, '1')
+                            })
+                            this.dataList = dataResult.sort((a, b) => b.createTime.localeCompare(a.createTime))
+                            this.pagination = pageResult
+                        })
+                        this.urgeToManager()
+                    } else {
+                        this.dataList = dataResult
+                        this.pagination = pageResult
+                    }
+                }
+                this.loading = false
+            }).catch(() => {
+                this.loading = false
+            })
+        },
+        // 查询
+        search () {
+            this.dataList = []
+            this.pagination = {}
+            this.getData(this.activeTab)
+        },
+        handleChange (activeName, oldActiveName) {
+            // this.$refs[oldActiveName][0].handleReset()
+        },
+        // 切换tab
+        changeTab () {
+            // 数据、筛选条件初始化
+            this.dataList = []
+            this.selection = []
+            this.pagination = {}
+            this.getData(this.activeTab)
+        },
+        handleSortChange (sort) {
+            console.log(sort)
+            ActionUtils.setSorts(this.sorts, sort)
+            this.getData(this.activeTab)
+        },
+        handlePaginationChange (page) {
+            ActionUtils.setPagination(this.pagination, page)
+            this.getData(this.activeTab)
+        },
+        getFormatParams (v, page) {
+            const params = this.$refs[this.activeTab] && this.$refs[this.activeTab].length ? this.$refs[this.activeTab][0].getSearcFormData() : {}
+            if (this.activeTab === 'finish') {
+                params.end = '1'
+            }
+            const s = this.activeTab === 'news' ? { 'PUBLIC_DATE_': 'DESC' } : this.sorts
+            return ActionUtils.formatParams(params, page, s)
+        },
+        // 处理表格点击事件
+        handleRowClick (data) {
+            if (this.activeTab === 'news') {
+                this.newsId = data.id
+                this.newsDialogVisible = true
+                return
+            }
+            this.taskId = data.id || ''
+            this.waiJian = data.waiJian || ''
+            this.instanceId = data.id || ''
+            this.defId = data.procDefId || ''
+            this.proInstId = data.id || ''
+            this.FlowName = data.name
+            this.dialogFormVisible = true
+        },
+        handleAction (command, position, selection, data) {
+            switch (command) {
+                case 'search':// 查询
+                    ActionUtils.setFirstPagination(this.pagination)
+                    this.search()
+                    break
+                case 'remove':// 删除
+                    ActionUtils.removeRecord(selection).then((ids) => {
+                        console.log(ids)
+                        this.handleRemove(ids)
+                    }).catch(() => { })
+                    break
+                default:
+                    break
+            }
+        },
+        // 删除暂存数据
+        handleRemove (ids) {
+            removeDraft({ ids }).then(() => {
+                ActionUtils.removeSuccessMessage()
+                this.selection = []
+                this.search()
+            })
+        },
+        // 数组去重
+        unique (arr) {
+            const res = new Map()
+            return arr.filter(arr => !res.has(arr.id) && res.set(arr.id, 1))
+        },
+        // 文字替换
+        getParenthesesStr (text) {
+            let result = ''
+            if (!text) return result
+            const regex1 = /\{(.+?)\}/g
+            const regex2 = /\((.+?)\)/g
+            const options1 = text.match(regex1)
+            const options2 = text.match(regex2)
+            const options = options1 && options1.length ? options1 : options2
+            if (options) {
+                const option = options[0]
+                if (option) {
+                    result = option.substring(1, option.length - 1)
+                }
+                if (options[1]) {
+                    const yersOption = options[1]
+                    if (yersOption) {
+                        result = result + '/' + yersOption.substring(1, yersOption.length - 1)
+                    }
+                }
+            }
+            return result.split('/')
+        },
+        /**
+         * 主管提醒
+         * 数据处理,将所有待办数据根据是否过期处理为两个数组
+         * 过期判断依据:普通事务-创建时间到当前时间超过三天即为过期;计划事务【事务名称中含计划】-创建当月月末前七天
+         * 逻辑说明:过期数组中不存于在主管提醒表中的数据插入主管提醒表,并发送内部通知,主管提醒表删除不存在于未过期数组中的数据
+         */
+        urgeToManager () {
+            const { userId } = this.$store.getters
+            const params = {
+                parameters: [],
+                sorts: []
+            }
+            const sql = `select id_, shi_wu_id_ as taskId from t_gqswb where position('${userId}' in chu_li_ren_id_) FOR UPDATE`
+            // Promise.all([pending(params), this.$common.request('sql', sql)]).then(([res1, res2]) => {
+            //     let workData = res1.data && res1.data.dataResult
+            //     let noticeData = res2.variables && res2.variables.data
+            //     if (!workData || !workData.length) {
+            //         return
+            //     }
+            //     this.dealData(workData, noticeData)
+            // })
+            pending(params).then(res1 => {
+                const workData = res1.data && res1.data.dataResult
+                this.$common.request('sql', sql).then(res2 => {
+                    const noticeData = res2.variables && res2.variables.data
+                    if (!workData || !workData.length) {
+                        return
+                    }
+                    this.dealData(workData, noticeData)
+                })
+            })
+        },
+        // 处理数据
+        dealData (workList, noticeList) {
+            const result = {
+                expire: [],
+                unexpire: [],
+                all: []
+            }
+            const currentTime = Date.now()
+            // 筛选已过期数据
+            workList.forEach(item => {
+                // 截取流程名
+                item.workName = item.subject.includes('#') ? item.subject.split('#')[0] : item.subject.split('(')[0]
+                item.workType = this.plan.includes(item.procDefKey) ? 'plan' : 'normal'
+                const isExpire = this.judgeExpire(item.createTime, currentTime, item.workType)
+                if (isExpire) {
+                    result.expire.push(item)
+                } else {
+                    result.unexpire.push(item)
+                }
+                result.all.push(item)
+            })
+            // console.log('处理后数据:', result)
+            // 有过期数据才执行过期数据处理
+            if (result.expire.length) {
+                this.dealExpile(result.expire, noticeList)
+            }
+            // 主管提醒表中有数据才执行数据删除
+            if (noticeList && noticeList.length) {
+                this.dealUnexpile(result.all, noticeList)
+            }
+        },
+        // 判断是否过期、获取办理状态
+        judgeExpire (time, current, type, isState) {
+            const D = new Date(time)
+            const a = new Date(time).getTime()
+            const b = new Date(current).getTime()
+            // 创建时间当月最后一天的时间戳
+            const c = new Date(D.getFullYear(), D.getMonth() + 1, 0).getTime() + 86400000
+            // 返回办理状态
+            if (isState) {
+                let state = ''
+                if (type === 'plan') {
+                    state = b >= c ? 'overtime' : b + (86400000 * 7) > c ? 'soon' : 'wait'
+                } else {
+                    state = a + (86400000 * 3) < b ? 'overtime' : 'wait'
+                }
+                return state
+            }
+            // 返回是否过期
+            if (type === 'plan') {
+                return b + (86400000 * 7) > c
+            } else {
+                return a + (86400000 * 3) < b
+            }
+        },
+        // 处理已过期数据
+        dealExpile (data, noticeList) {
+            // console.log('已过期流程数据:', data)
+            // console.log('过期事务表数据:', noticeList)
+            const { userId } = this.$store.getters
+            const addList = []
+            const sendList = []
+            const msgContent = {
+                plan: '距离过期还剩七天,请及时处理!',
+                normal: '至今三天未处理,已超时,请及时处理!'
+            }
+            const msgTitle = {
+                plan: '计划事务即将到期提醒',
+                normal: '事务超时提醒'
+            }
+            const nowTime = new Date(new Date().getTime() + 28800000).toJSON().slice(0, 16).replace('T', ' ')
+            data.forEach(item => {
+                const isExist = !!noticeList.find(i => i.taskId === item.taskId)
+                // 筛选出不存在于主管提醒表的过期数据
+                if (!isExist) {
+                    // 无部门信息的用户不往过期事务表加数据
+                    if (this.orgInfo.groupID) {
+                        const obj = {
+                            // 事务ID
+                            shi_wu_id_: item.taskId,
+                            // 完整名称
+                            wan_zheng_ming_ch: item.subject,
+                            // 事务说明
+                            shi_wu_shuo_ming_: item.subject.includes('#') ? item.subject.split('#')[1] : '',
+                            // 事务名称
+                            shi_wu_ming_cheng: item.workName,
+                            // 事务状态
+                            shi_wu_zhuang_tai: `待${item.name}`,
+                            // 事务类型
+                            shi_wu_lei_xing_: item.workType,
+                            chu_li_ren_ming_: item.ownerName,
+                            chu_li_ren_id_: this.getInfoByName(item.ownerName, 'id'),
+                            chu_li_ren_dian_h: this.getInfoByName(item.ownerName, 'phone'),
+                            bu_men_: this.orgInfo.orgName,
+                            bu_men_id_: this.orgInfo.groupID,
+                            // 主管ID与当前用户id相等时将主管ID设置为主任【】的ID,主管电话设为空
+                            zhu_guan_id_: this.orgInfo.id === userId ? '990927120278487040' : this.orgInfo.id,
+                            zhu_guan_dian_hua: this.orgInfo.id === userId ? '' : this.orgInfo.mobile,
+                            bian_zhi_shi_jian: item.createTime,
+                            ti_xing_ci_shu_: 1,
+                            duan_xin_ci_shu_: 0,
+                            ti_xing_shi_jian_: nowTime
+                        }
+                        addList.push(obj)
+                    }
+                    const msg = {
+                        subject: msgTitle[item.workType],
+                        content: `<p>事务【${item.workName}】${msgContent[item.workType]}<p>`,
+                        receiverId: userId,
+                        canreply: '0',
+                        taskId: item.taskId
+                    }
+                    sendList.push(msg)
+                }
+            })
+            const addParams = {
+                tableName: 't_gqswb',
+                paramWhere: addList
+            }
+            // console.log('新增过期事务表数据:', addList, '发送消息数据', sendList)
+            if (addList.length) {
+                this.$common.request('add', addParams)
+            }
+            if (sendList.length) {
+                this.sendMsg(sendList)
+            }
+        },
+        // 删除已办的提醒表数据
+        dealUnexpile (data, noticeList) {
+            // 清除存在于主管提醒表中【处理人含我】,但是不存在于待办中的数据
+            const deleteList = []
+            noticeList.forEach(item => {
+                const isExist = !!data.find(i => i.taskId === item.taskId)
+                if (!isExist) {
+                    deleteList.push(item.id_)
+                }
+            })
+            // console.log('过期事务表中需删除的数据:', deleteList)
+            if (!deleteList.length) {
+                return
+            }
+            const params = {
+                tableName: 't_gqswb',
+                paramWhere: {
+                    id_: deleteList.join(',')
+                }
+            }
+            this.$common.request('delete', params).then(() => {}).catch(err => {
+                console.log(err)
+            })
+        },
+        // 发送站内消息
+        sendMsg (data) {
+            data.forEach(item => {
+                save(item).then(() => {}).catch(err => {
+                    console.log(err)
+                })
+            })
+        },
+        // 通过名字获取id/电话
+        getInfoByName (names, type) {
+            const res = {
+                id: [],
+                phone: []
+            }
+            const temp = names.split(',')
+            temp.forEach(item => {
+                const t = this.userList.find(i => i.userName === item)
+                if (t) {
+                    res.id.push(t.userId)
+                    res.phone.push(t.phone)
+                }
+            })
+            return res[type].filter(i => i).join(',')
+        }
+    }
+}
+</script>
+<style lang="scss" scoped>
+    ::v-deep .el-table__row {
+        cursor: pointer;
+    }
+    ::v-deep .el-tabs__header {
+        margin-bottom: 0;
+    }
+    .el-completing {
+        background: #409eff !important;
+    }
+    .el-col {
+        min-height: 1px;
+    }
+    .firstcol {
+        padding-right: 10px;
+    }
+    .el-nothing {
+        font-size: 13px;
+    }
+    .calendar-day {
+        text-align: center;
+        color: #202535;
+        line-height: 30px;
+        font-size: 12px;
+    }
+    .is-selected {
+        color: #f8a535;
+        font-size: 10px;
+        margin-top: 5px;
+    }
+    #calendar .el-button-group > .el-button:not(:first-child):not(:last-child):after {
+        content: '当月';
+    }
+    #calendar .item {
+        position: relative;
+        margin: 0;
+        padding: 0;
+        height: auto;
+        border-radius: 4px;
+        -webkit-box-sizing: border-box;
+        box-sizing: border-box;
+        overflow: hidden;
+        color: #f8a535;
+    }
+    .ibps-list-split .ibps-list-item {
+        border-bottom: 1px solid #dcdfe6;
+        padding: 6px 0;
+    }
+    .jbd-font-style {
+        font-weight: bold;
+    }
+    .home-text-border {
+        color: #999999;
+        box-shadow: 0 0 0 0 rgba(0, 0, 0, 0.1), 0 0 0 0 rgba(0, 0, 0, 0.1), 0 0 0 0 rgba(0, 0, 0, 0.1), 0 1px 0px 0 rgba(0, 0, 0, 0.1);
+        min-height: 20px;
+        font-size: 14px;
+        margin-left: 60px;
+        margin-bottom: 5px;
+    }
+    .jbd-home-card {
+        overflow: auto;
+    }
+    .jbd-home-task {
+        width: 100%;
+        padding: 10px;
+        cursor: pointer;
+        font-size: 12px;
+        margin-bottom: 35px;
+    }
+    .jbd-home-card::-webkit-scrollbar {
+        display: none;
+    }
+    .jbd-control-cont {
+        text-align: center;
+        position: absolute;
+        z-index: 10;
+        right: 0px;
+        top: 50%;
+    }
+    .tab-container {
+        height: calc(100vh - 160px);
+        min-height: 600px;
+        >div {
+            display: inline-block;
+        }
+        .table-container {
+            width: 100%;
+            vertical-align: top;
+        }
+    }
+</style>

+ 10 - 2
src/views/system/dashboard/page.vue

@@ -8,7 +8,7 @@
         class="ibps-desktop-page"
         @scroll="({ x, y }) => { scrollTop = y }"
     >
-        <newHome v-if="cronTask" :plan="cronTask" @handleApprove="handleApprove" @handleUnreadMessage="handleUnreadMessage">
+        <!-- <newHome v-if="cronTask" :plan="cronTask" @handleApprove="handleApprove" @handleUnreadMessage="handleUnreadMessage">
             <template slot="myslot">
                 <el-upload
                     style="display: inline-block"
@@ -46,7 +46,13 @@
                     @click="downloadData()"
                 >下载桌面应用</el-button>
             </template>
-        </newHome>
+        </newHome> -->
+        <workbench
+            v-if="cronTask"
+            :plan="cronTask"
+            @handleApprove="handleApprove"
+            @handleUnreadMessage="handleUnreadMessage"
+        />
         <ibps-back-to-top
             :visibility-height="150"
             :scroll-top="scrollTop"
@@ -166,6 +172,7 @@
     import { StatisticsSign } from '@/api/platform/system/jbdHome'
     import { getToken } from '@/utils/auth'
     import newHome from './components/new-home'
+    import Workbench from './components/workbench'
     import curdPost from '@/business/platform/form/utils/custom/joinCURD.js'
 
     const _import = require('@/utils/util.import.' + process.env.NODE_ENV)
@@ -177,6 +184,7 @@
             IbpsBackToTop,
             Preview,
             newHome,
+            Workbench,
             BpmnFormrender,
             'ibps-grid-layout': GridLayout,
             'ibps-grid-item': GridItem

+ 1 - 1
src/views/system/login/page.vue

@@ -9,7 +9,7 @@
                             金源信通 -->
                         <img src="~@/assets/images/login/company.png" class="logo">
                         <!-- </h1> -->
-                        <h1 class="login-title">医学实验室管理系统</h1>
+                        <h1 class="login-title">医学实验室标准化智慧管理平台</h1>
                     </div>
 
                     <div class="jbd-login-page-main">