diff --git a/components/AiOkrTree/model/node.js b/components/AiOkrTree/model/node.js
index 2c6c3a02..7c758efd 100644
--- a/components/AiOkrTree/model/node.js
+++ b/components/AiOkrTree/model/node.js
@@ -1,4 +1,4 @@
-import { markNodeData, NODE_KEY } from './util';
+import {markNodeData} from './util';
 import objectAssign from './merge';
 
 const getPropertyFromData = function (node, prop) {
diff --git a/components/AiOkrTree/model/tree-store.js b/components/AiOkrTree/model/tree-store.js
index 35008fe4..eacad58d 100644
--- a/components/AiOkrTree/model/tree-store.js
+++ b/components/AiOkrTree/model/tree-store.js
@@ -1,5 +1,6 @@
 import Node from "./node";
-import { getNodeKey } from "./util";
+import {getNodeKey} from "./util";
+
 export default class TreeStore {
   constructor(options) {
     this.currentNode = null;
diff --git a/components/layout/AiDvDisplay/asset/displayItem-bg1.svg b/components/layout/AiDvDisplay/asset/displayItem-bg1.svg
index eb5e0259..41774e74 100644
--- a/components/layout/AiDvDisplay/asset/displayItem-bg1.svg
+++ b/components/layout/AiDvDisplay/asset/displayItem-bg1.svg
@@ -1,5 +1,5 @@
 
-
diff --git a/components/layout/AiDvSummary/asset/summary3-big.svg b/components/layout/AiDvSummary/asset/summary3-big.svg
index fe16d87d..12b9f6d5 100644
--- a/components/layout/AiDvSummary/asset/summary3-big.svg
+++ b/components/layout/AiDvSummary/asset/summary3-big.svg
@@ -1,5 +1,5 @@
 
-
+
     编组备份 3
     
         
@@ -55,4 +55,4 @@
             
         
     
-
\ No newline at end of file
+
diff --git a/components/layout/AiDvSummary/asset/summary3-small.svg b/components/layout/AiDvSummary/asset/summary3-small.svg
index 2a7af637..6d8f5b95 100644
--- a/components/layout/AiDvSummary/asset/summary3-small.svg
+++ b/components/layout/AiDvSummary/asset/summary3-small.svg
@@ -1,5 +1,5 @@
 
-
+
     编组备份 4
     
         
@@ -55,4 +55,4 @@
             
         
     
-
\ No newline at end of file
+
diff --git a/components/layout/AiDvSummary/asset/summary8-bg.svg b/components/layout/AiDvSummary/asset/summary8-bg.svg
index 2bbf3160..a1ce3429 100644
--- a/components/layout/AiDvSummary/asset/summary8-bg.svg
+++ b/components/layout/AiDvSummary/asset/summary8-bg.svg
@@ -1,5 +1,5 @@
 
-
+
     矩形
     
         
@@ -12,4 +12,4 @@
             
         
     
-
\ No newline at end of file
+
diff --git a/package.json b/package.json
index d0f37ccc..5973dc10 100644
--- a/package.json
+++ b/package.json
@@ -23,6 +23,8 @@
     "@amap/amap-jsapi-loader": "^1.0.1",
     "@jiaminghi/data-view": "^2.10.0",
     "@logicflow/core": "^1.2.1",
+    "ag-grid-community": "^31.0.2",
+    "ag-grid-vue": "^31.0.2",
     "bin-ace-editor": "^3.2.0",
     "dayjs": "^1.8.35",
     "dui": "^2.0.0",
@@ -61,7 +63,6 @@
     "sass": "~1.32.6",
     "sass-loader": "^7.3.1",
     "uglifyjs-webpack-plugin": "^2.2.0",
-    "v-viewer": "^1.6.4",
     "vue": "^2.7.14",
     "vue-router": "^3.3.4",
     "vue-template-compiler": "^2.7.14",
diff --git a/packages/bigscreen/designer/components/datasourcePicker.vue b/packages/bigscreen/designer/components/datasourcePicker.vue
index 5f1e1768..b98ed5c4 100644
--- a/packages/bigscreen/designer/components/datasourcePicker.vue
+++ b/packages/bigscreen/designer/components/datasourcePicker.vue
@@ -3,6 +3,8 @@
     
       
     
+    
+    
     
       
diff --git a/packages/bigscreen/designer/components/tableEditor.vue b/packages/bigscreen/designer/components/tableEditor.vue
new file mode 100644
index 00000000..532d3455
--- /dev/null
+++ b/packages/bigscreen/designer/components/tableEditor.vue
@@ -0,0 +1,23 @@
+
+
+
+  
+
diff --git a/packages/conv/AppVillageAlbum/components/List.vue b/packages/conv/AppVillageAlbum/components/List.vue
index a089b42e..36fd237d 100644
--- a/packages/conv/AppVillageAlbum/components/List.vue
+++ b/packages/conv/AppVillageAlbum/components/List.vue
@@ -7,18 +7,18 @@
       
         
           
+              v-model="search.type"
+              @change="search.current = 1, getList()"
+              placeholder="请选择相册主题"
+              :selectList="dict.getDict('villagePictureAlbumType')">
           
           
+              v-model="search.timeTag"
+              type="month"
+              size="small"
+              @change="search.current = 1, getList()"
+              value-format="yyyy-MM"
+              placeholder="请选择日期">
           
         
       
@@ -41,17 +41,17 @@
              
             
               
+                  type="text"
+                  icon="iconfont iconExported"
+                  class="list-item__operate--item"
+                  @click="downloadImg(item.url, dict.getLabel('villagePictureAlbumType', item.type))">
                 下载
               
               
+                  @click="remove(item.id)"
+                  type="text"
+                  icon="iconfont iconDelete"
+                  class="list-item__operate--item">
                 删除
               
             
@@ -66,473 +66,473 @@
 
 
 
 
 
diff --git a/packages/party/AppMeetingChinaunion/components/meetingDetail.vue b/packages/party/AppMeetingChinaunion/components/meetingDetail.vue
index 0176688f..c3f646fd 100644
--- a/packages/party/AppMeetingChinaunion/components/meetingDetail.vue
+++ b/packages/party/AppMeetingChinaunion/components/meetingDetail.vue
@@ -47,28 +47,28 @@
                         
                       
                 -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+              
+              
+              
+              
+              
+              
+              
+              
+              
+              
+              
+              
+              
+              
+              
+              
+              
+              
+              
+              
+              
+              
               
               {{ arrLabel(obj.appThreeMeetingOrganizationList, 'name') }}
               {{ arrLabel(obj.hostList, 'userName') }}
@@ -213,12 +213,8 @@
 
 
 
 
 
diff --git a/packages/publicity/AppPressCenter/components/newsDetail.vue b/packages/publicity/AppPressCenter/components/newsDetail.vue
index 17d4e4c2..6cf7ca7b 100644
--- a/packages/publicity/AppPressCenter/components/newsDetail.vue
+++ b/packages/publicity/AppPressCenter/components/newsDetail.vue
@@ -31,10 +31,6 @@
 
 
 
 
 
diff --git a/project/fengdu/app/AppIntegratingSupermarket/components/GoodsList.vue b/project/fengdu/app/AppIntegratingSupermarket/components/GoodsList.vue
index a57f1783..c3539f8a 100644
--- a/project/fengdu/app/AppIntegratingSupermarket/components/GoodsList.vue
+++ b/project/fengdu/app/AppIntegratingSupermarket/components/GoodsList.vue
@@ -5,44 +5,44 @@
         
           添加
           
+              v-model="search.type"
+              @change="(search.current = 1), getList()"
+              placeholder="请选择商品类型"
+              :selectList="dict.getDict('integralSGType')">
           
           
+              v-model="search.status"
+              @change="(search.current = 1), getList()"
+              placeholder="请选择类型"
+              :selectList="dict.getDict('integralSGStatus')">
           
         
         
           
+              v-model="search.title"
+              class="search-input"
+              size="small"
+              v-throttle="() => {search.current = 1, getList()}"
+              placeholder="请输入商品名称"
+              clearable
+              @clear="search.current = 1, search.title = '', getList()"
+              suffix-icon="iconfont iconSearch">
           
         
       
       
+          style="margin-top: 8px;"
+          :tableData="tableData"
+          :col-configs="colConfigs"
+          :total="total"
+          :current.sync="search.current"
+          :size.sync="search.size"
+          @getList="getList">
         
+            label="商品"
+            slot="goods"
+            align="left"
+            width="450">
           
             
               
-                {{dict.getLabel('integralSGTypeText', row.typeText)}}
+                {{ dict.getLabel('integralSGTypeText', row.typeText) }}
               
 
               {{ row.title }}
@@ -79,151 +79,151 @@
 
 
 
 
 
diff --git a/project/lulong/AppIntegratingOrder/components/ResidentList.vue b/project/lulong/AppIntegratingOrder/components/ResidentList.vue
index b9dbe5c8..abde0ad3 100644
--- a/project/lulong/AppIntegratingOrder/components/ResidentList.vue
+++ b/project/lulong/AppIntegratingOrder/components/ResidentList.vue
@@ -113,9 +113,6 @@
 
 
 
-  
+    
+    
+    
+    
+    
+    
+    web端应用库-展示页面
+    
+    
 
 
 
 
 
diff --git a/ui/lib/cdn/v-viewer/1.7.4/v-viewer.js b/ui/lib/cdn/v-viewer/1.7.4/v-viewer.js
new file mode 100644
index 00000000..6570964a
--- /dev/null
+++ b/ui/lib/cdn/v-viewer/1.7.4/v-viewer.js
@@ -0,0 +1,826 @@
+import Viewer from "viewerjs";
+import Vue from "vue";
+
+export { default as Viewer } from "viewerjs";
+var freeGlobal = typeof global == "object" && global && global.Object === Object && global;
+var freeGlobal$1 = freeGlobal;
+var freeSelf = typeof self == "object" && self && self.Object === Object && self;
+var root = freeGlobal$1 || freeSelf || Function("return this")();
+var root$1 = root;
+var Symbol$1 = root$1.Symbol;
+var Symbol$2 = Symbol$1;
+var objectProto$8 = Object.prototype;
+var hasOwnProperty$6 = objectProto$8.hasOwnProperty;
+var nativeObjectToString$1 = objectProto$8.toString;
+var symToStringTag$1 = Symbol$2 ? Symbol$2.toStringTag : void 0;
+function getRawTag(value) {
+  var isOwn = hasOwnProperty$6.call(value, symToStringTag$1), tag = value[symToStringTag$1];
+  try {
+    value[symToStringTag$1] = void 0;
+    var unmasked = true;
+  } catch (e) {
+  }
+  var result = nativeObjectToString$1.call(value);
+  if (unmasked) {
+    if (isOwn) {
+      value[symToStringTag$1] = tag;
+    } else {
+      delete value[symToStringTag$1];
+    }
+  }
+  return result;
+}
+var objectProto$7 = Object.prototype;
+var nativeObjectToString = objectProto$7.toString;
+function objectToString(value) {
+  return nativeObjectToString.call(value);
+}
+var nullTag = "[object Null]", undefinedTag = "[object Undefined]";
+var symToStringTag = Symbol$2 ? Symbol$2.toStringTag : void 0;
+function baseGetTag(value) {
+  if (value == null) {
+    return value === void 0 ? undefinedTag : nullTag;
+  }
+  return symToStringTag && symToStringTag in Object(value) ? getRawTag(value) : objectToString(value);
+}
+function isObjectLike(value) {
+  return value != null && typeof value == "object";
+}
+var symbolTag = "[object Symbol]";
+function isSymbol(value) {
+  return typeof value == "symbol" || isObjectLike(value) && baseGetTag(value) == symbolTag;
+}
+var isArray = Array.isArray;
+var isArray$1 = isArray;
+var reWhitespace = /\s/;
+function trimmedEndIndex(string) {
+  var index2 = string.length;
+  while (index2-- && reWhitespace.test(string.charAt(index2))) {
+  }
+  return index2;
+}
+var reTrimStart = /^\s+/;
+function baseTrim(string) {
+  return string ? string.slice(0, trimmedEndIndex(string) + 1).replace(reTrimStart, "") : string;
+}
+function isObject(value) {
+  var type = typeof value;
+  return value != null && (type == "object" || type == "function");
+}
+var NAN = 0 / 0;
+var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
+var reIsBinary = /^0b[01]+$/i;
+var reIsOctal = /^0o[0-7]+$/i;
+var freeParseInt = parseInt;
+function toNumber(value) {
+  if (typeof value == "number") {
+    return value;
+  }
+  if (isSymbol(value)) {
+    return NAN;
+  }
+  if (isObject(value)) {
+    var other = typeof value.valueOf == "function" ? value.valueOf() : value;
+    value = isObject(other) ? other + "" : other;
+  }
+  if (typeof value != "string") {
+    return value === 0 ? value : +value;
+  }
+  value = baseTrim(value);
+  var isBinary = reIsBinary.test(value);
+  return isBinary || reIsOctal.test(value) ? freeParseInt(value.slice(2), isBinary ? 2 : 8) : reIsBadHex.test(value) ? NAN : +value;
+}
+function identity(value) {
+  return value;
+}
+var asyncTag = "[object AsyncFunction]", funcTag$1 = "[object Function]", genTag = "[object GeneratorFunction]", proxyTag = "[object Proxy]";
+function isFunction(value) {
+  if (!isObject(value)) {
+    return false;
+  }
+  var tag = baseGetTag(value);
+  return tag == funcTag$1 || tag == genTag || tag == asyncTag || tag == proxyTag;
+}
+var coreJsData = root$1["__core-js_shared__"];
+var coreJsData$1 = coreJsData;
+var maskSrcKey = function() {
+  var uid = /[^.]+$/.exec(coreJsData$1 && coreJsData$1.keys && coreJsData$1.keys.IE_PROTO || "");
+  return uid ? "Symbol(src)_1." + uid : "";
+}();
+function isMasked(func) {
+  return !!maskSrcKey && maskSrcKey in func;
+}
+var funcProto$1 = Function.prototype;
+var funcToString$1 = funcProto$1.toString;
+function toSource(func) {
+  if (func != null) {
+    try {
+      return funcToString$1.call(func);
+    } catch (e) {
+    }
+    try {
+      return func + "";
+    } catch (e) {
+    }
+  }
+  return "";
+}
+var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
+var reIsHostCtor = /^\[object .+?Constructor\]$/;
+var funcProto = Function.prototype, objectProto$6 = Object.prototype;
+var funcToString = funcProto.toString;
+var hasOwnProperty$5 = objectProto$6.hasOwnProperty;
+var reIsNative = RegExp(
+  "^" + funcToString.call(hasOwnProperty$5).replace(reRegExpChar, "\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, "$1.*?") + "$"
+);
+function baseIsNative(value) {
+  if (!isObject(value) || isMasked(value)) {
+    return false;
+  }
+  var pattern = isFunction(value) ? reIsNative : reIsHostCtor;
+  return pattern.test(toSource(value));
+}
+function getValue(object, key) {
+  return object == null ? void 0 : object[key];
+}
+function getNative(object, key) {
+  var value = getValue(object, key);
+  return baseIsNative(value) ? value : void 0;
+}
+function apply(func, thisArg, args) {
+  switch (args.length) {
+    case 0:
+      return func.call(thisArg);
+    case 1:
+      return func.call(thisArg, args[0]);
+    case 2:
+      return func.call(thisArg, args[0], args[1]);
+    case 3:
+      return func.call(thisArg, args[0], args[1], args[2]);
+  }
+  return func.apply(thisArg, args);
+}
+var HOT_COUNT = 800, HOT_SPAN = 16;
+var nativeNow = Date.now;
+function shortOut(func) {
+  var count = 0, lastCalled = 0;
+  return function() {
+    var stamp = nativeNow(), remaining = HOT_SPAN - (stamp - lastCalled);
+    lastCalled = stamp;
+    if (remaining > 0) {
+      if (++count >= HOT_COUNT) {
+        return arguments[0];
+      }
+    } else {
+      count = 0;
+    }
+    return func.apply(void 0, arguments);
+  };
+}
+function constant(value) {
+  return function() {
+    return value;
+  };
+}
+var defineProperty = function() {
+  try {
+    var func = getNative(Object, "defineProperty");
+    func({}, "", {});
+    return func;
+  } catch (e) {
+  }
+}();
+var defineProperty$1 = defineProperty;
+var baseSetToString = !defineProperty$1 ? identity : function(func, string) {
+  return defineProperty$1(func, "toString", {
+    "configurable": true,
+    "enumerable": false,
+    "value": constant(string),
+    "writable": true
+  });
+};
+var baseSetToString$1 = baseSetToString;
+var setToString = shortOut(baseSetToString$1);
+var setToString$1 = setToString;
+var MAX_SAFE_INTEGER$1 = 9007199254740991;
+var reIsUint = /^(?:0|[1-9]\d*)$/;
+function isIndex(value, length) {
+  var type = typeof value;
+  length = length == null ? MAX_SAFE_INTEGER$1 : length;
+  return !!length && (type == "number" || type != "symbol" && reIsUint.test(value)) && (value > -1 && value % 1 == 0 && value < length);
+}
+function baseAssignValue(object, key, value) {
+  if (key == "__proto__" && defineProperty$1) {
+    defineProperty$1(object, key, {
+      "configurable": true,
+      "enumerable": true,
+      "value": value,
+      "writable": true
+    });
+  } else {
+    object[key] = value;
+  }
+}
+function eq(value, other) {
+  return value === other || value !== value && other !== other;
+}
+var objectProto$5 = Object.prototype;
+var hasOwnProperty$4 = objectProto$5.hasOwnProperty;
+function assignValue(object, key, value) {
+  var objValue = object[key];
+  if (!(hasOwnProperty$4.call(object, key) && eq(objValue, value)) || value === void 0 && !(key in object)) {
+    baseAssignValue(object, key, value);
+  }
+}
+function copyObject(source, props, object, customizer) {
+  var isNew = !object;
+  object || (object = {});
+  var index2 = -1, length = props.length;
+  while (++index2 < length) {
+    var key = props[index2];
+    var newValue = customizer ? customizer(object[key], source[key], key, object, source) : void 0;
+    if (newValue === void 0) {
+      newValue = source[key];
+    }
+    if (isNew) {
+      baseAssignValue(object, key, newValue);
+    } else {
+      assignValue(object, key, newValue);
+    }
+  }
+  return object;
+}
+var nativeMax$1 = Math.max;
+function overRest(func, start, transform) {
+  start = nativeMax$1(start === void 0 ? func.length - 1 : start, 0);
+  return function() {
+    var args = arguments, index2 = -1, length = nativeMax$1(args.length - start, 0), array = Array(length);
+    while (++index2 < length) {
+      array[index2] = args[start + index2];
+    }
+    index2 = -1;
+    var otherArgs = Array(start + 1);
+    while (++index2 < start) {
+      otherArgs[index2] = args[index2];
+    }
+    otherArgs[start] = transform(array);
+    return apply(func, this, otherArgs);
+  };
+}
+function baseRest(func, start) {
+  return setToString$1(overRest(func, start, identity), func + "");
+}
+var MAX_SAFE_INTEGER = 9007199254740991;
+function isLength(value) {
+  return typeof value == "number" && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
+}
+function isArrayLike(value) {
+  return value != null && isLength(value.length) && !isFunction(value);
+}
+function isIterateeCall(value, index2, object) {
+  if (!isObject(object)) {
+    return false;
+  }
+  var type = typeof index2;
+  if (type == "number" ? isArrayLike(object) && isIndex(index2, object.length) : type == "string" && index2 in object) {
+    return eq(object[index2], value);
+  }
+  return false;
+}
+function createAssigner(assigner) {
+  return baseRest(function(object, sources) {
+    var index2 = -1, length = sources.length, customizer = length > 1 ? sources[length - 1] : void 0, guard = length > 2 ? sources[2] : void 0;
+    customizer = assigner.length > 3 && typeof customizer == "function" ? (length--, customizer) : void 0;
+    if (guard && isIterateeCall(sources[0], sources[1], guard)) {
+      customizer = length < 3 ? void 0 : customizer;
+      length = 1;
+    }
+    object = Object(object);
+    while (++index2 < length) {
+      var source = sources[index2];
+      if (source) {
+        assigner(object, source, index2, customizer);
+      }
+    }
+    return object;
+  });
+}
+var objectProto$4 = Object.prototype;
+function isPrototype(value) {
+  var Ctor = value && value.constructor, proto = typeof Ctor == "function" && Ctor.prototype || objectProto$4;
+  return value === proto;
+}
+function baseTimes(n, iteratee) {
+  var index2 = -1, result = Array(n);
+  while (++index2 < n) {
+    result[index2] = iteratee(index2);
+  }
+  return result;
+}
+var argsTag$1 = "[object Arguments]";
+function baseIsArguments(value) {
+  return isObjectLike(value) && baseGetTag(value) == argsTag$1;
+}
+var objectProto$3 = Object.prototype;
+var hasOwnProperty$3 = objectProto$3.hasOwnProperty;
+var propertyIsEnumerable = objectProto$3.propertyIsEnumerable;
+var isArguments = baseIsArguments(function() {
+  return arguments;
+}()) ? baseIsArguments : function(value) {
+  return isObjectLike(value) && hasOwnProperty$3.call(value, "callee") && !propertyIsEnumerable.call(value, "callee");
+};
+var isArguments$1 = isArguments;
+function stubFalse() {
+  return false;
+}
+var freeExports$1 = typeof exports == "object" && exports && !exports.nodeType && exports;
+var freeModule$1 = freeExports$1 && typeof module == "object" && module && !module.nodeType && module;
+var moduleExports$1 = freeModule$1 && freeModule$1.exports === freeExports$1;
+var Buffer = moduleExports$1 ? root$1.Buffer : void 0;
+var nativeIsBuffer = Buffer ? Buffer.isBuffer : void 0;
+var isBuffer = nativeIsBuffer || stubFalse;
+var isBuffer$1 = isBuffer;
+var argsTag = "[object Arguments]", arrayTag = "[object Array]", boolTag = "[object Boolean]", dateTag = "[object Date]", errorTag = "[object Error]", funcTag = "[object Function]", mapTag = "[object Map]", numberTag = "[object Number]", objectTag = "[object Object]", regexpTag = "[object RegExp]", setTag = "[object Set]", stringTag = "[object String]", weakMapTag = "[object WeakMap]";
+var arrayBufferTag = "[object ArrayBuffer]", dataViewTag = "[object DataView]", float32Tag = "[object Float32Array]", float64Tag = "[object Float64Array]", int8Tag = "[object Int8Array]", int16Tag = "[object Int16Array]", int32Tag = "[object Int32Array]", uint8Tag = "[object Uint8Array]", uint8ClampedTag = "[object Uint8ClampedArray]", uint16Tag = "[object Uint16Array]", uint32Tag = "[object Uint32Array]";
+var typedArrayTags = {};
+typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = typedArrayTags[uint32Tag] = true;
+typedArrayTags[argsTag] = typedArrayTags[arrayTag] = typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = typedArrayTags[dataViewTag] = typedArrayTags[dateTag] = typedArrayTags[errorTag] = typedArrayTags[funcTag] = typedArrayTags[mapTag] = typedArrayTags[numberTag] = typedArrayTags[objectTag] = typedArrayTags[regexpTag] = typedArrayTags[setTag] = typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false;
+function baseIsTypedArray(value) {
+  return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[baseGetTag(value)];
+}
+function baseUnary(func) {
+  return function(value) {
+    return func(value);
+  };
+}
+var freeExports = typeof exports == "object" && exports && !exports.nodeType && exports;
+var freeModule = freeExports && typeof module == "object" && module && !module.nodeType && module;
+var moduleExports = freeModule && freeModule.exports === freeExports;
+var freeProcess = moduleExports && freeGlobal$1.process;
+var nodeUtil = function() {
+  try {
+    var types = freeModule && freeModule.require && freeModule.require("util").types;
+    if (types) {
+      return types;
+    }
+    return freeProcess && freeProcess.binding && freeProcess.binding("util");
+  } catch (e) {
+  }
+}();
+var nodeUtil$1 = nodeUtil;
+var nodeIsTypedArray = nodeUtil$1 && nodeUtil$1.isTypedArray;
+var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;
+var isTypedArray$1 = isTypedArray;
+var objectProto$2 = Object.prototype;
+var hasOwnProperty$2 = objectProto$2.hasOwnProperty;
+function arrayLikeKeys(value, inherited) {
+  var isArr = isArray$1(value), isArg = !isArr && isArguments$1(value), isBuff = !isArr && !isArg && isBuffer$1(value), isType = !isArr && !isArg && !isBuff && isTypedArray$1(value), skipIndexes = isArr || isArg || isBuff || isType, result = skipIndexes ? baseTimes(value.length, String) : [], length = result.length;
+  for (var key in value) {
+    if ((inherited || hasOwnProperty$2.call(value, key)) && !(skipIndexes && (key == "length" || isBuff && (key == "offset" || key == "parent") || isType && (key == "buffer" || key == "byteLength" || key == "byteOffset") || isIndex(key, length)))) {
+      result.push(key);
+    }
+  }
+  return result;
+}
+function overArg(func, transform) {
+  return function(arg) {
+    return func(transform(arg));
+  };
+}
+var nativeKeys = overArg(Object.keys, Object);
+var nativeKeys$1 = nativeKeys;
+var objectProto$1 = Object.prototype;
+var hasOwnProperty$1 = objectProto$1.hasOwnProperty;
+function baseKeys(object) {
+  if (!isPrototype(object)) {
+    return nativeKeys$1(object);
+  }
+  var result = [];
+  for (var key in Object(object)) {
+    if (hasOwnProperty$1.call(object, key) && key != "constructor") {
+      result.push(key);
+    }
+  }
+  return result;
+}
+function keys(object) {
+  return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);
+}
+var objectProto = Object.prototype;
+var hasOwnProperty = objectProto.hasOwnProperty;
+var assign = createAssigner(function(object, source) {
+  if (isPrototype(source) || isArrayLike(source)) {
+    copyObject(source, keys(source), object);
+    return;
+  }
+  for (var key in source) {
+    if (hasOwnProperty.call(source, key)) {
+      assignValue(object, key, source[key]);
+    }
+  }
+});
+var assign$1 = assign;
+var now = function() {
+  return root$1.Date.now();
+};
+var now$1 = now;
+var FUNC_ERROR_TEXT = "Expected a function";
+var nativeMax = Math.max, nativeMin = Math.min;
+function debounce(func, wait, options) {
+  var lastArgs, lastThis, maxWait, result, timerId, lastCallTime, lastInvokeTime = 0, leading = false, maxing = false, trailing = true;
+  if (typeof func != "function") {
+    throw new TypeError(FUNC_ERROR_TEXT);
+  }
+  wait = toNumber(wait) || 0;
+  if (isObject(options)) {
+    leading = !!options.leading;
+    maxing = "maxWait" in options;
+    maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
+    trailing = "trailing" in options ? !!options.trailing : trailing;
+  }
+  function invokeFunc(time) {
+    var args = lastArgs, thisArg = lastThis;
+    lastArgs = lastThis = void 0;
+    lastInvokeTime = time;
+    result = func.apply(thisArg, args);
+    return result;
+  }
+  function leadingEdge(time) {
+    lastInvokeTime = time;
+    timerId = setTimeout(timerExpired, wait);
+    return leading ? invokeFunc(time) : result;
+  }
+  function remainingWait(time) {
+    var timeSinceLastCall = time - lastCallTime, timeSinceLastInvoke = time - lastInvokeTime, timeWaiting = wait - timeSinceLastCall;
+    return maxing ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke) : timeWaiting;
+  }
+  function shouldInvoke(time) {
+    var timeSinceLastCall = time - lastCallTime, timeSinceLastInvoke = time - lastInvokeTime;
+    return lastCallTime === void 0 || timeSinceLastCall >= wait || timeSinceLastCall < 0 || maxing && timeSinceLastInvoke >= maxWait;
+  }
+  function timerExpired() {
+    var time = now$1();
+    if (shouldInvoke(time)) {
+      return trailingEdge(time);
+    }
+    timerId = setTimeout(timerExpired, remainingWait(time));
+  }
+  function trailingEdge(time) {
+    timerId = void 0;
+    if (trailing && lastArgs) {
+      return invokeFunc(time);
+    }
+    lastArgs = lastThis = void 0;
+    return result;
+  }
+  function cancel() {
+    if (timerId !== void 0) {
+      clearTimeout(timerId);
+    }
+    lastInvokeTime = 0;
+    lastArgs = lastCallTime = lastThis = timerId = void 0;
+  }
+  function flush() {
+    return timerId === void 0 ? result : trailingEdge(now$1());
+  }
+  function debounced() {
+    var time = now$1(), isInvoking = shouldInvoke(time);
+    lastArgs = arguments;
+    lastThis = this;
+    lastCallTime = time;
+    if (isInvoking) {
+      if (timerId === void 0) {
+        return leadingEdge(lastCallTime);
+      }
+      if (maxing) {
+        clearTimeout(timerId);
+        timerId = setTimeout(timerExpired, wait);
+        return invokeFunc(lastCallTime);
+      }
+    }
+    if (timerId === void 0) {
+      timerId = setTimeout(timerExpired, wait);
+    }
+    return result;
+  }
+  debounced.cancel = cancel;
+  debounced.flush = flush;
+  return debounced;
+}
+var render = function() {
+  var _vm = this;
+  var _h = _vm.$createElement;
+  var _c = _vm._self._c || _h;
+  return _c("div", [_vm._t("default", null, { "images": _vm.images, "options": _vm.options })], 2);
+};
+var staticRenderFns = [];
+function normalizeComponent(scriptExports, render2, staticRenderFns2, functionalTemplate, injectStyles, scopeId, moduleIdentifier, shadowMode) {
+  var options = typeof scriptExports === "function" ? scriptExports.options : scriptExports;
+  if (render2) {
+    options.render = render2;
+    options.staticRenderFns = staticRenderFns2;
+    options._compiled = true;
+  }
+  if (functionalTemplate) {
+    options.functional = true;
+  }
+  if (scopeId) {
+    options._scopeId = "data-v-" + scopeId;
+  }
+  var hook;
+  if (moduleIdentifier) {
+    hook = function(context) {
+      context = context || this.$vnode && this.$vnode.ssrContext || this.parent && this.parent.$vnode && this.parent.$vnode.ssrContext;
+      if (!context && typeof __VUE_SSR_CONTEXT__ !== "undefined") {
+        context = __VUE_SSR_CONTEXT__;
+      }
+      if (injectStyles) {
+        injectStyles.call(this, context);
+      }
+      if (context && context._registeredComponents) {
+        context._registeredComponents.add(moduleIdentifier);
+      }
+    };
+    options._ssrRegister = hook;
+  } else if (injectStyles) {
+    hook = shadowMode ? function() {
+      injectStyles.call(
+        this,
+        (options.functional ? this.parent : this).$root.$options.shadowRoot
+      );
+    } : injectStyles;
+  }
+  if (hook) {
+    if (options.functional) {
+      options._injectStyles = hook;
+      var originalRender = options.render;
+      options.render = function renderWithStyleInjection(h, context) {
+        hook.call(context);
+        return originalRender(h, context);
+      };
+    } else {
+      var existing = options.beforeCreate;
+      options.beforeCreate = existing ? [].concat(existing, hook) : [hook];
+    }
+  }
+  return {
+    exports: scriptExports,
+    options
+  };
+}
+const __vue2_script = {
+  props: {
+    images: {
+      type: Array
+    },
+    rebuild: {
+      type: Boolean,
+      default: false
+    },
+    trigger: {},
+    options: {
+      type: Object
+    }
+  },
+  data() {
+    return {};
+  },
+  computed: {},
+  watch: {
+    images() {
+      this.$nextTick(() => {
+        this.onChange();
+      });
+    },
+    trigger: {
+      handler() {
+        this.$nextTick(() => {
+          this.onChange();
+        });
+      },
+      deep: true
+    },
+    options: {
+      handler() {
+        this.$nextTick(() => {
+          this.rebuildViewer();
+        });
+      },
+      deep: true
+    }
+  },
+  mounted() {
+    this.createViewer();
+  },
+  unmounted() {
+    this.destroyViewer();
+  },
+  methods: {
+    onChange() {
+      if (this.rebuild) {
+        this.rebuildViewer();
+      } else {
+        this.updateViewer();
+      }
+    },
+    rebuildViewer() {
+      this.destroyViewer();
+      this.createViewer();
+    },
+    updateViewer() {
+      if (this.$viewer) {
+        this.$viewer.update();
+        this.$emit("inited", this.$viewer);
+      } else {
+        this.createViewer();
+      }
+    },
+    destroyViewer() {
+      this.$viewer && this.$viewer.destroy();
+    },
+    createViewer() {
+      this.$viewer = new Viewer(this.$el, this.options);
+      this.$emit("inited", this.$viewer);
+    }
+  }
+};
+const __cssModules = {};
+var __component__ = /* @__PURE__ */ normalizeComponent(
+  __vue2_script,
+  render,
+  staticRenderFns,
+  false,
+  __vue2_injectStyles,
+  null,
+  null,
+  null
+);
+function __vue2_injectStyles(context) {
+  for (let o in __cssModules) {
+    this[o] = __cssModules[o];
+  }
+}
+var component = /* @__PURE__ */ function() {
+  return __component__.exports;
+}();
+const directive = ({ name = "viewer", debug = false } = {}) => {
+  function createViewer(el, options, rebuild = false, observer = false) {
+    Vue.nextTick(() => {
+      if (observer && !imageDiff(el))
+        return;
+      if (rebuild || !el[`$${name}`]) {
+        destroyViewer(el);
+        el[`$${name}`] = new Viewer(el, options);
+        log("Viewer created");
+      } else {
+        el[`$${name}`].update();
+        log("Viewer updated");
+      }
+    });
+  }
+  function imageDiff(el) {
+    const imageContent = el.innerHTML.match(/![]() /g);
+    const viewerImageText = imageContent ? imageContent.join("") : void 0;
+    if (el.__viewerImageDiffCache === viewerImageText) {
+      log("Element change detected, but image(s) has not changed");
+      return false;
+    } else {
+      log("Image change detected");
+      el.__viewerImageDiffCache = viewerImageText;
+      return true;
+    }
+  }
+  function createObserver(el, options, debouncedCreateViewer, rebuild) {
+    destroyObserver(el);
+    const MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
+    if (!MutationObserver) {
+      log("Observer not supported");
+      return;
+    }
+    const observer = new MutationObserver((mutations) => {
+      mutations.forEach((mutation) => {
+        log(`Viewer mutation:${mutation.type}`);
+        debouncedCreateViewer(el, options, rebuild, true);
+      });
+    });
+    const config = { attributes: true, childList: true, characterData: true, subtree: true };
+    observer.observe(el, config);
+    el.__viewerMutationObserver = observer;
+    log("Observer created");
+  }
+  function createWatcher(el, { expression }, vnode, debouncedCreateViewer) {
+    const simplePathRE = /^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['[^']*?']|\["[^"]*?"]|\[\d+]|\[[A-Za-z_$][\w$]*])*$/;
+    if (!expression || !simplePathRE.test(expression)) {
+      log("Only simple dot-delimited paths can create watcher");
+      return;
+    }
+    el.__viewerUnwatch = vnode.context.$watch(expression, (newVal, oldVal) => {
+      log("Change detected by watcher: ", expression);
+      debouncedCreateViewer(el, newVal, true);
+    }, {
+      deep: true
+    });
+    log("Watcher created, expression: ", expression);
+  }
+  function destroyViewer(el) {
+    if (!el[`$${name}`]) {
+      return;
+    }
+    el[`$${name}`].destroy();
+    delete el[`$${name}`];
+    log("Viewer destroyed");
+  }
+  function destroyObserver(el) {
+    if (!el.__viewerMutationObserver) {
+      return;
+    }
+    el.__viewerMutationObserver.disconnect();
+    delete el.__viewerMutationObserver;
+    log("Observer destroyed");
+  }
+  function destroyWatcher(el) {
+    if (!el.__viewerUnwatch) {
+      return;
+    }
+    el.__viewerUnwatch();
+    delete el.__viewerUnwatch;
+    log("Watcher destroyed");
+  }
+  function log() {
+    debug && console.log(...arguments);
+  }
+  const directive2 = {
+    bind(el, binding, vnode) {
+      log("Viewer bind");
+      const debouncedCreateViewer = debounce(createViewer, 50);
+      debouncedCreateViewer(el, binding.value);
+      createWatcher(el, binding, vnode, debouncedCreateViewer);
+      if (!binding.modifiers.static) {
+        createObserver(el, binding.value, debouncedCreateViewer, binding.modifiers.rebuild);
+      }
+    },
+    unbind(el, binding) {
+      log("Viewer unbind");
+      destroyObserver(el);
+      destroyWatcher(el);
+      destroyViewer(el);
+    }
+  };
+  return directive2;
+};
+const api = ({ images = [], options = {} } = {}) => {
+  options = assign$1(options, {
+    inline: false
+  });
+  const ViewerToken = Vue.extend({
+    render(h) {
+      return h(
+        "div",
+        {
+          style: {
+            display: "none"
+          },
+          class: ["__viewer-token"]
+        },
+        images.map((attr) => {
+          return h(
+            "img",
+            {
+              attrs: typeof attr === "string" ? { src: attr } : attr
+            }
+          );
+        })
+      );
+    }
+  });
+  const token = new ViewerToken();
+  token.$mount();
+  document.body.appendChild(token.$el);
+  const $viewer = new Viewer(token.$el, options);
+  const $destroy = $viewer.destroy.bind($viewer);
+  $viewer.destroy = function() {
+    $destroy();
+    token.$destroy();
+    document.body.removeChild(token.$el);
+    return $viewer;
+  };
+  $viewer.show();
+  token.$el.addEventListener("hidden", function() {
+    if (this.viewer === $viewer) {
+      $viewer.destroy();
+    }
+  });
+  return $viewer;
+};
+var index = {
+  install(Vue2, { name = "viewer", debug = false, defaultOptions } = {}) {
+    Viewer.setDefaults(defaultOptions);
+    Vue2.component(name, assign$1(component, { name }));
+    Vue2.directive(name, directive({ name, debug }));
+    Vue2.prototype[`$${name}Api`] = api;
+  },
+  setDefaults(defaultOptions) {
+    Viewer.setDefaults(defaultOptions);
+  }
+};
+export { api, component, index as default, directive };
diff --git a/ui/lib/js/directives.js b/ui/lib/js/directives.js
index bdfbf6a5..e9e3aafb 100644
--- a/ui/lib/js/directives.js
+++ b/ui/lib/js/directives.js
@@ -1,3 +1,5 @@
+import {directive as viewer} from '../cdn/v-viewer/1.7.4/v-viewer'
+
 const map = {
   throttle: {
     bind: function (el, obj) {
@@ -24,7 +26,8 @@ const map = {
         el.style.display = 'none'
       }
     }
-  }
+  },
+  viewer: viewer({debug: true})
 }
 
 
diff --git a/ui/lib/js/encryption.js b/ui/lib/js/encryption.js
index 3f5d1064..940b410c 100644
--- a/ui/lib/js/encryption.js
+++ b/ui/lib/js/encryption.js
@@ -1,4 +1,4 @@
-import CryptoJs from  "crypto-js";
+import CryptoJs from "crypto-js";
 
 /**
  * 密码加密工具
diff --git a/ui/package.json b/ui/package.json
index 8a66b052..595b07fd 100644
--- a/ui/package.json
+++ b/ui/package.json
@@ -19,7 +19,6 @@
     "html2canvas": "^1.4.1",
     "jspdf": "^2.5.1",
     "echarts": "^5.1.2",
-    "v-viewer": "^1.5.1",
     "vue-cropper": "^0.5.5",
     "vue-qr": "^2.2.1",
     "vuedraggable": "^2.24.3",
diff --git a/ui/packages/basic/AiUploader.vue b/ui/packages/basic/AiUploader.vue
index 27224660..9b981e69 100644
--- a/ui/packages/basic/AiUploader.vue
+++ b/ui/packages/basic/AiUploader.vue
@@ -89,14 +89,8 @@
 
 
 
@@ -417,33 +410,33 @@ export default {
 .uploader {
   line-height: 1;
 
-  :deep(.el-upload ){
+  :deep(.el-upload ) {
     width: 100%;
     text-align: start;
   }
 
-  :deep(.validError ){
+  :deep(.validError ) {
     .el-button {
       border-color: #f46;
       color: #f46;
     }
   }
 
-  :deep(.el-upload--picture-card ){
+  :deep(.el-upload--picture-card ) {
     border: none;
   }
 
-  :deep( .el-list-leave-active), :deep( .el-upload-list__item ){
+  :deep( .el-list-leave-active), :deep( .el-upload-list__item ) {
     transition: all 0s !important;
   }
 
-  :deep(.el-upload-list--picture-card .el-upload-list__item ){
+  :deep(.el-upload-list--picture-card .el-upload-list__item ) {
     width: 120px;
     height: 120px;
     border-radius: 4px;
   }
 
-  :deep(.el-upload--picture-card ){
+  :deep(.el-upload--picture-card ) {
     width: auto;
     height: auto;
   }
@@ -453,7 +446,7 @@ export default {
     line-height: 16px;
   }
 
-  :deep(.fileItem ){
+  :deep(.fileItem ) {
     width: 100%;
     height: 60px;
     background: #FFFFFF;
diff --git a/ui/packages/common/AiUserGet/tree/model/node.js b/ui/packages/common/AiUserGet/tree/model/node.js
index 657b3b82..09f3931e 100644
--- a/ui/packages/common/AiUserGet/tree/model/node.js
+++ b/ui/packages/common/AiUserGet/tree/model/node.js
@@ -1,6 +1,6 @@
 import objectAssign from 'element-ui/src/utils/merge';
-import { markNodeData, NODE_KEY } from './util';
-import { arrayFindIndex } from 'element-ui/src/utils/util';
+import {markNodeData, NODE_KEY} from './util';
+import {arrayFindIndex} from 'element-ui/src/utils/util';
 
 export const getChildState = node => {
   let all = true;
diff --git a/ui/packages/common/AiUserGet/tree/model/tree-store.js b/ui/packages/common/AiUserGet/tree/model/tree-store.js
index 68f58e6d..18cf0574 100644
--- a/ui/packages/common/AiUserGet/tree/model/tree-store.js
+++ b/ui/packages/common/AiUserGet/tree/model/tree-store.js
@@ -1,5 +1,5 @@
 import Node from './node';
-import { getNodeKey } from './util';
+import {getNodeKey} from './util';
 
 export default class TreeStore {
 	constructor(options) {
diff --git a/ui/packages/common/AiWechatSelecter/tree/model/node.js b/ui/packages/common/AiWechatSelecter/tree/model/node.js
index 657b3b82..09f3931e 100644
--- a/ui/packages/common/AiWechatSelecter/tree/model/node.js
+++ b/ui/packages/common/AiWechatSelecter/tree/model/node.js
@@ -1,6 +1,6 @@
 import objectAssign from 'element-ui/src/utils/merge';
-import { markNodeData, NODE_KEY } from './util';
-import { arrayFindIndex } from 'element-ui/src/utils/util';
+import {markNodeData, NODE_KEY} from './util';
+import {arrayFindIndex} from 'element-ui/src/utils/util';
 
 export const getChildState = node => {
   let all = true;
diff --git a/ui/packages/common/AiWechatSelecter/tree/model/tree-store.js b/ui/packages/common/AiWechatSelecter/tree/model/tree-store.js
index 68f58e6d..18cf0574 100644
--- a/ui/packages/common/AiWechatSelecter/tree/model/tree-store.js
+++ b/ui/packages/common/AiWechatSelecter/tree/model/tree-store.js
@@ -1,5 +1,5 @@
 import Node from './node';
-import { getNodeKey } from './util';
+import {getNodeKey} from './util';
 
 export default class TreeStore {
 	constructor(options) {
diff --git a/vue.config.js b/vue.config.js
index 2d6fee04..bb82d7ea 100644
--- a/vue.config.js
+++ b/vue.config.js
@@ -1,6 +1,7 @@
 const path = require('path');
 const proxy = {
-  dv: "https://pingchangdjweb.icunwei.com/",
+  // dv: "https://pingchangdjweb.icunwei.com/",
+  dv: "http://192.168.1.87:9000",
   fengdu: "https://web.fdfengshou.cn/"
 }[process.env.VUE_APP_SCOPE] || "http://192.168.1.87:9000"
 module.exports = {
/g);
+    const viewerImageText = imageContent ? imageContent.join("") : void 0;
+    if (el.__viewerImageDiffCache === viewerImageText) {
+      log("Element change detected, but image(s) has not changed");
+      return false;
+    } else {
+      log("Image change detected");
+      el.__viewerImageDiffCache = viewerImageText;
+      return true;
+    }
+  }
+  function createObserver(el, options, debouncedCreateViewer, rebuild) {
+    destroyObserver(el);
+    const MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
+    if (!MutationObserver) {
+      log("Observer not supported");
+      return;
+    }
+    const observer = new MutationObserver((mutations) => {
+      mutations.forEach((mutation) => {
+        log(`Viewer mutation:${mutation.type}`);
+        debouncedCreateViewer(el, options, rebuild, true);
+      });
+    });
+    const config = { attributes: true, childList: true, characterData: true, subtree: true };
+    observer.observe(el, config);
+    el.__viewerMutationObserver = observer;
+    log("Observer created");
+  }
+  function createWatcher(el, { expression }, vnode, debouncedCreateViewer) {
+    const simplePathRE = /^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['[^']*?']|\["[^"]*?"]|\[\d+]|\[[A-Za-z_$][\w$]*])*$/;
+    if (!expression || !simplePathRE.test(expression)) {
+      log("Only simple dot-delimited paths can create watcher");
+      return;
+    }
+    el.__viewerUnwatch = vnode.context.$watch(expression, (newVal, oldVal) => {
+      log("Change detected by watcher: ", expression);
+      debouncedCreateViewer(el, newVal, true);
+    }, {
+      deep: true
+    });
+    log("Watcher created, expression: ", expression);
+  }
+  function destroyViewer(el) {
+    if (!el[`$${name}`]) {
+      return;
+    }
+    el[`$${name}`].destroy();
+    delete el[`$${name}`];
+    log("Viewer destroyed");
+  }
+  function destroyObserver(el) {
+    if (!el.__viewerMutationObserver) {
+      return;
+    }
+    el.__viewerMutationObserver.disconnect();
+    delete el.__viewerMutationObserver;
+    log("Observer destroyed");
+  }
+  function destroyWatcher(el) {
+    if (!el.__viewerUnwatch) {
+      return;
+    }
+    el.__viewerUnwatch();
+    delete el.__viewerUnwatch;
+    log("Watcher destroyed");
+  }
+  function log() {
+    debug && console.log(...arguments);
+  }
+  const directive2 = {
+    bind(el, binding, vnode) {
+      log("Viewer bind");
+      const debouncedCreateViewer = debounce(createViewer, 50);
+      debouncedCreateViewer(el, binding.value);
+      createWatcher(el, binding, vnode, debouncedCreateViewer);
+      if (!binding.modifiers.static) {
+        createObserver(el, binding.value, debouncedCreateViewer, binding.modifiers.rebuild);
+      }
+    },
+    unbind(el, binding) {
+      log("Viewer unbind");
+      destroyObserver(el);
+      destroyWatcher(el);
+      destroyViewer(el);
+    }
+  };
+  return directive2;
+};
+const api = ({ images = [], options = {} } = {}) => {
+  options = assign$1(options, {
+    inline: false
+  });
+  const ViewerToken = Vue.extend({
+    render(h) {
+      return h(
+        "div",
+        {
+          style: {
+            display: "none"
+          },
+          class: ["__viewer-token"]
+        },
+        images.map((attr) => {
+          return h(
+            "img",
+            {
+              attrs: typeof attr === "string" ? { src: attr } : attr
+            }
+          );
+        })
+      );
+    }
+  });
+  const token = new ViewerToken();
+  token.$mount();
+  document.body.appendChild(token.$el);
+  const $viewer = new Viewer(token.$el, options);
+  const $destroy = $viewer.destroy.bind($viewer);
+  $viewer.destroy = function() {
+    $destroy();
+    token.$destroy();
+    document.body.removeChild(token.$el);
+    return $viewer;
+  };
+  $viewer.show();
+  token.$el.addEventListener("hidden", function() {
+    if (this.viewer === $viewer) {
+      $viewer.destroy();
+    }
+  });
+  return $viewer;
+};
+var index = {
+  install(Vue2, { name = "viewer", debug = false, defaultOptions } = {}) {
+    Viewer.setDefaults(defaultOptions);
+    Vue2.component(name, assign$1(component, { name }));
+    Vue2.directive(name, directive({ name, debug }));
+    Vue2.prototype[`$${name}Api`] = api;
+  },
+  setDefaults(defaultOptions) {
+    Viewer.setDefaults(defaultOptions);
+  }
+};
+export { api, component, index as default, directive };
diff --git a/ui/lib/js/directives.js b/ui/lib/js/directives.js
index bdfbf6a5..e9e3aafb 100644
--- a/ui/lib/js/directives.js
+++ b/ui/lib/js/directives.js
@@ -1,3 +1,5 @@
+import {directive as viewer} from '../cdn/v-viewer/1.7.4/v-viewer'
+
 const map = {
   throttle: {
     bind: function (el, obj) {
@@ -24,7 +26,8 @@ const map = {
         el.style.display = 'none'
       }
     }
-  }
+  },
+  viewer: viewer({debug: true})
 }
 
 
diff --git a/ui/lib/js/encryption.js b/ui/lib/js/encryption.js
index 3f5d1064..940b410c 100644
--- a/ui/lib/js/encryption.js
+++ b/ui/lib/js/encryption.js
@@ -1,4 +1,4 @@
-import CryptoJs from  "crypto-js";
+import CryptoJs from "crypto-js";
 
 /**
  * 密码加密工具
diff --git a/ui/package.json b/ui/package.json
index 8a66b052..595b07fd 100644
--- a/ui/package.json
+++ b/ui/package.json
@@ -19,7 +19,6 @@
     "html2canvas": "^1.4.1",
     "jspdf": "^2.5.1",
     "echarts": "^5.1.2",
-    "v-viewer": "^1.5.1",
     "vue-cropper": "^0.5.5",
     "vue-qr": "^2.2.1",
     "vuedraggable": "^2.24.3",
diff --git a/ui/packages/basic/AiUploader.vue b/ui/packages/basic/AiUploader.vue
index 27224660..9b981e69 100644
--- a/ui/packages/basic/AiUploader.vue
+++ b/ui/packages/basic/AiUploader.vue
@@ -89,14 +89,8 @@
 
 
 
@@ -417,33 +410,33 @@ export default {
 .uploader {
   line-height: 1;
 
-  :deep(.el-upload ){
+  :deep(.el-upload ) {
     width: 100%;
     text-align: start;
   }
 
-  :deep(.validError ){
+  :deep(.validError ) {
     .el-button {
       border-color: #f46;
       color: #f46;
     }
   }
 
-  :deep(.el-upload--picture-card ){
+  :deep(.el-upload--picture-card ) {
     border: none;
   }
 
-  :deep( .el-list-leave-active), :deep( .el-upload-list__item ){
+  :deep( .el-list-leave-active), :deep( .el-upload-list__item ) {
     transition: all 0s !important;
   }
 
-  :deep(.el-upload-list--picture-card .el-upload-list__item ){
+  :deep(.el-upload-list--picture-card .el-upload-list__item ) {
     width: 120px;
     height: 120px;
     border-radius: 4px;
   }
 
-  :deep(.el-upload--picture-card ){
+  :deep(.el-upload--picture-card ) {
     width: auto;
     height: auto;
   }
@@ -453,7 +446,7 @@ export default {
     line-height: 16px;
   }
 
-  :deep(.fileItem ){
+  :deep(.fileItem ) {
     width: 100%;
     height: 60px;
     background: #FFFFFF;
diff --git a/ui/packages/common/AiUserGet/tree/model/node.js b/ui/packages/common/AiUserGet/tree/model/node.js
index 657b3b82..09f3931e 100644
--- a/ui/packages/common/AiUserGet/tree/model/node.js
+++ b/ui/packages/common/AiUserGet/tree/model/node.js
@@ -1,6 +1,6 @@
 import objectAssign from 'element-ui/src/utils/merge';
-import { markNodeData, NODE_KEY } from './util';
-import { arrayFindIndex } from 'element-ui/src/utils/util';
+import {markNodeData, NODE_KEY} from './util';
+import {arrayFindIndex} from 'element-ui/src/utils/util';
 
 export const getChildState = node => {
   let all = true;
diff --git a/ui/packages/common/AiUserGet/tree/model/tree-store.js b/ui/packages/common/AiUserGet/tree/model/tree-store.js
index 68f58e6d..18cf0574 100644
--- a/ui/packages/common/AiUserGet/tree/model/tree-store.js
+++ b/ui/packages/common/AiUserGet/tree/model/tree-store.js
@@ -1,5 +1,5 @@
 import Node from './node';
-import { getNodeKey } from './util';
+import {getNodeKey} from './util';
 
 export default class TreeStore {
 	constructor(options) {
diff --git a/ui/packages/common/AiWechatSelecter/tree/model/node.js b/ui/packages/common/AiWechatSelecter/tree/model/node.js
index 657b3b82..09f3931e 100644
--- a/ui/packages/common/AiWechatSelecter/tree/model/node.js
+++ b/ui/packages/common/AiWechatSelecter/tree/model/node.js
@@ -1,6 +1,6 @@
 import objectAssign from 'element-ui/src/utils/merge';
-import { markNodeData, NODE_KEY } from './util';
-import { arrayFindIndex } from 'element-ui/src/utils/util';
+import {markNodeData, NODE_KEY} from './util';
+import {arrayFindIndex} from 'element-ui/src/utils/util';
 
 export const getChildState = node => {
   let all = true;
diff --git a/ui/packages/common/AiWechatSelecter/tree/model/tree-store.js b/ui/packages/common/AiWechatSelecter/tree/model/tree-store.js
index 68f58e6d..18cf0574 100644
--- a/ui/packages/common/AiWechatSelecter/tree/model/tree-store.js
+++ b/ui/packages/common/AiWechatSelecter/tree/model/tree-store.js
@@ -1,5 +1,5 @@
 import Node from './node';
-import { getNodeKey } from './util';
+import {getNodeKey} from './util';
 
 export default class TreeStore {
 	constructor(options) {
diff --git a/vue.config.js b/vue.config.js
index 2d6fee04..bb82d7ea 100644
--- a/vue.config.js
+++ b/vue.config.js
@@ -1,6 +1,7 @@
 const path = require('path');
 const proxy = {
-  dv: "https://pingchangdjweb.icunwei.com/",
+  // dv: "https://pingchangdjweb.icunwei.com/",
+  dv: "http://192.168.1.87:9000",
   fengdu: "https://web.fdfengshou.cn/"
 }[process.env.VUE_APP_SCOPE] || "http://192.168.1.87:9000"
 module.exports = {