lex 2 lat temu
rodzic
commit
0c3071c7e5

+ 1 - 0
package.json

@@ -45,6 +45,7 @@
     "clipboard": "^2.0.6",
     "codemirror": "^5.58.1",
     "core-js": "^2.6.11",
+    "dayjs": "^1.11.3",
     "driver.js": "0.9.5",
     "dropzone": "5.5.1",
     "e-icon-picker": "1.0.7",

BIN
src/assets/system-complete.png


BIN
src/assets/system-reject.png


BIN
src/assets/system-transfer.png


BIN
src/assets/system-wait.png


+ 9 - 3
src/components/VueFormMaking/components/GenerateFormItem.vue

@@ -77,6 +77,9 @@
           :options="widget.options.remote?widget.options.remoteOptions:widget.options.options"
         />
       </template>
+      <template v-else-if="widget.type === 'textarea'">
+        <span v-html="dataFormatBr(dataModel)"></span>
+      </template>
       <template v-else>
         <div v-if="dataModel">
           <template v-if="widget.type == 'organ' || widget.type == 'school'">
@@ -230,7 +233,7 @@
           :clearable="widget.options.clearable"
           :placeholder="widget.options.placeholder"
           :style="{width: widget.options.width}"
-          :filterable="widget.options.filterable"
+          filterable
           @change="onChangeSelect"
         >
           <el-option v-for="item in (widget.options.remote ? widget.options.remoteOptions : widget.options.options)" :key="item.value" :value="item.value" :label="widget.options.showLabel || widget.options.remote?item.label:item.value" />
@@ -243,9 +246,9 @@
           :disabled="widget.options.disabled"
           :multiple="widget.options.multiple"
           clearable
+          filterable
           :placeholder="widget.options.placeholder"
           :style="{width: widget.options.width}"
-          :filterable="widget.options.filterable"
           :name="widget.model"
         >
           <el-option v-for="item in organList" :key="item.id" :value="item.id" :label="item.name" />
@@ -260,7 +263,7 @@
           clearable
           :placeholder="widget.options.placeholder"
           :style="{width: widget.options.width}"
-          :filterable="widget.options.filterable"
+          filterable
            :loading="selectLoading"
           @visible-change="onGetSchoolList"
         >
@@ -732,6 +735,9 @@ export default {
           }
         }
       }
+    },
+    dataFormatBr(str) {
+      return str.replace(/\n/ig, '<br />')
     }
   }
 }

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

