Yfangliang

Yfangliang 查看完整档案

北京编辑  |  填写毕业院校  |  填写所在公司/组织填写个人主网站
编辑
_ | |__ _ _ __ _ | '_ \| | | |/ _` | | |_) | |_| | (_| | |_.__/ \__,_|\__, | |___/ 个人简介什么都没有

个人动态

Yfangliang 发布了文章 · 2020-09-18

Linux系统恢复数据库命令

备份数据库

我们需要链接到安装oracle的机器上,我是使用的ssh远程链接的工具
1:我们需要输入命令
登录oracle  命令:su - oracle
2:需要备份的实例
命令:export ORACLE_SID=oadb
*代表你要备份的实例
3:导出的命令

//exp 用户名/密码 file:导入文件路径,最好从根目录开始,并且当前有用有权限
file 最好写绝对路径(完整路径)
命令  :exp oauser/oadb123 file=/root/oa20191213.oa.dmp
注意文件命必须是,dmp结尾。

恢复数据库

1:我们需要输入命令
登录oracle  命令:su - oracle
2: 导入的命令  必须设置root文件权限
//imp 用户名/密码 file:导入文件路径,最好从根目录开始,并且当前有用有权限
命令:imp OAUSER2/oadb123 full=y file=/u01/oracleBack.dmp ignore=y
         注意这里面可能会抱很多错。
(1) 例如当前的用户没有导入的权限,就需要授权
导入dmp文件,报 IMP-00013: only a DBA can import a file exported by another DBA 的错误,解决方法
1.首先应该登陆编辑模式,修改当前的用户的权限 :等同于登录 system用户
sqlplus / as sysdba
2.SQL>grant sysdba to oauser2;   //oauser2为用户
3.SQL>grant imp_full_database to oauser2;//oauser2为用户
(2) 在导入的时候可能以前的这个用户是存在的并且表也是存在的,那么在导入的时候会报错
我的解决方法是新建用户 另一种就是把但前的用户下面的表和数据全部删掉。
oracle删除用户  (会话太多的话,可以先关闭oracle服务再删除用户)
首先将索要删除的用户锁定(这句必须执行):

alter user 用户名 account lock;

//查询回话 如果回话太多得话就重新启动一下数据库
select saddr,sid,serial#,paddr,username,status from v$session where username = 'OAUSER';

//关闭回话
alter system kill session 'sid,serial';

//删除用户
drop user 用户名 cascade;
//查询用户对象是否减少
select count(*) from dba_objects where owner='oauser2';

oracle创建用户

    --oadb123    密码
    --OAUSER    用户名
    --OASPACE    表空间
注意:以下命令适用于致远OA
CREATE USER OAUSER2 PROFILE DEFAULT IDENTIFIED  BY oadb123 DEFAULT TABLESPACE OASPACE TEMPORARY TABLESPACE TEMP  ACCOUNT UNLOCK ;

GRANT CREATE VIEW,ALTER SESSION,CONNECT,RESOURCE,UNLIMITED TABLESPACE TO OAUSER2 ;

drop user OAUSER cascade;

启动与关闭oracle数据库

一、
[root@nstlbeta ~]# su - oracle
二、然后用sqlplus登录到数据库,关闭数据库
[oracle@nstlbeta bin]$ sqlplus /nolog  //登录sqlplus
SQL> connect /as sysdba  //连接oracle
SQL> startup //起动数据库
shutdown immediate;//关闭数据库
SQL> exit  //退出sqlplus ,起动监听

三、监听
输入命令su - oracle切换到oracle用户
输入lsnrctl status命令来查看 看到提示信息TNS:no listener,表示监听没有启动
输入lsnrctl start启动监听服务,当看到提示信息"The command completed successfully",则表示启动成功
输入lsnrctl stop可以关闭监听
/u01/app/oracle 进入oracle安装目录
执行 startup;
输入shutdown命令关闭oracle实例
以system用户身份登陆oracle

sqlplus /nolog

conn as sysdba
Linux服务器上设置oracle数据库开机自启动

  1. 前提条件:确保已经在Linux系统中正确安装好oracle数据库的服务,使用手动方式可以正常启动。
  2. 先以root身份登录到linux系统,使用客户端远程连接到linux服务器,推荐使用的远程连接软件是xshell。
  3. 键入命令"vi /etc/oratab"(使用vi编辑器编辑文件/etc/oratab)。
  4. 进入vi编辑器后,找到"orcl:/u01/app/oracle/product/12.1.0/dbhome_1:N",改为"orcl:/u01/app/oracle/product/12.1.0/dbhome_1:Y"。修改完成后,保存退出vi编辑器。

