Compare commits
2 Commits
f075e6b2b1
...
8faff7562d
| Author | SHA1 | Date |
|---|---|---|
|
|
8faff7562d | |
|
|
2d026feba3 |
|
|
@ -9,7 +9,6 @@ spring:
|
|||
username: root
|
||||
password: mkMReisAKl6I7rVqEY90
|
||||
driverClassName: com.mysql.cj.jdbc.Driver
|
||||
|
||||
# 初始连接数
|
||||
initialSize: 5
|
||||
# 最小连接池数量
|
||||
|
|
@ -53,5 +52,3 @@ spring:
|
|||
wall:
|
||||
config:
|
||||
multi-statement-allow: true
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -228,12 +228,21 @@ byteapi:
|
|||
apiKey:
|
||||
callBackUrl:
|
||||
|
||||
# 火山引擎 Ark API (Seedance 2.0)
|
||||
volcengine:
|
||||
region: cn-beijing
|
||||
# 素材库等 ark 控制面 OpenAPI(与 byteapi 数据面推理地址无关)
|
||||
# URL 请加引号;代码会去掉 https:// 再交给 SDK(SDK 自己会拼 https://,避免双 scheme)
|
||||
openApiEndpoint: "https://ark.cn-beijing.volces.com"
|
||||
ark:
|
||||
baseUrl:
|
||||
apiKey:
|
||||
callbackUrl:
|
||||
baseUrl: "https://ark.cn-beijing.volces.com"
|
||||
openApiVersion: "2024-01-01"
|
||||
apiKey: 3e33e034-7e25-4228-8864-b51b2a7a8f97
|
||||
callbackUrl: http://47.86.170.114:8011/api/ai/volcCallback
|
||||
ak: AKLTNmYyN2VhZTcyMDcxNDNlNzg3OGVlMDVmZjRhNWQwY2M
|
||||
sk: Tm1ZeU1UTmlORFk1WmpKa05HUmpaRGcxTWpjMFpqUmpOVE01TUdJME5URQ==
|
||||
url: https://ark.ap-southeast.bytepluses.com/api/v3
|
||||
apiKey: 3e33e034-7e25-4228-8864-b51b2a7a8f97
|
||||
callBackUrl: http://47.86.170.114:5173/
|
||||
|
||||
# 门户视频生成页:模型 / 比例 / 时长 / 分辨率均由此处维护,前后端不写死业务枚举
|
||||
portal:
|
||||
|
|
|
|||
|
|
@ -1,104 +1,269 @@
|
|||
package com.ruoyi.ai.service.impl;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.MapperFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
|
||||
import com.ruoyi.ai.service.IByteDeptApiKeyService;
|
||||
import com.fasterxml.jackson.databind.*;
|
||||
import com.ruoyi.ai.mapper.AiUserMapper;
|
||||
import com.ruoyi.common.core.domain.entity.AiUser;
|
||||
import com.ruoyi.common.core.domain.entity.SysDept;
|
||||
import com.ruoyi.common.utils.SecurityUtils;
|
||||
import com.ruoyi.common.utils.http.OkHttpUtils;
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.RequestBody;
|
||||
import okhttp3.Response;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import com.ruoyi.system.mapper.SysDeptMapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import okhttp3.*;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.Resource;
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.io.IOException;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.security.MessageDigest;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class BaseByteApiService {
|
||||
protected final ObjectMapper objectMapper = new ObjectMapper()
|
||||
@Resource
|
||||
private AiUserMapper userMapper;
|
||||
@Resource
|
||||
private SysDeptMapper deptMapper;
|
||||
protected String DEPT_ANCESTORS_SPLIT = ",";
|
||||
@Value("${volcengine.ak}")
|
||||
protected String accessKeyId;
|
||||
@Value("${volcengine.sk}")
|
||||
protected String secretAccessKey;
|
||||
@Value("${volcengine.region}")
|
||||
protected String region;
|
||||
|
||||
private static final String CONTENT_TYPE_JSON = "application/json; charset=utf-8";
|
||||
private static final MediaType JSON_MEDIA = MediaType.parse(CONTENT_TYPE_JSON);
|
||||
|
||||
private static final String SERVICE_ARK = "ark";
|
||||
private static final String VERSION = "2024-01-01";
|
||||
private static final String METHOD_POST = "POST";
|
||||
private static final String PATH_ROOT = "/";
|
||||
private static final String SIGNED_HEADERS = "content-type;host;x-content-sha256;x-date";
|
||||
|
||||
private OkHttpClient httpClient = OkHttpUtils.createOkHttpClient();
|
||||
private String controlApiHost;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
this.controlApiHost = "ark." + this.region + ".volcengineapi.com";
|
||||
this.httpClient = OkHttpUtils.createOkHttpClient();
|
||||
}
|
||||
|
||||
private final ObjectMapper jsonMapper = new ObjectMapper()
|
||||
.setSerializationInclusion(JsonInclude.Include.NON_NULL)
|
||||
.setPropertyNamingStrategy(PropertyNamingStrategies.UPPER_CAMEL_CASE)
|
||||
.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true)
|
||||
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
|
||||
.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);
|
||||
|
||||
// API地址(可配置在配置文件中)
|
||||
@Value("${byteapi.url}")
|
||||
protected String API_URL;
|
||||
|
||||
@Autowired
|
||||
protected IByteDeptApiKeyService byteDeptApiKeyService;
|
||||
|
||||
/**
|
||||
* POST JSON 调用方舟 OpenAPI;若响应含 {@code Result} 节点则解析为业务对象(与 api.docx 返回示例一致)。
|
||||
*/
|
||||
protected <T> T httpExecute(String path, Object request, Class<T> clz) throws IOException {
|
||||
String jsonBody = objectMapper.writeValueAsString(request);
|
||||
RequestBody body = RequestBody.create(
|
||||
MediaType.parse("application/json; charset=utf-8"),
|
||||
jsonBody);
|
||||
Request httpRequest = new Request.Builder()
|
||||
.url(API_URL + path)
|
||||
.header("Content-Type", "application/json")
|
||||
.header("Authorization", "Bearer " + resolveCurrentAiUserApiKey())
|
||||
.post(body)
|
||||
.build();
|
||||
try (Response response = OkHttpUtils.newCall(httpRequest).execute()) {
|
||||
if (!response.isSuccessful()) {
|
||||
String errorMsg = response.body() != null ? response.body().string() : "execute error";
|
||||
throw new RuntimeException("execute error:" + errorMsg);
|
||||
}
|
||||
if (response.body() == null) {
|
||||
throw new RuntimeException("response body null");
|
||||
}
|
||||
String responseBody = response.body().string();
|
||||
JsonNode root = objectMapper.readTree(responseBody);
|
||||
JsonNode result = root.get("Result");
|
||||
if (result != null && !result.isNull()) {
|
||||
return objectMapper.treeToValue(result, clz);
|
||||
}
|
||||
return objectMapper.readValue(responseBody, clz);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 无业务体返回的 OpenAPI 调用(如 DeleteAsset)。
|
||||
*/
|
||||
protected void httpExecuteNoContent(String path, Object request) throws IOException {
|
||||
String jsonBody = objectMapper.writeValueAsString(request);
|
||||
RequestBody body = RequestBody.create(
|
||||
MediaType.parse("application/json; charset=utf-8"),
|
||||
jsonBody);
|
||||
Request httpRequest = new Request.Builder()
|
||||
.url(API_URL + path)
|
||||
.header("Content-Type", "application/json")
|
||||
.header("Authorization", "Bearer " + resolveCurrentAiUserApiKey())
|
||||
.post(body)
|
||||
.build();
|
||||
try (Response response = OkHttpUtils.newCall(httpRequest).execute()) {
|
||||
if (!response.isSuccessful()) {
|
||||
String errorMsg = response.body() != null ? response.body().string() : "execute error";
|
||||
throw new RuntimeException("execute error:" + errorMsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||
|
||||
/**
|
||||
* 根据用户找到对应的project
|
||||
*/
|
||||
protected String getUserProject() {
|
||||
// TODO
|
||||
return "default";
|
||||
Long userId = SecurityUtils.getAiUserId();
|
||||
if (userId == null) {
|
||||
return null;
|
||||
}
|
||||
AiUser user = userMapper.selectAiUserById(userId);
|
||||
if (user == null) {
|
||||
return null;
|
||||
}
|
||||
// 第二层部门ID,API_KEY放在这里
|
||||
Long secondLvDeptId = getSecondLevelDept(user.getDeptId());
|
||||
if (secondLvDeptId == null) {
|
||||
return null;
|
||||
}
|
||||
SysDept secondDept = deptMapper.selectDeptById(secondLvDeptId);
|
||||
return secondDept.getProject();
|
||||
}
|
||||
|
||||
protected String resolveCurrentAiUserApiKey() {
|
||||
return byteDeptApiKeyService.resolveVolcApiKey(SecurityUtils.getAiUserId());
|
||||
/**
|
||||
* 找到当前部门所属第二部门ID
|
||||
*
|
||||
* @param deptId 当前部门
|
||||
*/
|
||||
protected Long getSecondLevelDept(long deptId) {
|
||||
SysDept dept = deptMapper.selectDeptById(deptId);
|
||||
String ancestors = dept.getAncestors();
|
||||
// 判断是第几层
|
||||
if (ancestors == null || ancestors.isEmpty() || "0".equals(ancestors)) {
|
||||
// 第一层
|
||||
return null;
|
||||
}
|
||||
String[] parentDeptArray = ancestors.split(DEPT_ANCESTORS_SPLIT);
|
||||
int length = parentDeptArray.length;
|
||||
if (length == 2) {
|
||||
// 只有一个上级,所以当前节点是第二层,直接返回
|
||||
return deptId;
|
||||
}
|
||||
// 大于二级
|
||||
return Long.parseLong(parentDeptArray[2]);
|
||||
}
|
||||
|
||||
public <R> R callApi(String action, Object request, Class<R> responseClass) throws IOException {
|
||||
String body = jsonMapper.writeValueAsString(request);
|
||||
SignedRequest signed = sign(action, body);
|
||||
RequestBody requestBody = RequestBody.create(JSON_MEDIA, body.getBytes(StandardCharsets.UTF_8));
|
||||
Request okRequest = new Request.Builder()
|
||||
.url(signed.url)
|
||||
.header("X-Content-Sha256", signed.xContentSha256)
|
||||
.header("X-Date", signed.xDate)
|
||||
.header("Content-Type", CONTENT_TYPE_JSON)
|
||||
.header("Authorization", signed.authorization)
|
||||
.post(requestBody)
|
||||
.build();
|
||||
try (Response response = httpClient.newCall(okRequest).execute()) {
|
||||
if (responseClass == null) {
|
||||
return null;
|
||||
}
|
||||
String respBody = response.body() != null ? response.body().string() : "";
|
||||
if (!response.isSuccessful()) {
|
||||
throw new IOException("HTTP " + response.code() + ": " + respBody);
|
||||
}
|
||||
return parseResult(respBody, responseClass);
|
||||
}
|
||||
}
|
||||
|
||||
private <T> T parseResult(String body, Class<T> resultType) throws IOException {
|
||||
JsonNode root = jsonMapper.readTree(body);
|
||||
JsonNode result = root.get("Result");
|
||||
if (result != null && !result.isNull()) {
|
||||
return jsonMapper.treeToValue(result, resultType);
|
||||
}
|
||||
return jsonMapper.readValue(body, resultType);
|
||||
}
|
||||
|
||||
private SignedRequest sign(String action, String body) throws IOException {
|
||||
ZonedDateTime nowUtc = ZonedDateTime.now(ZoneOffset.UTC);
|
||||
String xDate = nowUtc.format(DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmss'Z'"));
|
||||
String shortDate = xDate.substring(0, 8);
|
||||
String xContentSha256 = sha256Hex(body == null ? "" : body);
|
||||
|
||||
Map<String, Object> query = new TreeMap<>();
|
||||
query.put("Action", action);
|
||||
query.put("Version", VERSION);
|
||||
String canonicalQuery = canonicalQueryString(query);
|
||||
|
||||
String canonicalHeaders = String.join("\n",
|
||||
"content-type:" + CONTENT_TYPE_JSON,
|
||||
"host:" + controlApiHost,
|
||||
"x-content-sha256:" + xContentSha256,
|
||||
"x-date:" + xDate);
|
||||
|
||||
String canonicalRequest = String.join("\n",
|
||||
METHOD_POST.toUpperCase(),
|
||||
PATH_ROOT,
|
||||
canonicalQuery,
|
||||
canonicalHeaders,
|
||||
"",
|
||||
SIGNED_HEADERS,
|
||||
xContentSha256);
|
||||
|
||||
String hashedCanonical = sha256Hex(canonicalRequest);
|
||||
String credentialScope = shortDate + "/" + region + "/" + SERVICE_ARK + "/request";
|
||||
String stringToSign = String.join("\n", "HMAC-SHA256", xDate, credentialScope, hashedCanonical);
|
||||
|
||||
byte[] kDate = hmac256(secretAccessKey.getBytes(StandardCharsets.UTF_8), shortDate);
|
||||
byte[] kRegion = hmac256(kDate, region);
|
||||
byte[] kService = hmac256(kRegion, SERVICE_ARK);
|
||||
byte[] kSigning = hmac256(kService, "request");
|
||||
String signature = toHex(hmac256(kSigning, stringToSign));
|
||||
|
||||
String authorization = "HMAC-SHA256 Credential="
|
||||
+ accessKeyId + "/" + credentialScope
|
||||
+ ", SignedHeaders=" + SIGNED_HEADERS
|
||||
+ ", Signature=" + signature;
|
||||
|
||||
HttpUrl url = HttpUrl.parse("https://" + controlApiHost + "/?" + canonicalQuery);
|
||||
if (url == null) {
|
||||
throw new IOException("invalid control API URL");
|
||||
}
|
||||
return new SignedRequest(url, xContentSha256, xDate, authorization);
|
||||
}
|
||||
|
||||
private static String esc(String s) {
|
||||
if (s == null) {
|
||||
return "";
|
||||
}
|
||||
return s.replace("\\", "\\\\").replace("\"", "\\\"");
|
||||
}
|
||||
|
||||
private static String canonicalQueryString(Map<String, Object> params) throws IOException {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (String key : new TreeMap<>(params).keySet()) {
|
||||
Object val = params.get(key);
|
||||
if (val instanceof List) {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Object> list = (List<Object>) val;
|
||||
for (Object item : list) {
|
||||
sb.append(encode(key)).append("=").append(encode(String.valueOf(item))).append("&");
|
||||
}
|
||||
} else {
|
||||
sb.append(encode(key)).append("=").append(encode(String.valueOf(val))).append("&");
|
||||
}
|
||||
}
|
||||
if (sb.length() == 0) {
|
||||
return "";
|
||||
}
|
||||
return sb.substring(0, sb.length() - 1).replace("+", "%20");
|
||||
}
|
||||
|
||||
private static String encode(String raw) throws IOException {
|
||||
return URLEncoder.encode(raw, StandardCharsets.UTF_8.name()).replace("+", "%20");
|
||||
}
|
||||
|
||||
private static String sha256Hex(String content) throws IOException {
|
||||
try {
|
||||
MessageDigest md = MessageDigest.getInstance("SHA-256");
|
||||
return toHex(md.digest(content.getBytes(StandardCharsets.UTF_8)));
|
||||
} catch (Exception e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] hmac256(byte[] key, String data) throws IOException {
|
||||
try {
|
||||
Mac mac = Mac.getInstance("HmacSHA256");
|
||||
mac.init(new SecretKeySpec(key, "HmacSHA256"));
|
||||
return mac.doFinal(data.getBytes(StandardCharsets.UTF_8));
|
||||
} catch (Exception e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static String toHex(byte[] bytes) {
|
||||
StringBuilder sb = new StringBuilder(bytes.length * 2);
|
||||
for (byte b : bytes) {
|
||||
sb.append(String.format("%02x", b));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static final class SignedRequest {
|
||||
final HttpUrl url;
|
||||
final String xContentSha256;
|
||||
final String xDate;
|
||||
final String authorization;
|
||||
|
||||
SignedRequest(HttpUrl url, String xContentSha256, String xDate, String authorization) {
|
||||
this.url = url;
|
||||
this.xContentSha256 = xContentSha256;
|
||||
this.xDate = xDate;
|
||||
this.authorization = authorization;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -11,20 +11,21 @@ import com.ruoyi.common.core.response.asset.ListAssetsGroupResponse;
|
|||
import com.ruoyi.common.core.response.asset.UpdateAssetGroupResponse;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.IOException;
|
||||
|
||||
@Service
|
||||
public class ByteAssetGroupService extends BaseByteApiService implements IByteAssetGroupService {
|
||||
|
||||
private static final String LIST_ASSET_GROUPS_URL = "/open/ListAssetGroups";
|
||||
private static final String CREATE_ASSET_GROUP_URL = "/open/CreateAssetGroup";
|
||||
private static final String GET_ASSET_GROUP_URL = "/open/GetAssetGroup";
|
||||
private static final String UPDATE_ASSET_GROUP_URL = "/open/UpdateAssetGroup";
|
||||
private static final String ACTION_LIST_ASSET_GROUPS = "ListAssetGroups";
|
||||
private static final String ACTION_CREATE_ASSET_GROUP = "CreateAssetGroup";
|
||||
private static final String ACTION_GET_ASSET_GROUP = "GetAssetGroup";
|
||||
private static final String ACTION_UPDATE_ASSET_GROUP = "UpdateAssetGroup";
|
||||
|
||||
@Override
|
||||
public ListAssetsGroupResponse listAssetGroups(ListAssetsGroupRequest request) throws IOException {
|
||||
request.setProjectName(getUserProject());
|
||||
return httpExecute(LIST_ASSET_GROUPS_URL, request, ListAssetsGroupResponse.class);
|
||||
return callApi(ACTION_LIST_ASSET_GROUPS, request, ListAssetsGroupResponse.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -32,18 +33,18 @@ public class ByteAssetGroupService extends BaseByteApiService implements IByteAs
|
|||
// 固定值
|
||||
request.setGroupType("AIGC");
|
||||
request.setProjectName(getUserProject());
|
||||
return httpExecute(CREATE_ASSET_GROUP_URL, request, CreateAssetGroupResponse.class);
|
||||
return callApi(ACTION_CREATE_ASSET_GROUP, request, CreateAssetGroupResponse.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GetAssetGroupResponse getAssetGroup(GetAssetGroupRequest request) throws IOException {
|
||||
request.setProjectName(getUserProject());
|
||||
return httpExecute(GET_ASSET_GROUP_URL, request, GetAssetGroupResponse.class);
|
||||
return callApi(ACTION_GET_ASSET_GROUP, request, GetAssetGroupResponse.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UpdateAssetGroupResponse updateAssetGroup(UpdateAssetGroupRequest request) throws IOException {
|
||||
request.setProjectName(getUserProject());
|
||||
return httpExecute(UPDATE_ASSET_GROUP_URL, request, UpdateAssetGroupResponse.class);
|
||||
return callApi(ACTION_UPDATE_ASSET_GROUP, request, UpdateAssetGroupResponse.class);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import lombok.RequiredArgsConstructor;
|
|||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.IOException;
|
||||
|
||||
@Service
|
||||
|
|
@ -24,11 +25,11 @@ public class ByteAssetService extends BaseByteApiService implements IByteAssetSe
|
|||
|
||||
private final TencentCosUtil tencentCosUtil;
|
||||
|
||||
private static final String CREATE_ASSET_URL = "/open/CreateAsset";
|
||||
private static final String LIST_ASSETS_URL = "/open/ListAssets";
|
||||
private static final String GET_ASSET_URL = "/open/GetAsset";
|
||||
private static final String UPDATE_ASSET_URL = "/open/UpdateAsset";
|
||||
private static final String DELETE_ASSET_URL = "/open/DeleteAsset";
|
||||
private static final String ACTION_CREATE_ASSET = "CreateAsset";
|
||||
private static final String ACTION_LIST_ASSETS = "ListAssets";
|
||||
private static final String ACTION_GET_ASSET = "GetAsset";
|
||||
private static final String ACTION_UPDATE_ASSET = "UpdateAsset";
|
||||
private static final String ACTION_DELETE_ASSET = "DeleteAsset";
|
||||
|
||||
@Override
|
||||
public CreateAssetResponse createAsset(MultipartFile file, String groupId, String assetType, String name, String projectName) throws Exception {
|
||||
|
|
@ -45,30 +46,30 @@ public class ByteAssetService extends BaseByteApiService implements IByteAssetSe
|
|||
request.setName(name);
|
||||
request.setAssetType(assetType);
|
||||
request.setProjectName(getUserProject());
|
||||
return httpExecute(CREATE_ASSET_URL, request, CreateAssetResponse.class);
|
||||
return callApi(ACTION_CREATE_ASSET, request, CreateAssetResponse.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListAssetsResponse listAssets(ListAssetsRequest request) throws IOException {
|
||||
request.setProjectName(getUserProject());
|
||||
return httpExecute(LIST_ASSETS_URL, request, ListAssetsResponse.class);
|
||||
return callApi(ACTION_LIST_ASSETS, request, ListAssetsResponse.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GetAssetResponse getAsset(GetAssetRequest request) throws IOException {
|
||||
request.setProjectName(getUserProject());
|
||||
return httpExecute(GET_ASSET_URL, request, GetAssetResponse.class);
|
||||
return callApi(ACTION_GET_ASSET, request, GetAssetResponse.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UpdateAssetResponse updateAsset(UpdateAssetRequest request) throws IOException {
|
||||
request.setProjectName(getUserProject());
|
||||
return httpExecute(UPDATE_ASSET_URL, request, UpdateAssetResponse.class);
|
||||
return callApi(ACTION_UPDATE_ASSET, request, UpdateAssetResponse.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteAsset(DeleteAssetRequest request) throws IOException {
|
||||
request.setProjectName(getUserProject());
|
||||
httpExecuteNoContent(DELETE_ASSET_URL, request);
|
||||
callApi(ACTION_DELETE_ASSET, request, null);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
</select>
|
||||
|
||||
<select id="selectDeptById" parameterType="Long" resultMap="SysDeptResult">
|
||||
select d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.phone, d.email, d.byte_api_key, d.status,
|
||||
select d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.phone, d.email, d.byte_api_key, d.status, d.project,
|
||||
(select dept_name from sys_dept where dept_id = d.parent_id) parent_name
|
||||
from sys_dept d
|
||||
where d.dept_id = #{deptId}
|
||||
|
|
|
|||
Loading…
Reference in New Issue