Forráskód Böngészése

Merge branch 'dev' of ssh://10.10.100.21/source/saas-platform into dev

zhuth 7 éve
szülő
commit
732d887d35
34 módosított fájl, 958 hozzáadás és 50 törlés
  1. 2 1
      applications/document/document-server/src/main/java/com/usoftchina/saas/document/mapper/BankinformationMapper.java
  2. 1 1
      applications/document/document-server/src/main/java/com/usoftchina/saas/document/service/impl/BankinformationServiceImpl.java
  3. 2 2
      applications/document/document-server/src/main/resources/mapper/BankinformationMapper.xml
  4. 6 6
      applications/money/money-server/src/main/java/com/usoftchina/saas/money/service/impl/VerificationServiceImpl.java
  5. 19 6
      frontend/saas-portal-web/src/components/conenter/addenterprise.vue
  6. 17 17
      frontend/saas-portal-web/src/components/conenter/home.vue
  7. 23 12
      frontend/saas-portal-web/static/css/main.css
  8. BIN
      frontend/saas-portal-web/static/img/banner.png
  9. BIN
      frontend/saas-portal-web/static/img/banner@2x@2x.png
  10. BIN
      frontend/saas-portal-web/static/img/feature/blue1@2x.png
  11. BIN
      frontend/saas-portal-web/static/img/feature/blue3@2x.png
  12. BIN
      frontend/saas-portal-web/static/img/feature/for2x.png
  13. BIN
      frontend/saas-portal-web/static/img/feature/formin2x.png
  14. BIN
      frontend/saas-portal-web/static/img/feature/mix1x.png
  15. BIN
      frontend/saas-portal-web/static/img/feature/mix2x.png
  16. BIN
      frontend/saas-portal-web/static/img/feature/mix3x.png
  17. BIN
      frontend/saas-portal-web/static/img/feature/mix4x.png
  18. BIN
      frontend/saas-portal-web/static/img/feature/one2x.png
  19. BIN
      frontend/saas-portal-web/static/img/feature/onemin2x.png
  20. BIN
      frontend/saas-portal-web/static/img/feature/three2x.png
  21. BIN
      frontend/saas-portal-web/static/img/feature/threemin2x.png
  22. BIN
      frontend/saas-portal-web/static/img/feature/tow2x.png
  23. BIN
      frontend/saas-portal-web/static/img/feature/towmin2x.png
  24. BIN
      frontend/saas-portal-web/static/img/feature/yellow2@2x.png
  25. BIN
      frontend/saas-portal-web/static/img/feature/yellow4@2x.png
  26. 457 0
      frontend/saas-web/app/view/core/dbfind/AddMultiDbfindGridPanel.js
  27. 299 0
      frontend/saas-web/app/view/core/dbfind/AddMultiDbfindTrigger.js
  28. 2 2
      frontend/saas-web/app/view/core/dbfind/MultiDbfindTrigger.js
  29. 105 0
      frontend/saas-web/app/view/core/dbfind/types/ProductAddMultiDbfindTrigger.js
  30. 1 1
      frontend/saas-web/app/view/document/address/DataList.js
  31. 1 1
      frontend/saas-web/app/view/document/bom/FormController.js
  32. 1 1
      frontend/saas-web/app/view/document/bom/FormPanel.js
  33. 22 0
      frontend/saas-web/app/view/purchase/purchase/FormPanelController.js
  34. BIN
      frontend/saas-web/resources/images/loading.gif

+ 2 - 1
applications/document/document-server/src/main/java/com/usoftchina/saas/document/mapper/BankinformationMapper.java

@@ -3,6 +3,7 @@ package com.usoftchina.saas.document.mapper;
 import com.usoftchina.saas.base.mapper.CommonBaseMapper;
 import com.usoftchina.saas.commons.dto.ComboDTO;
 import com.usoftchina.saas.document.entities.Bankinformation;
+import com.usoftchina.saas.page.PageDefault;
 import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
@@ -25,7 +26,7 @@ public interface BankinformationMapper extends CommonBaseMapper<Bankinformation>
 
     List<ComboDTO> getCombo(@Param("companyId") Long companyId);
     String selectBankcode(@Param("bk_bankcode") String bk_bankcode, @Param("companyId") Long companyId);
-    Long selectBankId(String bk_bankcode);
+    Long selectBankId(@Param("bk_bankcode") String bk_bankcode, @Param("companyId") Long companyId);
 
     void check(Map<String, Object> map);
 

+ 1 - 1
applications/document/document-server/src/main/java/com/usoftchina/saas/document/service/impl/BankinformationServiceImpl.java

@@ -95,7 +95,7 @@ public class BankinformationServiceImpl extends CommonBaseServiceImpl<Bankinform
                 }
             }
 
-            Long id = bankinformationMapper.selectBankId(bankinformation.getBk_bankcode());
+            Long id = bankinformationMapper.selectBankId(bankinformation.getBk_bankcode(), BaseContextHolder.getCompanyId());
             if (bktion != null){
                 if (id.equals(bankinformation.getId())){
                     bankinformationMapper.updateByPrimaryKeySelective(bankinformation);

+ 2 - 2
applications/document/document-server/src/main/resources/mapper/BankinformationMapper.xml

@@ -329,8 +329,8 @@
         bk_bankcode = #{bk_bankcode,jdbcType=VARCHAR} and companyId = #{companyId}
     </select>
 
-  <select id="selectBankId" parameterType="java.lang.String" resultType="java.lang.Long">
-        select bk_id from bankinformation where bk_bankcode = #{bk_bankcode,jdbcType=VARCHAR}
+  <select id="selectBankId" resultType="java.lang.Long">
+        select bk_id from bankinformation where bk_bankcode = #{bk_bankcode,jdbcType=VARCHAR} and companyId = #{companyId}
    </select>
 
   <select id="selectamount" parameterType="java.lang.Long" resultType="java.lang.Double">

+ 6 - 6
applications/money/money-server/src/main/java/com/usoftchina/saas/money/service/impl/VerificationServiceImpl.java

@@ -226,8 +226,8 @@ public class VerificationServiceImpl extends CommonBaseServiceImpl<VerificationM
                     throw new BizException(code, error);
                 }
                 if(amount.doubleValue()<0 && nowbalanceDet.doubleValue()>0){
-                    String msg = BizExceptionCode.MONEY_NOWAMOUNT_POSITIVE.getMessage();
-                    int code = BizExceptionCode.MONEY_NOWAMOUNT_POSITIVE.getCode();
+                    String msg = BizExceptionCode.MONEY_NOWAMOUNT_NEGATIVE.getMessage();
+                    int code = BizExceptionCode.MONEY_NOWAMOUNT_NEGATIVE.getCode();
                     String error = String.format(msg, det.getVd_slkind());
                     throw new BizException(code, error);
                 }
@@ -247,8 +247,8 @@ public class VerificationServiceImpl extends CommonBaseServiceImpl<VerificationM
                     throw new BizException(code, error);
                 }
                 if(amount.doubleValue()<0 && nowbalanceDet.doubleValue()>0){
-                    String msg = BizExceptionCode.MONEY_NOWAMOUNT_POSITIVE.getMessage();
-                    int code = BizExceptionCode.MONEY_NOWAMOUNT_POSITIVE.getCode();
+                    String msg = BizExceptionCode.MONEY_NOWAMOUNT_NEGATIVE.getMessage();
+                    int code = BizExceptionCode.MONEY_NOWAMOUNT_NEGATIVE.getCode();
                     String error = String.format(msg, detail.getVcd_slkind());
                     throw new BizException(code, error);
                 }