说明:orcl为实例名;/u01/app/oracle/product/12.1.0/dbhome_1为oracle安装目录;会因每个人安装目录的情况不同而有所不同。

  1. 键入命令"vi /etc/rc.d/rc.local",打开修改文件的界面。
  2. 在vi编辑器中,添加如下内容:

su oracle -lc "/u01/app/oracle/product/12.1.0/dbhome_1/bin/lsnrctl start"

su oracle -lc /u01/app/oracle/product/12.1.0/dbhome_1/bin/dbstart

说明:/u01/app/oracle/product/12.1.0/dbhome_1为oracle的安装目录,要根据实际情况进行修改。

    7.保存并退出vi。

备份恢复另一种命令

1登录 sqlplus
sqlplus oauser/oadb123
2创建 备份或者还原目录索引   basedemo--为索引名称
create directory basetmp as 'homeoraclebasedemo';
3 给OAUSER用户 读写权限
grant read,write on directory basetmp to OAUSER;
4 返回oracle 用户
exit;
su - oracle;
5 导出dmp文件
expdp OAUSER/oadb123 directory=basetmp dumpfile=baseTable.dmp logfile=baseTable.log
6 恢复数据库 (同理,如果不是本地操作,需要1,2,3,4重复)
impdp OAUSER/oadb123 directory=basetmp dumpfile=baseTable.dmp remap_schema=OAUSER:OAUSER
Mr.tang:
create directory backupdata as 'D:appAdministratororadmp';
Mr.tang:
grant read,write on directory backupdata to jingyi;
Mr.tang:
expdp jxjd20170107/jxjd20170107 directory=backupdata dumpfile=jxjd20170918.dmp logfile=jxjd20170918.log

NC中点击前台的按钮所走的的类

   IplatFormEntry对应的实现类PlatFormEntryImpl里面的processAction方法。~~~~

查看原文

赞 0 收藏 0 评论 0

Yfangliang 发布了文章 · 2020-06-23

NC65开发遇到的问题

NC开发初步准备

安装orcle数据库
nc安装包
nc项目的配置文件配置数据源、服务器、安全日志等配置home\bin\sysConfig.bat
使用超级管理登录系统初步登录nc首先先创建自己的账套
登录自己的账套创建集团管理员-创建人员-分配角色-分配权限

NC安装开发工具

uap-stadio  配置需要的服务器地址
     新建组件项目-新建项目 在run的项目中配置-Dorg.owasp.esapi.resources=F:\yonyou\home\ierp\bin\esapi-Duap.hotwebs=lfw,portal,fs,uapws
需要发布webservice的时候接口代码写在模块下的public包中实现类写在private包下使用自带插件WsTool发布webservice生成wsdl文件,手动添加upm文件到META-INF下,添加自己的component.重启项目。

调试代码的html文件存放的位置例子:C:\Users\John\AppData\Local\UClient\apps\1d0c6632-a016-3f22-b986-eaf62ad1f859\nc\_client\_home\NCCACHE\SPR\_部门-保存20200513105438.html

NC问题总结

1  生成NC单据接口调用说明

2  NC生成接口事件监听,调用第三方接口传输数据

(1) 实现IBackgroundWorkPlugin接口 重写函数 再 开发配置--插件管理--业务插件注册 --后台类型任务注册 填写实现类路径

(2)动态建模平台--开发配置--插件管理--业务插件注册 -- 选择监听的业务模块  配置实现类路径

3 集成平台  必须买 
需要配置账套编码和集团编码才可以调用接口或者手动执行 日志输入指定的sql语句
1 应用集成平台-外部交换平台
外部系统信息配置—pfxx-demodata—
2检验文件管理
3 基础数据对照表 可以设置外部系统 设置基础数据对照关系
4 交换日志平台 所有调用NC接口日志数据

\## E:\home\pfxx 外部交换平台的配置文件

Billconfiginfo
模块每个接口对应的入口类

Billdefine
翻译的文件(前台配置的规则) 效验 打补丁的时候配置好

Businessprocessor
入口类 文件

Demodata
样例文件
    **对应文档接口的xml里面必要参数说明***

billtype属性,这个属性值决定了这个XML文件(文档)中所有单据的单据类型,外部交换平台所有的处理都是围绕单据类型的。(对应nc系统中的那个单据类型)

sender属性,这个属性值设置的是(外系统编码),指定的是数据的来源系统,即习惯上所说的发送方

