删除无用
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 124 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 245 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 137 KiB |
-563
@@ -1,563 +0,0 @@
|
||||
$s = class {
|
||||
constructor() {
|
||||
gl(this, "root_url", "https://www.cloudtentacles.com");
|
||||
gl(this, "cache", new Map)
|
||||
}
|
||||
static getInstance() {
|
||||
return $s.instance || ($s.instance = new $s)
|
||||
}
|
||||
PemToArrayBuffer(t) {
|
||||
const r = t.split(`
|
||||
`).filter(s => s.trim() && !s.includes("---")).join("")
|
||||
, a = window.atob(r)
|
||||
, o = new Uint8Array(a.length);
|
||||
for (let s = 0; s < a.length; s++)
|
||||
o[s] = a.charCodeAt(s);
|
||||
return o.buffer
|
||||
}
|
||||
async encryptWithPublicKey(t) {
|
||||
for (let s in t)
|
||||
(t[s] === void 0 || t[s] === null || t[s] === "") && delete t[s];
|
||||
const n = Date.now()
|
||||
, r = Math.random().toString(16)
|
||||
, a = "ct-client"
|
||||
, o = JSON.stringify(Object.assign({
|
||||
t: n,
|
||||
r,
|
||||
s: a
|
||||
}, t));
|
||||
try {
|
||||
if (window.crypto && window.crypto.subtle && window.crypto.subtle.importKey) {
|
||||
const i = await window.crypto.subtle.importKey("spki", this.PemToArrayBuffer($s.PublicKey), {
|
||||
name: "RSA-OAEP",
|
||||
hash: {
|
||||
name: "SHA-256"
|
||||
}
|
||||
}, !0, ["encrypt"])
|
||||
, u = new TextEncoder().encode(o)
|
||||
, c = await window.crypto.subtle.encrypt({
|
||||
name: "RSA-OAEP"
|
||||
}, i, u)
|
||||
, f = new Uint8Array(c);
|
||||
let p = "";
|
||||
for (let h = 0; h < f.byteLength; h++)
|
||||
p += String.fromCharCode(f[h]);
|
||||
return {
|
||||
covert: window.btoa(p),
|
||||
t: n,
|
||||
r
|
||||
}
|
||||
}
|
||||
console.warn("\u5F53\u524D\u5904\u4E8E\u975E\u5B89\u5168\u73AF\u5883\u6216\u6D4F\u89C8\u5668\u4E0D\u652F\u6301 WebCrypto\uFF0C\u5DF2\u56DE\u9000\u5230 forge \u52A0\u5BC6");
|
||||
const l = Td.pki.publicKeyFromPem($s.PublicKey).encrypt(o, "RSA-OAEP", {
|
||||
md: Td.md.sha256.create(),
|
||||
mgf1: {
|
||||
md: Td.md.sha256.create()
|
||||
}
|
||||
});
|
||||
return {
|
||||
covert: Td.util.encode64(l),
|
||||
t: n,
|
||||
r
|
||||
}
|
||||
} catch (s) {
|
||||
throw console.error("\u52A0\u5BC6\u5931\u8D25:", s),
|
||||
"\u52A0\u5BC6\u5904\u7406\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u6D4F\u89C8\u5668\u73AF\u5883"
|
||||
}
|
||||
}
|
||||
cacheCheck(t, n) {
|
||||
if (n > 0) {
|
||||
const r = this.cache.get(t);
|
||||
if (r && Date.now() - r.time <= n)
|
||||
return JSON.parse(JSON.stringify(r.value))
|
||||
}
|
||||
return null
|
||||
}
|
||||
parametersToKey(t, n) {
|
||||
let r = t;
|
||||
for (let a in n)
|
||||
a !== "token" && (r += `${a}:${n[a]}`);
|
||||
return r
|
||||
}
|
||||
async httpProto(t, n, r) {
|
||||
const a = this.parametersToKey(t, n)
|
||||
, o = this.cacheCheck(a, r.interval || 0);
|
||||
if (o)
|
||||
return o;
|
||||
const s = await B6({
|
||||
url: t,
|
||||
data: n,
|
||||
method: r.type
|
||||
})
|
||||
, {data: l, code: i, message: u, token: c} = s.data;
|
||||
switch (i) {
|
||||
case bu.AlreadyExpired:
|
||||
throw hs().setToken(""),
|
||||
ei.replace("/login"),
|
||||
"\u767B\u5F55\u5DF2\u8FC7\u671F";
|
||||
case bu.UpdateSuccess:
|
||||
hs().setToken(c);
|
||||
case bu.Success:
|
||||
return r.interval && r.interval > 0 && this.cache.set(a, {
|
||||
time: Date.now(),
|
||||
value: JSON.parse(JSON.stringify(l))
|
||||
}),
|
||||
l;
|
||||
case bu.Fail:
|
||||
throw u;
|
||||
default:
|
||||
throw "\u672A\u77E5\u9519\u8BEF"
|
||||
}
|
||||
}
|
||||
async https(t, n={}, r={}) {
|
||||
return await this.httpProto(t, n, Object.assign({}, $s.default_header, r))
|
||||
}
|
||||
async getVerifCode(t, n) {
|
||||
const r = await this.encryptWithPublicKey({
|
||||
account: t,
|
||||
phone: n
|
||||
});
|
||||
await this.https("/public/verif_code", r)
|
||||
}
|
||||
async logIn(t, n, r, a) {
|
||||
const o = await this.encryptWithPublicKey({
|
||||
account: t,
|
||||
password: cu(n),
|
||||
phone: r,
|
||||
code: a
|
||||
});
|
||||
return await this.https("/public/login", o)
|
||||
}
|
||||
async getUserInfo() {
|
||||
return await this.https("/user/info", {}, {
|
||||
load: !1
|
||||
})
|
||||
}
|
||||
async getAsset() {
|
||||
return await this.https("/user/get_asset", {}, {
|
||||
type: "GET",
|
||||
load: !1
|
||||
})
|
||||
}
|
||||
async getPermission() {
|
||||
return await this.https("/user/get_permission", {}, {
|
||||
type: "GET",
|
||||
load: !1
|
||||
})
|
||||
}
|
||||
async getRecordRange(t, n, r) {
|
||||
return await this.https("/record/range", {
|
||||
record_code: t,
|
||||
start_date: n,
|
||||
end_date: r
|
||||
}, {
|
||||
load: !1
|
||||
})
|
||||
}
|
||||
async getSkuList() {
|
||||
return await this.https("/sku/list", {}, {
|
||||
type: "GET",
|
||||
interval: 6e4
|
||||
})
|
||||
}
|
||||
async selectSkuList(t) {
|
||||
return await this.https("/sku/select_list", {
|
||||
id: t
|
||||
})
|
||||
}
|
||||
async getCategoryList() {
|
||||
return await this.https("/categories/get", {}, {
|
||||
type: "GET",
|
||||
interval: 6e4
|
||||
})
|
||||
}
|
||||
async getSubList() {
|
||||
return await this.https("/user/sub", {}, {
|
||||
type: "GET"
|
||||
})
|
||||
}
|
||||
async updatePwd(t, n) {
|
||||
const r = await this.encryptWithPublicKey({
|
||||
o_password: cu(t),
|
||||
n_password: cu(n)
|
||||
});
|
||||
return await this.https("/user/modify_pwd", r)
|
||||
}
|
||||
async giveAmount(t, n, r) {
|
||||
return await this.https("/user/give", {
|
||||
amount: t,
|
||||
sub_id: n,
|
||||
notes: r
|
||||
})
|
||||
}
|
||||
async giveSku(t, n, r, a) {
|
||||
return await this.https("/user/give_sku", {
|
||||
sku_id: t,
|
||||
sub_id: n,
|
||||
count: r,
|
||||
notes: a
|
||||
})
|
||||
}
|
||||
async recoveryAmount(t, n, r) {
|
||||
return await this.https("/user/recovery", {
|
||||
amount: t,
|
||||
sub_id: n,
|
||||
notes: r
|
||||
})
|
||||
}
|
||||
async getUserPreferentialPolicies() {
|
||||
return await this.https("/sku/user_pref_poli", {}, {
|
||||
type: "GET",
|
||||
interval: 6e4
|
||||
})
|
||||
}
|
||||
async buyGoods(t, n) {
|
||||
return await this.https("/sku/buy", {
|
||||
id: t,
|
||||
count: n
|
||||
})
|
||||
}
|
||||
async getKnapsack() {
|
||||
const t = await this.https("/user/get_knapsack", {}, {
|
||||
type: "GET"
|
||||
});
|
||||
return R8e().setKnapsackInfo(t),
|
||||
t
|
||||
}
|
||||
async use(t) {
|
||||
return await this.https("/sku/use", t)
|
||||
}
|
||||
async getIdleVirtualNumber(t) {
|
||||
return await this.https("/vn/list", {
|
||||
key: t
|
||||
})
|
||||
}
|
||||
async getVirtualNumberBindUrl(t, n) {
|
||||
return await this.https("/vn/bind_url", {
|
||||
id: t,
|
||||
key: n
|
||||
})
|
||||
}
|
||||
async getVirtualNumberGameUserName(t, n) {
|
||||
return await this.https("/vn/bind_info", [{
|
||||
id: t,
|
||||
key: n
|
||||
}])
|
||||
}
|
||||
async inquiryUID(t, n) {
|
||||
return await this.https("/vn/inquiry", {
|
||||
uid: t,
|
||||
key: n
|
||||
})
|
||||
}
|
||||
async applyVirtualNumber(t, n) {
|
||||
return await this.https("/vn/appoint", {
|
||||
key: t,
|
||||
phone: n
|
||||
})
|
||||
}
|
||||
async returnVirtualNumber(t, n) {
|
||||
return await this.https("/vn/back", {
|
||||
key: t,
|
||||
id: n
|
||||
})
|
||||
}
|
||||
async generateLoginCode(t, n) {
|
||||
return await this.https("/vn/generate_login_code", {
|
||||
key: t,
|
||||
id: n
|
||||
})
|
||||
}
|
||||
async verifyLoginCode(t, n, r) {
|
||||
return await this.https("/vn/verify_login_code", {
|
||||
key: t,
|
||||
id: n,
|
||||
code: r
|
||||
})
|
||||
}
|
||||
async vnVerifCode(t, n) {
|
||||
return await this.https("/public/vn_verif_code", {
|
||||
key: t,
|
||||
phone: n
|
||||
})
|
||||
}
|
||||
async getRecordList(t, n, r, a, o) {
|
||||
return await this.https("/record/paging", {
|
||||
record_code: t,
|
||||
page: n,
|
||||
size: r,
|
||||
start_date: a,
|
||||
end_date: o
|
||||
})
|
||||
}
|
||||
async sendEMailCode(t, n, r) {
|
||||
return await this.https("/vn/send_email_code", {
|
||||
id: t,
|
||||
key: n,
|
||||
uid: r
|
||||
})
|
||||
}
|
||||
async verifyEMailBindGame(t, n, r, a) {
|
||||
return await this.https("/vn/verify_email_code", {
|
||||
id: t,
|
||||
key: n,
|
||||
uid: r,
|
||||
code: a
|
||||
})
|
||||
}
|
||||
async direct_bind(t, n, r) {
|
||||
return await this.https("/vn/direct_bind", {
|
||||
id: t,
|
||||
key: n,
|
||||
uid: r
|
||||
})
|
||||
}
|
||||
async getUserAuthority(t) {
|
||||
return await this.https("/admin/get_user_permissions", {
|
||||
id: t
|
||||
})
|
||||
}
|
||||
async updateUserAuthority(t) {
|
||||
return await this.https("/admin/modify_user_permissions", t)
|
||||
}
|
||||
async modifyUser(t) {
|
||||
return await this.https("/admin/modify_user", t)
|
||||
}
|
||||
async getUserList() {
|
||||
return await this.https("/user/list", {}, {
|
||||
type: "GET"
|
||||
})
|
||||
}
|
||||
async getRelationshipList() {
|
||||
return await this.https("/relationship/list", {}, {
|
||||
type: "GET"
|
||||
})
|
||||
}
|
||||
async addRelationshipList(t, n) {
|
||||
return await this.https("/relationship/add", {
|
||||
user_id: t,
|
||||
sub_id: n
|
||||
})
|
||||
}
|
||||
async delRelationshipList(t, n) {
|
||||
return await this.https("/relationship/del", {
|
||||
user_id: t,
|
||||
sub_id: n
|
||||
})
|
||||
}
|
||||
async editRelationship(t, n) {
|
||||
return await this.https("/relationship/modify", {
|
||||
id: t,
|
||||
open_repay: n
|
||||
})
|
||||
}
|
||||
async getCategoryAllList() {
|
||||
return await this.https("/admin/get_categories_list", {}, {
|
||||
type: "GET"
|
||||
})
|
||||
}
|
||||
async getSkuAllList() {
|
||||
return await this.https("/admin/get_sku_list", {}, {
|
||||
type: "GET"
|
||||
})
|
||||
}
|
||||
async getPreferentialPoliciesAll() {
|
||||
return await this.https("/preferential/list", {}, {
|
||||
type: "GET"
|
||||
})
|
||||
}
|
||||
async getUserPreferentialPoliciesToID(t) {
|
||||
return await this.https("/preferential/get_relationship", {
|
||||
id: t
|
||||
})
|
||||
}
|
||||
async createUser(t) {
|
||||
const n = cu(t.password);
|
||||
return await this.https("/admin/creator_user", Object.assign(t, {
|
||||
password: n
|
||||
}))
|
||||
}
|
||||
async updateUserPassword(t, n) {
|
||||
const r = await this.encryptWithPublicKey({
|
||||
account: t,
|
||||
n_password: cu(n)
|
||||
});
|
||||
return await this.https("/admin/modify_pwd", r)
|
||||
}
|
||||
async updateUserStatus(t, n) {
|
||||
return await this.https("/admin/ban_user", {
|
||||
id: t,
|
||||
expire: n
|
||||
})
|
||||
}
|
||||
async createSku(t) {
|
||||
return await this.https("/admin/add_sku", t)
|
||||
}
|
||||
async createCategory(t) {
|
||||
return await this.https("/admin/add_category", t)
|
||||
}
|
||||
async createPreferentialPolicies(t) {
|
||||
return await this.https("/preferential/add", t)
|
||||
}
|
||||
async addUserPreferentialPolicies(t, n, r, a) {
|
||||
return await this.https("/preferential/add_relationship", {
|
||||
p_id: t,
|
||||
u_id: n,
|
||||
show_time: r,
|
||||
hide_time: a
|
||||
})
|
||||
}
|
||||
async addRelationshipLow(t) {
|
||||
return await this.https("/preferential/add_relationship_low", t)
|
||||
}
|
||||
async batchRelationshipLow(t) {
|
||||
return await this.https("/preferential/batch_relationship_low", t)
|
||||
}
|
||||
async delUserPreferentialPolicies(t, n) {
|
||||
return await this.https("/preferential/del_Relationship", {
|
||||
p_id: t,
|
||||
u_id: n
|
||||
})
|
||||
}
|
||||
async updateCategory(t) {
|
||||
return await this.https("/admin/modify_category", t)
|
||||
}
|
||||
async updateSku(t) {
|
||||
return await this.https("/admin/modify_sku", t)
|
||||
}
|
||||
async updatePreferentialPolicies(t) {
|
||||
return await this.https("/preferential/modify", t)
|
||||
}
|
||||
async upsertCustom(t) {
|
||||
return await this.https("/record/edit_custom", t)
|
||||
}
|
||||
async delCustom(t) {
|
||||
return await this.https("/record/remove_custom", {
|
||||
id: t
|
||||
})
|
||||
}
|
||||
async subRangeRecord(t) {
|
||||
return await this.https("/record/sub_range", {
|
||||
ids: t
|
||||
})
|
||||
}
|
||||
async transaction_record() {
|
||||
return await this.https("/record/transaction_record")
|
||||
}
|
||||
async recipient_record() {
|
||||
return await this.https("/record/recipient_record")
|
||||
}
|
||||
async observerSalesRecords(t, n, r) {
|
||||
return await this.https("/observer/sales_records", {
|
||||
ids: t,
|
||||
start_date: n,
|
||||
end_date: r
|
||||
})
|
||||
}
|
||||
async observerTransactionRecord(t) {
|
||||
return await this.https("/observer/transaction_record", {
|
||||
ids: t
|
||||
})
|
||||
}
|
||||
async observerHoldConsume(t) {
|
||||
return await this.https("/observer/hold_consume", {
|
||||
ids: t
|
||||
})
|
||||
}
|
||||
async observerPaging(t, n, r, a, o, s) {
|
||||
return await this.https("/observer/paging", {
|
||||
ids: t,
|
||||
record_code: n,
|
||||
page: r,
|
||||
size: a,
|
||||
start_date: o,
|
||||
end_date: s
|
||||
})
|
||||
}
|
||||
async observerSub(t) {
|
||||
return await this.https("/observer/sub", {
|
||||
ids: t
|
||||
})
|
||||
}
|
||||
async getYeZiList() {
|
||||
return await this.https("/utils/list")
|
||||
}
|
||||
async applyYeZiPhone(t) {
|
||||
return await this.https("/utils/apply", {
|
||||
id: t
|
||||
})
|
||||
}
|
||||
async releaseYeZiPhone(t) {
|
||||
return await this.https("/utils/release", {
|
||||
phone: t
|
||||
})
|
||||
}
|
||||
async messageYeZiPhone(t) {
|
||||
return await this.https("/utils/message", {
|
||||
phone: t
|
||||
})
|
||||
}
|
||||
async getProjectList() {
|
||||
return await this.https("/utils/project_list")
|
||||
}
|
||||
async getHaoZhuList() {
|
||||
return await this.https("/utils/list_hz")
|
||||
}
|
||||
async applyHaoZhuPhone(t) {
|
||||
return await this.https("/utils/apply_hz", {
|
||||
id: t + ""
|
||||
})
|
||||
}
|
||||
async releaseHaoZhuPhone(t) {
|
||||
return await this.https("/utils/release_hz", {
|
||||
phone: t
|
||||
})
|
||||
}
|
||||
async messageHaoZhuPhone(t) {
|
||||
return await this.https("/utils/message_hz", {
|
||||
phone: t
|
||||
})
|
||||
}
|
||||
async getHaoZhuProjectList() {
|
||||
return await this.https("/utils/project_list_hz")
|
||||
}
|
||||
async returnOfGoods(t) {
|
||||
return await this.https("/admin/return_of_goods", t)
|
||||
}
|
||||
async customRepay(t) {
|
||||
return await this.https("/admin/custom_repay", t)
|
||||
}
|
||||
async upsertSKU(t) {
|
||||
return await this.https("/sku/upsert", {
|
||||
data: t
|
||||
})
|
||||
}
|
||||
async upsertCDK(t) {
|
||||
await this.https("/admin/upsert_cdk", {
|
||||
data: t
|
||||
})
|
||||
}
|
||||
async getCDKList(t, n) {
|
||||
return await this.https("/admin/cdk", {
|
||||
page: t,
|
||||
size: n
|
||||
})
|
||||
}
|
||||
}
|
||||
;
|
||||
let Sr = $s;
|
||||
gl(Sr, "instance"),
|
||||
gl(Sr, "default_header", {
|
||||
type: "POST",
|
||||
interval: 0
|
||||
}),
|
||||
gl(Sr, "PublicKey", `-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsSzjk+9st2f8IpYqYaM5
|
||||
F7K27ZR2IvzxTr2w4zgZAS2+BRdgMvXUOITdFQT+ytYF/r3pIgTkL7MF9UQuylmb
|
||||
S57DiqGBLNBS7FzKyYzWTOc9yYA3+KrarbvpUn/Bm3UK+KKB17viPy+0pnNAHysJ
|
||||
pzqadmAtQhI1ZDujJ2sW+FkV/pC8KIFahiyPIHjncy1ZG/BbRF3BDhvDcr6O7scO
|
||||
GsHstGf9XsZBIITS5LYmlai7OdY4ZIVxUtQbfWzibihO+YDJJzFgt47drX0Ajo85
|
||||
PfQTPNA++KsXtwRX9M6Re3vkTDRsutIIWKtj8jqhUbbYS3vzS8GJnAWavUFVkR15
|
||||
0wIDAQAB
|
||||
-----END PUBLIC KEY-----`),
|
||||
gl(Sr, "LocalCacheKey", "YCJ-LocalCacheKey");
|
||||
-354
@@ -1,354 +0,0 @@
|
||||
# 前后端现状分析
|
||||
|
||||
## 当前结论
|
||||
|
||||
整体架构方向没有跑偏。
|
||||
|
||||
- 后端主干仍然是 `routes -> services -> repositories`
|
||||
- 前端后台管理也已经从“单页巨石”逐步转成“薄页面 + composable + 子组件 + 分领域 service”
|
||||
|
||||
和最初相比,当前最重要的变化有两点:
|
||||
|
||||
1. 平台配置这条前后端竖线,第一阶段拆分已经基本完成
|
||||
2. 真正还需要优先处理的,已经转向后端运行时巨石模块
|
||||
|
||||
所以现在不适合再把精力平均分散到全项目,而应该把已经拆开的区域收口,把还没拆开的大文件优先解决。
|
||||
|
||||
## 已完成
|
||||
|
||||
### 1. 平台配置页前端拆分
|
||||
|
||||
这部分已经不再是最初判断里的“一个页面承载四套完整平台流”。
|
||||
|
||||
- `8e1a4be` 拆分前端后台管理 API 客户端
|
||||
- `apps/frontend/src/services/admin.ts` 已改成聚合入口
|
||||
- 后台 API 已按领域拆到 `apps/frontend/src/services/admin/`
|
||||
|
||||
- `dff7da7` 拆分平台配置页脚本逻辑
|
||||
- `apps/frontend/src/views/admin/AdminPlatformShopsView.vue` 的平台状态和行为已经拆到 composable
|
||||
- 已有:
|
||||
- `useAdminAgisoPlatform.ts`
|
||||
- `useAdminNinetyonePlatform.ts`
|
||||
- `useAdminKuaishouEticketPlatform.ts`
|
||||
- `useAdminCloudtentaclesPlatform.ts`
|
||||
|
||||
- `4650c3e` 抽离平台配置页共享样式
|
||||
- 共享样式已统一收口到 `apps/frontend/src/styles/admin-platform-shops.css`
|
||||
|
||||
- `60c2d91`、`254a031`、`8f6a72f` 完成平台区块拆分
|
||||
- 四个平台区块已经分别下沉为独立组件:
|
||||
- `AdminPlatformAgisoSection.vue`
|
||||
- `AdminPlatformNinetyoneSection.vue`
|
||||
- `AdminPlatformKuaishouEticketSection.vue`
|
||||
- `AdminPlatformCloudtentaclesSection.vue`
|
||||
|
||||
- `58f25fa` 抽离平台配置结果信息卡片
|
||||
- 新增 `AdminResultCard.vue`
|
||||
- `快手核销` / `cloudtentacles` 的重复结果卡片已统一
|
||||
|
||||
### 2. `session-proof.js` 已完成第一轮拆分
|
||||
|
||||
这条线已经不是“下一步待开始”,而是已经落地完成。
|
||||
|
||||
当前 `apps/backend/src/services/session/` 下已经拆出:
|
||||
|
||||
- `session-proof-mode.js`
|
||||
- `session-proof-paths.js`
|
||||
- `session-proof-result-writer.js`
|
||||
- `session-proof-beijing-time.js`
|
||||
- `session-proof-renderer.js`
|
||||
- `session-proof-html.js`
|
||||
- `session-proof-constants.js`
|
||||
|
||||
`apps/backend/src/services/session/session-proof.js` 现在已经收敛成门面层,文件体量约 `145` 行,风险比之前明显下降。
|
||||
|
||||
### 3. 后台平台配置服务已完成按平台拆分
|
||||
|
||||
这条线也已经不是最初的 `admin-platform-config-service.js` 巨石形态了。
|
||||
|
||||
最近这波提交已经完成:
|
||||
|
||||
- `d629bc9` 整理后台平台配置服务目录结构
|
||||
- `d11879f` 下沉后台履约规则校验编排逻辑
|
||||
- `8c9d487` 下沉后台云触手会话结果组装逻辑
|
||||
- `dad646b` 抽离后台平台配置写入归一化逻辑
|
||||
- `3a7c311` 按平台拆分后台平台配置服务
|
||||
|
||||
当前 `apps/backend/src/services/admin/platform-config/` 已形成按职责拆分的目录:
|
||||
|
||||
- `service.js`
|
||||
- 只保留统一导出入口
|
||||
- `agiso-service.js`
|
||||
- `ninetyone-service.js`
|
||||
- `kuaishou-eticket-service.js`
|
||||
- `cloudtentacles-service.js`
|
||||
- `fulfillment-bindings-service.js`
|
||||
- `kuaishou-cloud-fulfillment-service.js`
|
||||
- 配套 helper / mapper / validation / test 文件
|
||||
|
||||
其中 `service.js` 已经从原来的 600+ 行缩到 53 行,平台配置后端竖线的第一阶段拆分已经完成。
|
||||
|
||||
## 已过时的判断
|
||||
|
||||
下面这些判断不应该再按旧版本理解。
|
||||
|
||||
### 1. `AdminPlatformShopsView.vue` 是前端第一优先级
|
||||
|
||||
这个判断已经过时。
|
||||
|
||||
原因:
|
||||
|
||||
- 四个平台模板已经拆开
|
||||
- 主要行为已经下沉到 composable
|
||||
- 剩余问题更多是收口、少量复用和测试,而不是继续大拆页面
|
||||
|
||||
新判断:
|
||||
|
||||
- 这条线仍可继续小步优化
|
||||
- 但优先级已经明显低于后端 `session.js`、`claim-session-service.js`、`admin-write-service.js`
|
||||
|
||||
### 2. `admin-platform-config-service.js` 是后端当前主战场
|
||||
|
||||
这个判断也已经过时。
|
||||
|
||||
原因:
|
||||
|
||||
- 这条线已经迁到 `apps/backend/src/services/admin/platform-config/`
|
||||
- 统一入口 `service.js` 已经很薄
|
||||
- 大部分公共逻辑也已经拆到 `context.js`、`writes.js`、`validation.js`、`mappers.js`、`fulfillment.js` 等模块
|
||||
|
||||
新判断:
|
||||
|
||||
- 平台配置后端已经从“继续大拆”阶段,进入“适度收口 + 补测试 + 控制 cloudtentacles 继续膨胀”阶段
|
||||
|
||||
### 3. 下一刀应该从 `session-proof.js` 开始
|
||||
|
||||
这个判断也已过时。
|
||||
|
||||
原因:
|
||||
|
||||
- `session-proof.js` 第一轮拆分已经完成
|
||||
- 现在更该处理的是仍然明显偏大的运行时主线文件
|
||||
|
||||
## 仍然优先拆分 / 优先优化
|
||||
|
||||
### 1. `apps/backend/src/services/admin/admin-write-service.js`
|
||||
|
||||
这是现在最胖、最值得优先处理的大文件之一,当前约 `1710` 行。
|
||||
|
||||
它更像“后台万能动作总线”,跨域过多:
|
||||
|
||||
- 库存
|
||||
- claim
|
||||
- webhook
|
||||
- cloudtentacles
|
||||
- 快手核销
|
||||
- 腾讯 session
|
||||
- task 手工动作
|
||||
|
||||
建议方向:
|
||||
|
||||
- `admin-inventory-write`
|
||||
- `admin-task-actions`
|
||||
- `admin-claim-actions`
|
||||
- `admin-webhook-actions`
|
||||
- `admin-manual-redeem-actions`
|
||||
|
||||
如果继续放大,这类文件会成为后续所有后台动作改动的冲突中心。
|
||||
|
||||
### 2. `apps/backend/src/services/claim/claim-session-service.js`
|
||||
|
||||
当前约 `1255` 行,仍然是后端运行时第二优先级。
|
||||
|
||||
问题主要在:
|
||||
|
||||
- 管理态 / 用户态创建逻辑平行复制
|
||||
- claim token、浏览器会话、任务同步、库存释放、自动发货收尾混在一起
|
||||
|
||||
建议方向:
|
||||
|
||||
- `claim-context`
|
||||
- `claim-session-lifecycle`
|
||||
- `claim-task-sync`
|
||||
- `claim-fulfillment-finalizer`
|
||||
|
||||
这条线和下单、兑换、任务状态强相关,越晚拆越难动。
|
||||
|
||||
### 3. `apps/backend/src/services/session/session.js`
|
||||
|
||||
当前约 `566` 行,虽然比前两项小,但仍然是高风险运行时核心。
|
||||
|
||||
它同时承担:
|
||||
|
||||
- Playwright 浏览器生命周期
|
||||
- 会话内存状态
|
||||
- 二维码抓取
|
||||
- 登录态判断
|
||||
- 角色信息同步
|
||||
- 兑换执行
|
||||
- 自动关闭
|
||||
|
||||
好消息是:`session-proof.js`、`session-qq.js`、`session-wx.js`、`session-redeem.js`、`session-page.js`、`session-state.js` 等子模块已经存在,说明这条线并不是没拆过。
|
||||
|
||||
当前更合适的目标不是“从零拆分”,而是继续把 `session.js` 剩余的编排职责下沉,最终把它收敛成真正的 orchestrator。
|
||||
|
||||
### 4. 平台配置竖线的收口项
|
||||
|
||||
虽然平台配置的大拆分已经完成,但这条线还有一些第二优先级问题:
|
||||
|
||||
- `apps/backend/src/services/admin/platform-config/cloudtentacles-service.js`
|
||||
- 当前约 `250` 行
|
||||
- 已经比原来小很多,但仍同时承载登录、会话校验、商品目录、虚拟号调试、完整 flow 调试
|
||||
- 如果后面 cloudtentacles 功能继续增加,可以进一步拆成:
|
||||
- `cloudtentacles-auth-service`
|
||||
- `cloudtentacles-catalog-service`
|
||||
- `cloudtentacles-virtual-number-service`
|
||||
|
||||
- `apps/frontend/src/views/admin/AdminPlatformShopsView.vue`
|
||||
- 当前约 `402` 行
|
||||
- 已经不是巨石模板问题,剩下主要是 overview 卡片和页面级加载编排还在父层
|
||||
|
||||
- `apps/frontend/src/services/admin/platform-config.ts`
|
||||
- 当前约 `373` 行
|
||||
- 还可以进一步按平台拆成更细的 `services/admin/platform-config/` 子文件
|
||||
- 但这属于可做项,不是最高优先级
|
||||
|
||||
### 5. `apps/backend/src/services/webhook/webhook-service.js`
|
||||
|
||||
这条线仍然适合改成流水线。
|
||||
|
||||
建议拆成:
|
||||
|
||||
- `webhook-parse`
|
||||
- `webhook-verify`
|
||||
- `webhook-ignore-policy`
|
||||
- `webhook-enrich`
|
||||
- `webhook-process`
|
||||
- `webhook-replay`
|
||||
|
||||
它不是眼下最大的文件,但属于典型“流程很多、分支很多、回归成本高”的区域。
|
||||
|
||||
### 6. `apps/backend/src/config/runtime.js`
|
||||
|
||||
仍需要“配置声明化”优化。
|
||||
|
||||
目前问题不是功能错,而是长期可维护性差:
|
||||
|
||||
- env override 越堆越长
|
||||
- 新平台配置接入成本越来越高
|
||||
- 难测、难查、难对照
|
||||
|
||||
建议后期改成:
|
||||
|
||||
- 配置 schema
|
||||
- env 映射表
|
||||
- 默认值与来源声明
|
||||
|
||||
## 质量防线现状
|
||||
|
||||
这个判断仍然成立,而且现在重要性更高。
|
||||
|
||||
当前风险:
|
||||
|
||||
- 后端高风险模块仍然存在 `@ts-nocheck`
|
||||
- 平台配置页和后台平台配置服务最近连续经历了多轮重构
|
||||
- 当前主要还是依赖 `typecheck + test + build` 防回归
|
||||
|
||||
这能挡住:
|
||||
|
||||
- 类型问题
|
||||
- 引用错误
|
||||
- 明显的构建错误
|
||||
- 一部分纯函数退化
|
||||
|
||||
但仍挡不住:
|
||||
|
||||
- 页面条件渲染退化
|
||||
- 管理台复杂交互异常
|
||||
- 任务状态流转串线
|
||||
- 外部平台调试链路断裂
|
||||
|
||||
建议至少补两层最小防线:
|
||||
|
||||
1. 前端
|
||||
- 平台配置页基础渲染 smoke 测试
|
||||
- 关键按钮存在性 / 条件渲染测试
|
||||
|
||||
2. 后端
|
||||
- `claim-session-service.js` 关键状态流转测试
|
||||
- `admin-write-service.js` 高风险动作 smoke 测试
|
||||
|
||||
## 暂时不用急着拆
|
||||
|
||||
### 腾讯浏览器前端链路
|
||||
|
||||
- `TencentBrowserView.vue`
|
||||
- `session-qq.js`
|
||||
- `session-wx.js`
|
||||
|
||||
这些区域当前模式相对健康,仍然可以作为其它模块拆分时的参考。
|
||||
|
||||
## 下一步计划
|
||||
|
||||
### 已完成阶段
|
||||
|
||||
1. 拆分前端后台管理 API 客户端
|
||||
2. 拆分平台配置页脚本逻辑
|
||||
3. 抽离平台配置页共享样式
|
||||
4. 拆分 Agiso / 91卡券 / 快手核销 / cloudtentacles 四个平台区块
|
||||
5. 抽离结果信息卡片
|
||||
6. 拆分 `session-proof.js`
|
||||
7. 重构后台 `platform-config` 目录并完成按平台拆分
|
||||
|
||||
### 下一阶段建议
|
||||
|
||||
#### Phase 1:先处理 `admin-write-service.js`
|
||||
|
||||
目标:
|
||||
|
||||
- 优先拆掉当前最大的后台动作总线
|
||||
- 先按职责切片,不改路由公开接口
|
||||
- 把高频变更区域从一个文件拆成多个动作模块
|
||||
|
||||
建议步骤:
|
||||
|
||||
1. 先按动作域分段
|
||||
- inventory
|
||||
- task
|
||||
- claim
|
||||
- webhook
|
||||
- redeem
|
||||
|
||||
2. 把纯组装和副作用编排分开
|
||||
|
||||
3. 保留 `admin-write-service.js` 作为门面导出层
|
||||
|
||||
#### Phase 2:再处理 `claim-session-service.js`
|
||||
|
||||
前提:
|
||||
|
||||
- `admin-write-service.js` 的动作边界更清楚
|
||||
- claim / task / inventory 之间的依赖关系已经更容易梳理
|
||||
|
||||
#### Phase 3:继续收口 `session.js`
|
||||
|
||||
重点:
|
||||
|
||||
- 不是重写
|
||||
- 而是继续把剩余运行时编排下沉到已有 session 子模块
|
||||
|
||||
#### Phase 4:补平台配置页与后台动作的最小 smoke 测试
|
||||
|
||||
这一步不一定最先做,但应该尽早插入,避免后续继续重构时缺乏防线。
|
||||
|
||||
## 当前建议
|
||||
|
||||
平台配置这条前后端竖线现在可以先收口,不建议继续把它当主战场。
|
||||
|
||||
更合适的下一步是:
|
||||
|
||||
1. 开始拆 `apps/backend/src/services/admin/admin-write-service.js`
|
||||
2. 同步梳理 `claim-session-service.js` 的职责边界
|
||||
3. 尽快补一层最小 smoke 测试
|
||||
|
||||
如果继续执行,下一刀最值得从 `admin-write-service.js` 开始。
|
||||
Reference in New Issue
Block a user