@@ -530,9 +530,9 @@ public class VerificationServiceImpl extends CommonBaseServiceImpl<VerificationM
     @Override
     public void deleteDetail2(Long id) {
         if (null != id) {
-            verificationdetailMapper.deleteByParentPrimaryKey(id);
             Verificationdetail verificationdetail = verificationdetailMapper.selectByPrimaryKey(Integer.valueOf(String.valueOf(id)));
-            Verification verification = verificationMapper.selectByPrimaryKey(verificationdetail.getVcd_vcid());
+            Verification verification = verificationMapper.selectByPrimaryKey(verificationdetail.getVcd_vcid().intValue());
+            verificationdetailMapper.deleteByParentPrimaryKey(id);
             DocBaseDTO baseDTO = new DocBaseDTO();
             baseDTO.setId(id);
             baseDTO.setCode(verification.getVc_code());

+ 19 - 6
frontend/saas-portal-web/src/components/conenter/addenterprise.vue

@@ -18,7 +18,7 @@
                     <ul>
                         <li style="margin: 0">
                             <span class="qy-biaoti"><span class="xingxing">*</span>公司名称</span>
-                            <input class="inpind" ref="qyname" @change= "spaceName" type="text">
+                            <input class="inpind" ref="qyname" @change= "spaceName" type="text" placeholder="请填写公司全称">
                             <dir class="qy-Tips"><span ref="qyno" style="color:red"></span></dir>
                         </li>
                         <li>
@@ -123,7 +123,7 @@ import { setTimeout } from 'timers';
             spaceName(){
                 let qyname = this.$refs.qyname.value.replace(/\s+/g, "");//公司名字过滤空格
                 if(qyname == ''){
-                    this.$refs.qyno.innerHTML = '企业名不能为空';
+                    this.$refs.qyno.innerHTML = '企业名不能为空';
                 } else {
                     if (this.reg.test(qyname)) {
                         this.$refs.qyno.innerHTML = '不能包含非法字符';
@@ -157,7 +157,7 @@ import { setTimeout } from 'timers';
             yzusername(){
                 let name = this.$refs.name.value.replace(/\s+/g, "");//姓名过滤空格
                 if (name == '') {
-                    this.$refs.usname.innerHTML = '姓名不能为空'
+                    this.$refs.usname.innerHTML = '个人姓名不能为空'
                 } else {
                     if (this.reg.test(name)) {
                         this.$refs.usname.innerHTML = '不能包含非法字符'
@@ -172,7 +172,7 @@ import { setTimeout } from 'timers';
             address(){
                 let address = this.$refs.address.value.replace(/\s+/g, "");//过滤空格
                 if (address == '') {
-                    this.$refs.ress.innerHTML = '地址不能为空'
+                    this.$refs.ress.innerHTML = '企业地址不能为空'
                     this.isaddressname = false
                 } else {
                     this.isaddressname = true
@@ -223,8 +223,10 @@ import { setTimeout } from 'timers';
                 // console.log('邮箱',this.isemail)//邮箱正则
                 if (name == '') {
                     this.$refs.tjtishi.innerHTML = '个人姓名不能为空';
+                    this.remotxt()
                 } else if (qyname == '') {
                     this.$refs.tjtishi.innerHTML = '企业名字不能为空';
+                    this.remotxt()
                 } else {
                     switch (this.qymingzi && this.isaddress && this.isname && this.isspaceName && this.isemail && this.isaddressname) {
                         case this.qymingzi:
@@ -257,27 +259,38 @@ import { setTimeout } from 'timers';
                             })
                             this.$refs.tjtishi.innerHTML = '';
                         } else {
-                            this.$refs.tjtishi.innerHTML = '企业名字已在优软云注册';
+                            this.$refs.tjtishi.innerHTML = '该企业已在优软云注册';
+                            this.remotxt()
                         }
                         break;
                         case this.isaddressname:
                         this.$refs.tjtishi.innerHTML = '企业地址不能为空';
+                        this.remotxt()
                         break;
                         case this.isaddress:
                         this.$refs.tjtishi.innerHTML = '企业地址不能包含非法字符';
+                        this.remotxt()
                         break;
                         case this.isname:
                         this.$refs.tjtishi.innerHTML = '个人姓名不能包含非法字符';
+                        this.remotxt()
                         break;
                         case this.isspaceName:
                         this.$refs.tjtishi.innerHTML = '企业名字不能包含非法字符';
+                        this.remotxt()
                         break;
                         case this.isemail:
-                        this.$refs.tjtishi.innerHTML = '请输入正确邮箱';
+                        this.$refs.tjtishi.innerHTML = '请填写正确的邮箱';
+                        this.remotxt()
                         break;
                     }
                 }
             },
+            remotxt(){
+                setTimeout(()=>{
+                    this.$refs.tjtishi.innerHTML = ' ';
+                },3000)
+            },
             //获取省市区
             selected(data){
                 this.province = data.province.value;

+ 17 - 17
frontend/saas-portal-web/src/components/conenter/home.vue

@@ -85,51 +85,51 @@
       <!-- 特色 -->
       <section id="feature">
         <div class="container ts-worp">
-          <div class="section-title text-center">
+          <div class="section-title text-center" style="margin-bottom: 50px">
             <p class="ts-title">我们的特色</p>
             <p class="ts-text">云端部署 &nbsp;&nbsp; 轻量应用</p>
           </div>
           <!-- 1 -->
           <div class="ts-box">
-            <div class="ts-boximg">
-              <img style="margin-left: 18px;" src="/static/img/feature/mix1x.png" alt="">
+            <div>
+              <img class="left" src="/static/img/feature/for2x.png" alt="">
             </div>
             <div>
-              <img class="ts-img" src="/static/img/feature/blue1@2x.png" alt="">
+              <img class="right" src="/static/img/feature/onemin2x.png" alt="">
             </div>
           </div>
           <!-- 2 -->
-          <div class="ts-box">
+          <div class="ts-box ts-boxtow">
             <div>
-              <img class="ts-img" src="/static/img/feature/yellow2@2x.png" alt="">
+              <img class="left" src="/static/img/feature/towmin2x.png" alt="">
             </div>
-            <div class="ts-boximg">
-              <img style="float: right;" src="/static/img/feature/mix2x.png" alt="">
+            <div>
+              <img class="right" style="margin-right:20px; width:80%" src="/static/img/feature/three2x.png" alt="">
             </div>
           </div>
           <!-- 3 -->
-          <div class="ts-box">
-            <div class="ts-boximg">
-              <img src="/static/img/feature/mix3x.png" alt="">
+          <div class="ts-box" style="padding-bottom:0px">
+            <div>
+              <img class="left" style="width:88%" src="/static/img/feature/one2x.png" alt="">
             </div>
             <div>
-              <img class="ts-img" src="/static/img/feature/blue3@2x.png" alt="">
+              <img class="right" style="margin-top:-30%;" src="/static/img/feature/threemin2x.png" alt="">
             </div>
           </div>
           <!-- 4 -->
-          <div class="ts-box">
+          <div class="ts-box ts-boxtow ts-forbox" style="padding-bottom:0px">
             <div>
-              <img style="width:94%" class="ts-img" src="/static/img/feature/yellow4@2x.png" alt="">
+              <img class="left" style="margin-top:-39%;" src="/static/img/feature/formin2x.png" alt="">
             </div>
-            <div class="ts-boximg">
-              <img style="float: right;" src="/static/img/feature/mix4x.png" alt="">
+            <div>
+              <img class="right" style="margin-right:30px;" src="/static/img/feature/tow2x.png" alt="">
             </div>
           </div>
         </div>
       </section>
 
       <!-- Service section 功能-->
-      <section id="service">
+      <section id="service" style="padding-top: 0">
         <div class="container" style="position: relative;">
           <img class="gn-beijing" src="/static/img/gongneng/xu xian@3x.png" alt="">
           <div class="row">

+ 23 - 12
frontend/saas-portal-web/static/css/main.css

@@ -151,17 +151,32 @@ main > section {
 }
 .ts-box {
     overflow: hidden;
-    position: relative;
-    padding: 150px 0;
-    width: 98%;
+    /* position: relative; */
+    padding: 100px 50px 100px 20px;
+    width: 100%;
+    display: table;
+    background: #F8FAFD;
 }
-.ts-boximg {
-    position: absolute;
-    top: 50px;
+.ts-boxtow {
+    padding: 100px 20px 100px 50px;
+    background: white;
+}
+.ts-box div {
+    display: table-cell;
+    vertical-align: middle;
+}
+.ts-box img {
+    width: 95%;
 }
-.ts-boximg img {
-    width: 65%;
+.ts-forbox img {
+    width: 100%;
 }
+/* .ts-imgmax {
+    width: 100%;
+}
+.ts-imgmin {
+    width: 100%;
+} */
 .ts-title {
     font-family: PingFangSC-Regular !important;
     color: #0D253E !important;
@@ -175,10 +190,6 @@ main > section {
 .right {
     float: right;
 }
-.ts-img {
-    width: 98%;
-    margin-left: 2%;
-}
 .right-text {
     text-align: right;
 }

BIN
frontend/saas-portal-web/static/img/banner.png


BIN
frontend/saas-portal-web/static/img/banner@2x@2x.png


BIN
frontend/saas-portal-web/static/img/feature/blue1@2x.png


BIN
frontend/saas-portal-web/static/img/feature/blue3@2x.png


BIN
frontend/saas-portal-web/static/img/feature/for2x.png


BIN
frontend/saas-portal-web/static/img/feature/formin2x.png


BIN
frontend/saas-portal-web/static/img/feature/mix1x.png


BIN
frontend/saas-portal-web/static/img/feature/mix2x.png


BIN
frontend/saas-portal-web/static/img/feature/mix3x.png


BIN
frontend/saas-portal-web/static/img/feature/mix4x.png


BIN
frontend/saas-portal-web/static/img/feature/one2x.png


BIN
frontend/saas-portal-web/static/img/feature/onemin2x.png


BIN
frontend/saas-portal-web/static/img/feature/three2x.png


BIN
frontend/saas-portal-web/static/img/feature/threemin2x.png


BIN
frontend/saas-portal-web/static/img/feature/tow2x.png


BIN
frontend/saas-portal-web/static/img/feature/towmin2x.png


BIN
frontend/saas-portal-web/static/img/feature/yellow2@2x.png


BIN
frontend/saas-portal-web/static/img/feature/yellow4@2x.png


+ 457 - 0
frontend/saas-web/app/view/core/dbfind/AddMultiDbfindGridPanel.js

@@ -0,0 +1,457 @@
+Ext.define('saas.view.core.dbfind.AddMultiDbfindGridPanel', {
+    extend: 'Ext.grid.Panel',
+    xtype: 'addmultidbfindgridpanel',
+
+    dataUrl: '',
+    dbSearchFields: [],
+    condition:'',
+    selectRecordArr:[],
+
+    selModel: {
+        checkOnly:true,
+        type:'checkboxmodel',
+        ignoreRightMouseSelection : false,
+        listeners:{
+            select:function(selModel,record,c,d){
+                if(!selModel.noChange){
+                    var selectRecordArr = selModel.view.ownerCt.selectRecordArr;
+                    selectRecordArr.push(record);
+                }
+            },
+            deselect:function(selModel,record){
+                if(!selModel.noChange){
+                    var selectRecordArr = selModel.view.ownerCt.selectRecordArr;
+                    var index = -1;
+                    index = selectRecordArr.findIndex(function(f){
+                        return f.id==record.id
+                    });
+                    if(index>-1){
+                        selectRecordArr.splice(index,1);
+                    }
+                }
+            }
+         }
+    },
+    
+    listeners:{
+        boxready: function(grid, width, height, eOpts) {
+            var store = grid.getStore(),
+            gridBodyBox = grid.body.dom.getBoundingClientRect(),
+            gridBodyBoxHeight = gridBodyBox.height;
+
+            var pageSize = Math.floor(gridBodyBoxHeight / 33);
+
+            store.setPageSize(pageSize);
+        },
+        itemdblclick:function( view, record, item, index, e, eOpts ) {
+            var grid = view.ownerCt;
+            var index = -1;
+            index = grid.selectRecordArr.findIndex(function(f){
+                return f.id==record.id
+            });
+            grid.selModel.noChange = true;
+            if(index==-1){
+                grid.selectRecordArr.push(record);
+                grid.selModel.select(grid.selectRecordArr);
+                // grid.store.loadPage(grid.store.currentPage);
+                grid.updateLayout();
+                grid.view.updateLayout();
+                Ext.resumeLayouts();
+            }else{
+                grid.selectRecordArr.splice(index,1);
+                grid.selModel.deselect(record);
+            }
+            grid.selModel.noChange = false;
+        }
+    },
+
+    initComponent: function() {
+        var me = this;
+        me.selectRecordArr = [];
+        if(me.columns){
+            var fields = me.columns.map(column => column.dataIndex);
+            me.store = Ext.create('Ext.data.Store',{
+                fields:fields,
+                autoLoad: true,
+                pageSize: 6,
+                data: [],
+                proxy: {
+                    type: 'ajax',
+                    url: me.dataUrl,
+                    timeout:8000,
+                    actionMethods: {
+                        read: 'GET'
+                    },
+                    reader: {
+                        type: 'json',
+                        rootProperty: 'data.list',
+                        totalProperty: 'data.total',
+                    },
+                    listeners: {
+                        exception: function(proxy, response, operation, eOpts) {
+                            if(operation.success) {
+                                if(response.timedout) {
+                                    saas.util.BaseUtil.showErrorToast('请求超时');
+                                }
+                            }else {
+                                console.error('exception: ', response.responseJson);
+                                saas.util.BaseUtil.showErrorToast('查询失败:' + response.responseJson.message);
+                            }
+                        }
+                    }
+                },
+                listeners: {
+                    beforeload: function (store, op) {
+                        var condition = me.condition;
+                        if (Ext.isEmpty(condition)) {
+                            condition = [];
+                        }
+                        //添加默认条件
+                        if(me.ownerCt.trigger.defaultCondition) {
+                            condition.push({
+                                type: 'condition',
+                                value: me.ownerCt.trigger.defaultCondition
+                            });
+                        }
+                        Ext.apply(store.proxy.extraParams, {
+                            number: op._page,
+                            size: store.pageSize,
+                            condition: JSON.stringify(condition)
+                        });
+                    }
+                }
+            });
+
+            Ext.apply(me, {
+                dockedItems:[{
+                    xtype:'toolbar',
+                    dock:'top',
+                    items:me.getSearchFields().concat([{
+                        xtype:'button',
+                        text:'查询',
+                        handler:function(b){
+                            var grid = me,items=[];
+                            grid.condition = '';
+                            Ext.Array.each(grid.dbSearchFields,function(f) {
+                                var field = b.ownerCt.down('[name='+f.name+']')
+                                items.push(field);
+                            });
+                            grid.condition = grid.getCondition(items);
+                            grid.store.loadPage(1);
+                            grid.selModel.noChange = true;
+                            grid.selModel.deselectAll();
+                            grid.selModel.select(grid.selectRecordArr);
+                            grid.selModel.noChange = false;
+                        }
+                    },'->',{
+                        text:'确定',
+                        cls:'x-formpanel-btn-blue',
+                        handler:function(b){
+                            debugger
+                            var grid = me;//grid
+                            var selectRecordArr = grid.selectRecordArr;
+                            var dbfinds = grid.dbfinds;
+                            //点开放大镜的行
+                            var mainGrid = grid.dbfindtrigger.column.ownerCt.ownerCt;
+                            var rec = mainGrid.selModel.getLastSelected();
+                            var nowRec = mainGrid.store.getData().getByKey(rec.id);
+                            var v = '';
+                            Ext.Array.each(selectRecordArr,function(record,_index) {
+                                    v = v + record.get(dbfinds[0].from)+','
+                            });
+                            if(v.length>0){
+                                nowRec.set(dbfinds[0].to,v.substring(0,v.length-1));
+                            }
+                            mainGrid.up('detailGridField').fireEvent('edit');
+                            grid.ownerCt.close();
+                        }
+                    },{
+                        xtype:'button',
+                        text:'新增',
+                        handler:function(b){
+                            var grid = me;
+                            var trigger = grid.ownerCt.trigger;
+                            saas.util.BaseUtil.openTab(trigger.addXtype, '新增'+trigger.addTitle,trigger.addXtype + '_add');
+                        },
+                        listeners:{
+                            afterrender:function(b){
+                                var grid = me;
+                                var trigger = grid.ownerCt.trigger;
+                                if(!trigger.addXtype||trigger.addXtype==''){
+                                    b.hide();
+                                }
+                            }
+                        }
+                    }])
+                },{
+                    xtype: 'pagingtoolbar',
+                    dock: 'bottom',
+                    displayInfo: true,
+                    height:32,
+                    style:'padding: 0;',
+                    store: me.store,
+                    items:[{
+                        xtype:'checkbox',
+                        id:'showSelectRecord',
+                        boxLabel:'已选中数据',
+                        handler:function(b){
+                            var grid = me;
+                            if(b.checked){
+                                grid.store.loadData(grid.selectRecordArr);
+                                grid.selModel.noChange = true;
+                                grid.selModel.deselectAll();
+                                grid.selModel.select(grid.selectRecordArr);
+                                grid.selModel.noChange = false;
+                                //刷新展示数据
+                                var dataCount = grid.selectRecordArr.length,msg;
+                                var display = b.ownerCt.child('#displayItem');
+                                if (dataCount === 0) {
+                                    msg = b.ownerCt.emptyMsg;
+                                } else {
+                                    msg = Ext.String.format(
+                                        b.ownerCt.displayMsg,
+                                        1,
+                                        dataCount,
+                                        dataCount
+                                    );
+                                }
+                                display.setText(msg);
+                                b.ownerCt.child('#inputItem').setValue(1);
+                                b.ownerCt.child("#afterTextItem").setText('页,共'+dataCount+'页');
+                            }else{
+                                grid.selModel.noChange = true;
+                                grid.selModel.deselectAll();
+                                grid.selModel.select(grid.selectRecordArr);
+                                grid.selModel.noChange = false;
+                                grid.store.loadPage(1);
+                            }
+                        }
+                    }],
+                    moveFirst: function() {
+                        if(Ext.getCmp('showSelectRecord').checked==false){
+                            if (this.fireEvent('beforechange', this, 1) !== false) {
+                                this.store.loadPage(1);
+                                this.ownerCt.selModel.noChange = true;
+                                this.ownerCt.selModel.deselectAll();
+                                this.ownerCt.selModel.select(this.ownerCt.selectRecordArr);
+                                this.ownerCt.selModel.noChange = false;
+                                return true;
+                            }
+                        }
+                        return false;
+                    },
+                    movePrevious: function() {
+                        var me = this,
+                            store = me.store,
+                            prev = store.currentPage - 1;
+                        if(Ext.getCmp('showSelectRecord').checked==false){
+                            if (prev > 0) {
+                                if (me.fireEvent('beforechange', me, prev) !== false) {
+                                    store.previousPage();
+                                    this.ownerCt.selModel.noChange = true;
+                                    this.ownerCt.selModel.deselectAll();
+                                    this.ownerCt.selModel.select(this.ownerCt.selectRecordArr);
+                                    this.ownerCt.selModel.noChange = false;
+                                    return true;
+                                }
+                            }
+                        }
+                        return false;
+                    },
+                    moveNext: function() {
+                        var me = this,
+                            store = me.store,
+                            total = me.getPageData().pageCount,
+                            next = store.currentPage + 1;
+                        if(Ext.getCmp('showSelectRecord').checked==false){
+                            if (next <= total) {
+                                if (me.fireEvent('beforechange', me, next) !== false) {
+                                    store.nextPage();
+                                    this.ownerCt.selModel.noChange = true;
+                                    this.ownerCt.selModel.deselectAll();
+                                    this.ownerCt.selModel.select(this.ownerCt.selectRecordArr);
+                                    this.ownerCt.selModel.noChange = false;
+                                    return true;
+                                }
+                            }
+                        }
+                        return false;
+                    },
+                    moveLast: function() {
+                        var me = this,
+                            last = me.getPageData().pageCount;
+                        if(Ext.getCmp('showSelectRecord').checked==false){
+                            if (me.fireEvent('beforechange', me, last) !== false) {
+                                me.store.loadPage(last);
+                                this.ownerCt.selModel.noChange = true;
+                                this.ownerCt.selModel.deselectAll();
+                                this.ownerCt.selModel.select(this.ownerCt.selectRecordArr);
+                                this.ownerCt.selModel.noChange = false;
+                                return true;
+                            }
+                        }
+                        return false;
+                    },
+                    doRefresh: function() {
+                        var me = this,
+                            store = me.store,
+                            current = store.currentPage;
+                        if(Ext.getCmp('showSelectRecord').checked==false){
+                            if (me.fireEvent('beforechange', me, current) !== false) {
+                                store.loadPage(current);
+                                this.ownerCt.selModel.noChange = true;
+                                this.ownerCt.selModel.deselectAll();
+                                this.ownerCt.selModel.select(this.ownerCt.selectRecordArr);
+                                this.ownerCt.selModel.noChange = false;
+                                return true;
+                            }
+                        }
+                        return false;
+                    },
+                    updateInfo: function() {
+                        var me = this,
+                            displayItem = me.child('#displayItem'),
+                            store = me.store,
+                            pageData = me.getPageData(),
+                            count, msg;
+                        if (displayItem) {
+                            count = store.getCount();
+                            if (count === 0) {
+                                msg = me.emptyMsg;
+                            } else {
+                                msg = Ext.String.format(me.displayMsg, pageData.fromRecord, pageData.toRecord, pageData.total);
+                            }
+                            displayItem.setText(msg);
+                        }
+                    }
+                }]
+            });
+        }
+        me.callParent(arguments);
+    },
+
+    getSearchFields: function() {
+        var me = this,
+        searchFields = me.dbSearchFields;
+
+        Ext.Array.each(searchFields, function(f) {
+            f.enableKeyEvents = true;
+            f.listeners = {
+                keydown: function(th, e, eOpts) {
+                    if(e.keyCode == 13) {
+                        me.condition = '', items = [];
+                        Ext.Array.each(searchFields,function(f) {
+                            var field = th.ownerCt.down('[name='+f.name+']')
+                            items.push(field);
+                        });
+                        me.condition = me.getCondition(items);
+                        me.store.loadPage(1);
+                    }
+                }
+            }
+        });
+
+        return searchFields;
+    },
+
+     /**
+     * 获得过滤条件
+     */
+    getCondition: function(items) {
+        var me = this,
+        conditions = [];
+
+        for(var i = 0; i < items.length; i++) {
+            var item = items[i];
+            var field = item.name,
+            func = item.getCondition,
+            value = item.value,
+            condition;
+
+            if(value&&value!=''){
+                if(typeof func == 'function') {
+                    condition = {
+                        type: 'condition',
+                        value: func(value)
+                    }
+                }else {
+                    var xtype = item.xtype || 'textfield',
+                    type = item.fieldType || me.getDefaultFieldType(xtype),
+                    operation = item.operation || me.getDefaultFieldOperation(xtype),
+                    conditionValue = me.getConditionValue(xtype, value);
+        
+                    if(!conditionValue) {
+                        continue;
+                    }
+                    condition = {
+                        type: type,
+                        field: field,
+                        operation: operation,
+                        value: conditionValue
+                    }
+                }
+                conditions.push(condition);
+            }
+        };
+        return conditions;
+    },
+
+    getDefaultFieldType: function(xtype) {
+        var type;
+
+        if(Ext.Array.contains(['numberfield'], xtype)) {
+            type = 'number';
+        }else if(Ext.Array.contains(['datefield', 'condatefield'], xtype)) {
+            type = 'date';
+        }else if(Ext.Array.contains(['combobox', 'multicombo', 'combo', 'radiofield', 'radio'], xtype)) {
+            type = 'enum';
+        }else {
+            type = 'string';
+        }
+
+        return type;
+    },
+
+    getDefaultFieldOperation: function(xtype) {
+        var operation;
+
+        if(Ext.Array.contains(['numberfield'], xtype)) {
+            operation = '=';
+        }else if(Ext.Array.contains(['datefield'], xtype)) {
+            operation = '=';
+        }else if(Ext.Array.contains(['condatefield'], xtype)) {
+            operation = 'between';
+        }else if(Ext.Array.contains(['combobox', 'multicombo', 'combo'], xtype)) {
+            operation = 'in';
+        }else {
+            operation = 'like';
+        }
+
+        return operation;
+    },
+
+    /**
+     * 处理部分字段值
+     */
+    getConditionValue: function(xtype, value) {
+        var conditionValue;
+        if(xtype == 'datefield') {
+            conditionValue = Ext.Date.format(new Date(from), 'Y-m-d H:i:s');
+        }else if(xtype == 'condatefield') {
+            var from = value.from,
+            to = value.to;
+
+            conditionValue = Ext.Date.format(new Date(from), 'Y-m-d 00:00:00') + ',' + Ext.Date.format(new Date(to), 'Y-m-d 23:59:59');
+        }else if(xtype == 'combobox' || xtype == 'combo') {
+            conditionValue = '\'' + value + '\'';
+        }else if(xtype == 'multicombo') {
+            conditionValue = value.map(function(v) {
+                return '\'' + v.value + '\'';
+            }).join(',');
+        }else {
+            conditionValue = value;
+        }
+
+        return conditionValue;
+    }
+});

+ 299 - 0
frontend/saas-web/app/view/core/dbfind/AddMultiDbfindTrigger.js

@@ -0,0 +1,299 @@
+/**
+ *  选中的数据会按照主字段,号隔开
+ */
+Ext.define('saas.view.core.dbfind.AddMultiDbfindTrigger', {
+	extend: 'Ext.form.ComboBox',
+	alias: 'widget.addmultidbfindtrigger',
+	triggerCls: 'x-form-search-trigger',
+    queryMode: 'local',
+    displayField: 'dispaly',
+    valueField: 'value',
+    triggerCls: 'x-form-search-trigger',
+    minChars:1, // 设置用户输入字符多少时触发查询
+    tpl: '',
+    enableKeyEvents:true,
+    initComponent:function() {
+        var me = this;
+        me.store=Ext.create('Ext.data.Store', {
+            fields: ['display','value'],
+            data : [{
+                'display':me.value,
+                'value':me.value
+            }]
+        });
+        this.callParent();
+    },
+    //输入值之后进行模糊查询
+    doQuery: function(queryString, forceAll, rawQuery) {
+        if(!this.fireEvent('beforequery', this)) {
+            return;
+        };
+    	queryString = queryString || '';
+    	var me = this;
+        me.judge(me);
+        var field=[];
+        var sfield='';
+        var dbfinds=me.dbfinds;
+        var dbtpls=me.dbtpls;
+        me.lastQueryValue=queryString;
+        if(queryString.trim()==''){
+            me.collapse( );
+        }else{
+            if(!dbfinds||!dbtpls){
+                me.collapse( );
+            }else{                   
+                //加载tpl模板
+                if(dbtpls.length>0){
+                    var span="";
+                    var width=0;
+                    for(var i=0;i<dbtpls.length;i++){
+                        if(i==0){
+                            span=span+'<span style="width:'+dbtpls[i].width+'px;overflow: hidden;white-space: nowrap;text-overflow: ellipsis;float:left;">{'+dbtpls[i].field+'}</span>';//display:block;
+                        }else{
+                            span=span+'<span style="padding:0 0 0 20px;width:'+dbtpls[i].width+'px;overflow: hidden;white-space: nowrap;text-overflow: ellipsis;float:left;">{'+dbtpls[i].field+'}</span>';
+                        }
+                        if(dbtpls[i].dbField=="true"){
+                            me.searchFieldArray=dbtpls[i].field;
+                        }
+                        width=width+dbtpls[i].width+20;
+                        field.push(dbtpls[i].field);
+                        sfield=sfield+dbtpls[i].field+',';
+                    }
+                    me.defaultListConfig.minWidth=width+10;
+                    me.defaultListConfig.maxHeight=210;
+                    me.defaultListConfig.autoScroll=true;
+                    me.searchField=sfield.substring(0,sfield.length-1);
+                    me.tpl=Ext.create('Ext.XTemplate',
+                            '<ul style="padding-left: 0px;"><tpl for=".">',
+                            '<li role="option" class="x-boundlist-item" style="list-style:none;">' ,
+                            '<div style="height:30px;">',
+                            ''+span+'',
+                            '</li>',
+                        '</tpl></ul>'
+                    );
+                    me.store.setFields(field);
+                }
+            }
+            //加载数据
+            var data,dbCondition=[];
+            if(me.dbfinds){
+                var dbtplcondition = "";
+                for (let index = 0; index < dbfinds.length; index++) {
+                    var item = dbfinds[index].from;
+                    if(!dbfinds[index].ignore){
+                        dbtplcondition+= "upper("+item+") like '%"+queryString.toUpperCase()+"%' or ";
+                    }
+                }
+                dbtplcondition = "(" + dbtplcondition.substring(0,dbtplcondition.length-4) + ")";
+                if(dbtplcondition.length>0){
+                    dbCondition = [{
+                        type: 'condition',
+                        value:dbtplcondition
+                    }];
+                }
+            }
+            //添加默认条件
+            if(me.defaultCondition) {
+                dbCondition.push({
+                    type: 'condition',
+                    value: me.defaultCondition
+                });
+            }
+            Ext.Ajax.request({
+                url: me.dataUrl,
+                params: {
+                    number: 1,
+                    size: 10,
+                    condition:JSON.stringify(dbCondition),
+                    page: 1,
+                    start: 0,
+                    limit: 10
+                },
+                method: 'GET',
+                success: function(response, opts) {
+                    data = Ext.decode(response.responseText);
+                    data = data.data?data.data.list:[];
+                    if(data!=null && data.length>0 && me.store && field.length>0){
+                        me.store.loadData(data,false);
+                        me.expand();
+                    }else{
+                        me.store.removeAll();
+                        me.collapse();
+                    }
+                },
+                failure: function(response, opts) {}
+            });                
+        }
+        return true;
+    },
+    onTriggerClick:function(f){
+        if(!this.fireEvent('beforetriggerclick', this)) {
+            return;
+        };
+        f.blur(f);
+        //判断dbfindtrigger归属
+        f.judge(f);
+        var panel = f.up('core-tab-panel'),panelEl;
+        if(!f.column&&f.ownerCt.ownerCt.id.indexOf('window-')>-1){
+            panelEl = f.ownerCt.ownerCt.getEl();
+        }else{
+            panelEl = panel.getEl()
+        }
+        var box = panelEl.getBox();
+        var height = box.height;
+        var width = box.width;
+        var win = panel.add(Ext.create('Ext.window.Window', {   
+            cls:'x-window-dbfind', 
+            trigger:f,
+            belong:f.ownerCt,  
+            modal:true,
+            height: height * 0.8,
+            width: width * 0.8,
+            title: '查找' + f.addTitle,
+            scrollable: true,
+            bodyPadding: 10,
+            constrain: true,
+            closable: true,
+            layout:'fit',
+            renderTo:Ext.getCmp('main-tab-panel').getActiveTab().getEl(),
+            items:[{
+                xtype:'addmultidbfindgridpanel',
+                columns: f.dbColumns,
+                dataUrl: f.dataUrl,
+                dbfinds: f.dbfinds,
+                belong: f.belong,
+                dbSearchFields:f.dbSearchFields?f.dbSearchFields:[],
+                dbfindtrigger:f
+            }]
+        }));
+        win.show();
+    },
+
+    listeners: {
+        // blur:function(f,e){
+        //     var me = f,data;
+        //     var dbfinds = me.dbfinds;
+        //     if(f.value&&f.value!=''){
+        //         //添加默认条件
+        //         var searchField = null;
+        //         var dbCondition = [];
+        //         if(me.defaultCondition) {
+        //             dbCondition.push({
+        //                 type: 'condition',
+        //                 value: me.defaultCondition
+        //             });
+        //         }
+        //         for (let index = 0; index < dbfinds.length; index++) {
+        //             var item = dbfinds[index].to;
+        //             if(item==me.name){
+        //                 searchField = dbfinds[index].from;
+        //             }
+        //         }
+        //         dbCondition.push({
+        //             type: 'condition',
+        //             value: searchField + " like '%"+me.value+"%'"
+        //         });
+        //         Ext.Ajax.request({
+        //             url: me.dataUrl,
+        //             async:false,
+        //             params: {
+        //                 number: 1,
+        //                 size: 1,
+        //                 condition:JSON.stringify(dbCondition),
+        //                 page: 1,
+        //                 start: 0,
+        //                 limit: 10
+        //             },
+        //             method: 'GET',
+        //             success: function(response, opts) {
+        //                 data = Ext.decode(response.responseText);
+        //                 data = data.data?data.data.list:[];
+        //             },
+        //             failure: function(response, opts) {}
+        //         }); 
+        //     }
+        //     if(!f.value||f.value==''||data.length>1||data.length==0){
+        //         if(dbfinds&&dbfinds.length>0){
+        //             if(me.belong=='grid'){
+        //                 for (let index = 0; index < dbfinds.length; index++) {
+        //                     var item = dbfinds[index];
+        //                     var rec = me.column.ownerCt.ownerCt.selModel.getLastSelected();
+        //                     var nowRec = me.column.ownerCt.ownerCt.store.getData().getByKey(rec.id);
+        //                     if(nowRec.get(item.to)&&nowRec.get(item.to)!=""){
+        //                         nowRec.set(item.to,null);
+        //                     }
+        //                     if(nowRec.modified){
+        //                         delete nowRec.modified[item.to];
+        //                     }
+        //                     if(JSON.stringify(nowRec.modified)=="{}"){
+        //                         nowRec.dirty = false
+        //                     }
+        //                     if(me.name==item.to){
+        //                         me.column.getEditor().setValue('');
+        //                     }
+        //                 }
+        //             }
+        //         }
+        //     }else if(data.length==1){
+        //         if(dbfinds&&dbfinds.length>0){
+        //             if(me.belong=='grid'){
+        //                 for (let index = 0; index < dbfinds.length; index++) {
+        //                     var item = dbfinds[index];
+        //                     var rec = me.column.ownerCt.ownerCt.selModel.getLastSelected();
+        //                     var nowRec = me.column.ownerCt.ownerCt.store.getData().getByKey(rec.id);
+        //                     nowRec.set(item.to,data[0][item.from]);
+        //                     if(me.name==item.to){
+        //                         me.column.getEditor().setValue(data[0][item.from]);
+        //                     }
+        //                 }
+        //             }
+        //         }
+        //     }
+        // },
+        select:function(combo,record,eOpts){
+            var me = combo;
+            var dbfinds = me.dbfinds;
+            if(dbfinds&&dbfinds.length>0){
+                if(me.belong=='grid'){
+                    for (let index = 0; index < dbfinds.length; index++) {
+                        var item = dbfinds[index];
+                        var rec = me.column.ownerCt.ownerCt.selModel.getLastSelected();
+                        var nowRec = me.column.ownerCt.ownerCt.store.getData().getByKey(rec.id);
+                        nowRec.set(item.to,record.get(item.from));
+                        if(me.name==item.to){
+                            me.column.getEditor().setValue(record.get(item.from));
+                        }
+                    }
+                }else if(me.belong=='form'){
+                    for (let index = 0; index < dbfinds.length; index++) {
+                        var item = dbfinds[index];
+                        var field = me.ownerCt.down('[name='+item.to+']');
+                        if(field){
+                            var val = record.get(item.from);
+                            if(field.xtype=='dbfindtrigger'){
+                                field.setRawValue(val);
+                                field.value = val;
+                                field.lastTriggerValue=val;
+                            }else{
+                                field.setValue(val);
+                            }    
+                        }
+                    }
+                }
+            }
+        }
+    },
+
+    judge:function(f){
+        if(f.ownerCt.xtype.trim().toUpperCase().indexOf('QUERYFORMPANEL')>-1){
+            f.belong = 'form';
+            return f.ownerCt.ownerCt
+        }else if(f.ownerCt.xtype.trim().toUpperCase().indexOf('FORMPANEL')>-1){
+            f.belong = 'form';
+            return f.ownerCt
+        }else if(f.column){
+            f.belong = 'grid';
+            return f.column.ownerCt.ownerCt.ownerCt
+        }
+    }
+});

+ 2 - 2
frontend/saas-web/app/view/core/dbfind/MultiDbfindTrigger.js

@@ -148,8 +148,8 @@ Ext.define('saas.view.core.dbfind.MultiDbfindTrigger', {
             trigger:f,
             belong:f.ownerCt,  
             modal:true,
-            height: '80%',
-            width: '80%',
+            height: height * 0.8,
+            width: width * 0.8,
             title: '查找' + f.addTitle,
             scrollable: true,
             bodyPadding: 10,

+ 105 - 0
frontend/saas-web/app/view/core/dbfind/types/ProductAddMultiDbfindTrigger.js

@@ -0,0 +1,105 @@
+/**
+ * 物料资料放大镜(多选)
+ */
+Ext.define('saas.view.core.dbfind.types.ProductAddMultiDbfindTrigger', {
+    extend: 'saas.view.core.dbfind.AddMultiDbfindTrigger',
+    xtype: 'productAddMultiDbfindTrigger',
+
+    //数据接口
+    dataUrl: '/api/document/product/list',
+    addXtype: 'document-product-formpanel',
+    addTitle: '物料资料',
+    //联想设置
+    dbtpls: [{
+        field: 'pr_code',
+        width: 150
+    }, {
+        field: 'pr_detail',
+        width: 200
+    }],
+    defaultCondition: "pr_statuscode='ENABLE'",
+    dbSearchFields: [{
+        emptyText: '输入物料编号、名称或规格',
+        width: 200,
+        xtype: "textfield",
+        name: "search",
+        allowBlank: true,
+        width:300,
+        getCondition: function (v) {
+            return "(upper(pr_code) like '%" + v.toUpperCase() + "%' or upper(pr_detail) like '%" + v.toUpperCase() + "%' or upper(pr_spec) like '%" + v.toUpperCase() + "%')";
+        }
+    }],
+    //窗口列设置
+    dbColumns: [{
+        text: "物料ID",
+        hidden: true,
+        dataIndex: "id"
+    }, {
+        text: "物料编号",       
+        dataIndex: "pr_code",
+        width: 150
+    },{
+        text: "类型",
+        dataIndex: "pr_kind",
+        width: 110
+    },{
+        text: "物料名称",
+        width: 200,
+        dataIndex: "pr_detail"
+    }, {
+        text : "型号", 
+        dataIndex : "pr_orispeccode", 
+        width : 150.0
+    }, {
+        text : "规格", 
+        dataIndex : "pr_spec", 
+        width : 150.0
+    },{
+        text: "品牌",
+        dataIndex: "pr_brand",
+        width: 110
+    },{
+        text: "库存",
+        dataIndex: "po_onhand",
+        width: 110,
+        xtype: 'numbercolumn',
+        renderer : function(v) {
+            var arr = (v + '.').split('.');
+            var xr = (new Array(arr[1].length)).fill('0');
+            var format = '0,000.' + xr.join();
+            return Ext.util.Format.number(v, format);
+        },
+    },{
+        text: "单位",
+        dataIndex: "pr_unit",
+        width: 80
+    }, {
+        text: "采购提前期",
+        dataIndex: "pr_leadtime",
+        hidden: true
+    }, {
+        text: "仓库id",
+        dataIndex: "pr_whid",
+        hidden: true
+    }, {
+        text: "仓库编号",
+        dataIndex: "pr_whcode",
+        hidden: true
+    }, {
+        text: "仓库",
+        dataIndex: "pr_whname",
+        width: 200,
+        hidden: true
+    }, {
+        text: "最新采购单价",
+        dataIndex: "pr_purcprice",
+        xtype: 'numbercolumn',
+        hidden:true
+    }, {
+        text: "最新出货单价",
+        dataIndex: "pr_saleprice",
+        xtype: 'numbercolumn',
+        hidden:true
+    }]
+
+});

+ 1 - 1
frontend/saas-web/app/view/document/address/DataList.js

@@ -7,7 +7,7 @@ Ext.define('saas.view.document.address.DataList', {
     viewModel: 'document-address-datalist',
     defaultType:'address',
     windowType:'document-address-window',
-    _openUrl:'api/',
+    _openUrl:'/api/document/address/setDefault',
     tbar: ['->',{
         xtype:'button',
         text:'新增',

+ 1 - 1
frontend/saas-web/app/view/document/bom/FormController.js

@@ -42,7 +42,7 @@ Ext.define('saas.view.document.bom.FormController', {
                     }) ;   
                 }
             },
-            'productMultiDbfindTrigger[name=bd_replace]':{
+            'productAddMultiDbfindTrigger[name=bd_replace]':{
                 beforerender:function(f){
                     Ext.apply(f,{
                         //放大镜赋值设置

+ 1 - 1
frontend/saas-web/app/view/document/bom/FormPanel.js

@@ -187,7 +187,7 @@ Ext.define('saas.view.document.bom.FormPanel', {
                     queryMode : "local", 
                     store : null, 
                     valueField : "value", 
-                    xtype : "productMultiDbfindTrigger"
+                    xtype : "productAddMultiDbfindTrigger"
                 }
             }, {
                 text : "备注", 

+ 22 - 0
frontend/saas-web/app/view/purchase/purchase/FormPanelController.js

@@ -62,6 +62,28 @@ Ext.define('saas.view.purchase.purchase.FormPanelController', {
 
                 }
             },
+            'remotecombo[name=pu_shipaddresscode]':{
+                afterrender:function(f){
+                    if(f.ownerCt.initId==0){
+                        //读取默认地址
+                        saas.util.BaseUtil.request({
+                            url: '/api/document/address/getDefault',
+                            method: 'GET',
+                        })
+                        .then(function (localJson) {
+                            var data = localJson.data;
+                            if(data&&data.ad_address){
+                                f.setValue(data.ad_address)
+                            }else{
+                                saas.util.BaseUtil.showErrorToast('未设置默认采购交货地址,维护后新增会自动给采购交货地址赋默认值');
+                            }
+                        })
+                        .catch(function (res) {
+                            saas.util.BaseUtil.showErrorToast('获取默认采购交货地址失败' + res.message);
+                        });
+                    }
+                }
+            }
         });
     },
 

BIN
frontend/saas-web/resources/images/loading.gif