account属性,这个属性指定要将数据导入至NC系统的哪个帐套。

receiver属性,这个属性指定数据的接收方。接收方又是有一定格式的,可以将这个格式用一个正则表达式表示为:
接收方  =(公司编码|公司主键)(@主体帐簿编码)?
也就是说接收方根据单据类型的需要,可以是公司或者公司下的主体帐簿。当接收方是公司,如编码为“yy”名称为“yk”的公司,其主键为“1046”,那么根据外部交换平台总体参数设置中的接收公司匹配规则的设置(参考2.5节)可设为receiver=yy或者receiver=1046。当接收方是公司下的主体帐簿时,如编码为“yy”名称为“yk”主键为“1046”的公司下有一编码为“yy-0001”名称为“yy公司基准帐簿”的主体帐簿时,根据外部交换平台总体参数设置中的接收公司匹配规则可将接收方属性设置为receiver=yy@yy-0001或者receiver=1046@yy-0001。

filename属性,在数据导入过程中,对于每张单据我们都可以记录其原始数据、翻译后数据,对整个文档我们也可以记录其导入后的回执信息,这个filename属性的值就是用于记录上述数据文件时的文件名。当然,如果您没有设置的话,系统会为每个导入的文档默认生成文件名。

isexchange属性,这个属性值决定了在外系统的数据在导入NC系统的过程中,是否使用外部交换平台提供的翻译转换和校验功能。正常情况下应将这个属性设置为“Y”,或者干脆不设。除非从其他NC系统产生的符合NC转换后标准的XML数据直接导入NC系统,并且很多基础档案数据字段直接用的是PK值,此时可以设置属性为“N”和“n”,可避免无谓的翻译转换。

在我们制作好的XML进行发送加载的时候,翻译转换可能会将某一个属性重复翻译而导致发送失败,这时我们可以将isexchange属性设置为“N”。

replace 属性,这个属性值决定是否允许将相同单据往同一个接收方重复导入。V50版的插件一般允许相同单据重复导入,除了将第一次导入视作新增之外,其余导入视作更新。关于这方面的具体内容请参见2.6节内容。如果不允许相同单据的重复导入,那么将这个属性值设置为“N”或者“n”。否则将其设置为“Y”或者干脆不设。

Exportbill

Prxxtemp
交互的文件  indocs 原始的xml   trans…翻译后文件

Receivedbills
回传的xml文件

注:

    ***按钮添加修改***
开发配置--功能注册—对应的xml文件  代码都放在模块的client里面

同步基础档案,找到基础档案原xml 查看源码类调用接口

管理员账号 定时任务配置:开发配置—后台任务管理—后台任务类型注册

按钮配置:

    在何种状态下显示
    property name="actionType" value="edit"/>
    表示按钮在界面中的位置
    property name="target" ref="linkQueryActionGroup"/>
    <property name="pos" value="after"/>
    将按钮的Bean放入到按钮扩展类中
    property name="action" ref="tidaiping"></property>

按钮添加监听
<property name="interceptor">
<!--此处可以扩展添加自己的拦截器-->
<bean id="editOADjtbInterceptor" class="nc.ws.intf.EditOADjtbInterceptor">
<property name="model"><ref bean="bmModel"/></property>
<property name="editor"><ref bean="billForm"/></property>
</bean>
</property>
EditOADjtbInterceptor 类为监听类 添加billForm属性获取页面数据需要

private AbstractAppModel model;
private IModelDataManager dataManager;
protected BillForm billform;
private ShowUpableBillForm editor;

Demo  按钮类
private SettleModel model;
private ArapBillCardForm editor;

在配置文件java实现类中注入两个(Demo)(EditOADjtbInterceptor)
在按钮中添加监听
bean.setEditor(getBillFormEditor());
bean.setInterceptor(getEditOADjtbInterceptor());
在监听中添加
bean.setBillform(getBillFormEditor());