@@ -57,7 +57,7 @@ const actions = {
         const { data } = response
         if (response.code == 200) {
           console.log(data)
-          const token = data.authentication.access_token
+          const token = data.authentication.token_type + ' ' + data.authentication.access_token
           commit('SET_REFRESH_TOKEN', data.authentication.refresh_token)
           commit('SET_EXPIRES_IN', data.authentication.expires_in)
           commit('SET_TOKEN', token)

+ 12 - 4
src/utils/auth.js

@@ -1,6 +1,6 @@
 import Cookies from 'js-cookie'
 
-const TokenKey = 'Admin-Token'
+const TokenKey = getKeyWordKey()
 const host = location.hostname
 const ip = /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/
 function getCookieDomain() {
@@ -18,21 +18,29 @@ function getCookieDomain() {
   return '.' + host
 }
 
+// 获取关键字
+function getKeyWordKey() {
+  const origin = window.location.origin
+  return origin.indexOf('online.') >= 0 ? 'dy_admin_token' : 'dy_admin_token_test'
+}
+
 export function getToken() {
+  console.log(location.origin, TokenKey)
   if (!(ip.test(host) === true) && !host === 'localhost') {
-    Cookies.remove('Admin-Token')
+    Cookies.remove('dy_admin_token')
   }
   return Cookies.get(TokenKey, { domain: getCookieDomain() })
 }
 
+
 export function setToken(token) {
   if (!(ip.test(host) === true) && !host === 'localhost') {
-    Cookies.remove('Admin-Token')
+    Cookies.remove('dy_admin_token')
   }
   return Cookies.set(TokenKey, token, { domain: getCookieDomain() })
 }
 
 export function removeToken() {
-  Cookies.remove('Admin-Token')
+  Cookies.remove('dy_admin_token')
   return Cookies.remove(TokenKey, { domain: getCookieDomain() })
 }

+ 5 - 3
src/utils/request.js

@@ -21,7 +21,9 @@ service.interceptors.request.use(
       // let each request carry token
       // ['X-Token'] is a custom headers key
       // please modify it according to the actual situation
-      config.headers['Authorization'] = 'Bearer ' + getToken()
+      const token = getToken()
+      // 为了处理两端登录问题
+      config.headers['Authorization'] = token.charAt(0).toUpperCase() + token.slice(1)
     }
     return config
   },
@@ -45,7 +47,7 @@ service.interceptors.response.use(
    */
   response => {
     const code = response.data.code
-    if (code === 401) {
+    if (code === 401 || code == 403) {
       store.dispatch('user/resetToken')
       if (location.href.indexOf('login') !== -1) {
         location.reload() // 为了重新实例化vue-router对象 避免bug
@@ -84,7 +86,7 @@ service.interceptors.response.use(
       //   location.reload() // 为了重新实例化vue-router对象 避免bug
       // })
       return false
-    } else if (code === 400 || code === 403 || code !== 200) {
+    } else if (code === 400 || code !== 200) {
       Message({
         message: response.data.msg,
         type: 'error',

+ 381 - 105
src/views/process/list/handle.vue

@@ -2,7 +2,7 @@
   <div class="app-container">
     <div v-if="isLoadingStatus" />
     <div v-else>
-      <el-card class="box-card">
+      <!-- <el-card class="box-card">
         <div class="text item">
           <el-steps
             v-if="
@@ -13,7 +13,6 @@
             :active="activeIndex"
             finish-status="success"
           >
-            <!-- :simple="true" -->
             <template v-for="(item, index) in circulationList">
               <el-step
                 v-if="
@@ -25,15 +24,12 @@
                 :key="index"
                 :title="item.state || item.label"
               >
-                <!-- &&item.state !== '评论' -->
                 <template #description>
-                  <!-- 判断是否有审核数据 -->
                   <template v-if="!item.create_time">
                     <p
                       class="apply-status"
                       v-if="item.assignUsers && item.assignUsers.length > 0"
                     >
-                      <!-- 判断是否是自己审批 -->
                       <template
                         v-if="
                           item.assignUsers[0].userId == userInfo.userId &&
@@ -68,11 +64,7 @@
                         item.circulation ? `(${item.circulation})` : null
                       }}
                     </p>
-                    <!-- <p class="remarks" v-if="item.remarks">
-                      {{ item.remarks }}
-                    </p> -->
                   </template>
-                  <!-- 有抄送人并且,本节点已经审批完成了 -->
                   <template
                     v-if="
                       item.cc_user &&
@@ -80,23 +72,6 @@
                         activeIndex > index
                     "
                   >
-                    <!-- 已抄送1人 -->
-                    <!-- <div class="ccUsers" @click="onCCChange(item)">
-                      <span>已抄送{{ item.cc_user.length }}人</span>
-                      <van-icon
-                        v-show="!item.ccStatus"
-                        style="color: #CCCCCC"
-                        name="arrow-down"
-                      />
-                      <van-icon
-                        v-show="item.ccStatus"
-                        style="color: #CCCCCC"
-                        name="arrow-up"
-                      />
-                    </div>
-                    <div class="ccUserDetail" v-if="item.ccStatus">
-                      <span>{{ item.cc_user.join(",") }}</span>
-                    </div> -->
                   </template>
                 </template>
               </el-step>
@@ -110,7 +85,7 @@
             />
           </div>
         </div>
-      </el-card>
+      </el-card> -->
 
       <el-alert
         v-if="
@@ -189,7 +164,11 @@
             />
           </template>
         </div>
-        <div v-if="processStructureValue.userAuthority && is_end == 0">
+        <div
+          v-if="
+            (processStructureValue.userAuthority || ownerApply) && is_end == 0
+          "
+        >
           <hr
             style="
               background-color: #d9d9d9;
@@ -230,27 +209,30 @@
               >
               <el-button
                 type="warning"
+                v-if="is_end == 1 && processStructureValue.userAuthority"
                 round
                 @click="handleInversion(endNodeDetail)"
                 >转交</el-button
               >
-              <el-button
-                v-for="(item, index) in btn_group"
-                :key="index"
-                :type="item.className"
-                @click="submitAction(item)"
-                round
-                >{{ item.labelShow }}</el-button
-              >
+              <template v-if="processStructureValue.userAuthority">
+                <el-button
+                  v-for="(item, index) in btn_group"
+                  :key="index"
+                  :type="item.className"
+                  @click="submitAction(item)"
+                  round
+                  >{{ item.labelShow }}</el-button
+                >
 
-              <!-- 拒绝按钮内置 -->
-              <el-button
-                v-if="endNodeDetail.id"
-                type="danger"
-                round
-                @click="submitAction(endNodeDetail)"
-                >{{ endNodeDetail.label }}</el-button
-              >
+                <!-- 拒绝按钮内置 -->
+                <el-button
+                  v-if="endNodeDetail.id"
+                  type="danger"
+                  round
+                  @click="submitAction(endNodeDetail)"
+                  >{{ endNodeDetail.label }}</el-button
+                >
+              </template>
 
               <!-- <div
               v-if="isActiveProcessing && currentNode.activeOrder"
@@ -280,7 +262,7 @@
         </div>
       </el-card>
 
-      <el-card class="box-card" style="margin-top: 15px">
+      <!-- <el-card class="box-card" style="margin-top: 15px">
         <div slot="header" class="clearfix">
           <span>工单流转历史</span>
         </div>
@@ -337,13 +319,167 @@
                       size="mini"
                       >预览</el-button
                     >
-                    <!-- <a :href="uploadUrlItem.url" target="_blank">{{ uploadUrlItem.name || uploadUrlItem.url }}</a> -->
                   </div>
                 </div>
               </template>
             </el-table-column>
           </el-table>
         </div>
+      </el-card> -->
+
+      <el-card class="box-card">
+        <div slot="header" class="clearfix">
+          <span>流程</span>
+        </div>
+        <div class="text item">
+          <el-timeline
+            v-if="
+              currentNode.clazz !== undefined &&
+                currentNode.clazz !== null &&
+                currentNode.clazz !== ''
+            "
+          >
+            <el-timeline-item
+              v-for="(item, index) in circulationList"
+              :key="index"
+              :icon="formatIcon(item, index, 'icon')"
+              :class="activeIndex >= index ? 'large-icon' : ''"
+              size="large"
+            >
+            <!-- :color="formatIcon(item, index, 'color')" -->
+              <div class="step-title">
+                {{ item.state || item.label }}
+                <span class="apply-time">
+                  {{
+                    item.create_time
+                      ? dayjs(item.create_time).format("MM-DD HH:mm")
+                      : null
+                  }}
+                </span>
+              </div>
+
+              <template v-if="!item.create_time">
+                <p
+                  class="apply-status"
+                  v-if="item.assignUsers && item.assignUsers.length > 0"
+                >
+                  <!-- 判断是否是自己审批 -->
+                  <template
+                    v-if="
+                      item.assignUsers[0].userId == userInfo.userId &&
+                        activeIndex == index
+                    "
+                  >
+                    我(审批中)
+                  </template>
+                  <template v-else>
+                    <template v-if="item.isCounterSign">
+                      <span
+                        v-for="(au, aIndex) in item.assignUsers"
+                        :key="aIndex"
+                      >
+                        {{ au.username
+                        }}{{
+                          aIndex < item.assignUsers.length - 1 ? "," : null
+                        }}
+                      </span>
+                    </template>
+                    <template v-else>
+                      {{ item.assignUsers[0].username }}
+                    </template>
+                    {{ activeIndex == index ? `(审批中)` : null }}
+                  </template>
+                </p>
+              </template>
+              <template v-else>
+                <p class="apply-status" v-if="item.processor">
+                  {{ item.processor
+                  }}{{ item.circulation ? `(${item.circulation})` : null }}
+                </p>
+                <p class="remarks" v-if="item.remarks">
+                  {{ item.remarks }}
+                </p>
+
+                <!-- 判断是否有添加图片 -->
+                <div
+                  class="imgUploader"
+                  v-if="
+                    item.fileUrl &&
+                      item.fileUrl.file &&
+                      item.fileUrl.image.length > 0
+                  "
+                >
+                  <el-image
+                    v-for="(file, index) in item.fileUrl.image"
+                    :key="index"
+                    style="width: 40px; height: 40px; margin-right: 12px;"
+                    :src="file"
+                    :preview-src-list="item.fileUrl.image"
+                  >
+                  </el-image>
+
+                </div>
+                <!-- 判断是否有添加的文件 -->
+                <div
+                  v-if="
+                    item.fileUrl &&
+                      item.fileUrl.file &&
+                      item.fileUrl.file.length > 0
+                  "
+                >
+                  <div
+                    v-for="(uploadUrlItem, uploadUrlIndex) in item.fileUrl.file"
+                    :key="uploadUrlIndex"
+                    style="margin-bottom: 3px"
+                    class="fileUploader"
+                  >
+                    <i style="color: #909399;" class="el-icon-document" />
+                    <span style="margin-right: 10px;">{{ uploadUrlItem.name || uploadUrlItem.url }}</span>
+                    <el-button
+                      round
+                      size="mini"
+                      @click="onDownload(uploadUrlItem, 'download')"
+                      >下载</el-button
+                    >
+                    <el-button
+                      round
+                      type="primary"
+                      @click="onDownload(uploadUrlItem)"
+                      v-if="checkFileSuffix(uploadUrlItem.url)"
+                      size="mini"
+                      >预览</el-button
+                    >
+                  </div>
+                </div>
+              </template>
+
+              <!-- 有抄送人并且,本节点已经审批完成了 -->
+              <template
+                v-if="
+                  item.cc_user && item.cc_user.length > 0 && activeIndex > index
+                "
+              >
+                <!-- 已抄送1人 -->
+                <div class="ccUsers" @click="onCCChange(item)">
+                  <span>已抄送{{ item.cc_user.length }}人</span>
+                  <van-icon
+                    v-show="!item.ccStatus"
+                    style="color: #CCCCCC"
+                    name="arrow-down"
+                  />
+                  <van-icon
+                    v-show="item.ccStatus"
+                    style="color: #CCCCCC"
+                    name="arrow-up"
+                  />
+                </div>
+                <div class="ccUserDetail" v-if="item.ccStatus">
+                  <span>{{ item.cc_user.join(",") }}</span>
+                </div>
+              </template>
+            </el-timeline-item>
+          </el-timeline>
+        </div>
       </el-card>
     </div>
     <el-dialog title="转交工单" :visible.sync="dialogVisible" width="40%">
@@ -363,6 +499,7 @@ import Vue from "vue";
 import { GenerateForm } from "@/components/VueFormMaking";
 import "form-making/dist/FormMaking.css";
 Vue.component(GenerateForm.name, GenerateForm);
+import dayjs from "dayjs";
 
 import {
   processStructure,
@@ -411,6 +548,7 @@ export default {
       processStructureValue: {
         workOrder: { title: "" }
       },
+      ownerApply: false, // 是否是自己提交的申请
       endNodeDetail: {}, // 结束结节信息
       ruleForm: {
         title: "",
@@ -428,7 +566,6 @@ export default {
       tenantId: 1,
       btn_group: [],
       is_end: 0, // 是否结束
-      ownerApply: false, // 是否是自己提交的申请
       remoteFunc: {
         // 获取用户列表
         userList(resolve) {
@@ -460,10 +597,6 @@ export default {
     try {
       let user = await getInfo();
       this.userInfo = user.data;
-      // console.log(
-      //   this.processStructureValue.workOrder.creator,
-      //   user.data.userId
-      // );
       this.ownerApply =
         this.processStructureValue.workOrder.creator == user.data.userId
           ? true
@@ -473,6 +606,7 @@ export default {
     }
   },
   methods: {
+    dayjs,
     // 获取学校列表
     onDownload(item, type) {
       if (type == "download") {
@@ -654,10 +788,25 @@ export default {
         this.circulationList = JSON.parse(
           JSON.stringify(this.circulationHistoryList)
         );
-
         this.circulationHistoryList.forEach(item => {
           const file = item.file_url ? JSON.parse(item.file_url) : [];
+          const tempFile = {
+            image: [],
+            file: []
+          };
+          // console.log(file)
+          file.forEach(item => {
+            if (item.type == "image") {
+              tempFile.image.push(item.url);
+            } else if (item.type == "file") {
+              tempFile.file.push(item);
+            }
+          });
+          item.fileUrl = tempFile;
+        });
 
+        this.circulationList.forEach(item => {
+          const file = item.file_url ? JSON.parse(item.file_url) : [];
           const tempFile = {
             image: [],
             file: []
@@ -672,7 +821,7 @@ export default {
           });
           item.fileUrl = tempFile;
         });
-        // console.log(this.circulationHistoryList, "circulationHistoryList");
+        console.log(this.circulationHistoryList, "circulationHistoryList");
 
         // 获取当前展示节点列表
         // this.nodeStepList = this.processStructureValue.circulationHistory
@@ -948,64 +1097,83 @@ export default {
         promiseList.push(this.$refs["generateForm-" + tpl.id][0].getData());
       }
       console.log({
-              tasks: this.processStructureValue.process.task,
-              source_state: this.processStructureValue.workOrder.current_state,
-              target_state: item.target,
-              circulation: item.label,
-              flow_properties:
-                item.flowProperties === undefined
-                  ? 2
-                  : parseInt(item.flowProperties),
-              work_order_id: parseInt(this.$route.query.workOrderId),
-              remarks: this.dataList.remarks,
-              fileUrl: JSON.stringify(this.fileUrl || []),
-              tpls: this.tpls
-            })
+        tasks: this.processStructureValue.process.task,
+        source_state: this.processStructureValue.workOrder.current_state,
+        target_state: item.target,
+        circulation: item.label,
+        flow_properties:
+          item.flowProperties === undefined ? 2 : parseInt(item.flowProperties),
+        work_order_id: parseInt(this.$route.query.workOrderId),
+        remarks: this.dataList.remarks,
+        fileUrl: JSON.stringify(this.fileUrl || []),
+        tpls: this.tpls
+      });
+
       this.$refs["dataFrom"].validate(_ => {
         if (_) {
-          Promise.all(promiseList).then(values => {
-            for (var tplDataIndex in this.tpls) {
-              this.tpls[tplDataIndex].tplValue = values[tplDataIndex];
-            }
+          const flow =
+            item.flowProperties === undefined
+              ? 2
+              : parseInt(item.flowProperties);
+          let str = "同意";
+          if (flow == 1) {
+            str = "同意";
+          } else if (flow == 0) {
+            str = "拒绝";
+          } else {
+            str = "操作";
+          }
+          const tips = `您是否${str}此审批?`;
+          this.$confirm(tips, "提示", {
+            confirmButtonText: "确定",
+            cancelButtonText: "取消",
+            type: "warning"
+          }).then(() => {
+            Promise.all(promiseList).then(values => {
+              for (var tplDataIndex in this.tpls) {
+                this.tpls[tplDataIndex].tplValue = values[tplDataIndex];
+              }
 
-            let fileList = [];
-            this.tpls &&
-              this.tpls.forEach(tpl => {
-                for (let val in tpl.tplValue) {
-                  if (val.indexOf("file") != -1) {
-                    const file = tpl.tplValue[val] || [];
-                    file.forEach(item => {
-                      fileList.push(item.url);
-                    });
+              let fileList = [];
+              this.tpls &&
+                this.tpls.forEach(tpl => {
+                  for (let val in tpl.tplValue) {
+                    if (val.indexOf("file") != -1) {
+                      const file = tpl.tplValue[val] || [];
+                      file.forEach(item => {
+                        fileList.push(item.url);
+                      });
+                    }
                   }
-                }
-              });
-            handleWorkOrder({
-              tasks: this.processStructureValue.process.task,
-              source_state: this.processStructureValue.workOrder.current_state,
-              target_state: item.target,
-              circulation: item.label,
-              flow_properties:
-                item.flowProperties === undefined
-                  ? 2
-                  : parseInt(item.flowProperties),
-              work_order_id: parseInt(this.$route.query.workOrderId),
-              remarks: this.dataList.remarks,
-              fileUrl: JSON.stringify(this.fileUrl || []),
-              tpls: this.tpls
-            }).then(async response => {
-              if (response.code === 200) {
-                // this.$router.push({ name: 'upcoming' })
-
-                await asyncPlayLog({
-                  workOrderId: parseInt(this.$route.query.workOrderId),
-                  fileUrl: fileList.join(",")
                 });
-                // window.location.reload()
-                this.getProcessNodeList();
+              handleWorkOrder({
+                tasks: this.processStructureValue.process.task,
+                source_state: this.processStructureValue.workOrder
+                  .current_state,
+                target_state: item.target,
+                circulation: item.label,
+                flow_properties:
+                  item.flowProperties === undefined
+                    ? 2
+                    : parseInt(item.flowProperties),
+                work_order_id: parseInt(this.$route.query.workOrderId),
+                remarks: this.dataList.remarks,
+                fileUrl: JSON.stringify(this.fileUrl || []),
+                tpls: this.tpls
+              }).then(async response => {
+                if (response.code === 200) {
+                  // this.$router.push({ name: 'upcoming' })
 
-                await store.dispatch("user/getInitData");
-              }
+                  await asyncPlayLog({
+                    workOrderId: parseInt(this.$route.query.workOrderId),
+                    fileUrl: fileList.join(",")
+                  });
+                  // window.location.reload()
+                  this.getProcessNodeList();
+
+                  await store.dispatch("user/getInitData");
+                }
+              });
             });
           });
         }
@@ -1060,6 +1228,25 @@ export default {
           this.organList = tempOrgan;
         }
       });
+    },
+    formatIcon(item, index, type) {
+      // 格式化ICON
+      console.log(item, index)
+      console.log(this.activeIndex)
+      if(this.activeIndex >= index) {
+        if(item.circulation == '转交') {
+          return 'icon-transfer'
+        } else if(this.activeIndex == index) {
+          return 'icon-wait'
+        } else if(item.status == 0) {
+          return 'el-icon-error'
+        } else {
+          return 'el-icon-success'
+        }
+      }
+
+      // #fd803a 
+      return ''
     }
   }
 };
@@ -1076,4 +1263,93 @@ export default {
 // /deep/.el-step__icon.is-text {
 //   border: 0;
 // }
+
+.step-title {
+  color: #000;
+  font-size: 16px;
+}
+.apply-time {
+  font-size: #999;
+  color: #999;
+  padding-left: 10px;
+}
+.apply-status {
+  line-height: 1.5;
+  color: #999;
+  margin: 5px 0;
+}
+
+.remarks {
+  background: #f5f5f5;
+  padding: 8px;
+  color: #323233;
+  border-radius: 6px; 
+}
+
+.imgUploader {
+  background: #f5f5f5;
+  margin-top: 8px;
+  padding: 8px;
+  border-radius: 6px;
+
+  .el-image {
+    vertical-align: middle;
+  }
+}
+
+.fileUploader {
+  margin-top: 8px;
+  background: #f5f5f5;
+  padding: 6px;
+  border-radius: 4px;
+}
+
+/deep/.icon-transfer, /deep/.icon-wait {
+  display: flex;
+  align-items: center;
+  box-sizing: content-box;
+  background-color: #fff;
+  padding: 2px 0;
+  height: 23px;
+  &::before {
+    content: ' ';
+    display: inline-block;
+    width: 23px;
+    height: 23px;
+    background: url('../../../assets/system-transfer.png') no-repeat center;
+    background-size: contain;
+  }
+}
+
+/deep/.icon-wait {
+  &::before {
+    content: ' ';
+    display: inline-block;
+    width: 23px;
+    height: 23px;
+    background: url('../../../assets/system-wait.png') no-repeat center;
+    background-size: contain;
+  }
+}
+
+.large-icon {
+  /deep/.el-timeline-item__node--large {
+    top: -8px;
+    left: -7px;
+    width: 24px;
+    height: 24px;
+    background-color: transparent;
+  }
+
+  /deep/.el-icon-success, /deep/.el-icon-error {
+    font-size: 24px;
+    color: #22b4a9;
+    background-color: #fff;
+    padding: 2px 0;
+  }
+
+  /deep/.el-icon-error {
+    color: #ff2e2e
+  }
+}
 </style>