Commit b5d338d010170e2c77e305b325790ef5373b1a2b

Authored by 杨鸣坤
1 parent c8ae8b9c

楚江ERP:审核状态回显修改,增加元素字段

... ... @@ -103,6 +103,7 @@ create table if not exists `tbl_contract_distributor_standard`
103 103 `surface` TEXT COMMENT '表面',
104 104 `tolerance` TEXT COMMENT '公差',
105 105 `performance` TEXT COMMENT '性能',
  106 + `component` TEXT COMMENT '元素',
106 107 `packaging` TEXT COMMENT '包装',
107 108 `special_terms` VARCHAR(50) COMMENT '特别条款要求',
108 109 `designated_consignee` TEXT COMMENT '需方指定收货人',
... ... @@ -115,16 +116,20 @@ create table if not exists `tbl_contract_distributor_standard`
115 116 `formal_file_name` VARCHAR(255) COMMENT '正式合同文件名称',
116 117 `formal_standardized` TINYINT(1) COMMENT '正式合同是否规范 (0-不规范, 1-规范)',
117 118 `formal_approved` varchar(20) COMMENT '正式合同是否审核完成(AUDIT:审核中,PASS:审核通过,REFUSE:已驳回,CANCEL:已取消)',
  119 + `formal_approver_id` varchar(32) COMMENT '正式合同审批人ID',
  120 + `formal_time` datetime COMMENT '正式合同审批完成时间',
118 121 `standard_file_id` VARCHAR(100) COMMENT '标准合同文件ID',
119 122 `standard_file_name` VARCHAR(255) COMMENT '标准合同文件名称',
120 123 `standard_standardized` TINYINT(1) COMMENT '标准合同是否规范 (0-不规范, 1-规范)',
121   - `standard_approved` varchar(20) COMMENT '标准合同是否审核完成(AUDIT:审核中,PASS:审核通过,REFUSE:已驳回,CANCEL:已取消)',
  124 + `standard_approved` varchar(20) COMMENT '标准合同是否审核完成(AUDIT:审核中,PASS:审核通过,REFUSE:已驳回,CANCEL:已取消)',
  125 + `standard_approver_id` varchar(32) COMMENT '标准合同审批人ID',
  126 + `standard_time` datetime COMMENT '标准合同审批完成时间',
122 127 `create_by_id` varchar(32) not null comment '创建人ID',
123 128 `create_by` varchar(20) not null comment '创建人',
124 129 `update_by_id` varchar(32) not null comment '更新人ID',
125 130 `update_by` varchar(20) not null comment '更新人',
126   - `create_time` datetime default now() comment '创建时间',
127   - `update_time` datetime default now() comment '更新时间'
  131 + `create_time` datetime default now() comment '创建时间',
  132 + `update_time` datetime default now() comment '更新时间'
128 133 );
129 134
130 135 -- 经销合同物料行
... ...
... ... @@ -11,6 +11,7 @@ import org.hibernate.validator.constraints.Length;
11 11 import javax.validation.constraints.NotBlank;
12 12 import java.math.BigDecimal;
13 13 import java.time.LocalDate;
  14 +import java.time.LocalDateTime;
14 15 import java.util.List;
15 16
16 17 /**
... ... @@ -215,6 +216,12 @@ public class GetContractDistributorStandardBo extends BaseBo<ContractDistributor
215 216 private String performance;
216 217
217 218 /**
  219 + * 元素
  220 + */
  221 + @ApiModelProperty(value = "元素")
  222 + private String component;
  223 +
  224 + /**
218 225 * 包装
219 226 */
220 227 @ApiModelProperty("包装")
... ... @@ -317,6 +324,18 @@ public class GetContractDistributorStandardBo extends BaseBo<ContractDistributor
317 324 private String formalApproved;
318 325
319 326 /**
  327 + * 正式合同审批人ID
  328 + */
  329 + @ApiModelProperty(value = "正式合同审批人ID")
  330 + private String formalApproverId;
  331 +
  332 + /**
  333 + * 正式合同审批完成时间
  334 + */
  335 + @ApiModelProperty(value = "正式合同审批完成时间")
  336 + private LocalDateTime formalTime;
  337 +
  338 + /**
320 339 * 标准合同文件ID
321 340 */
322 341 @ApiModelProperty("标准合同文件ID")
... ... @@ -340,6 +359,18 @@ public class GetContractDistributorStandardBo extends BaseBo<ContractDistributor
340 359 @ApiModelProperty(value = "标准合同是否审核完成(AUDIT:审核中,PASS:审核通过,REFUSE:已驳回,CANCEL:已取消)")
341 360 private String standardApproved;
342 361
  362 + /**
  363 + * 标准合同审批人ID
  364 + */
  365 + @ApiModelProperty(value = "标准合同审批人ID")
  366 + private String standardApproverId;
  367 +
  368 + /**
  369 + * 标准合同审批完成时间
  370 + */
  371 + @ApiModelProperty(value = "标准合同审批完成时间")
  372 + private LocalDateTime standardTime;
  373 +