监听器类中的beforeAction方法
String actionName = null;
if(e == null)
actionName = ArapConstant.SAVE;
else
actionName = e.getActionCommand();
String operateCode = getOperateCode(actionName);
if(operateCode != null){
BaseAggVO bill[] = null;        //获取页面上主表类数组
BaseItemVO[] bills=null;        //获取页面上子表类数组
BaseBillVO basebill=null;        //主表对象
BaseItemVO baseitem=null;        //子表对象
if(getBillform() != null && getBillform().getBillCardPanel() != null && getBillform().getBillCardPanel().isShowing()){
Object selectedata = getBillform().getValue();
bill = (new BaseAggVO[] {(BaseAggVO)selectedata});
}else{
Object datas[] = ((ArapBillManageModel)getModel()).getSelectedOperaDatas();
bill = new BaseAggVO[datas.length];
System.arraycopy(((Object) (datas)), 0, bill, 0, datas.length);
}
for(int i = 0; i < bill.length; i++){
basebill=bill[i].getHeadVO();
System.out.println(basebill.getApprovenote());
System.out.println(basebill.getApprover());
System.out.println(basebill.getBillmaker());
System.out.println(basebill.getBillstatus());
System.out.println(basebill.getPrimaryKey());
bills=bill[i].getItems();
}
for(int i=0;i<bills.length;i++){
baseitem=bills[i];
System.out.println(baseitem.getBillno());
System.out.println(baseitem.getMoney\_de());
System.out.println(baseitem.getSupplier());
System.out.println(baseitem.getSubjcode());        //科目
System.out.println(baseitem.getBusidate());        //起算日期
}
if(basebill.getSupplier()==null || "".equals(basebill.getSupplier())){
MessageDialog.showWarningDlg(getEditor(), "提示", "税码没选因为当前单据主表未选择供应商!");
return false;
}
if(basebill.getSupplier()!=null && baseitem.getTaxcodeid()==null || "".equals(baseitem.getTaxcodeid())){
MessageDialog.showWarningDlg(getEditor(), "提示", "税码没选因为当前单据主表未选择供应商!");
return false;
}
}

return true;

数据库表

BD\_cachetabversion 缓存表

xml传入系统的中间表

xx\_idcontrast
yszf\_sendoa  这是发送OA的日志表

nc打包笔记

nc打包的步骤,如果涉及到接口,放到meta-inf  下面的有upm  文件,还有classes文件里面放impl的文件或者是private模块下的;

外部接口的话 放到对应模块下面的classess文件下面;

如果是对应的源码放到对应的位置下面

nc中遇到的问题

1.如文件配置错误:文件路径=单据类型,异常信息:从后台读取交换规则定义文件发生错误

(1):可能的情况,nchome\pfxx\businessprocessor路径下的定义文件有问题
(2):定义文件没有成功读取到,可以尝试将对应要读取的定义文件直接放置到businessprocessor里,而不是放置到模块下的文件夹中,然后再重启服务

2.没有取得对应的单据定义,请检查是否存在单据类型:单据类型的定义文件。文件目录:NCHOME\pfxx\businessprocessor

(2.1):解决方法,可以尝试将对应单据类型定义文件中的level="-1",这个level代表的是单据加锁级别,这个标记删除之后再重新重启服务器

3.打开XML交换规则定义文件失败!文件不存在!

(3.1):解决办法,这个是NCHOME\pfxx\businessprocessor中的单据类型文件中的单据加锁级别导致的问题,将单据的加锁级别标志删除之后再重启服务即可

4.若定义文件(xml)改了之后,如加了中文,重新打开无法在浏览器中显示

(4.1):解决办法:可以将编码格式改成GBK

5.若接口返回插件:业务插件处理错误:插件类=nc.bs.bd.pfxx.plugin.PsndocPfxxPlugin,异常信息:业务插件处理错误:插件类=nc.bs.bd.pfxx.plugin.PsndocPfxxPlugin,异常信息:null

 (5.1)这个应该是nc前台删除数据后,再次通过xml同步问档,代码中swapContext.getDocID()还能够取到值,获取到原来的key所以走了更新方法,后面PsndocVO oldvo = queryOldPSndovCO(vopk);走个方法查数据库的时候这些没有查到报错,如果没有处理异常就会报出null。

 (5.2)如果nc前台删除数据后还想要通过xml文件同步数据需要删除中间表中的数据select * from xx\_idcontrast where fileid='OA传输的billid'  其中的fileid是xml的bill id="****"这个属性。

人员接口出现的错误

  (6.1) 一个人员必须要设置一个主职而且同步多个职位的时候要先同步主职的xml然后才是兼职的xml还有兼职拼接的xml必须是bill id 跟主职的bill id保持一致。

查看原文

赞 0 收藏 0 评论 0

Yfangliang 发布了文章 · 2020-03-18

框架配置

配置springboot跟memcached结合的时候如果启动出现
1584518760(1).jpg

可能存在的原因

  1. 需要在SpringBoot的启动Application前面加上 @EnableSwagger2注解。
查看原文

赞 0 收藏 0 评论 0

Yfangliang 发布了文章 · 2020-03-03

使用AQS重写自己的锁解决线程安全性问题(验证锁能重入)

实现AQS的帮助类(自己实现的加锁类)

public class MyLock2 implements Lock{

    private Helper helper=new Helper();

    @Override
    public void lock() {
        helper.acquire(1);
    }

    @Override
    public void lockInterruptibly() throws InterruptedException {
        helper.acquireInterruptibly(1);
    }

    @Override
    public boolean tryLock() {
        return helper.tryAcquire(1);
    }

    @Override
    public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
        return helper.tryAcquireSharedNanos(1,unit.toNanos(time));
    }

    @Override
    public void unlock() {
        helper.release(1);
    }

    @Override
    public Condition newCondition() {
        return helper.newCondition();
    }

    private class Helper extends AbstractQueuedSynchronizer{
        //有一种特殊情况,如果当前进来的线程跟当前保存的线程是同一线程则允许拿到锁
        @Override
        protected boolean tryAcquire(int arg) {
            int state=getState();
            Thread t=Thread.currentThread();
            if(state==0){
                if(compareAndSetState(0,arg)){
                    setExclusiveOwnerThread(t);
                    return true;
                }
            }else if(getExclusiveOwnerThread()==t){  //判断进入的线程是否是当前保存的锁
                setState(state+1);
                return true;
            }
            return false;
        }

        @Override
        protected boolean tryRelease(int arg) {
            if(Thread.currentThread()!=getExclusiveOwnerThread()){
                throw new RuntimeException();
            }
            int state=getState()-arg;
            boolean flag=false;
            if(state==0){
                setExclusiveOwnerThread(null);
                flag=true;
            }
            setState(state);
            return flag;
        }

        protected Condition newCondition(){
            return new ConditionObject();
        }
    }
}

测试是否能够进行锁重入

public class Main {
    private  int value;
    private MyLock2 myLock2=new MyLock2();
    public int getValue(){
        myLock2.lock();
        try {
            Thread.sleep(1000);
            return value++;
        } catch (InterruptedException e) {
            throw new RuntimeException();
        }finally {
            myLock2.unlock();
        }
    }

    public void getValue1(){
        myLock2.lock();
        System.out.println("调用方法getValue1");
        getValue2();
        myLock2.unlock();
    }
    public void getValue2(){
        myLock2.lock();
        System.out.println("调用方法getValue2");
        myLock2.unlock();
    }

    public static void main(String[] args){
        Main m=new Main();
        new Thread(new Runnable() {
            @Override
            public void run() {
                m.getValue1();
            }
        }).start();
    }
}
查看原文

赞 0 收藏 0 评论 0

Yfangliang 发布了文章 · 2020-03-03

使用AQS重写自己的锁解决线程安全性问题(存在问题锁不能重入)

重写一个锁的类里面包含内部类(非公共)继承AQS*

public class MyLock2 implements Lock{
    
    private Helper helper=new Helper();

    @Override
    public void lock() {
        helper.acquire(1);
    }

    @Override
    public void lockInterruptibly() throws InterruptedException {
        helper.acquireInterruptibly(1);
    }

    @Override
    public boolean tryLock() {
        return helper.tryAcquire(1);
    }

    @Override
    public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
        return helper.tryAcquireSharedNanos(1,unit.toNanos(time));
    }

    @Override
    public void unlock() {
        helper.release(1);
    }

    @Override
    public Condition newCondition() {
        return helper.newCondition();
    }

    private class Helper extends AbstractQueuedSynchronizer{
        //如果第一个线程拿到锁返回true
        //如果第二个线程拿不到锁返回false
        //如何判断是第一个线程进来还是其他线程进来?
        @Override
        protected boolean tryAcquire(int arg) {
            int state=getState();
            if(state==0){
                if(compareAndSetState(0,arg)){
                    setExclusiveOwnerThread(Thread.currentThread());
                    return true;
                }
            }
            return false;
        }

        @Override
        protected boolean tryRelease(int arg) {
            if(Thread.currentThread()!=getExclusiveOwnerThread()){
                throw new RuntimeException();
            }
            int state=getState()-arg;
            boolean flag=false;
            if(state==0){
                setExclusiveOwnerThread(null);
                flag=true;
            }
            setState(state);
            return flag;
        }

        protected Condition newCondition(){
            return new ConditionObject();
        }
    }
}

测试是否存在线程安全性问题