343 374 public GetContractDistributorStandardBo() {
344 375
345 376 }
... ...
... ... @@ -151,6 +151,12 @@ public class QueryContractDistributorStandardBo extends BaseBo<ContractDistribut
151 151 @ApiModelProperty(value = "标准合同是否审核完成(AUDIT:审核中,PASS:审核通过,REFUSE:已驳回,CANCEL:已取消)")
152 152 private String standardApproved;
153 153
  154 + /**
  155 + * 是否展示审核按钮(非持久化字段)
  156 + */
  157 + @ApiModelProperty(value = "是否展示审核按钮")
  158 + private Boolean showExamine;
  159 +
154 160 public QueryContractDistributorStandardBo() {
155 161
156 162 }
... ...
... ... @@ -133,6 +133,11 @@ public class ContractDistributorStandard extends BaseEntity implements BaseDto {
133 133 private String performance;
134 134
135 135 /**
  136 + * 元素
  137 + */
  138 + private String component;
  139 +
  140 + /**
136 141 * 包装
137 142 */
138 143 private String packaging;
... ... @@ -193,6 +198,16 @@ public class ContractDistributorStandard extends BaseEntity implements BaseDto {
193 198 private String formalApproved;
194 199
195 200 /**
  201 + * 正式合同审批人ID
  202 + */
  203 + private String formalApproverId;
  204 +
  205 + /**
  206 + * 正式合同审批完成时间
  207 + */
  208 + private LocalDateTime formalTime;
  209 +
  210 + /**
196 211 * 标准合同文件ID
197 212 */
198 213 private String standardFileId;
... ... @@ -213,6 +228,16 @@ public class ContractDistributorStandard extends BaseEntity implements BaseDto {
213 228 private String standardApproved;
214 229
215 230 /**
  231 + * 标准合同审批人ID
  232 + */
  233 + private String standardApproverId;
  234 +
  235 + /**
  236 + * 标准合同审批完成时间
  237 + */
  238 + private LocalDateTime standardTime;
  239 +
  240 + /**
216 241 * 创建人ID
217 242 */
218 243 @TableField(fill = FieldFill.INSERT)
... ... @@ -263,4 +288,10 @@ public class ContractDistributorStandard extends BaseEntity implements BaseDto {
263 288 */
264 289 private BigDecimal totalAmountIncludingTax;
265 290
  291 + /**
  292 + * 是否展示审核按钮(非持久化字段)
  293 + */
  294 + @TableField(exist = false)
  295 + private Boolean showExamine;
  296 +
266 297 }
... ...
1 1 package com.lframework.xingyun.sc.handlers;
2 2
3   -import com.fasterxml.jackson.core.JsonProcessingException;
4   -import com.fasterxml.jackson.databind.ObjectMapper;
5 3 import com.lframework.starter.bpm.dto.FlowInstanceExtDto;
6 4 import com.lframework.starter.bpm.enums.FlowInstanceStatus;
7 5 import com.lframework.starter.bpm.service.BusinessDataHandlerService;
... ... @@ -9,6 +7,7 @@ import com.lframework.starter.web.core.components.redis.RedisHandler;
9 7 import com.lframework.starter.web.core.utils.JsonUtil;
10 8 import com.lframework.xingyun.sc.entity.CorePersonnelHistory;
11 9 import com.lframework.xingyun.sc.enums.CustomerDevelopStatus;
  10 +import com.lframework.xingyun.sc.service.contract.ContractDistributorStandardService;
12 11 import com.lframework.xingyun.sc.service.customer.CorePersonnelHistoryService;
13 12 import com.lframework.xingyun.sc.service.customer.CustomerCreditHistoryService;
14 13 import com.lframework.xingyun.sc.service.customer.CustomerCreditService;
... ... @@ -44,12 +43,14 @@ public class BusinessDataHandlerServiceImpl implements BusinessDataHandlerServic
44 43 private CorePersonnelHistoryService corePersonnelHistoryService;
45 44 @Autowired
46 45 private RedisHandler redisHandler;
  46 + @Resource
  47 + private ContractDistributorStandardService contractDistributorStandardService;
47 48
48 49
49 50 /**
50 51 * 业务状态数据处理器
51 52 *
52   - * @param listenerVariable 流程变量
  53 + * @param listenerVariable 流程变量
53 54 */
54 55 @Override
55 56 public void businessStatusHandler(ListenerVariable listenerVariable) {
... ... @@ -80,17 +81,48 @@ public class BusinessDataHandlerServiceImpl implements BusinessDataHandlerServic
80 81 case "CUSTOMER_CREDIT":
81 82 handleCustomerCreditData(flowStatus, businessId);
82 83 break;
  84 + case "FORMAL_CONTRACT":
  85 + handleFormalContractAuditData(flowStatus, businessId);
  86 + break;
  87 + case "STANDARD_CONTRACT":
  88 + handleStandardContractAuditData(flowStatus, businessId);
  89 + break;
83 90 default:
84 91 break;
85 92 }
86 93 log.info("==================== 业务状态数据处理结束......");
87 94 }
88 95
  96 + private void handleFormalContractAuditData(String flowStatus, String businessId) {
  97 + if (FlowInstanceStatus.APPROVE_PASS.getCode().equals(flowStatus)
  98 + || FlowInstanceStatus.FINISH.getCode().equals(flowStatus)) {
  99 + contractDistributorStandardService.updateFormalContractStatus(businessId, "PASS");
  100 + } else if (FlowInstanceStatus.REVOKE.getCode().equals(flowStatus)
  101 + || FlowInstanceStatus.REFUSE.getCode().equals(flowStatus)
  102 + || FlowInstanceStatus.TERMINATION.getCode().equals(flowStatus)) {
  103 + contractDistributorStandardService.updateFormalContractStatus(businessId, "REFUSE");
  104 + } else if (FlowInstanceStatus.UNDO.getCode().equals(flowStatus)) {
  105 + contractDistributorStandardService.updateFormalContractStatus(businessId, "CANCEL");
  106 + }
  107 + }
  108 +
  109 + private void handleStandardContractAuditData(String flowStatus, String businessId) {
  110 + if (FlowInstanceStatus.APPROVE_PASS.getCode().equals(flowStatus)
  111 + || FlowInstanceStatus.FINISH.getCode().equals(flowStatus)) {
  112 + contractDistributorStandardService.updateStandardContractStatus(businessId, "PASS");
  113 + } else if (FlowInstanceStatus.REVOKE.getCode().equals(flowStatus)
  114 + || FlowInstanceStatus.REFUSE.getCode().equals(flowStatus)
  115 + || FlowInstanceStatus.TERMINATION.getCode().equals(flowStatus)) {
  116 + contractDistributorStandardService.updateStandardContractStatus(businessId, "REFUSE");
  117 + } else if (FlowInstanceStatus.UNDO.getCode().equals(flowStatus)) {
  118 + contractDistributorStandardService.updateStandardContractStatus(businessId, "CANCEL");
  119 + }
  120 + }
89 121
90 122 /**
91 123 * 客户开发业务数据处理
92 124 *
93   - * @param businessId 业务ID
  125 + * @param businessId 业务ID
94 126 */
95 127 private void handleCustomerDevelopData(String flowStatus, String businessId) {
96 128 if (FlowInstanceStatus.APPROVE_PASS.getCode().equals(flowStatus)
... ...
... ... @@ -4,7 +4,11 @@ import com.baomidou.mybatisplus.core.conditions.Wrapper;
4 4 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
5 5 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
6 6 import com.github.pagehelper.PageInfo;
  7 +import com.lframework.starter.bpm.dto.FlowTaskDto;
  8 +import com.lframework.starter.bpm.mappers.FlowTaskWrapperMapper;
7 9 import com.lframework.starter.bpm.service.FlowInstanceWrapperService;
  10 +import com.lframework.starter.bpm.vo.flow.task.QueryTodoTaskListVo;
  11 +import com.lframework.starter.web.core.components.security.SecurityUtil;
8 12 import com.lframework.xingyun.sc.entity.ContractDistributorLine;
9 13 import com.lframework.xingyun.sc.entity.ContractDistributorStandard;
10 14 import com.lframework.starter.web.core.impl.BaseMpServiceImpl;
... ... @@ -35,9 +39,13 @@ import org.springframework.cache.annotation.Cacheable;
35 39 import org.springframework.stereotype.Service;
36 40 import org.springframework.transaction.annotation.Transactional;
37 41
  42 +import javax.annotation.Resource;
38 43 import java.io.Serializable;
  44 +import java.time.LocalDateTime;
39 45 import java.util.ArrayList;
  46 +import java.util.Date;
40 47 import java.util.List;
  48 +import java.util.Set;
41 49 import java.util.stream.Collectors;
42 50
43 51 @Service
... ... @@ -51,6 +59,8 @@ public class ContractDistributorStandardServiceImpl extends
51 59 private ContractDistributorLineService contractDistributorLineService;
52 60 @Autowired
53 61 private FlowInstanceWrapperService flowInstanceWrapperService;
  62 + @Resource
  63 + private FlowTaskWrapperMapper flowTaskWrapperMapper;
54 64
55 65
56 66 @Override
... ... @@ -61,6 +71,22 @@ public class ContractDistributorStandardServiceImpl extends
61 71
62 72 PageHelperUtil.startPage(pageIndex, pageSize);
63 73 List<ContractDistributorStandard> datas = this.query(vo);
  74 + if (CollectionUtils.isEmpty(datas)) {
  75 + return PageResultUtil.convert(new PageInfo<>(datas));
  76 + }
  77 +
  78 + // 获取当前人员的待办任务数据
  79 + List<FlowTaskDto> flowTaskList = flowTaskWrapperMapper.queryTodoList(new QueryTodoTaskListVo(), SecurityUtil.getCurrentUser().getId());
  80 + if (CollectionUtils.isEmpty(flowTaskList)) {
  81 + return PageResultUtil.convert(new PageInfo<>(datas));
  82 + }
  83 +
  84 + Set<String> ids = flowTaskList.stream()
  85 + .map(FlowTaskDto::getBusinessId)
  86 + .collect(Collectors.toSet());
  87 + for (ContractDistributorStandard standard : datas) {
  88 + standard.setShowExamine(ids.contains(standard.getId()));
  89 + }
64 90
65 91 return PageResultUtil.convert(new PageInfo<>(datas));
66 92 }
... ... @@ -105,6 +131,7 @@ public class ContractDistributorStandardServiceImpl extends
105 131 data.setSurface(vo.getSurface());
106 132 data.setTolerance(vo.getTolerance());
107 133 data.setPerformance(vo.getPerformance());
  134 + data.setComponent(vo.getComponent());
108 135 data.setPackaging(vo.getPackaging());
109 136 data.setSpecialTerms(vo.getSpecialTerms());
110 137 data.setDesignatedConsignee(vo.getDesignatedConsignee());
... ... @@ -161,6 +188,7 @@ public class ContractDistributorStandardServiceImpl extends
161 188 .set(ContractDistributorStandard::getSurface, vo.getSurface())
162 189 .set(ContractDistributorStandard::getTolerance, vo.getTolerance())
163 190 .set(ContractDistributorStandard::getPerformance, vo.getPerformance())
  191 + .set(ContractDistributorStandard::getComponent, vo.getComponent())
164 192 .set(ContractDistributorStandard::getPackaging, vo.getPackaging())
165 193 .set(ContractDistributorStandard::getSpecialTerms, vo.getSpecialTerms())
166 194 .set(ContractDistributorStandard::getDesignatedConsignee, vo.getDesignatedConsignee())
... ... @@ -258,6 +286,56 @@ public class ContractDistributorStandardServiceImpl extends
258 286 flowInstanceWrapperService.startInstance(FORMAL_FLAG, data.getId(), FORMAL_FLAG, data);
259 287 }
260 288
  289 + @Override
  290 + @OpLog(type = OtherOpLogType.class, name = "正式合同附件审批完成,ID:{}, 审批状态:{}", params = {"#id", "#formalApproved"})
  291 + @Transactional(rollbackFor = Exception.class)
  292 + public void updateFormalContractStatus(String id, String formalApproved) {
  293 + if (StringUtils.isBlank(id) || StringUtils.isBlank(formalApproved)) {
  294 + return;
  295 + }
  296 +
  297 + Wrapper<ContractDistributorStandard> wrapper = Wrappers.lambdaUpdate(ContractDistributorStandard.class)
  298 + .set(ContractDistributorStandard::getFormalApproved, formalApproved)
  299 + .set(ContractDistributorStandard::getFormalApproverId, SecurityUtil.getCurrentUser().getId())
  300 + .set(ContractDistributorStandard::getFormalTime, LocalDateTime.now())
  301 + .eq(ContractDistributorStandard::getId, id);
  302 +
  303 + getBaseMapper().update(wrapper);
  304 +
  305 + UpdateContractDistributorStandardVo vo = new UpdateContractDistributorStandardVo();
  306 + vo.setId(id);
  307 + vo.setFormalApproved(formalApproved);
  308 + vo.setFormalTime(LocalDateTime.now());
  309 + vo.setFormalApproved(SecurityUtil.getCurrentUser().getId());
  310 + OpLogUtil.setVariable("id", id);
  311 + OpLogUtil.setExtra(vo);
  312 + }
  313 +
  314 + @Override
  315 + @OpLog(type = OtherOpLogType.class, name = "标准合同附件审批完成,ID:{}, 审批状态:{}", params = {"#id", "#standardApproved"})
  316 + @Transactional(rollbackFor = Exception.class)
  317 + public void updateStandardContractStatus(String id, String standardApproved) {
  318 + if (StringUtils.isBlank(id) || StringUtils.isBlank(standardApproved)) {
  319 + return;
  320 + }
  321 +
  322 + Wrapper<ContractDistributorStandard> wrapper = Wrappers.lambdaUpdate(ContractDistributorStandard.class)
  323 + .set(ContractDistributorStandard::getStandardApproved, standardApproved)
  324 + .set(ContractDistributorStandard::getStandardApproverId, SecurityUtil.getCurrentUser().getId())
  325 + .set(ContractDistributorStandard::getStandardTime, LocalDateTime.now())
  326 + .eq(ContractDistributorStandard::getId, id);
  327 +
  328 + getBaseMapper().update(wrapper);
  329 +
  330 + UpdateContractDistributorStandardVo vo = new UpdateContractDistributorStandardVo();
  331 + vo.setId(id);
  332 + vo.setStandardApproved(standardApproved);
  333 + vo.setStandardTime(LocalDateTime.now());
  334 + vo.setStandardApproved(SecurityUtil.getCurrentUser().getId());
  335 + OpLogUtil.setVariable("id", id);
  336 + OpLogUtil.setExtra(vo);
  337 + }
  338 +
261 339 @CacheEvict(value = ContractDistributorStandard.CACHE_NAME, key = "@cacheVariables.tenantId() + #key")
262 340 @Override
263 341 public void cleanCacheByKey(Serializable key) {
... ...
... ... @@ -59,4 +59,8 @@ public interface ContractDistributorStandardService extends BaseMpService<Contra
59 59 */
60 60 void uploadFormalContract(UpdateContractDistributorStandardVo vo);
61 61
  62 + void updateFormalContractStatus(String id, String formalApproved);
  63 +
  64 + void updateStandardContractStatus(String id, String standardApproved);
  65 +
62 66 }
\ No newline at end of file
... ...
... ... @@ -167,6 +167,13 @@ public class CreateContractDistributorStandardVo implements BaseVo, Serializable
167 167 private String performance;
168 168
169 169 /**
  170 + * 元素
  171 + */
  172 + @ApiModelProperty(value = "元素")
  173 + @Length(message = "元素最多允许65,535个字符!")
  174 + private String component;
  175 +
  176 + /**
170 177 * 包装
171 178 */
172 179 @ApiModelProperty(value = "包装")
... ...
... ... @@ -15,6 +15,7 @@ import io.swagger.annotations.ApiModelProperty;
15 15 import org.hibernate.validator.constraints.Length;
16 16
17 17 import java.io.Serializable;
  18 +import java.time.LocalDateTime;
18 19 import java.util.List;
19 20
20 21 @Data
... ... @@ -169,6 +170,13 @@ public class UpdateContractDistributorStandardVo implements BaseVo, Serializable
169 170 private String performance;
170 171
171 172 /**
  173 + * 元素
  174 + */
  175 + @ApiModelProperty(value = "元素")
  176 + @Length(message = "元素最多允许65,535个字符!")
  177 + private String component;
  178 +
  179 + /**
172 180 * 包装
173 181 */
174 182 @ApiModelProperty(value = "包装")
... ... @@ -275,6 +283,18 @@ public class UpdateContractDistributorStandardVo implements BaseVo, Serializable
275 283 private String formalApproved;
276 284
277 285 /**
  286 + * 正式合同审批人ID
  287 + */
  288 + @ApiModelProperty(value = "正式合同审批人ID")
  289 + private String formalApproverId;
  290 +
  291 + /**
  292 + * 正式合同审批完成时间
  293 + */
  294 + @ApiModelProperty(value = "正式合同审批完成时间")
  295 + private LocalDateTime formalTime;
  296 +
  297 + /**
278 298 * 标准合同文件ID
279 299 */
280 300 @ApiModelProperty(value = "标准合同文件ID")
... ... @@ -298,4 +318,16 @@ public class UpdateContractDistributorStandardVo implements BaseVo, Serializable
298 318 */
299 319 @ApiModelProperty(value = "标准合同是否审核完成(AUDIT:审核中,PASS:审核通过,REFUSE:已驳回,CANCEL:已取消)")
300 320 private String standardApproved;
  321 +
  322 + /**
  323 + * 标准合同审批人ID
  324 + */
  325 + @ApiModelProperty(value = "标准合同审批人ID")
  326 + private String standardApproverId;
  327 +
  328 + /**
  329 + * 标准合同审批完成时间
  330 + */
  331 + @ApiModelProperty(value = "标准合同审批完成时间")
  332 + private LocalDateTime standardTime;
301 333 }
... ...
... ... @@ -24,6 +24,7 @@
24 24 <result column="surface" property="surface"/>
25 25 <result column="tolerance" property="tolerance"/>
26 26 <result column="performance" property="performance"/>
  27 + <result column="component" property="component"/>
27 28 <result column="packaging" property="packaging"/>
28 29 <result column="special_terms" property="specialTerms"/>
29 30 <result column="designated_consignee" property="designatedConsignee"/>
... ... @@ -45,10 +46,14 @@
45 46 <result column="formal_file_name" property="formalFileName"/>
46 47 <result column="formal_standardized" property="formalStandardized"/>
47 48 <result column="formal_approved" property="formalApproved"/>
  49 + <result column="formal_approver_id" property="formalApproverId"/>
  50 + <result column="formal_time" property="formalTime"/>
48 51 <result column="standard_file_id" property="standardFileId"/>
49 52 <result column="standard_file_name" property="standardFileName"/>
50 53 <result column="standard_standardized" property="standardStandardized"/>
51 54 <result column="standard_approved" property="standardApproved"/>
  55 + <result column="standard_approver_id" property="standardApproverId"/>
  56 + <result column="standard_time" property="standardTime"/>
52 57 </resultMap>
53 58
54 59 <sql id="ContractDistributorStandard_sql">
... ... @@ -74,6 +79,7 @@
74 79 tb.surface,
75 80 tb.tolerance,
76 81 tb.performance,
  82 + tb.component,
77 83 tb.packaging,
78 84 tb.special_terms,
79 85 tb.designated_consignee,
... ... @@ -95,10 +101,14 @@
95 101 tb.formal_file_name,
96 102 tb.formal_standardized,
97 103 tb.formal_approved,
  104 + tb.formal_approver_id,
  105 + tb.formal_time,
98 106 tb.standard_file_id,
99 107 tb.standard_file_name,
100 108 tb.standard_standardized,
101   - tb.standard_approved
  109 + tb.standard_approved,
  110 + tb.standard_approver_id,
  111 + tb.standard_time
102 112 FROM tbl_contract_distributor_standard AS tb
103 113 </sql>
104 114
... ...