public class Main {
    private  int value;
    private MyLock2 myLock2=new MyLock2();
    public int getValue(){
        myLock2.lock();
        try {
            Thread.sleep(1000);
            return value++;
        } catch (InterruptedException e) {
            throw new RuntimeException();
        }finally {
            myLock2.unlock();
        }
    }

    public static void main(String[] args){
        Main m=new Main();
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true){
                    System.out.println(Thread.currentThread().getName()+"得到的结果>>>>>>"+m.getValue());
                }
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true){
                    System.out.println(Thread.currentThread().getName()+"得到的结果>>>>>>"+m.getValue());
                }
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true){
                    System.out.println(Thread.currentThread().getName()+"得到的结果>>>>>>"+m.getValue());
                }
            }
        }).start();
    }
}
查看原文

赞 0 收藏 0 评论 0

Yfangliang 发布了文章 · 2020-03-02

linux上如何安装Docker

自我理解docker实际上类似于虚拟机,镜像类似于操作系统。

下面介绍安装docker步骤

1.检查内核版本,返回的值大于3.10即可。

  uname -r

2.使用root权限的用户登入终端。

3.确保yum是最新的      yum update

4.安装 Docker

yuminstall-y docker-engine

安装成功后,使用docker version命令查看是否安装成功

5.启动docker

service.docker.start

6.验证启动是否成功(能否使用docker命令来操作)

docker images 查看镜像

7.设置开机自启动

sudosystemctlenabledocker

查看原文

赞 0 收藏 0 评论 0

Yfangliang 发布了文章 · 2020-02-26

PS常用快捷键

  1. 打开一个文件的快捷键    ctrl+o
  2. 创建新的画布
    16k-- 216*191 长*宽(mm单位) 像素是300以上 宽度越大分辨率越小,如果抠取的图片需要在网页上显示的时候像素设置为72像素。(单位上都是像素)保存文件 如果没有做完的图片使用.tif或者是psd格式这样图层还能继续修改。

3.界面设置   Ctrl+K
4.标尺    Ctrl+R (在标尺鼠标右键可以选择单位)
5.参考线   放到刻度尺上,按左键拖出来就是参考线了。(一般的网络印刷体)

    定位到某一个位置的时候,按住`shift`键先放开鼠标左键然后再放开`shift`键
    点击视图菜单添加参考线(显示比较准确)
    显示隐藏(ctrl+;)
    更改参考线方法    `alt` 快捷键

6.图像大小   Alt+Ctrl+I   查看图像大小

7.网格的应用

    `Ctrl+'`  显示网格线
    `Ctrl+k`  设置网格

8.屏幕的缩放

        1: `ctrl+'+'` 放大   `ctrl+'-'`  缩小
        2: 按下  alt+鼠标滚轮(指定某一个位置放大)
        3: 按下  ctrl+ 空格键 

9.图像的调节大小   ctrl+alt+i (按下alt键取消键变为复位键) (包括界面的大小跟图片的大小)
10.画布的大小   ctr+alt+c (只是背景的大小修改)
11.填充颜色alt+delete前景色
12.取消选区ctrl+D 取消选区
13.自由变换ctrl+T 自由变换
14.等比例放大alt+shift 等比例放大
15复制相同的图层 &nbps;&nbps;先将图层分为图层组ctrl+alt+shift+t 快捷键
16.内容识别缩放alt+shift+ctrl+c
17.自由变换ctrl+T
18.将图层变为普通图层ctrl+鼠标左键单击
19.反向选中选区ctrl+shift+I
20.填充选中区的前景色alt+delete键
21.填充选中区的背景色ctrl+delete键

查看原文

赞 0 收藏 0 评论 0

Yfangliang 关注了用户 · 2020-02-26

lzg9527 @michael_5c03399eed011

专注web前端开发,熟悉html5,css3,javascript,vue,react

关注 7593

Yfangliang 关注了用户 · 2020-02-26

ming @helloxiaoming

Strive to become better and better

关注 3015

Yfangliang 关注了用户 · 2020-02-26

阿山 @a_shan

一只英语专业的程序猿

微信公众号:GitWeb

微信交流群:公众号内加好友(备注思否),拉你进群

关注 2896

认证与成就

  • 获得 0 次点赞
  • 获得 0 枚徽章 获得 0 枚金徽章, 获得 0 枚银徽章, 获得 0 枚铜徽章

擅长技能
编辑

(゚∀゚ )
暂时没有

开源项目 & 著作
编辑

(゚∀゚ )
暂时没有

注册于 2020-02-26
个人主页被 352 人浏览