ERP前端代码更新 2026-04-06
This commit is contained in:
parent
9f64a4d6f4
commit
118b547820
0
.env.development
Normal file → Executable file
0
.env.development
Normal file → Executable file
0
.env.production
Normal file → Executable file
0
.env.production
Normal file → Executable file
0
.gitignore
vendored
Normal file → Executable file
0
.gitignore
vendored
Normal file → Executable file
0
.vscode/extensions.json
vendored
Normal file → Executable file
0
.vscode/extensions.json
vendored
Normal file → Executable file
102
LOGIN_TESTING.md
102
LOGIN_TESTING.md
@ -1,102 +0,0 @@
|
|||||||
# 登录页面测试指南
|
|
||||||
|
|
||||||
## 🎯 测试账号(模拟模式)
|
|
||||||
|
|
||||||
当前登录页面支持以下测试账号(当 `VITE_USE_MOCK=true` 时):
|
|
||||||
|
|
||||||
| 账号 | 密码 | 角色 | 描述 |
|
|
||||||
|------|------|------|------|
|
|
||||||
| `admin@erp.com` | `password123` | `admin` | 系统管理员,拥有所有权限 |
|
|
||||||
| `user@erp.com` | `user123456` | `user` | 普通用户,基础权限 |
|
|
||||||
| `test@erp.com` | `test123456` | `test` | 测试用户,受限权限 |
|
|
||||||
|
|
||||||
## 🚀 如何使用
|
|
||||||
|
|
||||||
### 1. 启动开发服务器
|
|
||||||
```bash
|
|
||||||
npm run dev
|
|
||||||
# 或
|
|
||||||
yarn dev
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. 访问登录页面
|
|
||||||
打开浏览器访问:`http://localhost:5173/login`
|
|
||||||
|
|
||||||
### 3. 识别模拟模式
|
|
||||||
- **页面右上角**显示黄色"模拟模式"标签
|
|
||||||
- **页脚**显示可用的模拟账号
|
|
||||||
- **登录过程**为模拟延迟(800ms)
|
|
||||||
|
|
||||||
### 4. 登录测试
|
|
||||||
1. 选择"密码登录"方式
|
|
||||||
2. 输入任一测试账号和密码
|
|
||||||
3. 点击"登录"按钮
|
|
||||||
4. 成功后将跳转到首页 (`/`)
|
|
||||||
|
|
||||||
## ⚙️ 环境配置
|
|
||||||
|
|
||||||
### 启用/禁用模拟模式
|
|
||||||
在 `.env.development` 文件中:
|
|
||||||
```env
|
|
||||||
# 启用模拟登录(默认)
|
|
||||||
VITE_USE_MOCK=true
|
|
||||||
|
|
||||||
# 禁用模拟登录,使用真实API
|
|
||||||
VITE_USE_MOCK=false
|
|
||||||
```
|
|
||||||
|
|
||||||
### API配置
|
|
||||||
```env
|
|
||||||
# 后端API地址
|
|
||||||
VITE_API_BASE_URL=http://localhost:8080/api
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🔧 模拟登录实现细节
|
|
||||||
|
|
||||||
### 前端模拟逻辑
|
|
||||||
- **位置**: `src/views/Auth/LoginEnhanced.vue` 中的 `mockLogin()` 函数
|
|
||||||
- **验证**: 检查账号密码是否匹配预设测试账号
|
|
||||||
- **用户数据**: 生成模拟用户信息(ID、角色、权限等)
|
|
||||||
- **状态存储**: 使用 Pinia store + localStorage(模拟记住我)
|
|
||||||
|
|
||||||
### 模拟用户权限
|
|
||||||
| 角色 | 权限 |
|
|
||||||
|------|------|
|
|
||||||
| `admin` | `['dashboard', 'goods', 'order', 'system']` |
|
|
||||||
| `user` | `['dashboard', 'goods']` |
|
|
||||||
| `test` | `['dashboard']` |
|
|
||||||
|
|
||||||
## 🎨 页面功能
|
|
||||||
|
|
||||||
### 登录方式
|
|
||||||
1. **密码登录** - 使用邮箱和密码
|
|
||||||
2. **短信登录** - 界面已完成,API待实现
|
|
||||||
|
|
||||||
### 特色功能
|
|
||||||
- ✅ 明/暗色主题切换(自动记忆)
|
|
||||||
- ✅ 响应式设计(支持移动端)
|
|
||||||
- ✅ 表单实时验证
|
|
||||||
- ✅ 社交登录(微信、企业微信、钉钉)
|
|
||||||
- ✅ 记住我功能
|
|
||||||
- ✅ 协议声明
|
|
||||||
|
|
||||||
## 🐛 故障排除
|
|
||||||
|
|
||||||
### 常见问题
|
|
||||||
1. **登录失败**:检查是否输入了正确的测试账号密码
|
|
||||||
2. **页面样式异常**:确保安装了所有依赖 `npm install`
|
|
||||||
3. **路由问题**:检查 `src/router/complete-fixed.ts` 和 `complete.ts` 中的路由配置
|
|
||||||
|
|
||||||
### 开发建议
|
|
||||||
- 模拟模式仅用于前端开发和测试
|
|
||||||
- 对接真实API时,设置 `VITE_USE_MOCK=false`
|
|
||||||
- 正式环境应使用 `.env.production` 配置文件
|
|
||||||
|
|
||||||
## 📁 相关文件
|
|
||||||
- `src/views/Auth/LoginEnhanced.vue` - 登录页面主文件
|
|
||||||
- `src/stores/user.ts` - 用户状态管理
|
|
||||||
- `src/api/auth.ts` - 登录相关API
|
|
||||||
- `.env.development` - 开发环境配置
|
|
||||||
|
|
||||||
---
|
|
||||||
*最后更新: 2026-03-24*
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
# Vue 3 + Vite
|
|
||||||
|
|
||||||
This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
|
|
||||||
|
|
||||||
Learn more about IDE Support for Vue in the [Vue Docs Scaling up Guide](https://vuejs.org/guide/scaling-up/tooling.html#ide-support).
|
|
||||||
1
assets/Admin-BrBLLsD_.js
Executable file
1
assets/Admin-BrBLLsD_.js
Executable file
File diff suppressed because one or more lines are too long
1
assets/Admin-CGtBF8xn.css
Executable file
1
assets/Admin-CGtBF8xn.css
Executable file
@ -0,0 +1 @@
|
|||||||
|
.admin-container[data-v-b97571e9]{padding:20px}.search-card[data-v-b97571e9]{margin-bottom:20px}.card-header[data-v-b97571e9]{justify-content:space-between;align-items:center;display:flex}.pagination-wrapper[data-v-b97571e9]{justify-content:flex-end;margin-top:20px;display:flex}
|
||||||
1
assets/AfterSaleList-BzfOWTm7.css
Executable file
1
assets/AfterSaleList-BzfOWTm7.css
Executable file
@ -0,0 +1 @@
|
|||||||
|
.after-sale-container[data-v-e7704552]{background:#f8f9fa;min-height:100vh;padding:20px}.stats-row[data-v-e7704552]{margin-bottom:16px}.stat-card[data-v-e7704552]{text-align:center}.stat-item[data-v-e7704552]{flex-direction:column;align-items:center;padding:10px 0;display:flex}.stat-value[data-v-e7704552]{font-size:32px;font-weight:600}.stat-value.pending[data-v-e7704552]{color:#909399}.stat-value.processing[data-v-e7704552]{color:#e6a23c}.stat-value.completed[data-v-e7704552]{color:#67c23a}.stat-label[data-v-e7704552]{color:#909399;margin-top:4px;font-size:14px}.main-tabs[data-v-e7704552]{background:#fff;border-radius:8px;padding:16px}.main-card[data-v-e7704552]{border-radius:8px}.card-header[data-v-e7704552]{justify-content:space-between;align-items:center;display:flex}.filter-bar[data-v-e7704552]{flex-wrap:wrap;align-items:center;gap:12px;margin-bottom:16px;display:flex}.section[data-v-e7704552]{margin-top:24px}.section h4[data-v-e7704552]{color:#303133;margin-bottom:12px}.section h5[data-v-e7704552]{color:#606266;margin:12px 0 8px;font-size:14px}.selected-order-card[data-v-e7704552]{background:#f5f7fa}.order-info[data-v-e7704552]{flex-wrap:wrap;gap:20px;margin-bottom:12px;display:flex}.order-info span[data-v-e7704552]{color:#606266}.form-tip[data-v-e7704552]{color:#909399;margin-left:12px;font-size:12px}.detail-content[data-v-e7704552]{padding:0 10px}.pagination-wrapper[data-v-e7704552]{justify-content:flex-end;margin-top:16px;display:flex}
|
||||||
1
assets/AfterSaleList-LCoLBlEe.js
Executable file
1
assets/AfterSaleList-LCoLBlEe.js
Executable file
File diff suppressed because one or more lines are too long
1
assets/Config-Bf5OelgV.css
Executable file
1
assets/Config-Bf5OelgV.css
Executable file
@ -0,0 +1 @@
|
|||||||
|
.config-container[data-v-48a34711]{padding:20px}.config-tabs[data-v-48a34711]{background:#fff}.suffix[data-v-48a34711]{color:#909399;margin-left:8px}
|
||||||
1
assets/Config-CHcKHtCr.js
Executable file
1
assets/Config-CHcKHtCr.js
Executable file
File diff suppressed because one or more lines are too long
1
assets/Dashboard-TYKD7muw.css
Executable file
1
assets/Dashboard-TYKD7muw.css
Executable file
@ -0,0 +1 @@
|
|||||||
|
.dashboard-container[data-v-3f0af19b]{padding:20px}.stats-row[data-v-3f0af19b]{margin-bottom:20px}.stat-card[data-v-3f0af19b]{background:#fff;border-radius:8px;align-items:center;padding:20px;display:flex;box-shadow:0 2px 12px #0000001a}.stat-icon[data-v-3f0af19b]{color:#fff;border-radius:8px;justify-content:center;align-items:center;width:60px;height:60px;margin-right:20px;font-size:28px;display:flex}.stat-card.tenant .stat-icon[data-v-3f0af19b]{background:linear-gradient(135deg,#667eea 0%,#764ba2 100%)}.stat-card.order .stat-icon[data-v-3f0af19b]{background:linear-gradient(135deg,#f093fb 0%,#f5576c 100%)}.stat-card.revenue .stat-icon[data-v-3f0af19b]{background:linear-gradient(135deg,#4facfe 0%,#00f2fe 100%)}.stat-card.pending .stat-icon[data-v-3f0af19b]{background:linear-gradient(135deg,#fa709a 0%,#fee140 100%)}.stat-content[data-v-3f0af19b]{flex:1}.stat-value[data-v-3f0af19b]{color:#303133;font-size:28px;font-weight:700}.stat-label[data-v-3f0af19b]{color:#909399;margin-top:4px;font-size:14px}.stat-trend[data-v-3f0af19b]{margin-top:8px;font-size:12px}.trend-value[data-v-3f0af19b]{font-weight:700}.trend-value.up[data-v-3f0af19b]{color:#67c23a}.trend-value.down[data-v-3f0af19b]{color:#f56c6c}.trend-label[data-v-3f0af19b]{color:#909399;margin-left:8px}.charts-row[data-v-3f0af19b]{margin-bottom:20px}.chart-card[data-v-3f0af19b]{height:350px}.chart-container[data-v-3f0af19b]{height:280px}.card-header[data-v-3f0af19b]{font-weight:700}.bottom-row .el-card[data-v-3f0af19b]{height:280px}.pending-list[data-v-3f0af19b]{flex-direction:column;gap:16px;display:flex}.pending-item[data-v-3f0af19b]{background:#f5f7fa;border-radius:8px;padding:12px}.pending-content[data-v-3f0af19b]{background:#fff;border-radius:4px;align-items:center;gap:8px;padding:8px 16px;display:flex}.status-list[data-v-3f0af19b]{flex-direction:column;gap:16px;display:flex}.status-item[data-v-3f0af19b]{background:#f5f7fa;border-radius:8px;justify-content:space-between;align-items:center;padding:12px;display:flex}.status-label[data-v-3f0af19b]{color:#606266}.status-value[data-v-3f0af19b]{color:#303133;font-weight:700}
|
||||||
39
assets/Dashboard-X5UFysZh.js
Executable file
39
assets/Dashboard-X5UFysZh.js
Executable file
File diff suppressed because one or more lines are too long
1
assets/Edit-1Yow_gWs.css
Executable file
1
assets/Edit-1Yow_gWs.css
Executable file
@ -0,0 +1 @@
|
|||||||
|
.goods-edit-container[data-v-0d7a8ec1]{background:#f8f9fa;min-height:calc(100vh - 64px);padding:24px}.sub-items-toolbar[data-v-0d7a8ec1]{margin-bottom:12px}
|
||||||
1
assets/Edit-CeeIoUlF.js
Executable file
1
assets/Edit-CeeIoUlF.js
Executable file
File diff suppressed because one or more lines are too long
1
assets/List-ByaWNfBv.js
Executable file
1
assets/List-ByaWNfBv.js
Executable file
File diff suppressed because one or more lines are too long
1
assets/List-Djvd2WOK.css
Executable file
1
assets/List-Djvd2WOK.css
Executable file
@ -0,0 +1 @@
|
|||||||
|
.goods-list-container[data-v-2d0a0855]{background:#f8f9fa;min-height:calc(100vh - 64px);padding:24px}.card-header[data-v-2d0a0855]{color:#1a1a2e;justify-content:space-between;align-items:center;font-size:16px;font-weight:600;display:flex}.header-right[data-v-2d0a0855]{align-items:center;display:flex}
|
||||||
1
assets/Login-BESGi_b1.js
Executable file
1
assets/Login-BESGi_b1.js
Executable file
File diff suppressed because one or more lines are too long
1
assets/Login-Ch8cQwoZ.css
Executable file
1
assets/Login-Ch8cQwoZ.css
Executable file
File diff suppressed because one or more lines are too long
1
assets/OrderList-Dg3_JjaG.css
Executable file
1
assets/OrderList-Dg3_JjaG.css
Executable file
File diff suppressed because one or more lines are too long
1
assets/OrderList-DhLSSK-m.js
Executable file
1
assets/OrderList-DhLSSK-m.js
Executable file
File diff suppressed because one or more lines are too long
1
assets/OrderPullList-C52vI6fa.css
Executable file
1
assets/OrderPullList-C52vI6fa.css
Executable file
@ -0,0 +1 @@
|
|||||||
|
.order-pull-container[data-v-2e6e7b92]{padding:16px}.card-header[data-v-2e6e7b92]{justify-content:space-between;align-items:center;display:flex}.search-bar[data-v-2e6e7b92]{margin-bottom:16px}
|
||||||
1
assets/OrderPullList-DdF7dB9a.js
Executable file
1
assets/OrderPullList-DdF7dB9a.js
Executable file
File diff suppressed because one or more lines are too long
1
assets/Package-0Gwdjasn.css
Executable file
1
assets/Package-0Gwdjasn.css
Executable file
@ -0,0 +1 @@
|
|||||||
|
.package-container[data-v-93d81e67]{padding:20px}.search-card[data-v-93d81e67]{margin-bottom:20px}.card-header[data-v-93d81e67]{justify-content:space-between;align-items:center;display:flex}.package-name[data-v-93d81e67]{align-items:center;gap:8px;display:flex}.price[data-v-93d81e67]{color:#f56c6c;font-weight:700}.features-list[data-v-93d81e67]{flex-wrap:wrap;gap:4px;display:flex}.more[data-v-93d81e67]{color:#909399;font-size:12px}.pagination-wrapper[data-v-93d81e67]{justify-content:flex-end;margin-top:20px;display:flex}
|
||||||
1
assets/Package-CFnVrxqs.js
Executable file
1
assets/Package-CFnVrxqs.js
Executable file
File diff suppressed because one or more lines are too long
1
assets/Stock-BHXWC1pP.css
Executable file
1
assets/Stock-BHXWC1pP.css
Executable file
@ -0,0 +1 @@
|
|||||||
|
.stock-container[data-v-b66beaf0]{background:#f8f9fa;min-height:calc(100vh - 64px);padding:24px}.card-header[data-v-b66beaf0]{color:#1a1a2e;justify-content:space-between;align-items:center;font-size:16px;font-weight:600;display:flex}
|
||||||
1
assets/Stock-J2j7dkEc.js
Executable file
1
assets/Stock-J2j7dkEc.js
Executable file
@ -0,0 +1 @@
|
|||||||
|
import{B as e,F as t,Gt as n,H as r,R as i,U as a,a as o,b as s,d as c,et as l,f as u,m as d,t as f,tt as p,ut as m,v as h,y as g}from"./_plugin-vue_export-helper-BmDUjPB3.js";import{c as _,o as v,r as y}from"./index-BdquF2dM.js";import{t as b}from"./request-D2yY8ZUb.js";import{t as x}from"./warehouse-DjgOFCsD.js";function S(e){return b.get(`/stocks`,{params:e})}function C(e){return b.put(`/stocks/update-threshold`,e)}var w={class:`stock-container`},T={style:{"margin-bottom":`15px`,display:`flex`,gap:`10px`,"flex-wrap":`wrap`}},E=f(s({__name:`Stock`,setup(s){let f=v(),b=m([]),E=m(!1),D=m(1),O=m(10),k=m(0),A=m([]),j=m({warehouseId:``,keyword:``}),M=async()=>{let e=await x({pageSize:100});e.code===200&&(A.value=e.data.list)},N=async()=>{E.value=!0;try{let e=await S({warehouseId:j.value.warehouseId,keyword:j.value.keyword,currentPage:D.value,pageSize:O.value});e.code===200&&(b.value=e.data.list,k.value=e.data.total)}finally{E.value=!1}},P=()=>{j.value={warehouseId:``,keyword:``},D.value=1,N()},F=e=>e.quantity<=0?`danger`:e.quantity<=e.warningThreshold?`warning`:`success`,I=e=>e.quantity<=0?`缺货`:e.quantity<=e.warningThreshold?`预警`:`正常`,L=async(e,t)=>{let n=await C({skuCode:e.skuCode,warehouseId:e.warehouseId,threshold:t});n.code===200?y.success(`预警阈值更新成功`):y.error(n.message||`更新失败`)},R=e=>{f.push(`/warehouse/stock-detail/${e.id}`)};return t(()=>{M(),N()}),(t,s)=>{let f=r(`el-option`),m=r(`el-select`),v=r(`el-input`),y=r(`el-button`),x=r(`el-table-column`),S=r(`el-input-number`),C=r(`el-tag`),M=r(`el-table`),z=r(`el-pagination`),B=r(`el-card`),V=a(`loading`);return i(),d(`div`,w,[g(B,null,{header:l(()=>[...s[4]||=[c(`div`,{class:`card-header`},[c(`span`,null,`库存管理`)],-1)]]),default:l(()=>[c(`div`,T,[g(m,{modelValue:j.value.warehouseId,"onUpdate:modelValue":s[0]||=e=>j.value.warehouseId=e,placeholder:`选择仓库`,clearable:``,style:{width:`180px`}},{default:l(()=>[(i(!0),d(o,null,e(A.value,e=>(i(),u(f,{key:e.id,label:e.name,value:e.id},null,8,[`label`,`value`]))),128))]),_:1},8,[`modelValue`]),g(v,{modelValue:j.value.keyword,"onUpdate:modelValue":s[1]||=e=>j.value.keyword=e,placeholder:`商品名称/编码/条码`,style:{width:`250px`},clearable:``,onKeyup:_(N,[`enter`])},null,8,[`modelValue`]),g(y,{type:`primary`,onClick:N},{default:l(()=>[...s[5]||=[h(`查询`,-1)]]),_:1}),g(y,{onClick:P},{default:l(()=>[...s[6]||=[h(`重置`,-1)]]),_:1})]),p((i(),u(M,{data:b.value,border:``,style:{width:`100%`}},{default:l(()=>[g(x,{prop:`skuCode`,label:`商品编码`,width:`150`}),g(x,{prop:`skuName`,label:`商品名称`,"min-width":`200`}),g(x,{prop:`barcode`,label:`条码`,width:`130`}),g(x,{prop:`warehouseName`,label:`仓库`,width:`150`}),g(x,{prop:`quantity`,label:`实物库存`,width:`100`}),g(x,{prop:`lockedQuantity`,label:`锁定库存`,width:`100`}),g(x,{prop:`availableQuantity`,label:`可用库存`,width:`100`}),g(x,{prop:`warningThreshold`,label:`预警阈值`,width:`120`},{default:l(({row:e})=>[g(S,{modelValue:e.warningThreshold,"onUpdate:modelValue":t=>e.warningThreshold=t,min:0,size:`small`,style:{width:`100px`},onChange:t=>L(e,t)},null,8,[`modelValue`,`onUpdate:modelValue`,`onChange`])]),_:1}),g(x,{prop:`status`,label:`状态`,width:`100`},{default:l(({row:e})=>[g(C,{type:F(e)},{default:l(()=>[h(n(I(e)),1)]),_:2},1032,[`type`])]),_:1}),g(x,{label:`操作`,width:`120`,fixed:`right`},{default:l(({row:e})=>[g(y,{size:`small`,type:`primary`,onClick:t=>R(e)},{default:l(()=>[...s[7]||=[h(`详情`,-1)]]),_:1},8,[`onClick`])]),_:1})]),_:1},8,[`data`])),[[V,E.value]]),g(z,{"current-page":D.value,"onUpdate:currentPage":s[2]||=e=>D.value=e,"page-size":O.value,"onUpdate:pageSize":s[3]||=e=>O.value=e,"page-sizes":[10,20,50],total:k.value,layout:`total, sizes, prev, pager, next, jumper`,onSizeChange:N,onCurrentChange:N,style:{"margin-top":`20px`,"text-align":`right`}},null,8,[`current-page`,`page-size`,`total`])]),_:1})])}}}),[[`__scopeId`,`data-v-b66beaf0`]]);export{E as default};
|
||||||
1
assets/Tenant-Cm4txsEM.css
Executable file
1
assets/Tenant-Cm4txsEM.css
Executable file
@ -0,0 +1 @@
|
|||||||
|
.tenant-container[data-v-cd1afe62]{padding:20px}.search-card[data-v-cd1afe62]{margin-bottom:20px}.card-header[data-v-cd1afe62]{justify-content:space-between;align-items:center;display:flex}.tenant-name[data-v-cd1afe62]{align-items:center;gap:8px;display:flex}.expired[data-v-cd1afe62]{color:#f56c6c}.pagination-wrapper[data-v-cd1afe62]{justify-content:flex-end;margin-top:20px;display:flex}
|
||||||
1
assets/Tenant-pWHhJhkV.js
Executable file
1
assets/Tenant-pWHhJhkV.js
Executable file
File diff suppressed because one or more lines are too long
1
assets/Warehouse-CRSQRe3f.js
Executable file
1
assets/Warehouse-CRSQRe3f.js
Executable file
@ -0,0 +1 @@
|
|||||||
|
import{B as e,F as t,Gt as n,H as r,R as i,U as a,a as o,b as s,d as c,et as l,f as u,m as d,t as f,tt as p,ut as m,v as h,y as g}from"./_plugin-vue_export-helper-BmDUjPB3.js";import{n as _,o as v,r as y}from"./index-BdquF2dM.js";import"./request-D2yY8ZUb.js";import{t as b}from"./warehouse-DjgOFCsD.js";var x={class:`warehouse-container`},S={class:`card-header`},C={key:0},w={key:1},T={key:0},E={key:1},D=f(s({__name:`index`,setup(s){let f=v(),D=m([]),O=m(!1),k=m(1),A=m(10),j=m(0),M=e=>({qimen:`奇门`,jst:`聚水潭`,wdt:`旺店通`})[e]||e,N=e=>({common:`通用`,jd:`京东`,pdd:`拼多多`,taobao:`淘宝/天猫`})[e]||e,P=async()=>{O.value=!0;try{let e=await b({currentPage:k.value,pageSize:A.value});e.code===200&&(D.value=e.data.list,j.value=e.data.total)}finally{O.value=!1}},F=()=>{f.push(`/warehouse/edit`)},I=e=>{f.push(`/warehouse/edit/${e}`)},L=e=>{f.push(`/warehouse/bind-template/${e}`)},R=e=>{_.confirm(`确定删除该仓库吗?`,`提示`,{confirmButtonText:`确定`,cancelButtonText:`取消`,type:`warning`}).then(async()=>{let t=await R(e);t.code===200?(y.success(`删除成功`),P()):y.error(t.message||`删除失败`)}).catch(()=>{})};return t(()=>{P()}),(t,s)=>{let f=r(`el-button`),m=r(`el-table-column`),_=r(`el-tag`),v=r(`el-table`),y=r(`el-pagination`),b=r(`el-card`),z=a(`loading`);return i(),d(`div`,x,[g(b,null,{header:l(()=>[c(`div`,S,[s[3]||=c(`span`,null,`仓库列表`,-1),g(f,{type:`primary`,onClick:F},{default:l(()=>[...s[2]||=[h(`新增仓库`,-1)]]),_:1})])]),default:l(()=>[p((i(),u(v,{data:D.value,border:``,style:{width:`100%`}},{default:l(()=>[g(m,{prop:`name`,label:`仓库名称`,"min-width":`150`}),g(m,{prop:`type`,label:`仓库类型`,width:`120`},{default:l(({row:e})=>[g(_,{type:e.type===`erp`?`success`:`primary`},{default:l(()=>[h(n(e.type===`erp`?`ERP仓库`:`云仓`),1)]),_:2},1032,[`type`])]),_:1}),g(m,{prop:`cloudSystem`,label:`云仓系统`,width:`120`},{default:l(({row:e})=>[e.type===`cloud`?(i(),d(`span`,C,n(M(e.cloudSystem)),1)):(i(),d(`span`,w,`-`))]),_:1}),g(m,{prop:`ownerCode`,label:`货主编码`,width:`120`}),g(m,{prop:`cloudCode`,label:`云仓编码`,width:`120`}),g(m,{prop:`createdAt`,label:`创建时间`,width:`180`}),g(m,{label:`已绑平台`,width:`200`},{default:l(({row:t})=>[t.bindings&&t.bindings.length>0?(i(),d(`div`,T,[(i(!0),d(o,null,e(t.bindings,e=>(i(),u(_,{key:e.id,size:`small`,style:{"margin-right":`5px`,"margin-bottom":`3px`}},{default:l(()=>[h(n(N(e.platform))+`: `+n(e.templateName),1)]),_:2},1024))),128))])):(i(),d(`span`,E,`-`))]),_:1}),g(m,{label:`操作`,width:`300`,fixed:`right`},{default:l(({row:e})=>[g(f,{type:`primary`,size:`small`,onClick:t=>I(e.id)},{default:l(()=>[...s[4]||=[h(`编辑`,-1)]]),_:1},8,[`onClick`]),g(f,{type:`success`,size:`small`,onClick:t=>L(e.id)},{default:l(()=>[...s[5]||=[h(`绑定模板`,-1)]]),_:1},8,[`onClick`]),g(f,{type:`danger`,size:`small`,onClick:t=>R(e.id)},{default:l(()=>[...s[6]||=[h(`删除`,-1)]]),_:1},8,[`onClick`])]),_:1})]),_:1},8,[`data`])),[[z,O.value]]),g(y,{"current-page":k.value,"onUpdate:currentPage":s[0]||=e=>k.value=e,"page-size":A.value,"onUpdate:pageSize":s[1]||=e=>A.value=e,"page-sizes":[10,20,50],total:j.value,layout:`total, sizes, prev, pager, next, jumper`,onSizeChange:P,onCurrentChange:P,style:{"margin-top":`20px`,"text-align":`right`}},null,8,[`current-page`,`page-size`,`total`])]),_:1})])}}}),[[`__scopeId`,`data-v-4fb085e3`]]);export{D as default};
|
||||||
1
assets/Warehouse-ulTjVKJZ.css
Executable file
1
assets/Warehouse-ulTjVKJZ.css
Executable file
@ -0,0 +1 @@
|
|||||||
|
.warehouse-container[data-v-4fb085e3]{background:#f8f9fa;min-height:calc(100vh - 64px);padding:24px}.card-header[data-v-4fb085e3]{color:#1a1a2e;justify-content:space-between;align-items:center;font-size:16px;font-weight:600;display:flex}
|
||||||
1
assets/Welcome-DnyaE-5Y.css
Executable file
1
assets/Welcome-DnyaE-5Y.css
Executable file
@ -0,0 +1 @@
|
|||||||
|
.welcome-container[data-v-b2b1d097]{background:#f8f9fa;min-height:calc(100vh - 120px);padding:24px}.welcome-card[data-v-b2b1d097]{background:#fff;border-radius:12px;max-width:1200px;margin:0 auto;padding:32px;box-shadow:0 4px 16px #00000014}.welcome-header[data-v-b2b1d097]{text-align:center;border-bottom:1px solid #e9ecef;margin-bottom:32px;padding-bottom:24px}.welcome-icon[data-v-b2b1d097]{margin-bottom:16px}.welcome-header h1[data-v-b2b1d097]{color:#1a1a2e;margin:0;font-size:24px;font-weight:600}.welcome-content[data-v-b2b1d097]{padding:0 12px}.welcome-text[data-v-b2b1d097]{color:#6c757d;text-align:center;margin-bottom:24px;font-size:15px}.user-tag[data-v-b2b1d097]{color:#1a1a2e;background:linear-gradient(135deg,#d4af37,#f5e6a3);border:none;margin:0 8px;padding:6px 14px;font-size:14px;font-weight:600}.user-info-card[data-v-b2b1d097]{background:#fafafa;border-radius:10px;margin-bottom:32px;padding:20px}.info-card-title[data-v-b2b1d097]{color:#1a1a2e;border-bottom:2px solid #d4af37;margin-bottom:16px;padding-bottom:10px;font-size:15px;font-weight:600;display:inline-block}.system-features[data-v-b2b1d097]{margin-bottom:32px}.section-title[data-v-b2b1d097]{color:#1a1a2e;border-bottom:2px solid #d4af37;margin-bottom:20px;padding-bottom:10px;font-size:15px;font-weight:600;display:inline-block}.feature-card[data-v-b2b1d097]{text-align:center;cursor:pointer;background:#fff;border:1px solid #e9ecef;border-radius:12px;height:100%;padding:24px 20px;transition:all .3s}.feature-card[data-v-b2b1d097]:hover{border-color:#d4af37;transform:translateY(-4px);box-shadow:0 8px 24px #0000001a}.feature-icon-wrap[data-v-b2b1d097]{border-radius:12px;justify-content:center;align-items:center;width:56px;height:56px;margin:0 auto 16px;display:flex}.feature-icon-wrap.gold[data-v-b2b1d097]{color:#d4af37;background:linear-gradient(135deg,#d4af3726,#d4af370d)}.feature-icon-wrap.blue[data-v-b2b1d097]{color:#1a1a2e;background:linear-gradient(135deg,#1a1a2e1a,#1a1a2e0d)}.feature-icon-wrap.green[data-v-b2b1d097]{color:#52c41a;background:linear-gradient(135deg,#52c41a1a,#52c41a0d)}.feature-card h4[data-v-b2b1d097]{color:#1a1a2e;margin:0 0 8px;font-size:15px;font-weight:600}.feature-card p[data-v-b2b1d097]{color:#6c757d;margin:0;font-size:13px;line-height:1.5}.quick-actions[data-v-b2b1d097]{margin-bottom:24px}.action-btn[data-v-b2b1d097]{border-radius:8px!important;justify-content:center!important;align-items:center!important;padding:10px 20px!important;font-weight:500!important;display:inline-flex!important}.gold-btn[data-v-b2b1d097]{color:#1a1a2e!important;background:linear-gradient(135deg,#d4af37,#f5e6a3)!important;border:none!important;box-shadow:0 4px 12px #d4af374d!important}.gold-btn[data-v-b2b1d097]:hover{transform:translateY(-2px);box-shadow:0 6px 16px #d4af3766!important}.white-btn[data-v-b2b1d097]{color:#1a1a2e!important;background:#fff!important;border:1px solid #e9ecef!important}.white-btn[data-v-b2b1d097]:hover{color:#d4af37!important;border-color:#d4af37!important}.welcome-footer[data-v-b2b1d097]{margin-top:32px}.footer-text[data-v-b2b1d097]{text-align:center;color:#adb5bd;justify-content:center;align-items:center;font-size:13px;display:flex}@media (width<=768px){.welcome-container[data-v-b2b1d097]{padding:12px}.welcome-card[data-v-b2b1d097]{padding:20px}.feature-card[data-v-b2b1d097]{margin-bottom:16px;padding:16px}}
|
||||||
1
assets/Welcome-DwFFMcoh.js
Executable file
1
assets/Welcome-DwFFMcoh.js
Executable file
File diff suppressed because one or more lines are too long
1
assets/_plugin-vue_export-helper-BmDUjPB3.js
Executable file
1
assets/_plugin-vue_export-helper-BmDUjPB3.js
Executable file
File diff suppressed because one or more lines are too long
1
assets/dist-CxIYsDur.js
Executable file
1
assets/dist-CxIYsDur.js
Executable file
File diff suppressed because one or more lines are too long
1
assets/goods-tPYeTpYk.js
Executable file
1
assets/goods-tPYeTpYk.js
Executable file
@ -0,0 +1 @@
|
|||||||
|
import{t as e}from"./request-D2yY8ZUb.js";function t(t){return e.get(`/goods`,{params:t})}function n(t){return e.get(`/goods/${t}`)}function r(t){return e.post(`/goods`,t)}function i(t,n){return e.put(`/goods/${t}`,n)}function a(t){return e.delete(`/goods/${t}`)}function o(e){return Promise.resolve({code:200,message:`推送功能开发中`,data:null})}function s(){return e.get(`/goods/all`)}const c=s;export{t as a,n as i,a as n,o,c as r,i as s,r as t};
|
||||||
53
assets/index-BdquF2dM.js
Executable file
53
assets/index-BdquF2dM.js
Executable file
File diff suppressed because one or more lines are too long
1
assets/index-DWQKLU3Q.css
Executable file
1
assets/index-DWQKLU3Q.css
Executable file
File diff suppressed because one or more lines are too long
11
assets/request-D2yY8ZUb.js
Executable file
11
assets/request-D2yY8ZUb.js
Executable file
File diff suppressed because one or more lines are too long
1
assets/superAdmin-DRegPzth.js
Executable file
1
assets/superAdmin-DRegPzth.js
Executable file
@ -0,0 +1 @@
|
|||||||
|
import{t as e}from"./request-D2yY8ZUb.js";function t(){return e({url:`/sa/dashboard`,method:`get`})}function n(t){return e({url:`/sa/tenants`,method:`get`,params:t})}function r(t){return e({url:`/sa/tenants`,method:`post`,data:t})}function i(t,n){return e({url:`/api/sa/tenants/${t}`,method:`put`,data:n})}function a(t){return e({url:`/api/sa/tenants/${t}`,method:`delete`})}function o(t){return e({url:`/api/sa/tenants/${t}/toggle-status`,method:`post`})}function s(t){return e({url:`/api/sa/tenants/${t}/suspend`,method:`post`})}function c(t){return e({url:`/sa/packages`,method:`get`,params:t})}function l(){return e({url:`/sa/packages/all`,method:`get`})}function u(t){return e({url:`/sa/packages`,method:`post`,data:t})}function d(t,n){return e({url:`/api/sa/packages/${t}`,method:`put`,data:n})}function f(t){return e({url:`/api/sa/packages/${t}`,method:`delete`})}function p(t){return e({url:`/api/sa/packages/${t}/set-default`,method:`post`})}function m(){return e({url:`/sa/configs`,method:`get`})}function h(t){return e({url:`/sa/configs`,method:`put`,data:t})}function g(t){return e({url:`/sa/admins`,method:`get`,params:t})}function _(t){return e({url:`/sa/admins`,method:`post`,data:t})}function v(t,n){return e({url:`/api/sa/admins/${t}`,method:`put`,data:n})}function y(t){return e({url:`/api/sa/admins/${t}`,method:`delete`})}function b(t){return e({url:`/api/sa/admins/${t}/toggle-status`,method:`post`})}function x(t,n){return e({url:`/api/sa/admins/${t}/reset-password`,method:`post`,data:{password:n}})}export{o as _,f as a,d as b,m as c,c as d,n as f,b as g,s as h,y as i,t as l,p as m,u as n,a as o,x as p,r,g as s,_ as t,l as u,v,i as x,h as y};
|
||||||
1
assets/warehouse-DjgOFCsD.js
Executable file
1
assets/warehouse-DjgOFCsD.js
Executable file
@ -0,0 +1 @@
|
|||||||
|
import{t as e}from"./request-D2yY8ZUb.js";function t(t){return e.get(`/warehouses`,{params:t})}export{t};
|
||||||
0
public/diagnose-vue.html → diagnose-vue.html
Normal file → Executable file
0
public/diagnose-vue.html → diagnose-vue.html
Normal file → Executable file
0
public/diagnose.html → diagnose.html
Normal file → Executable file
0
public/diagnose.html → diagnose.html
Normal file → Executable file
0
public/emergency-print.html → emergency-print.html
Normal file → Executable file
0
public/emergency-print.html → emergency-print.html
Normal file → Executable file
@ -1,22 +0,0 @@
|
|||||||
import js from '@eslint/js';
|
|
||||||
import globals from 'globals';
|
|
||||||
import pluginVue from 'eslint-plugin-vue';
|
|
||||||
import tseslint from 'typescript-eslint';
|
|
||||||
|
|
||||||
export default [
|
|
||||||
js.configs.recommended,
|
|
||||||
...tseslint.configs.recommended,
|
|
||||||
...pluginVue.configs['flat/recommended'],
|
|
||||||
{
|
|
||||||
languageOptions: {
|
|
||||||
ecmaVersion: 2020,
|
|
||||||
sourceType: 'module',
|
|
||||||
globals: {
|
|
||||||
...globals.browser,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
rules: {
|
|
||||||
// 你可以在这里添加或覆盖规则
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
5
index.html
Normal file → Executable file
5
index.html
Normal file → Executable file
@ -5,9 +5,12 @@
|
|||||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>new-erp</title>
|
<title>new-erp</title>
|
||||||
|
<script type="module" crossorigin src="/assets/index-BdquF2dM.js"></script>
|
||||||
|
<link rel="modulepreload" crossorigin href="/assets/_plugin-vue_export-helper-BmDUjPB3.js">
|
||||||
|
<link rel="modulepreload" crossorigin href="/assets/dist-CxIYsDur.js">
|
||||||
|
<link rel="stylesheet" crossorigin href="/assets/index-DWQKLU3Q.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
<script type="module" src="/src/main.js"></script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
0
public/login-fallback.html → login-fallback.html
Normal file → Executable file
0
public/login-fallback.html → login-fallback.html
Normal file → Executable file
0
public/plugins/cainiao-install.bat → plugins/cainiao-install.bat
Normal file → Executable file
0
public/plugins/cainiao-install.bat → plugins/cainiao-install.bat
Normal file → Executable file
0
public/plugins/cainiao-setup.exe → plugins/cainiao-setup.exe
Normal file → Executable file
0
public/plugins/cainiao-setup.exe → plugins/cainiao-setup.exe
Normal file → Executable file
0
public/plugins/pdd-install.bat → plugins/pdd-install.bat
Normal file → Executable file
0
public/plugins/pdd-install.bat → plugins/pdd-install.bat
Normal file → Executable file
0
public/plugins/print-plugin-client.js → plugins/print-plugin-client.js
Normal file → Executable file
0
public/plugins/print-plugin-client.js → plugins/print-plugin-client.js
Normal file → Executable file
0
public/simple-login.html → simple-login.html
Normal file → Executable file
0
public/simple-login.html → simple-login.html
Normal file → Executable file
@ -1,3 +0,0 @@
|
|||||||
<template>
|
|
||||||
<router-view />
|
|
||||||
</template>
|
|
||||||
@ -1,58 +0,0 @@
|
|||||||
// 售后管理 API
|
|
||||||
import request from '@/utils/request'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 售后列表
|
|
||||||
*/
|
|
||||||
export function getAfterSalesList(params?: any) {
|
|
||||||
return request.get('/after-sales', { params })
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 售后单详情
|
|
||||||
*/
|
|
||||||
export function getAfterSaleDetail(id: string) {
|
|
||||||
return request.get(`/after-sales/${id}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建售后单
|
|
||||||
*/
|
|
||||||
export function createAfterSale(data: any) {
|
|
||||||
return request.post('/after-sales', data)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新售后单状态
|
|
||||||
*/
|
|
||||||
export function updateAfterSaleStatus(id: string, data: any) {
|
|
||||||
return request.put(`/after-sales/${id}/status`, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除售后单
|
|
||||||
*/
|
|
||||||
export function deleteAfterSale(id: string) {
|
|
||||||
return request.delete(`/after-sales/${id}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取可售后的订单(已发货)
|
|
||||||
*/
|
|
||||||
export function getAvailableOrders(params?: any) {
|
|
||||||
return request.get('/after-sales/available-orders', { params })
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取所有可售后的订单(包含未发货的仅退款)
|
|
||||||
*/
|
|
||||||
export function getAllAvailableOrders(params?: any) {
|
|
||||||
return request.get('/after-sales/all-available-orders', { params })
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 售后统计
|
|
||||||
*/
|
|
||||||
export function getAfterSaleStats() {
|
|
||||||
return request.get('/after-sales/stats')
|
|
||||||
}
|
|
||||||
129
src/api/ai.ts
129
src/api/ai.ts
@ -1,129 +0,0 @@
|
|||||||
// AI 对话管理 API
|
|
||||||
import request from '@/utils/request'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 消息角色类型
|
|
||||||
*/
|
|
||||||
export type MessageRole = 'user' | 'assistant' | 'system'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 消息接口定义
|
|
||||||
*/
|
|
||||||
export interface Message {
|
|
||||||
id: string
|
|
||||||
role: MessageRole
|
|
||||||
content: string
|
|
||||||
createdAt: string
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 对话接口定义
|
|
||||||
*/
|
|
||||||
export interface Conversation {
|
|
||||||
id: string
|
|
||||||
title: string
|
|
||||||
messages: Message[]
|
|
||||||
model?: string
|
|
||||||
createdAt: string
|
|
||||||
updatedAt: string
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* AI 模型接口定义
|
|
||||||
*/
|
|
||||||
export interface AIModel {
|
|
||||||
id: string
|
|
||||||
name: string
|
|
||||||
provider: string
|
|
||||||
description?: string
|
|
||||||
isActive?: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* AI 能力接口定义
|
|
||||||
*/
|
|
||||||
export interface AICapability {
|
|
||||||
id: string
|
|
||||||
name: string
|
|
||||||
description: string
|
|
||||||
enabled: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 聊天请求参数
|
|
||||||
*/
|
|
||||||
export interface ChatParams {
|
|
||||||
conversationId?: string
|
|
||||||
message: string
|
|
||||||
model?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 执行任务请求参数
|
|
||||||
*/
|
|
||||||
export interface ExecuteTaskParams {
|
|
||||||
task: string
|
|
||||||
context?: Record<string, any>
|
|
||||||
options?: Record<string, any>
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取对话列表
|
|
||||||
*/
|
|
||||||
export function getConversations() {
|
|
||||||
return request.get('/ai/conversations')
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取对话详情
|
|
||||||
* @param id 对话ID
|
|
||||||
*/
|
|
||||||
export function getConversationDetail(id: string) {
|
|
||||||
return request.get(`/ai/conversations/${id}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除对话
|
|
||||||
* @param id 对话ID
|
|
||||||
*/
|
|
||||||
export function deleteConversation(id: string) {
|
|
||||||
return request.delete(`/ai/conversations/${id}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 发送聊天消息
|
|
||||||
* @param params 聊天参数
|
|
||||||
*/
|
|
||||||
export function sendChatMessage(params: ChatParams) {
|
|
||||||
return request.post('/ai/chat', params)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 执行 AI 任务
|
|
||||||
* @param params 任务参数
|
|
||||||
*/
|
|
||||||
export function executeTask(params: ExecuteTaskParams) {
|
|
||||||
return request.post('/ai/execute-task', params)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取 AI 能力列表
|
|
||||||
*/
|
|
||||||
export function getCapabilities() {
|
|
||||||
return request.get('/ai/capabilities')
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取模型列表
|
|
||||||
*/
|
|
||||||
export function getModels() {
|
|
||||||
return request.get('/ai/models')
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 切换模型
|
|
||||||
* @param data 包含模型 ID 的数据
|
|
||||||
*/
|
|
||||||
export function switchModel(data: { modelId: string }) {
|
|
||||||
return request.post('/ai/models/switch', data)
|
|
||||||
}
|
|
||||||
@ -1,65 +0,0 @@
|
|||||||
// src/api/brand.ts
|
|
||||||
import request from '@/utils/request'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 品牌数据类型
|
|
||||||
*/
|
|
||||||
export interface Brand {
|
|
||||||
id?: number
|
|
||||||
name: string
|
|
||||||
code?: string
|
|
||||||
logo?: string
|
|
||||||
status?: number
|
|
||||||
description?: string
|
|
||||||
created_at?: string
|
|
||||||
updated_at?: string
|
|
||||||
[key: string]: any
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取品牌列表
|
|
||||||
* @param params 查询参数(page, limit, name, status)
|
|
||||||
*/
|
|
||||||
export function getBrandList(params?: any) {
|
|
||||||
return request.get('/brands', { params })
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取品牌详情
|
|
||||||
* @param id 品牌ID
|
|
||||||
*/
|
|
||||||
export function getBrandDetail(id: number) {
|
|
||||||
return request.get(`/brands/${id}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建品牌
|
|
||||||
* @param data 品牌数据
|
|
||||||
*/
|
|
||||||
export function createBrand(data: Brand) {
|
|
||||||
return request.post('/brands', data)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新品牌
|
|
||||||
* @param id 品牌ID
|
|
||||||
* @param data 更新数据
|
|
||||||
*/
|
|
||||||
export function updateBrand(id: number, data: Partial<Brand>) {
|
|
||||||
return request.put(`/brands/${id}`, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除品牌
|
|
||||||
* @param id 品牌ID
|
|
||||||
*/
|
|
||||||
export function deleteBrand(id: number) {
|
|
||||||
return request.delete(`/brands/${id}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取所有品牌用于下拉选择
|
|
||||||
*/
|
|
||||||
export function getAllBrands() {
|
|
||||||
return request.get('/brands/all')
|
|
||||||
}
|
|
||||||
@ -1,151 +0,0 @@
|
|||||||
import request from '@/utils/request'
|
|
||||||
|
|
||||||
// ==================== 类型定义 ====================
|
|
||||||
|
|
||||||
/** 配送单状态 */
|
|
||||||
export type DeliveryOrderStatus = 'pending' | 'printed' | 'shipped' | 'sync_failed' | 'completed'
|
|
||||||
|
|
||||||
/** 配送单商品项 */
|
|
||||||
export interface DeliveryOrderItem {
|
|
||||||
id?: string
|
|
||||||
skuCode: string
|
|
||||||
skuName?: string
|
|
||||||
quantity: number
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 配送单 */
|
|
||||||
export interface DeliveryOrder {
|
|
||||||
id?: string
|
|
||||||
orderNo?: string
|
|
||||||
warehouseId: string
|
|
||||||
warehouseName?: string
|
|
||||||
platformOrderId?: string
|
|
||||||
platformOrderNo?: string
|
|
||||||
status: DeliveryOrderStatus
|
|
||||||
totalAmount?: number
|
|
||||||
expressCompany?: string
|
|
||||||
trackingNo?: string
|
|
||||||
items: DeliveryOrderItem[]
|
|
||||||
createTime?: string
|
|
||||||
updateTime?: string
|
|
||||||
printTime?: string
|
|
||||||
shipTime?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 待发货列表查询参数 */
|
|
||||||
export interface PendingDeliveryParams {
|
|
||||||
page?: number
|
|
||||||
pageSize?: number
|
|
||||||
warehouseId?: string
|
|
||||||
keyword?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 标记打印请求 */
|
|
||||||
export interface MarkPrintedDto {
|
|
||||||
orderIds: string[]
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 重新打印请求 */
|
|
||||||
export interface ReprintDto {
|
|
||||||
orderIds: string[]
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 发货请求 */
|
|
||||||
export interface ShipDto {
|
|
||||||
orderId: string
|
|
||||||
expressCompany: string
|
|
||||||
trackingNo: string
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 打印日志 */
|
|
||||||
export interface PrintLog {
|
|
||||||
id?: string
|
|
||||||
orderId: string
|
|
||||||
orderNo?: string
|
|
||||||
printType: 'original' | 'reprint'
|
|
||||||
printedAt: string
|
|
||||||
printedBy?: string
|
|
||||||
printer?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 打印日志查询参数 */
|
|
||||||
export interface PrintLogParams {
|
|
||||||
page?: number
|
|
||||||
pageSize?: number
|
|
||||||
orderNo?: string
|
|
||||||
startDate?: string
|
|
||||||
endDate?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
// ==================== API 函数 ====================
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取待发货列表
|
|
||||||
* @param params 查询参数
|
|
||||||
*/
|
|
||||||
export function getPendingDeliveryList(params?: PendingDeliveryParams) {
|
|
||||||
return request.get<PendingDeliveryResponse>('/delivery/pending-delivery', { params })
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 标记已打印
|
|
||||||
* @param data 订单ID列表
|
|
||||||
*/
|
|
||||||
export function markPrinted(data: MarkPrintedDto) {
|
|
||||||
return request.post<void>('/delivery/mark-printed', data)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 重新打印
|
|
||||||
* @param data 订单ID列表
|
|
||||||
*/
|
|
||||||
export function reprintDelivery(data: ReprintDto) {
|
|
||||||
return request.post<void>('/delivery/reprint', data)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取打印日志
|
|
||||||
* @param params 查询参数
|
|
||||||
*/
|
|
||||||
export function getPrintLogs(params?: PrintLogParams) {
|
|
||||||
return request.get<PrintLogResponse>('/delivery/print-logs', { params })
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 发货
|
|
||||||
* @param data 发货信息
|
|
||||||
*/
|
|
||||||
export function shipDelivery(data: ShipDto) {
|
|
||||||
return request.post<void>('/delivery/ship', data)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 同步失败重试(批量)
|
|
||||||
*/
|
|
||||||
export function syncFailedRetry() {
|
|
||||||
return request.post<void>('/delivery/sync-failed')
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 重试同步单个订单
|
|
||||||
* @param id 配送单ID
|
|
||||||
*/
|
|
||||||
export function retrySyncDelivery(id: string) {
|
|
||||||
return request.post<void>(`/delivery/retry-sync/${id}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ==================== 响应类型 ====================
|
|
||||||
|
|
||||||
export interface PendingDeliveryResponse {
|
|
||||||
list: DeliveryOrder[]
|
|
||||||
total: number
|
|
||||||
page: number
|
|
||||||
pageSize: number
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface PrintLogResponse {
|
|
||||||
list: PrintLog[]
|
|
||||||
total: number
|
|
||||||
page: number
|
|
||||||
pageSize: number
|
|
||||||
}
|
|
||||||
227
src/api/goods.ts
227
src/api/goods.ts
@ -1,227 +0,0 @@
|
|||||||
// src/api/goods.ts
|
|
||||||
import request from '@/utils/request'
|
|
||||||
|
|
||||||
// ============ 类型定义 ============
|
|
||||||
|
|
||||||
/** 商品类型 */
|
|
||||||
export type GoodsType = 'normal' | 'combo'
|
|
||||||
|
|
||||||
/** 商品状态 */
|
|
||||||
export type GoodsStatus = 'active' | 'inactive'
|
|
||||||
|
|
||||||
/** 商品 */
|
|
||||||
export interface Goods {
|
|
||||||
id: number
|
|
||||||
name: string
|
|
||||||
code: string
|
|
||||||
barcode?: string
|
|
||||||
type: GoodsType
|
|
||||||
type_label?: string
|
|
||||||
retail_price: string
|
|
||||||
cost_price: string
|
|
||||||
unit?: string
|
|
||||||
brand?: { id: number; name: string } | null
|
|
||||||
suppliers?: string
|
|
||||||
weight?: string
|
|
||||||
packaging_cost?: string
|
|
||||||
shipping_packaging_cost?: string
|
|
||||||
volume?: string
|
|
||||||
length?: string
|
|
||||||
width?: string
|
|
||||||
height?: string
|
|
||||||
batch_management: boolean
|
|
||||||
created_at: string
|
|
||||||
updated_at: string
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 商品列表查询参数 */
|
|
||||||
export interface GoodsListParams {
|
|
||||||
keyword?: string
|
|
||||||
category?: string
|
|
||||||
type?: GoodsType
|
|
||||||
status?: GoodsStatus
|
|
||||||
page?: number
|
|
||||||
limit?: number
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 商品列表响应 */
|
|
||||||
export interface GoodsListResponse {
|
|
||||||
list: Goods[]
|
|
||||||
total: number
|
|
||||||
current_page: number
|
|
||||||
last_page: number
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 创建/更新商品请求 */
|
|
||||||
export interface GoodsFormData {
|
|
||||||
name: string
|
|
||||||
code: string
|
|
||||||
type: GoodsType
|
|
||||||
barcode?: string
|
|
||||||
retail_price?: number | string
|
|
||||||
cost_price?: number | string
|
|
||||||
unit?: string
|
|
||||||
brand_id?: number
|
|
||||||
weight?: number | string
|
|
||||||
packaging_cost?: number | string
|
|
||||||
}
|
|
||||||
|
|
||||||
/** SKU绑定请求 */
|
|
||||||
export interface BindSkuData {
|
|
||||||
goodsId: string
|
|
||||||
skuCode: string
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 批量绑定请求 */
|
|
||||||
export interface BatchBindData {
|
|
||||||
goodsId: string
|
|
||||||
skuCodes: string[]
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 自动匹配请求 */
|
|
||||||
export interface AutoMatchData {
|
|
||||||
warehouseId: string
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 匹配结果查询参数 */
|
|
||||||
export interface MatchResultsParams {
|
|
||||||
warehouseId?: string
|
|
||||||
status?: string
|
|
||||||
page?: number
|
|
||||||
limit?: number
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 匹配结果项 */
|
|
||||||
export interface MatchResult {
|
|
||||||
id: string
|
|
||||||
goodsId: string
|
|
||||||
goodsName: string
|
|
||||||
skuCode: string
|
|
||||||
warehouseId: string
|
|
||||||
warehouseName: string
|
|
||||||
matchStatus: 'matched' | 'unmatched' | 'pending'
|
|
||||||
matchType?: 'auto' | 'manual'
|
|
||||||
createdAt: string
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============ API 函数 ============
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取商品列表(分页)
|
|
||||||
*/
|
|
||||||
export function getGoodsList(params?: GoodsListParams) {
|
|
||||||
return request.get<GoodsListResponse>('/goods', { params })
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取商品详情
|
|
||||||
*/
|
|
||||||
export function getGoodsDetail(id: string | number) {
|
|
||||||
return request.get<Goods>(`/goods/${id}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建商品
|
|
||||||
*/
|
|
||||||
export function createGoods(data: GoodsFormData) {
|
|
||||||
return request.post<Goods>('/goods', data)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新商品
|
|
||||||
*/
|
|
||||||
export function updateGoods(id: string | number, data: Partial<GoodsFormData>) {
|
|
||||||
return request.put<Goods>(`/goods/${id}`, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除商品
|
|
||||||
*/
|
|
||||||
export function deleteGoods(id: string | number) {
|
|
||||||
return request.delete<void>(`/goods/${id}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 全量同步商品
|
|
||||||
* 注意: 后端暂无此接口
|
|
||||||
*/
|
|
||||||
export function syncAllGoods() {
|
|
||||||
return Promise.resolve({
|
|
||||||
code: 200,
|
|
||||||
message: '同步功能开发中',
|
|
||||||
data: null
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 绑定SKU
|
|
||||||
*/
|
|
||||||
export function bindSku(data: BindSkuData) {
|
|
||||||
return request.post<void>('/goods/bind-sku', data)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 解除SKU绑定
|
|
||||||
*/
|
|
||||||
export function unbindSku(data: BindSkuData) {
|
|
||||||
return request.post<void>('/goods/unbind-sku', data)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 批量绑定SKU
|
|
||||||
*/
|
|
||||||
export function batchBindSku(data: BatchBindData) {
|
|
||||||
return request.post<void>('/goods/batch-bind', data)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 自动匹配
|
|
||||||
*/
|
|
||||||
export function autoMatchGoods(data: AutoMatchData) {
|
|
||||||
return request.post<void>('/goods/auto-match', data)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取匹配结果列表
|
|
||||||
*/
|
|
||||||
export function getMatchResults(params?: MatchResultsParams) {
|
|
||||||
return request.get<{ list: MatchResult[]; total: number }>('/goods/match-results', { params })
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 推送商品到云仓
|
|
||||||
* 注意: 后端暂无此接口
|
|
||||||
*/
|
|
||||||
export function pushGoodsToCloud(data: { goodsIds: number[]; warehouseId: number }) {
|
|
||||||
return Promise.resolve({
|
|
||||||
code: 200,
|
|
||||||
message: '推送功能开发中',
|
|
||||||
data: null
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取推送日志
|
|
||||||
* 注意: 后端暂无此接口
|
|
||||||
*/
|
|
||||||
export function getPushLogs(params?: { page?: number; pageSize?: number }) {
|
|
||||||
return Promise.resolve({
|
|
||||||
code: 200,
|
|
||||||
data: {
|
|
||||||
list: [],
|
|
||||||
total: 0,
|
|
||||||
page: params?.page || 1,
|
|
||||||
pageSize: params?.pageSize || 10
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取所有商品(下拉选择用)
|
|
||||||
*/
|
|
||||||
export function getAllGoods() {
|
|
||||||
return request.get('/goods/all')
|
|
||||||
}
|
|
||||||
|
|
||||||
// 别名兼容
|
|
||||||
export const getAllGoodsForSelect = getAllGoods
|
|
||||||
@ -1,65 +0,0 @@
|
|||||||
// 操作日志 API
|
|
||||||
import request from '@/utils/request'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 操作日志项接口定义
|
|
||||||
*/
|
|
||||||
export interface OperationLogItem {
|
|
||||||
id: number
|
|
||||||
operateTime: string
|
|
||||||
userName: string
|
|
||||||
operateType: string
|
|
||||||
operateDesc: string
|
|
||||||
result: number
|
|
||||||
ipAddress: string
|
|
||||||
userAgent: string
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 操作日志列表查询参数
|
|
||||||
*/
|
|
||||||
export interface OperationLogParams {
|
|
||||||
currentPage?: number
|
|
||||||
pageSize?: number
|
|
||||||
keyword?: string
|
|
||||||
operateType?: string
|
|
||||||
startDate?: string
|
|
||||||
endDate?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取操作日志列表
|
|
||||||
* @param params 查询参数
|
|
||||||
*/
|
|
||||||
export function getOperationLogs(params?: OperationLogParams) {
|
|
||||||
return request.get('/operation-logs', { params })
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取操作日志详情
|
|
||||||
* @param id 日志ID
|
|
||||||
*/
|
|
||||||
export function getOperationLogDetail(id: number) {
|
|
||||||
return request.get(`/operation-logs/${id}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 导出操作日志
|
|
||||||
* @param params 导出参数
|
|
||||||
*/
|
|
||||||
export function exportLogs(params?: OperationLogParams) {
|
|
||||||
return request.get('/operation-logs/export', { params })
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 添加操作日志
|
|
||||||
*/
|
|
||||||
export function addOperationLog(data: {
|
|
||||||
operateType: string
|
|
||||||
operateDesc: string
|
|
||||||
result: number
|
|
||||||
userId?: number
|
|
||||||
userName?: string
|
|
||||||
}) {
|
|
||||||
return request.post('/operation-logs', data)
|
|
||||||
}
|
|
||||||
@ -1,76 +0,0 @@
|
|||||||
// src/api/platform-product.ts
|
|
||||||
import request from '@/utils/request'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 平台商品
|
|
||||||
*/
|
|
||||||
export interface PlatformProduct {
|
|
||||||
id: number
|
|
||||||
platform_id: number
|
|
||||||
platform_name: string
|
|
||||||
platform_code: string
|
|
||||||
outer_id: string
|
|
||||||
num_iid: string
|
|
||||||
title: string
|
|
||||||
price: string
|
|
||||||
pic_url: string
|
|
||||||
seller_nick: string
|
|
||||||
approve_status: string
|
|
||||||
listed_time: string
|
|
||||||
unsale_time: string
|
|
||||||
stock: number
|
|
||||||
has_sync: boolean
|
|
||||||
bound_goods_id?: number
|
|
||||||
bound_goods_name?: string
|
|
||||||
bound_sku_code?: string
|
|
||||||
last_sync_at?: string
|
|
||||||
created_at: string
|
|
||||||
updated_at: string
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 平台商品列表查询参数
|
|
||||||
*/
|
|
||||||
export interface PlatformProductListParams {
|
|
||||||
platform_id?: number
|
|
||||||
keyword?: string
|
|
||||||
sync_status?: 'all' | 'synced' | 'unsynced'
|
|
||||||
page?: number
|
|
||||||
limit?: number
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取平台商品列表
|
|
||||||
*/
|
|
||||||
export function getPlatformProductList(params?: PlatformProductListParams) {
|
|
||||||
return request.get<{
|
|
||||||
list: PlatformProduct[]
|
|
||||||
total: number
|
|
||||||
page: number
|
|
||||||
last_page: number
|
|
||||||
}>('/platform-products', { params })
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取平台商品详情
|
|
||||||
*/
|
|
||||||
export function getPlatformProductDetail(id: number) {
|
|
||||||
return request.get<PlatformProduct>(`/platform-products/${id}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 同步平台商品
|
|
||||||
*/
|
|
||||||
export function syncPlatformProducts(platformId: number) {
|
|
||||||
return request.post<{ synced_count: number }>('/platform-products/sync', { platform_id: platformId })
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 绑定平台商品到ERP商品
|
|
||||||
*/
|
|
||||||
export function bindPlatformProduct(platformProductId: number, goodsId: number, skuCode?: string) {
|
|
||||||
return request.post(`/platform-products/${platformProductId}/bind`, {
|
|
||||||
goods_id: goodsId,
|
|
||||||
sku_code: skuCode
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@ -1,113 +0,0 @@
|
|||||||
// src/api/platform.ts
|
|
||||||
import request from '@/utils/request'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 平台数据类型
|
|
||||||
*/
|
|
||||||
export interface Platform {
|
|
||||||
id?: number
|
|
||||||
name: string
|
|
||||||
code: string
|
|
||||||
status?: number
|
|
||||||
created_at?: string
|
|
||||||
updated_at?: string
|
|
||||||
[key: string]: any
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 平台统计数据类型
|
|
||||||
*/
|
|
||||||
export interface PlatformStats {
|
|
||||||
total: number
|
|
||||||
active: number
|
|
||||||
inactive: number
|
|
||||||
today_add: number
|
|
||||||
[key: string]: any
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取平台列表
|
|
||||||
* @param params 查询参数(page, limit, name, status)
|
|
||||||
*/
|
|
||||||
export function getPlatformList(params?: any) {
|
|
||||||
return request.get('/platforms', { params })
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取平台详情
|
|
||||||
* @param id 平台ID
|
|
||||||
*/
|
|
||||||
export function getPlatformDetail(id: number) {
|
|
||||||
return request.get(`/platforms/${id}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建平台
|
|
||||||
* @param data 平台数据
|
|
||||||
*/
|
|
||||||
export function createPlatform(data: Platform) {
|
|
||||||
return request.post('/platforms', data)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新平台
|
|
||||||
* @param id 平台ID
|
|
||||||
* @param data 更新数据
|
|
||||||
*/
|
|
||||||
export function updatePlatform(id: number, data: Partial<Platform>) {
|
|
||||||
return request.put(`/platforms/${id}`, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除平台
|
|
||||||
* @param id 平台ID
|
|
||||||
*/
|
|
||||||
export function deletePlatform(id: number) {
|
|
||||||
return request.delete(`/platforms/${id}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 同步平台数据
|
|
||||||
*/
|
|
||||||
export function syncPlatform() {
|
|
||||||
return request.post('/platforms/sync')
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 批量更新平台
|
|
||||||
* @param data 批量更新数据
|
|
||||||
*/
|
|
||||||
export function batchUpdatePlatform(data: Partial<Platform>[]) {
|
|
||||||
return request.post('/platforms/batch-update', data)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取平台统计
|
|
||||||
*/
|
|
||||||
export function getPlatformStats() {
|
|
||||||
return request.get('/platforms/stats')
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取所有平台用于下拉选择
|
|
||||||
*/
|
|
||||||
export function getAllPlatforms() {
|
|
||||||
return request.get('/platforms/all')
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取面单账号列表
|
|
||||||
*/
|
|
||||||
export function getWaybillAccounts(platformId?: number) {
|
|
||||||
return Promise.resolve({
|
|
||||||
code: 200,
|
|
||||||
data: { list: [], total: 0 }
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 同步面单账号
|
|
||||||
*/
|
|
||||||
export function syncWaybillAccounts(platformId: number) {
|
|
||||||
return Promise.resolve({ code: 200, message: '功能开发中', data: null })
|
|
||||||
}
|
|
||||||
@ -1,166 +0,0 @@
|
|||||||
// src/api/platformGoods.ts
|
|
||||||
|
|
||||||
// 模拟店铺数据
|
|
||||||
const mockShops = {
|
|
||||||
taobao: [
|
|
||||||
{ id: 'tb1', name: '淘宝官方旗舰店' },
|
|
||||||
{ id: 'tb2', name: '淘宝专营店' }
|
|
||||||
],
|
|
||||||
jd: [
|
|
||||||
{ id: 'jd1', name: '京东自营店' },
|
|
||||||
{ id: 'jd2', name: '京东专营店' }
|
|
||||||
],
|
|
||||||
pdd: [
|
|
||||||
{ id: 'pdd1', name: '拼多多官方旗舰店' },
|
|
||||||
{ id: 'pdd2', name: '拼多多专营店' }
|
|
||||||
],
|
|
||||||
douyin: [
|
|
||||||
{ id: 'dy1', name: '抖音小店' },
|
|
||||||
{ id: 'dy2', name: '抖音专营店' }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
// 模拟平台商品数据(按平台和店铺组织)
|
|
||||||
const mockPlatformGoods: Record<string, Record<string, any[]>> = {
|
|
||||||
taobao: {
|
|
||||||
tb1: [
|
|
||||||
{
|
|
||||||
id: 'tb_spu_1',
|
|
||||||
type: 'spu',
|
|
||||||
name: '连衣裙',
|
|
||||||
code: 'TB-SPU-001',
|
|
||||||
price: 199.0,
|
|
||||||
status: 'onsale',
|
|
||||||
bound: false,
|
|
||||||
skus: [
|
|
||||||
{
|
|
||||||
id: 'tb_sku_11',
|
|
||||||
spuId: 'tb_spu_1',
|
|
||||||
type: 'sku',
|
|
||||||
name: '红色-S',
|
|
||||||
code: 'TB-SKU-001-R-S',
|
|
||||||
price: 199.0,
|
|
||||||
status: 'onsale',
|
|
||||||
bound: false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'tb_sku_12',
|
|
||||||
spuId: 'tb_spu_1',
|
|
||||||
type: 'sku',
|
|
||||||
name: '红色-M',
|
|
||||||
code: 'TB-SKU-001-R-M',
|
|
||||||
price: 199.0,
|
|
||||||
status: 'onsale',
|
|
||||||
bound: true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'tb_spu_2',
|
|
||||||
type: 'spu',
|
|
||||||
name: '运动鞋',
|
|
||||||
code: 'TB-SPU-002',
|
|
||||||
price: 299.0,
|
|
||||||
status: 'onsale',
|
|
||||||
bound: false,
|
|
||||||
skus: [
|
|
||||||
{
|
|
||||||
id: 'tb_sku_21',
|
|
||||||
spuId: 'tb_spu_2',
|
|
||||||
type: 'sku',
|
|
||||||
name: '白色-42',
|
|
||||||
code: 'TB-SKU-002-W-42',
|
|
||||||
price: 299.0,
|
|
||||||
status: 'onsale',
|
|
||||||
bound: false
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
tb2: []
|
|
||||||
},
|
|
||||||
jd: {},
|
|
||||||
pdd: {},
|
|
||||||
douyin: {}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 辅助函数:平台代码转中文名称
|
|
||||||
function getPlatformName(platform: string): string {
|
|
||||||
const map: Record<string, string> = {
|
|
||||||
taobao: '淘宝',
|
|
||||||
jd: '京东',
|
|
||||||
pdd: '拼多多',
|
|
||||||
douyin: '抖音'
|
|
||||||
}
|
|
||||||
return map[platform] || platform
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取平台-店铺树结构
|
|
||||||
*/
|
|
||||||
export function getPlatformShopTree() {
|
|
||||||
return new Promise<{ code: number; data: any[] }>((resolve) => {
|
|
||||||
setTimeout(() => {
|
|
||||||
const tree = Object.keys(mockShops).map(platform => ({
|
|
||||||
id: `platform-${platform}`,
|
|
||||||
label: getPlatformName(platform),
|
|
||||||
type: 'platform',
|
|
||||||
platform,
|
|
||||||
children: mockShops[platform].map(shop => ({
|
|
||||||
id: `shop-${shop.id}`,
|
|
||||||
label: shop.name,
|
|
||||||
type: 'shop',
|
|
||||||
platform,
|
|
||||||
shopId: shop.id,
|
|
||||||
leaf: true
|
|
||||||
}))
|
|
||||||
}))
|
|
||||||
resolve({ code: 200, data: tree })
|
|
||||||
}, 200)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取店铺列表(兼容旧接口)
|
|
||||||
export function getShopsByPlatform(platform: string) {
|
|
||||||
return new Promise<{ code: number; data: any[] }>((resolve) => {
|
|
||||||
setTimeout(() => {
|
|
||||||
resolve({ code: 200, data: mockShops[platform] || [] })
|
|
||||||
}, 200)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 下载平台商品
|
|
||||||
export function downloadPlatformGoods(params: {
|
|
||||||
platform: string
|
|
||||||
shopId: string
|
|
||||||
downloadType: string
|
|
||||||
specifyIds?: string
|
|
||||||
}) {
|
|
||||||
console.log('downloadPlatformGoods called with params:', params)
|
|
||||||
return new Promise<{ code: number; message?: string }>((resolve) => {
|
|
||||||
setTimeout(() => {
|
|
||||||
resolve({ code: 200, message: '下载任务已提交' })
|
|
||||||
}, 500)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取已下载的平台商品列表
|
|
||||||
export function getPlatformGoodsList(params: { platform: string; shopId: string }) {
|
|
||||||
console.log('getPlatformGoodsList called with params:', params)
|
|
||||||
return new Promise<{ code: number; data: any[] }>((resolve) => {
|
|
||||||
setTimeout(() => {
|
|
||||||
const goods = mockPlatformGoods[params.platform]?.[params.shopId] || []
|
|
||||||
resolve({ code: 200, data: goods })
|
|
||||||
}, 300)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 绑定ERP商品与平台SKU
|
|
||||||
export function bindErpSku(data: { skuId: string; erpGoodsId: string }) {
|
|
||||||
console.log('bindErpSku called with data:', data)
|
|
||||||
return new Promise<{ code: number; message?: string }>((resolve) => {
|
|
||||||
setTimeout(() => {
|
|
||||||
resolve({ code: 200, message: '绑定成功' })
|
|
||||||
}, 300)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@ -1,119 +0,0 @@
|
|||||||
// 打印任务 API
|
|
||||||
import request from '@/utils/request'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建打印任务
|
|
||||||
*/
|
|
||||||
export function createJob(data: {
|
|
||||||
platform: string
|
|
||||||
plugin_code: string
|
|
||||||
order_id?: number
|
|
||||||
template_id?: number
|
|
||||||
print_data: Record<string, any>
|
|
||||||
priority?: number
|
|
||||||
}) {
|
|
||||||
return request.post('/print-jobs', data)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 批量创建打印任务
|
|
||||||
*/
|
|
||||||
export function createBatchJobs(data: {
|
|
||||||
platform: string
|
|
||||||
plugin_code: string
|
|
||||||
template_id?: number
|
|
||||||
orders: Array<{
|
|
||||||
order_id?: number
|
|
||||||
priority?: number
|
|
||||||
print_data: Record<string, any>
|
|
||||||
}>
|
|
||||||
}) {
|
|
||||||
return request.post('/print-jobs/batch', data)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取打印队列
|
|
||||||
*/
|
|
||||||
export function getQueue(params?: {
|
|
||||||
status?: string
|
|
||||||
platform?: string
|
|
||||||
page?: number
|
|
||||||
pageSize?: number
|
|
||||||
}) {
|
|
||||||
return request.get('/print-jobs/queue', { params })
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取打印历史
|
|
||||||
*/
|
|
||||||
export function getHistory(params?: {
|
|
||||||
page?: number
|
|
||||||
per_page?: number
|
|
||||||
}) {
|
|
||||||
return request.get('/print-jobs/history', { params })
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取打印统计
|
|
||||||
*/
|
|
||||||
export function getStats() {
|
|
||||||
return request.get('/print-jobs/stats')
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 批量加入队列
|
|
||||||
*/
|
|
||||||
export function batchQueue(jobIds: number[]) {
|
|
||||||
return request.post('/print-jobs/batch-queue', { job_ids: jobIds })
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 清空已完成任务
|
|
||||||
*/
|
|
||||||
export function clearCompleted() {
|
|
||||||
return request.post('/print-jobs/clear-completed')
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 重试任务
|
|
||||||
*/
|
|
||||||
export function retryJob(jobId: number) {
|
|
||||||
return request.post(`/print-jobs/${jobId}/retry`)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 取消任务
|
|
||||||
*/
|
|
||||||
export function cancelJob(jobId: number) {
|
|
||||||
return request.post(`/print-jobs/${jobId}/cancel`)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ========== 设备端 API(插件调用)==========
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取下一个待打印任务
|
|
||||||
*/
|
|
||||||
export function getNextJob(deviceId: string) {
|
|
||||||
return request.get('/print-device/next-job', { params: { device_id: deviceId } })
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 认领打印任务
|
|
||||||
*/
|
|
||||||
export function claimJob(jobId: number, deviceId: string) {
|
|
||||||
return request.post('/print-device/claim', { job_id: jobId, device_id: deviceId })
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 标记打印完成
|
|
||||||
*/
|
|
||||||
export function completeJob(jobId: number, deviceId: string) {
|
|
||||||
return request.post('/print-device/complete', { job_id: jobId, device_id: deviceId })
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 标记打印失败
|
|
||||||
*/
|
|
||||||
export function failJob(jobId: number, error: string, deviceId?: string) {
|
|
||||||
return request.post('/print-device/fail', { job_id: jobId, error, device_id: deviceId })
|
|
||||||
}
|
|
||||||
@ -1,78 +0,0 @@
|
|||||||
// 打印插件管理 API
|
|
||||||
import request from '@/utils/request'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取插件列表
|
|
||||||
*/
|
|
||||||
export function getPlugins(platform?: string) {
|
|
||||||
return request.get('/print-plugins', { params: { platform } })
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取插件详情
|
|
||||||
*/
|
|
||||||
export function getPlugin(code: string) {
|
|
||||||
return request.get(`/print-plugins/${code}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取插件最新版本
|
|
||||||
*/
|
|
||||||
export function getLatestVersion(code: string) {
|
|
||||||
return request.get(`/print-plugins/${code}/version`)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 下载插件
|
|
||||||
*/
|
|
||||||
export function downloadPlugin(code: string) {
|
|
||||||
return request.get(`/print-plugins/${code}/download`, { responseType: 'blob' })
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取用户已安装插件
|
|
||||||
*/
|
|
||||||
export function getInstallations() {
|
|
||||||
return request.get('/print-plugins/auth/installations')
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 检查插件版本
|
|
||||||
*/
|
|
||||||
export function checkVersion(pluginCode: string, deviceId: string) {
|
|
||||||
return request.post('/print-plugins/auth/check-version', { plugin_code: pluginCode, device_id: deviceId })
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 注册插件安装
|
|
||||||
*/
|
|
||||||
export function registerPlugin(data: {
|
|
||||||
plugin_code: string
|
|
||||||
version: string
|
|
||||||
device_id: string
|
|
||||||
device_name?: string
|
|
||||||
os_version?: string
|
|
||||||
}) {
|
|
||||||
return request.post('/print-plugins/auth/register', data)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 发送心跳
|
|
||||||
*/
|
|
||||||
export function sendHeartbeat(deviceId: string) {
|
|
||||||
return request.post('/print-plugins/auth/heartbeat', { device_id: deviceId })
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 卸载插件
|
|
||||||
*/
|
|
||||||
export function uninstall(pluginCode: string, deviceId: string) {
|
|
||||||
return request.post('/print-plugins/auth/uninstall', { plugin_code: pluginCode, device_id: deviceId })
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取设备状态
|
|
||||||
*/
|
|
||||||
export function getDeviceStatus(deviceId: string) {
|
|
||||||
return request.get(`/print-plugins/auth/device/${deviceId}/status`)
|
|
||||||
}
|
|
||||||
414
src/api/print.ts
414
src/api/print.ts
@ -1,414 +0,0 @@
|
|||||||
import request from '@/utils/request'
|
|
||||||
|
|
||||||
export interface OrderItem {
|
|
||||||
id: number
|
|
||||||
shortId: string
|
|
||||||
platformOrderSn: string
|
|
||||||
shopName: string
|
|
||||||
platformName: string
|
|
||||||
createTime: string
|
|
||||||
receiverName: string
|
|
||||||
receiverPhone: string
|
|
||||||
receiverAddress: string
|
|
||||||
goodsAmount: string
|
|
||||||
erpStatus: number
|
|
||||||
isBindErp: boolean
|
|
||||||
platformGoodsName: string
|
|
||||||
erpGoodsName: string
|
|
||||||
platformSku: string
|
|
||||||
erpSku: string
|
|
||||||
goodsName: string
|
|
||||||
bindStatusText: string
|
|
||||||
warehouseName?: string
|
|
||||||
warehouseType?: string
|
|
||||||
expressName?: string
|
|
||||||
expressId?: string
|
|
||||||
items?: any[]
|
|
||||||
printResult?: number
|
|
||||||
printLogs?: any[]
|
|
||||||
printError?: string
|
|
||||||
expressNo?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface PrintBatchItem {
|
|
||||||
id: number
|
|
||||||
batchNo: string
|
|
||||||
printTime: string
|
|
||||||
printUserId: number
|
|
||||||
printUserName: string
|
|
||||||
orderCount: number
|
|
||||||
status: number // 0:打印中,1:成功,2:部分成功,3:失败
|
|
||||||
remark: string
|
|
||||||
createdAt: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface PrintBatchDetail extends PrintBatchItem {
|
|
||||||
orders: Array<OrderItem & { printSuccess?: boolean; errorMsg?: string; expressNo?: string }>
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface CreateBatchParams {
|
|
||||||
orderIds: number[]
|
|
||||||
orders: Array<OrderItem & { printSuccess?: boolean; errorMsg?: string; expressNo?: string }>
|
|
||||||
remark?: string
|
|
||||||
printUserId: number
|
|
||||||
printUserName: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface BatchListParams {
|
|
||||||
batchNo?: string
|
|
||||||
startDate?: string
|
|
||||||
endDate?: string
|
|
||||||
printUser?: string
|
|
||||||
status?: number
|
|
||||||
currentPage: number
|
|
||||||
pageSize: number
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ApiResponse<T> {
|
|
||||||
code: number
|
|
||||||
data: T
|
|
||||||
message?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ExpressItem {
|
|
||||||
id: string
|
|
||||||
name: string
|
|
||||||
code: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface TemplateItem {
|
|
||||||
id: string
|
|
||||||
name: string
|
|
||||||
expressId: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface PrinterStatus {
|
|
||||||
type: 'idle' | 'printing' | 'error'
|
|
||||||
errorCode?: string
|
|
||||||
message?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ExpressBalance {
|
|
||||||
expressId: string
|
|
||||||
expressName: string
|
|
||||||
platform: string
|
|
||||||
balance: number
|
|
||||||
warningThreshold?: number
|
|
||||||
status: 'normal' | 'low' | 'empty'
|
|
||||||
message?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
// 模拟数据
|
|
||||||
const mockExpressList: ExpressItem[] = [
|
|
||||||
{ id: '1', name: '顺丰速运', code: 'SF' },
|
|
||||||
{ id: '2', name: '中通快递', code: 'ZTO' },
|
|
||||||
{ id: '3', name: '圆通速递', code: 'YTO' },
|
|
||||||
{ id: '4', name: '韵达快递', code: 'YD' }
|
|
||||||
]
|
|
||||||
|
|
||||||
const mockTemplateList: TemplateItem[] = [
|
|
||||||
{ id: '101', name: '标准模板', expressId: '1' },
|
|
||||||
{ id: '102', name: '生鲜模板', expressId: '1' },
|
|
||||||
{ id: '201', name: '标准模板', expressId: '2' },
|
|
||||||
{ id: '301', name: '标准模板', expressId: '3' }
|
|
||||||
]
|
|
||||||
|
|
||||||
const PRINT_BATCH_STORAGE_KEY = 'print_batches'
|
|
||||||
|
|
||||||
// 从 localStorage 加载批次
|
|
||||||
const loadPrintBatches = (): PrintBatchDetail[] => {
|
|
||||||
const stored = localStorage.getItem(PRINT_BATCH_STORAGE_KEY)
|
|
||||||
if (stored) {
|
|
||||||
try {
|
|
||||||
return JSON.parse(stored)
|
|
||||||
} catch (e) {
|
|
||||||
console.error('解析打印批次失败', e)
|
|
||||||
return []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return []
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getPrintBatches(params: BatchListParams): Promise<ApiResponse<{ list: PrintBatchItem[]; total: number }>> {
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
setTimeout(() => {
|
|
||||||
let list: PrintBatchItem[] = loadPrintBatches()
|
|
||||||
if (params.batchNo) {
|
|
||||||
list = list.filter(b => b.batchNo.includes(params.batchNo))
|
|
||||||
}
|
|
||||||
if (params.startDate && params.endDate) {
|
|
||||||
list = list.filter(b => b.printTime >= params.startDate && b.printTime <= params.endDate)
|
|
||||||
}
|
|
||||||
if (params.printUser) {
|
|
||||||
list = list.filter(b => b.printUserName === params.printUser)
|
|
||||||
}
|
|
||||||
if (params.status !== undefined) {
|
|
||||||
list = list.filter(b => b.status === params.status)
|
|
||||||
}
|
|
||||||
list.sort((a, b) => new Date(b.printTime).getTime() - new Date(a.printTime).getTime())
|
|
||||||
const total = list.length
|
|
||||||
const start = (params.currentPage - 1) * params.pageSize
|
|
||||||
const end = start + params.pageSize
|
|
||||||
list = list.slice(start, end)
|
|
||||||
resolve({ code: 200, data: { list, total } })
|
|
||||||
}, 300)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getPrintBatchDetail(id: string | number): Promise<ApiResponse<PrintBatchDetail>> {
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
setTimeout(() => {
|
|
||||||
const batches = loadPrintBatches()
|
|
||||||
const batch = batches.find(b => b.id === Number(id))
|
|
||||||
if (!batch) {
|
|
||||||
// 动态生成模拟数据
|
|
||||||
const fakeBatch: PrintBatchDetail = {
|
|
||||||
id: Number(id),
|
|
||||||
batchNo: `PRT${String(id).padStart(12, '0')}`,
|
|
||||||
printTime: new Date().toLocaleString(),
|
|
||||||
printUserId: 1001,
|
|
||||||
printUserName: 'admin',
|
|
||||||
orderCount: 3,
|
|
||||||
status: 1,
|
|
||||||
remark: '动态生成的模拟批次(原批次不存在)',
|
|
||||||
createdAt: new Date().toLocaleString(),
|
|
||||||
orders: [
|
|
||||||
{
|
|
||||||
id: 1,
|
|
||||||
shortId: 'S001',
|
|
||||||
platformOrderSn: 'PDD123456',
|
|
||||||
shopName: '拼多多专营店',
|
|
||||||
platformName: '拼多多',
|
|
||||||
createTime: '2025-03-08 09:00:00',
|
|
||||||
receiverName: '张三',
|
|
||||||
receiverPhone: '13800138001',
|
|
||||||
receiverAddress: '北京市朝阳区xx路1号',
|
|
||||||
goodsAmount: '100.00',
|
|
||||||
erpStatus: 1,
|
|
||||||
isBindErp: true,
|
|
||||||
platformGoodsName: '商品A',
|
|
||||||
erpGoodsName: '商品A',
|
|
||||||
platformSku: 'SKU-A',
|
|
||||||
erpSku: 'SKU-A',
|
|
||||||
goodsName: '商品A',
|
|
||||||
bindStatusText: '已绑定',
|
|
||||||
warehouseName: '主仓',
|
|
||||||
warehouseType: 'erp',
|
|
||||||
expressName: '顺丰速运',
|
|
||||||
expressId: '1',
|
|
||||||
printSuccess: true,
|
|
||||||
expressNo: 'SF1234567890'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
resolve({ code: 200, data: fakeBatch, message: '批次不存在,已返回模拟数据' })
|
|
||||||
return
|
|
||||||
}
|
|
||||||
resolve({ code: 200, data: batch })
|
|
||||||
}, 300)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export function reprintBatch(id: number): Promise<ApiResponse<null>> {
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
setTimeout(() => {
|
|
||||||
resolve({ code: 200, data: null, message: '重新打印任务已提交' })
|
|
||||||
}, 300)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createPrintBatch(data: CreateBatchParams): Promise<ApiResponse<PrintBatchDetail>> {
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
setTimeout(() => {
|
|
||||||
const batches = loadPrintBatches()
|
|
||||||
const successCount = data.orders.filter(o => o.printSuccess).length
|
|
||||||
let status: number
|
|
||||||
if (successCount === data.orders.length) status = 1
|
|
||||||
else if (successCount > 0) status = 2
|
|
||||||
else status = 3
|
|
||||||
|
|
||||||
const newBatch: PrintBatchDetail = {
|
|
||||||
id: Date.now(),
|
|
||||||
batchNo: `PRT${new Date().toISOString().slice(0,10).replace(/-/g,'')}${String(Math.floor(Math.random()*10000)).padStart(6,'0')}`,
|
|
||||||
printTime: new Date().toLocaleString(),
|
|
||||||
printUserId: data.printUserId,
|
|
||||||
printUserName: data.printUserName,
|
|
||||||
orderCount: data.orders.length,
|
|
||||||
status,
|
|
||||||
remark: data.remark || '',
|
|
||||||
createdAt: new Date().toLocaleString(),
|
|
||||||
orders: data.orders.map(order => ({ ...order }))
|
|
||||||
}
|
|
||||||
batches.unshift(newBatch)
|
|
||||||
localStorage.setItem(PRINT_BATCH_STORAGE_KEY, JSON.stringify(batches))
|
|
||||||
resolve({ code: 200, data: newBatch })
|
|
||||||
}, 300)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getExpressList(): Promise<ApiResponse<ExpressItem[]>> {
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
setTimeout(() => resolve({ code: 200, data: mockExpressList }), 200)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getTemplateList(expressId?: string): Promise<ApiResponse<TemplateItem[]>> {
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
setTimeout(() => {
|
|
||||||
let list = mockTemplateList
|
|
||||||
if (expressId) list = list.filter(t => t.expressId === expressId)
|
|
||||||
resolve({ code: 200, data: list })
|
|
||||||
}, 200)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export function generateWaybill(params: any): Promise<ApiResponse<{ html: string }>> {
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
setTimeout(() => {
|
|
||||||
const express = mockExpressList.find(e => e.id === params.expressId)
|
|
||||||
const template = mockTemplateList.find(t => t.id === params.templateId)
|
|
||||||
const html = `
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>电子面单</title>
|
|
||||||
<style>
|
|
||||||
body { font-family: 'SimHei', sans-serif; margin: 20px; }
|
|
||||||
.waybill { border: 1px solid #333; padding: 20px; width: 300px; margin: 0 auto; position: relative; }
|
|
||||||
h3 { text-align: center; }
|
|
||||||
.info { margin: 10px 0; }
|
|
||||||
.seq { position: absolute; top: 10px; right: 10px; font-size: 20px; font-weight: bold; color: #f00; }
|
|
||||||
.tracking-number { font-size: 18px; font-weight: bold; color: #000; margin: 10px 0; }
|
|
||||||
.print-time { position: absolute; bottom: 10px; right: 10px; font-size: 12px; color: #999; }
|
|
||||||
.batch-no { position: absolute; bottom: 10px; left: 10px; font-size: 12px; color: #999; }
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="waybill">
|
|
||||||
<div class="seq">#${params.seq || 'N/A'}</div>
|
|
||||||
<h3>电子面单</h3>
|
|
||||||
<div class="tracking-number">运单号:${params.expressNo || 'SF' + Date.now()}</div>
|
|
||||||
<div class="info">快递公司:${express?.name || '未知'}</div>
|
|
||||||
<div class="info">模板:${template?.name || '未知'}</div>
|
|
||||||
<div class="info">订单ID:${params.orderId}</div>
|
|
||||||
<div class="info">收件人:张三</div>
|
|
||||||
<div class="info">地址:北京市朝阳区xx路1号</div>
|
|
||||||
<div class="info">联系电话:13800138001</div>
|
|
||||||
<div class="print-time">打印时间:${params.printTime || new Date().toLocaleString()}</div>
|
|
||||||
<div class="batch-no">批次号:${params.batchNo || ''}</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
`
|
|
||||||
resolve({ code: 200, data: { html } })
|
|
||||||
}, 300)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export function testPrinterConnection(port: number, path: string = ''): Promise<boolean> {
|
|
||||||
return Promise.resolve(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
export function queryManualPrinterStatus(port: number, path: string = ''): Promise<{ ready: boolean; error?: string }> {
|
|
||||||
return Promise.resolve({ ready: true })
|
|
||||||
}
|
|
||||||
|
|
||||||
export function connectManualPrinterStatus(port: number, path: string = '') {}
|
|
||||||
export function disconnectPrinterStatus() {}
|
|
||||||
export function onPrinterStatus(callback: (status: PrinterStatus) => void) { return () => {} }
|
|
||||||
|
|
||||||
export function queryExpressBalance(expressIds?: string[]): Promise<ApiResponse<ExpressBalance[]>> {
|
|
||||||
return Promise.resolve({
|
|
||||||
code: 200,
|
|
||||||
data: [
|
|
||||||
{ expressId: '1', expressName: '顺丰速运', platform: 'all', balance: 150, status: 'normal' },
|
|
||||||
{ expressId: '2', expressName: '中通快递', platform: 'pdd', balance: 35, status: 'normal' }
|
|
||||||
]
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export function fetchExpressNumbers(expressIds: string[]): Promise<ApiResponse<Array<{ expressId: string; expressName: string; success: boolean; message?: string }>>> {
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
setTimeout(() => {
|
|
||||||
const results = expressIds.map(id => {
|
|
||||||
const express = mockExpressList.find(e => e.id === id)
|
|
||||||
const name = express?.name || '未知'
|
|
||||||
const success = Math.random() > 0.3
|
|
||||||
let message = ''
|
|
||||||
if (!success) {
|
|
||||||
const reasons = ['面单余额不足,请联系快递充值', '该区域不可达,请更换快递', '快递接口异常', '请稍后重试']
|
|
||||||
message = reasons[Math.floor(Math.random() * reasons.length)]
|
|
||||||
}
|
|
||||||
return { expressId: id, expressName: name, success, message }
|
|
||||||
})
|
|
||||||
resolve({ code: 200, data: results })
|
|
||||||
}, 800)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取所有订单打印记录(扁平化)
|
|
||||||
export function getOrderPrintLogs(params: any): Promise<ApiResponse<{ list: any[]; total: number }>> {
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
setTimeout(() => {
|
|
||||||
const batches = loadPrintBatches()
|
|
||||||
let orders: any[] = []
|
|
||||||
batches.forEach(batch => {
|
|
||||||
if (batch.orders && Array.isArray(batch.orders)) {
|
|
||||||
batch.orders.forEach(order => {
|
|
||||||
orders.push({
|
|
||||||
...order,
|
|
||||||
batchId: batch.id,
|
|
||||||
batchNo: batch.batchNo,
|
|
||||||
batchPrintTime: batch.printTime,
|
|
||||||
batchStatus: batch.status
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
// 如果没有订单数据,返回模拟数据以便测试
|
|
||||||
if (orders.length === 0) {
|
|
||||||
orders = [
|
|
||||||
{
|
|
||||||
id: 1001,
|
|
||||||
shortId: 'S001',
|
|
||||||
platformOrderSn: 'PDD123456789',
|
|
||||||
batchId: 999,
|
|
||||||
batchNo: 'PRT202603090001',
|
|
||||||
batchPrintTime: '2026-03-09 14:30:00',
|
|
||||||
receiverName: '张三',
|
|
||||||
goodsAmount: '199.00',
|
|
||||||
expressName: '顺丰速运',
|
|
||||||
expressId: '1',
|
|
||||||
expressNo: 'SF1234567890',
|
|
||||||
printSuccess: true,
|
|
||||||
errorMsg: undefined
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 1002,
|
|
||||||
shortId: 'S002',
|
|
||||||
platformOrderSn: 'JD987654321',
|
|
||||||
batchId: 999,
|
|
||||||
batchNo: 'PRT202603090001',
|
|
||||||
batchPrintTime: '2026-03-09 14:30:00',
|
|
||||||
receiverName: '李四',
|
|
||||||
goodsAmount: '299.00',
|
|
||||||
expressName: '中通快递',
|
|
||||||
expressId: '2',
|
|
||||||
expressNo: 'ZTO987654321',
|
|
||||||
printSuccess: false,
|
|
||||||
errorMsg: '面单余额不足'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
// 按打印时间倒序
|
|
||||||
orders.sort((a, b) => new Date(b.batchPrintTime).getTime() - new Date(a.batchPrintTime).getTime())
|
|
||||||
const total = orders.length
|
|
||||||
// 处理分页参数
|
|
||||||
const currentPage = params.currentPage || 1
|
|
||||||
const pageSize = params.pageSize || 10
|
|
||||||
const start = (currentPage - 1) * pageSize
|
|
||||||
const end = start + pageSize
|
|
||||||
const list = orders.slice(start, end)
|
|
||||||
resolve({ code: 200, data: { list, total } })
|
|
||||||
}, 300)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@ -1,172 +0,0 @@
|
|||||||
import request from '@/utils/request'
|
|
||||||
|
|
||||||
// ==================== 类型定义 ====================
|
|
||||||
|
|
||||||
/** 采购单状态 */
|
|
||||||
export type PurchaseOrderStatus = 'draft' | 'pending_review' | 'approved' | 'rejected' | 'pushed' | 'cancelled'
|
|
||||||
|
|
||||||
/** 采购单商品项 */
|
|
||||||
export interface PurchaseOrderItem {
|
|
||||||
id?: string
|
|
||||||
skuCode: string
|
|
||||||
skuName?: string
|
|
||||||
quantity: number
|
|
||||||
unitPrice?: number
|
|
||||||
totalPrice?: number
|
|
||||||
receivedQuantity?: number
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 采购单 */
|
|
||||||
export interface PurchaseOrder {
|
|
||||||
id?: string
|
|
||||||
orderNo?: string
|
|
||||||
supplierId: string
|
|
||||||
supplierName?: string
|
|
||||||
warehouseId: string
|
|
||||||
warehouseName?: string
|
|
||||||
status: PurchaseOrderStatus
|
|
||||||
totalAmount?: number
|
|
||||||
remark?: string
|
|
||||||
items: PurchaseOrderItem[]
|
|
||||||
createTime?: string
|
|
||||||
updateTime?: string
|
|
||||||
reviewer?: string
|
|
||||||
reviewTime?: string
|
|
||||||
reviewComment?: string
|
|
||||||
cloudPushTime?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 采购单列表查询参数 */
|
|
||||||
export interface PurchaseListParams {
|
|
||||||
page?: number
|
|
||||||
pageSize?: number
|
|
||||||
status?: PurchaseOrderStatus
|
|
||||||
supplierId?: string
|
|
||||||
warehouseId?: string
|
|
||||||
keyword?: string
|
|
||||||
startDate?: string
|
|
||||||
endDate?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 创建采购单请求 */
|
|
||||||
export interface CreatePurchaseOrderDto {
|
|
||||||
supplierId: string
|
|
||||||
warehouseId: string
|
|
||||||
remark?: string
|
|
||||||
items: PurchaseOrderItem[]
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 更新采购单请求 */
|
|
||||||
export interface UpdatePurchaseOrderDto {
|
|
||||||
supplierId?: string
|
|
||||||
warehouseId?: string
|
|
||||||
remark?: string
|
|
||||||
items?: PurchaseOrderItem[]
|
|
||||||
}
|
|
||||||
|
|
||||||
// ==================== API 函数 ====================
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取采购单列表
|
|
||||||
* @param params 查询参数
|
|
||||||
*/
|
|
||||||
export function getPurchaseList(params?: PurchaseListParams) {
|
|
||||||
return request.get<PurchaseListResponse>('/purchase-orders', { params })
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取采购单详情
|
|
||||||
* @param id 采购单ID
|
|
||||||
*/
|
|
||||||
export function getPurchaseDetail(id: string) {
|
|
||||||
return request.get<PurchaseOrder>(`/purchase-orders/${id}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建采购单
|
|
||||||
* @param data 采购单数据
|
|
||||||
*/
|
|
||||||
export function createPurchaseOrder(data: CreatePurchaseOrderDto) {
|
|
||||||
return request.post<PurchaseOrder>('/purchase-orders', data)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新采购单
|
|
||||||
* @param id 采购单ID
|
|
||||||
* @param data 更新数据
|
|
||||||
*/
|
|
||||||
export function updatePurchaseOrder(id: string, data: UpdatePurchaseOrderDto) {
|
|
||||||
return request.put<PurchaseOrder>(`/purchase-orders/${id}`, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 提交采购单审核
|
|
||||||
* @param id 采购单ID
|
|
||||||
*/
|
|
||||||
export function submitPurchaseReview(id: string) {
|
|
||||||
return request.post<void>(`/purchase-orders/${id}/submit-review`)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 审核通过采购单
|
|
||||||
* @param id 采购单ID
|
|
||||||
*/
|
|
||||||
export function approvePurchaseOrder(id: string) {
|
|
||||||
return request.post<void>(`/purchase-orders/${id}/approve`)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 驳回采购单
|
|
||||||
* @param id 采购单ID
|
|
||||||
* @param comment 驳回原因
|
|
||||||
*/
|
|
||||||
export function rejectPurchaseOrder(id: string, comment: string) {
|
|
||||||
return request.post<void>(`/purchase-orders/${id}/reject`, { comment })
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 推送采购单到云仓
|
|
||||||
* @param id 采购单ID
|
|
||||||
*/
|
|
||||||
export function pushPurchaseToCloud(id: string) {
|
|
||||||
return request.post<void>(`/purchase-orders/${id}/push-cloud`)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 取消推送采购单
|
|
||||||
* @param id 采购单ID
|
|
||||||
*/
|
|
||||||
export function cancelPushPurchase(id: string) {
|
|
||||||
return request.post<void>(`/purchase-orders/${id}/cancel-push`)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 别名兼容
|
|
||||||
export const approvePurchase = approvePurchaseOrder
|
|
||||||
export const rejectPurchase = rejectPurchaseOrder
|
|
||||||
export const submitReview = submitPurchaseReview
|
|
||||||
export const createPurchase = createPurchaseOrder
|
|
||||||
export const updatePurchase = updatePurchaseOrder
|
|
||||||
export const getPurchase = getPurchaseDetail
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除采购单
|
|
||||||
*/
|
|
||||||
export function deletePurchase(id: string) {
|
|
||||||
return request.delete<void>(`/purchase-orders/${id}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建草稿采购单
|
|
||||||
*/
|
|
||||||
export function createDraftPurchase(data: any) {
|
|
||||||
return Promise.resolve({ code: 200, message: '功能开发中', data: null })
|
|
||||||
}
|
|
||||||
|
|
||||||
// ==================== 响应类型 ====================
|
|
||||||
|
|
||||||
export interface PurchaseListResponse {
|
|
||||||
list: PurchaseOrder[]
|
|
||||||
total: number
|
|
||||||
page: number
|
|
||||||
pageSize: number
|
|
||||||
}
|
|
||||||
@ -1,116 +0,0 @@
|
|||||||
import request from '@/utils/request'
|
|
||||||
|
|
||||||
// ==================== 类型定义 ====================
|
|
||||||
|
|
||||||
/** 收货单状态 */
|
|
||||||
export type ReceivingOrderStatus = 'pending' | 'partial' | 'completed' | 'cancelled'
|
|
||||||
|
|
||||||
/** 收货单商品项 */
|
|
||||||
export interface ReceivingOrderItem {
|
|
||||||
id?: string
|
|
||||||
skuCode: string
|
|
||||||
skuName?: string
|
|
||||||
expectedQuantity: number
|
|
||||||
receivedQuantity: number
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 收货单 */
|
|
||||||
export interface ReceivingOrder {
|
|
||||||
id?: string
|
|
||||||
orderNo?: string
|
|
||||||
purchaseOrderId?: string
|
|
||||||
purchaseOrderNo?: string
|
|
||||||
warehouseId: string
|
|
||||||
warehouseName?: string
|
|
||||||
supplierId?: string
|
|
||||||
supplierName?: string
|
|
||||||
status: ReceivingOrderStatus
|
|
||||||
totalAmount?: number
|
|
||||||
remark?: string
|
|
||||||
items: ReceivingOrderItem[]
|
|
||||||
createTime?: string
|
|
||||||
updateTime?: string
|
|
||||||
receiver?: string
|
|
||||||
receiveTime?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 收货单列表查询参数 */
|
|
||||||
export interface ReceivingListParams {
|
|
||||||
page?: number
|
|
||||||
pageSize?: number
|
|
||||||
status?: ReceivingOrderStatus
|
|
||||||
purchaseOrderId?: string
|
|
||||||
warehouseId?: string
|
|
||||||
keyword?: string
|
|
||||||
startDate?: string
|
|
||||||
endDate?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 创建收货单请求 */
|
|
||||||
export interface CreateReceivingOrderDto {
|
|
||||||
purchaseOrderId: string
|
|
||||||
warehouseId: string
|
|
||||||
remark?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 更新收货单请求 */
|
|
||||||
export interface UpdateReceivingOrderDto {
|
|
||||||
remark?: string
|
|
||||||
items?: ReceivingOrderItem[]
|
|
||||||
}
|
|
||||||
|
|
||||||
// ==================== API 函数 ====================
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取收货单列表
|
|
||||||
* @param params 查询参数
|
|
||||||
*/
|
|
||||||
export function getReceivingList(params?: ReceivingListParams) {
|
|
||||||
return request.get<ReceivingListResponse>('/receiving-orders', { params })
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取收货单详情
|
|
||||||
* @param id 收货单ID
|
|
||||||
*/
|
|
||||||
export function getReceivingDetail(id: string) {
|
|
||||||
return request.get<ReceivingOrder>(`/receiving-orders/${id}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建收货单
|
|
||||||
* @param data 收货单数据
|
|
||||||
*/
|
|
||||||
export function createReceivingOrder(data: CreateReceivingOrderDto) {
|
|
||||||
return request.post<ReceivingOrder>('/receiving-orders', data)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新收货单
|
|
||||||
* @param id 收货单ID
|
|
||||||
* @param data 更新数据
|
|
||||||
*/
|
|
||||||
export function updateReceivingOrder(id: string, data: UpdateReceivingOrderDto) {
|
|
||||||
return request.put<ReceivingOrder>(`/receiving-orders/${id}`, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 确认收货
|
|
||||||
*/
|
|
||||||
export function receive(data: {
|
|
||||||
receivingId: string
|
|
||||||
items: { skuCode: string; receivedQuantity: number }[]
|
|
||||||
receiver?: string
|
|
||||||
remark?: string
|
|
||||||
}) {
|
|
||||||
return request.post('/receiving-orders/receive', data)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ==================== 响应类型 ====================
|
|
||||||
|
|
||||||
export interface ReceivingListResponse {
|
|
||||||
list: ReceivingOrder[]
|
|
||||||
total: number
|
|
||||||
page: number
|
|
||||||
pageSize: number
|
|
||||||
}
|
|
||||||
@ -1,64 +0,0 @@
|
|||||||
import request from '@/utils/request'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取角色列表
|
|
||||||
*/
|
|
||||||
export function getRoleList() {
|
|
||||||
return request.get('/roles')
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取角色详情
|
|
||||||
*/
|
|
||||||
export function getRoleDetail(id: string) {
|
|
||||||
return request.get(`/roles/${id}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建角色
|
|
||||||
*/
|
|
||||||
export function createRole(data: any) {
|
|
||||||
return request.post('/roles', data)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新角色
|
|
||||||
*/
|
|
||||||
export function updateRole(id: string, data: any) {
|
|
||||||
return request.put(`/roles/${id}`, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除角色
|
|
||||||
*/
|
|
||||||
export function deleteRole(id: string) {
|
|
||||||
return request.delete(`/roles/${id}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取角色权限
|
|
||||||
*/
|
|
||||||
export function getRolePermissions(id: string) {
|
|
||||||
return request.get(`/roles/${id}/permissions`)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 分配角色权限
|
|
||||||
*/
|
|
||||||
export function assignRolePermissions(id: string, permissions: string[]) {
|
|
||||||
return request.put(`/roles/${id}/permissions`, { permissions })
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取权限列表
|
|
||||||
*/
|
|
||||||
export function getPermissionList() {
|
|
||||||
return request.get('/permissions')
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取权限分组
|
|
||||||
*/
|
|
||||||
export function getPermissionGroups() {
|
|
||||||
return request.get('/permissions/groups')
|
|
||||||
}
|
|
||||||
@ -1,93 +0,0 @@
|
|||||||
// src/api/shop.ts
|
|
||||||
import request from '@/utils/request'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 店铺数据
|
|
||||||
*/
|
|
||||||
export interface Shop {
|
|
||||||
id?: number
|
|
||||||
name: string
|
|
||||||
platform_id?: number
|
|
||||||
platform_name?: string
|
|
||||||
shop_id?: string
|
|
||||||
app_key?: string
|
|
||||||
app_secret?: string
|
|
||||||
access_token?: string
|
|
||||||
refresh_token?: string
|
|
||||||
token_expires_at?: string
|
|
||||||
status?: number
|
|
||||||
created_at?: string
|
|
||||||
updated_at?: string
|
|
||||||
[key: string]: any
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取平台列表(店铺绑定用)
|
|
||||||
*/
|
|
||||||
export function getShopList(params?: any) {
|
|
||||||
return request.get('/shops/platforms', { params })
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取店铺详情
|
|
||||||
*/
|
|
||||||
export function getShopDetail(id: number) {
|
|
||||||
return request.get(`/shops/${id}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取授权URL
|
|
||||||
*/
|
|
||||||
export function getAuthUrl(platformId: number) {
|
|
||||||
return request.post('/shops/auth-url', { platform_id: platformId })
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 刷新店铺Token
|
|
||||||
*/
|
|
||||||
export function refreshShopToken(id: number) {
|
|
||||||
return request.post(`/shops/${id}/refresh`)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除店铺
|
|
||||||
*/
|
|
||||||
export function deleteShop(id: number) {
|
|
||||||
return request.delete(`/shops/${id}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取所有店铺
|
|
||||||
*/
|
|
||||||
export function getAllShops() {
|
|
||||||
return request.get('/shops/all')
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取平台授权URL
|
|
||||||
*/
|
|
||||||
export function getPlatformAuthUrl(platformId: number) {
|
|
||||||
return getAuthUrl(platformId)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取平台配置
|
|
||||||
*/
|
|
||||||
export function getPlatformConfig(platformId: number) {
|
|
||||||
return Promise.resolve({
|
|
||||||
code: 200,
|
|
||||||
message: '功能开发中',
|
|
||||||
data: null
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理授权回调
|
|
||||||
*/
|
|
||||||
export function handleAuthCallback(code: string) {
|
|
||||||
return Promise.resolve({
|
|
||||||
code: 200,
|
|
||||||
message: '功能开发中',
|
|
||||||
data: null
|
|
||||||
})
|
|
||||||
}
|
|
||||||
182
src/api/stock.ts
182
src/api/stock.ts
@ -1,182 +0,0 @@
|
|||||||
// src/api/stock.ts
|
|
||||||
import request from '@/utils/request'
|
|
||||||
|
|
||||||
// ============ 类型定义 ============
|
|
||||||
|
|
||||||
/** 库存记录 - 对应后端返回字段(snake_case) */
|
|
||||||
export interface Stock {
|
|
||||||
id: number
|
|
||||||
sku_code: string
|
|
||||||
sku_name: string
|
|
||||||
warehouse_id: number
|
|
||||||
warehouse_name: string
|
|
||||||
quantity: number
|
|
||||||
locked_quantity: number
|
|
||||||
available_quantity: number
|
|
||||||
defective_quantity: number
|
|
||||||
warning_threshold: number
|
|
||||||
is_low: boolean
|
|
||||||
created_at: string
|
|
||||||
updated_at: string
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 库存列表查询参数 */
|
|
||||||
export interface StockListParams {
|
|
||||||
warehouse_id?: number
|
|
||||||
sku_code?: string
|
|
||||||
keyword?: string
|
|
||||||
low_stock?: boolean
|
|
||||||
page?: number
|
|
||||||
limit?: number
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 库存列表响应 */
|
|
||||||
export interface StockListResponse {
|
|
||||||
list: Stock[]
|
|
||||||
total: number
|
|
||||||
current_page: number
|
|
||||||
last_page: number
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 库存操作日志 */
|
|
||||||
export interface StockLog {
|
|
||||||
id: number
|
|
||||||
stock_id: number
|
|
||||||
type: 'inbound' | 'outbound' | 'adjust' | 'lock' | 'unlock' | 'defective_inbound' | 'defective_outbound'
|
|
||||||
quantity: number
|
|
||||||
before_quantity: number
|
|
||||||
after_quantity: number
|
|
||||||
reason?: string
|
|
||||||
operator?: string
|
|
||||||
created_at: string
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 库存详情响应 */
|
|
||||||
export interface StockDetailResponse {
|
|
||||||
stock: Stock
|
|
||||||
logs: StockLog[]
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 库存日志查询参数 */
|
|
||||||
export interface StockLogsParams {
|
|
||||||
stock_id?: number
|
|
||||||
sku_code?: string
|
|
||||||
warehouse_id?: number
|
|
||||||
type?: string
|
|
||||||
start_date?: string
|
|
||||||
end_date?: string
|
|
||||||
page?: number
|
|
||||||
limit?: number
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 更新阈值请求 */
|
|
||||||
export interface UpdateThresholdData {
|
|
||||||
sku_code: string
|
|
||||||
warehouse_id: number
|
|
||||||
threshold: number
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 手动入库请求 */
|
|
||||||
export interface InboundData {
|
|
||||||
sku_code: string
|
|
||||||
warehouse_id: number
|
|
||||||
quantity: number
|
|
||||||
reason?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 手动出库请求 */
|
|
||||||
export interface OutboundData {
|
|
||||||
sku_code: string
|
|
||||||
warehouse_id: number
|
|
||||||
quantity: number
|
|
||||||
reason?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 不良品入库请求 */
|
|
||||||
export interface DefectiveInboundData {
|
|
||||||
sku_code: string
|
|
||||||
warehouse_id: number
|
|
||||||
quantity: number
|
|
||||||
reason?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 库存调整请求 */
|
|
||||||
export interface AdjustData {
|
|
||||||
sku_code: string
|
|
||||||
warehouse_id: number
|
|
||||||
adjust_quantity: number
|
|
||||||
reason: string
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============ API 函数 ============
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取库存列表
|
|
||||||
* @param params 查询参数(仓库ID、SKU、关键词、低库存筛选、分页)
|
|
||||||
*/
|
|
||||||
export function getStockList(params?: StockListParams) {
|
|
||||||
return request.get<StockListResponse>('/stocks', { params })
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取库存详情
|
|
||||||
* @param params { sku_code, warehouse_id }
|
|
||||||
*/
|
|
||||||
export function getStockDetail(params: { sku_code: string; warehouse_id: number }) {
|
|
||||||
return request.get<StockDetailResponse>('/stocks/detail', { params })
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取库存日志
|
|
||||||
* @param params 查询参数
|
|
||||||
*/
|
|
||||||
export function getStockLogs(params?: StockLogsParams) {
|
|
||||||
return request.get<{ list: StockLog[]; total: number }>('/stocks/logs', { params })
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新预警阈值
|
|
||||||
* @param data { sku_code, warehouse_id, threshold }
|
|
||||||
*/
|
|
||||||
export function updateThreshold(data: UpdateThresholdData) {
|
|
||||||
return request.put<void>('/stocks/update-threshold', data)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 手动入库
|
|
||||||
* @param data { sku_code, warehouse_id, quantity, reason }
|
|
||||||
*/
|
|
||||||
export function inbound(data: InboundData) {
|
|
||||||
return request.post<Stock>('/stocks/inbound', data)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 手动出库
|
|
||||||
* @param data { sku_code, warehouse_id, quantity, reason }
|
|
||||||
*/
|
|
||||||
export function outbound(data: OutboundData) {
|
|
||||||
return request.post<Stock>('/stocks/outbound', data)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 不良品入库
|
|
||||||
* @param data { sku_code, warehouse_id, quantity, reason }
|
|
||||||
*/
|
|
||||||
export function defectiveInbound(data: DefectiveInboundData) {
|
|
||||||
return request.post<Stock>('/stocks/defective-inbound', data)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 库存调整
|
|
||||||
* @param data { sku_code, warehouse_id, adjust_quantity, reason }
|
|
||||||
*/
|
|
||||||
export function adjustStock(data: AdjustData) {
|
|
||||||
return request.post<Stock>('/stocks/adjust', data)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新库存预警阈值
|
|
||||||
*/
|
|
||||||
export function updateWarningThreshold(data: { sku_code: string; warehouse_id: number; threshold: number }) {
|
|
||||||
return request.put('/stocks/update-threshold', data)
|
|
||||||
}
|
|
||||||
@ -1,67 +0,0 @@
|
|||||||
// src/api/supplier.ts
|
|
||||||
import request from '@/utils/request'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 供应商数据类型
|
|
||||||
*/
|
|
||||||
export interface Supplier {
|
|
||||||
id?: number
|
|
||||||
name: string
|
|
||||||
code?: string
|
|
||||||
contact?: string
|
|
||||||
phone?: string
|
|
||||||
email?: string
|
|
||||||
address?: string
|
|
||||||
status?: number
|
|
||||||
created_at?: string
|
|
||||||
updated_at?: string
|
|
||||||
[key: string]: any
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取供应商列表
|
|
||||||
* @param params 查询参数(page, limit, name, status)
|
|
||||||
*/
|
|
||||||
export function getSupplierList(params?: any) {
|
|
||||||
return request.get('/suppliers', { params })
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取供应商详情
|
|
||||||
* @param id 供应商ID
|
|
||||||
*/
|
|
||||||
export function getSupplierDetail(id: number) {
|
|
||||||
return request.get(`/suppliers/${id}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建供应商
|
|
||||||
* @param data 供应商数据
|
|
||||||
*/
|
|
||||||
export function createSupplier(data: Supplier) {
|
|
||||||
return request.post('/suppliers', data)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新供应商
|
|
||||||
* @param id 供应商ID
|
|
||||||
* @param data 更新数据
|
|
||||||
*/
|
|
||||||
export function updateSupplier(id: number, data: Partial<Supplier>) {
|
|
||||||
return request.put(`/suppliers/${id}`, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除供应商
|
|
||||||
* @param id 供应商ID
|
|
||||||
*/
|
|
||||||
export function deleteSupplier(id: number) {
|
|
||||||
return request.delete(`/suppliers/${id}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取所有供应商用于下拉选择
|
|
||||||
*/
|
|
||||||
export function getAllSuppliers() {
|
|
||||||
return request.get('/suppliers/all')
|
|
||||||
}
|
|
||||||
@ -1,70 +0,0 @@
|
|||||||
// 模板管理 API
|
|
||||||
import request from '@/utils/request'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 模板接口定义
|
|
||||||
*/
|
|
||||||
export interface Template {
|
|
||||||
id: string
|
|
||||||
name: string
|
|
||||||
platform: string
|
|
||||||
size: string
|
|
||||||
style: string
|
|
||||||
defaultExpress?: string
|
|
||||||
senderName: string
|
|
||||||
senderPhone: string
|
|
||||||
senderAddress: string
|
|
||||||
showProduct: boolean
|
|
||||||
remark?: string
|
|
||||||
updatedAt: string
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 模板列表查询参数
|
|
||||||
*/
|
|
||||||
export interface TemplateListParams {
|
|
||||||
currentPage?: number
|
|
||||||
pageSize?: number
|
|
||||||
keyword?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取模板列表
|
|
||||||
* @param params 分页参数
|
|
||||||
*/
|
|
||||||
export function getTemplateList(params?: TemplateListParams) {
|
|
||||||
return request.get('/templates', { params })
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取模板详情
|
|
||||||
* @param id 模板ID
|
|
||||||
*/
|
|
||||||
export function getTemplateDetail(id: string) {
|
|
||||||
return request.get(`/templates/${id}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建模板
|
|
||||||
* @param data 模板数据
|
|
||||||
*/
|
|
||||||
export function createTemplate(data: Partial<Template>) {
|
|
||||||
return request.post('/templates', data)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新模板
|
|
||||||
* @param id 模板ID
|
|
||||||
* @param data 更新数据
|
|
||||||
*/
|
|
||||||
export function updateTemplate(id: string, data: Partial<Template>) {
|
|
||||||
return request.put(`/templates/${id}`, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除模板
|
|
||||||
* @param id 模板ID
|
|
||||||
*/
|
|
||||||
export function deleteTemplate(id: string) {
|
|
||||||
return request.delete(`/templates/${id}`)
|
|
||||||
}
|
|
||||||
@ -1,64 +0,0 @@
|
|||||||
import request from '@/utils/request'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取第三方配置
|
|
||||||
*/
|
|
||||||
export function getThirdPartyConfigs() {
|
|
||||||
return request.get('/third-party-config', { params: { group: 'third_party' } })
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 保存第三方配置
|
|
||||||
*/
|
|
||||||
export function saveThirdPartyConfigs(configs: any[]) {
|
|
||||||
return request.put('/third-party-config', { group: 'third_party', configs })
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取单个配置
|
|
||||||
*/
|
|
||||||
export function getConfig(key: string) {
|
|
||||||
return request.get(`/third-party-config/${key}`, { params: { group: 'third_party' } })
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取邮件配置
|
|
||||||
*/
|
|
||||||
export function getMailConfig() {
|
|
||||||
return request.get('/third-party-config', { params: { group: 'mail' } })
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 保存邮件配置
|
|
||||||
*/
|
|
||||||
export function saveMailConfig(configs: any[]) {
|
|
||||||
return request.put('/third-party-config', { group: 'mail', configs })
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取短信配置
|
|
||||||
*/
|
|
||||||
export function getSmsConfig() {
|
|
||||||
return request.get('/third-party-config', { params: { group: 'sms' } })
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 保存短信配置
|
|
||||||
*/
|
|
||||||
export function saveSmsConfig(configs: any[]) {
|
|
||||||
return request.put('/third-party-config', { group: 'sms', configs })
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取微信配置
|
|
||||||
*/
|
|
||||||
export function getWechatConfig() {
|
|
||||||
return request.get('/third-party-config', { params: { group: 'wechat' } })
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 保存微信配置
|
|
||||||
*/
|
|
||||||
export function saveWechatConfig(configs: any[]) {
|
|
||||||
return request.put('/third-party-config', { group: 'wechat', configs })
|
|
||||||
}
|
|
||||||
198
src/api/user.ts
198
src/api/user.ts
@ -1,198 +0,0 @@
|
|||||||
// 用户管理 API
|
|
||||||
import request from '@/utils/request'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取用户列表
|
|
||||||
*/
|
|
||||||
export function getUserList(params?: any) {
|
|
||||||
return request.get('/users', { params })
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取用户详情
|
|
||||||
*/
|
|
||||||
export function getUserDetail(id: string) {
|
|
||||||
return request.get(`/users/${id}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建用户(添加制)
|
|
||||||
*/
|
|
||||||
export function createUser(data: any) {
|
|
||||||
return request.post('/users', data)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新用户
|
|
||||||
*/
|
|
||||||
export function updateUser(id: string, data: any) {
|
|
||||||
return request.put(`/users/${id}`, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除用户
|
|
||||||
*/
|
|
||||||
export function deleteUser(id: string) {
|
|
||||||
return request.delete(`/users/${id}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 禁用用户
|
|
||||||
*/
|
|
||||||
export function disableUser(id: string) {
|
|
||||||
return request.post(`/users/${id}/disable`)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 启用用户
|
|
||||||
*/
|
|
||||||
export function enableUser(id: string) {
|
|
||||||
return request.post(`/users/${id}/enable`)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 邀请用户(邀请制)
|
|
||||||
*/
|
|
||||||
export function inviteUser(data: any) {
|
|
||||||
return request.post('/users/invite', data)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置用户权限
|
|
||||||
*/
|
|
||||||
export function setUserPermissions(id: string, data: { permissions: string[], warehouseIds: number[] }) {
|
|
||||||
return request.put(`/users/${id}/permissions`, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取用户权限
|
|
||||||
*/
|
|
||||||
export function getUserPermissions(id: string) {
|
|
||||||
return request.get(`/users/${id}/permissions`)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取用户登录日志
|
|
||||||
*/
|
|
||||||
export function getUserLoginLogs(id: string, params?: any) {
|
|
||||||
if (id === 'me') {
|
|
||||||
return request.get('/user/login-logs', { params })
|
|
||||||
}
|
|
||||||
return request.get(`/users/${id}/login-logs`, { params })
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取用户操作日志
|
|
||||||
*/
|
|
||||||
export function getUserOperationLogs(id: string, params?: any) {
|
|
||||||
return request.get(`/users/${id}/operation-logs`, { params })
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取当前用户信息
|
|
||||||
*/
|
|
||||||
export function getCurrentUser() {
|
|
||||||
return request.get('/user/')
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新当前用户信息
|
|
||||||
*/
|
|
||||||
export function updateCurrentUser(data: any) {
|
|
||||||
return request.put('/user/profile', data)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 修改密码
|
|
||||||
*/
|
|
||||||
export function changePassword(data: { oldPassword: string, newPassword: string, confirmPassword: string }) {
|
|
||||||
return request.put('/user/password', {
|
|
||||||
current_password: data.oldPassword,
|
|
||||||
new_password: data.newPassword,
|
|
||||||
new_password_confirmation: data.confirmPassword
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 重置密码(超管用)
|
|
||||||
*/
|
|
||||||
export function resetPassword(id: string) {
|
|
||||||
return request.post(`/users/${id}/reset-password`)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 发送配对码邮件
|
|
||||||
*/
|
|
||||||
export function sendPairCode(data: { username: string, expireHours: number }) {
|
|
||||||
return request.post('/auth/send-pair-code', data)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 验证配对码
|
|
||||||
*/
|
|
||||||
export function verifyPairCode(data: { code: string }) {
|
|
||||||
return request.post('/auth/verify-pair-code', data)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取设备授信列表
|
|
||||||
*/
|
|
||||||
export function getTrustedDevices() {
|
|
||||||
return request.get('/user/devices')
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 取消设备授信
|
|
||||||
*/
|
|
||||||
export function revokeDevice(deviceId: string) {
|
|
||||||
return request.delete(`/user/devices/${deviceId}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 批准设备申请
|
|
||||||
*/
|
|
||||||
export function approveDevice(deviceId: string) {
|
|
||||||
return request.post(`/user/devices/${deviceId}/approve`)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 拒绝设备申请
|
|
||||||
*/
|
|
||||||
export function rejectDevice(deviceId: string) {
|
|
||||||
return request.post(`/users/devices/${deviceId}/reject`)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 绑定微信
|
|
||||||
*/
|
|
||||||
export function bindWechat(data: { code: string }) {
|
|
||||||
return request.post('/users/bind-wechat', data)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 解绑微信
|
|
||||||
*/
|
|
||||||
export function unbindWechat() {
|
|
||||||
return request.delete('/users/bind-wechat')
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取微信登录二维码
|
|
||||||
*/
|
|
||||||
export function getWechatQRCode() {
|
|
||||||
return request.get('/users/wechat/qrcode')
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 检查微信登录状态
|
|
||||||
*/
|
|
||||||
export function checkWechatLogin(qrcodeId: string) {
|
|
||||||
return request.get(`/users/wechat/check/${qrcodeId}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 发送邮箱修改验证码
|
|
||||||
*/
|
|
||||||
export function sendEmailChangeCode(data: { email: string }) {
|
|
||||||
return request.post('/user/send-email-change-code', data)
|
|
||||||
}
|
|
||||||
@ -1,61 +0,0 @@
|
|||||||
// src/utils/request.ts
|
|
||||||
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios';
|
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
|
||||||
// import { useUserStore } from '@/stores/user'; // 后续引入
|
|
||||||
|
|
||||||
// 创建 axios 实例
|
|
||||||
const service: AxiosInstance = axios.create({
|
|
||||||
baseURL: import.meta.env.VITE_API_BASE_URL || '/api', // 环境变量配置
|
|
||||||
timeout: 15000, // 15秒超时
|
|
||||||
headers: { 'Content-Type': 'application/json;charset=UTF-8' }
|
|
||||||
});
|
|
||||||
|
|
||||||
// 请求拦截器
|
|
||||||
service.interceptors.request.use(
|
|
||||||
(config) => {
|
|
||||||
// TODO: 从 Pinia 获取 token 并注入 Header
|
|
||||||
// const userStore = useUserStore();
|
|
||||||
// if (userStore.token) {
|
|
||||||
// config.headers['Authorization'] = `Bearer ${userStore.token}`;
|
|
||||||
// }
|
|
||||||
return config;
|
|
||||||
},
|
|
||||||
(error) => {
|
|
||||||
console.error('Request Error:', error);
|
|
||||||
return Promise.reject(error);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// 响应拦截器
|
|
||||||
service.interceptors.response.use(
|
|
||||||
(response: AxiosResponse) => {
|
|
||||||
const res = response.data;
|
|
||||||
|
|
||||||
// 假设后端返回格式:{ code: 200, data: {}, msg: 'success' }
|
|
||||||
// 请根据实际后端接口调整判断逻辑
|
|
||||||
if (res.code !== 200 && res.code !== 0) {
|
|
||||||
ElMessage.error(res.msg || '系统错误');
|
|
||||||
|
|
||||||
// 特殊状态码处理:401 未登录,403 无权限
|
|
||||||
if (res.code === 401) {
|
|
||||||
// TODO: 跳转登录页
|
|
||||||
// userStore.logout();
|
|
||||||
}
|
|
||||||
return Promise.reject(new Error(res.msg || 'Error'));
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
},
|
|
||||||
(error: AxiosError) => {
|
|
||||||
console.error('Response Error:', error);
|
|
||||||
let msg = '网络异常,请稍后重试';
|
|
||||||
if (error.response?.status === 401) msg = '未授权,请重新登录';
|
|
||||||
if (error.response?.status === 403) msg = '拒绝访问';
|
|
||||||
if (error.response?.status === 404) msg = '资源不存在';
|
|
||||||
if (error.response?.status === 500) msg = '服务器内部错误';
|
|
||||||
|
|
||||||
ElMessage.error(msg);
|
|
||||||
return Promise.reject(error);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
export default service;
|
|
||||||
@ -1,130 +0,0 @@
|
|||||||
// src/api/warehouse.ts
|
|
||||||
import request from '@/utils/request'
|
|
||||||
|
|
||||||
// ============ 类型定义 ============
|
|
||||||
|
|
||||||
/** 仓库类型 */
|
|
||||||
export type WarehouseType = 'erp' | 'cloud' | 'physical' | 'virtual'
|
|
||||||
|
|
||||||
/** 仓库状态 */
|
|
||||||
export type WarehouseStatus = 'active' | 'inactive'
|
|
||||||
|
|
||||||
/** 仓库 - 对应后端返回字段(snake_case) */
|
|
||||||
export interface Warehouse {
|
|
||||||
id: number
|
|
||||||
name: string
|
|
||||||
type: WarehouseType
|
|
||||||
cloud_system?: string | null
|
|
||||||
owner_code?: string | null
|
|
||||||
cloud_code?: string | null
|
|
||||||
app_key?: string | null
|
|
||||||
app_secret?: string | null
|
|
||||||
remark?: string | null
|
|
||||||
created_at: string
|
|
||||||
updated_at: string
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 仓库列表查询参数 */
|
|
||||||
export interface WarehouseListParams {
|
|
||||||
keyword?: string
|
|
||||||
type?: WarehouseType
|
|
||||||
status?: WarehouseStatus
|
|
||||||
page?: number
|
|
||||||
limit?: number
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 仓库列表响应 */
|
|
||||||
export interface WarehouseListResponse {
|
|
||||||
list: Warehouse[]
|
|
||||||
total: number
|
|
||||||
current_page: number
|
|
||||||
last_page: number
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 创建仓库请求 */
|
|
||||||
export interface CreateWarehouseData {
|
|
||||||
name: string
|
|
||||||
type: WarehouseType
|
|
||||||
cloud_system?: string
|
|
||||||
owner_code?: string
|
|
||||||
cloud_code?: string
|
|
||||||
app_key?: string
|
|
||||||
app_secret?: string
|
|
||||||
remark?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 更新仓库请求 */
|
|
||||||
export interface UpdateWarehouseData {
|
|
||||||
name?: string
|
|
||||||
type?: WarehouseType
|
|
||||||
cloud_system?: string
|
|
||||||
owner_code?: string
|
|
||||||
cloud_code?: string
|
|
||||||
app_key?: string
|
|
||||||
app_secret?: string
|
|
||||||
remark?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============ API 函数 ============
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取仓库列表
|
|
||||||
* @param params 查询参数(关键词、类型、分页)
|
|
||||||
*/
|
|
||||||
export function getWarehouseList(params?: WarehouseListParams) {
|
|
||||||
return request.get<WarehouseListResponse>('/warehouses', { params })
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取仓库详情
|
|
||||||
* @param id 仓库ID
|
|
||||||
*/
|
|
||||||
export function getWarehouseDetail(id: string | number) {
|
|
||||||
return request.get<Warehouse>(`/warehouses/${id}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建仓库
|
|
||||||
* @param data 仓库数据
|
|
||||||
*/
|
|
||||||
export function createWarehouse(data: CreateWarehouseData) {
|
|
||||||
return request.post<Warehouse>('/warehouses', data)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新仓库
|
|
||||||
* @param id 仓库ID
|
|
||||||
* @param data 更新数据
|
|
||||||
*/
|
|
||||||
export function updateWarehouse(id: string | number, data: UpdateWarehouseData) {
|
|
||||||
return request.put<Warehouse>(`/warehouses/${id}`, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除仓库
|
|
||||||
* @param id 仓库ID
|
|
||||||
*/
|
|
||||||
export function deleteWarehouse(id: string | number) {
|
|
||||||
return request.delete<void>(`/warehouses/${id}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取仓库模板绑定列表
|
|
||||||
*/
|
|
||||||
export function getWarehouseBindings(warehouseId: string) {
|
|
||||||
return request.get(`/warehouse/bindings/${warehouseId}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 添加仓库模板绑定
|
|
||||||
*/
|
|
||||||
export function addBinding(data: any) {
|
|
||||||
return request.post('/warehouse/bindings', data)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新仓库模板绑定
|
|
||||||
*/
|
|
||||||
export function updateBinding(id: string, data: any) {
|
|
||||||
return request.put(`/warehouse/bindings/${id}`, data)
|
|
||||||
}
|
|
||||||
@ -1 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>
|
|
||||||
|
Before Width: | Height: | Size: 496 B |
@ -1,41 +0,0 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
defineProps<{
|
|
||||||
msg: string
|
|
||||||
}>()
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div class="greetings">
|
|
||||||
<h1 class="green">{{ msg }}</h1>
|
|
||||||
<h3>
|
|
||||||
You’ve successfully created a project with
|
|
||||||
<a href="https://vite.dev/" target="_blank" rel="noopener">Vite</a> +
|
|
||||||
<a href="https://vuejs.org/" target="_blank" rel="noopener">Vue 3</a>. What's next?
|
|
||||||
</h3>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
h1 {
|
|
||||||
font-weight: 500;
|
|
||||||
font-size: 2.6rem;
|
|
||||||
position: relative;
|
|
||||||
top: -10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
h3 {
|
|
||||||
font-size: 1.2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.greetings h1,
|
|
||||||
.greetings h3 {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 1024px) {
|
|
||||||
.greetings h1,
|
|
||||||
.greetings h3 {
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@ -1,53 +0,0 @@
|
|||||||
<template>
|
|
||||||
<el-dialog v-model="visible" title="批量打印" width="600px" :close-on-click-modal="false" @close="handleClose">
|
|
||||||
<div>
|
|
||||||
<p>这是一个独立的打印对话框组件</p>
|
|
||||||
<p>选中订单数:{{ orderIds.length }}</p>
|
|
||||||
<p>环境模式:{{ envMode }}</p>
|
|
||||||
<el-switch
|
|
||||||
v-model="envMode"
|
|
||||||
active-value="production"
|
|
||||||
inactive-value="simulate"
|
|
||||||
active-text="生产模式"
|
|
||||||
inactive-text="模拟模式"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<template #footer>
|
|
||||||
<el-button @click="visible = false">取消</el-button>
|
|
||||||
<el-button type="primary" @click="handleConfirm">确定</el-button>
|
|
||||||
</template>
|
|
||||||
</el-dialog>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { ref, watch } from 'vue'
|
|
||||||
import { ElMessage } from 'element-plus'
|
|
||||||
|
|
||||||
const props = defineProps<{
|
|
||||||
modelValue: boolean
|
|
||||||
orderIds: number[]
|
|
||||||
orders: any[]
|
|
||||||
}>()
|
|
||||||
|
|
||||||
const emit = defineEmits(['update:modelValue'])
|
|
||||||
|
|
||||||
const visible = ref(props.modelValue)
|
|
||||||
const envMode = ref<'simulate' | 'production'>('simulate')
|
|
||||||
|
|
||||||
watch(() => props.modelValue, (val) => {
|
|
||||||
visible.value = val
|
|
||||||
})
|
|
||||||
|
|
||||||
watch(visible, (val) => {
|
|
||||||
emit('update:modelValue', val)
|
|
||||||
})
|
|
||||||
|
|
||||||
const handleClose = () => {
|
|
||||||
visible.value = false
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleConfirm = () => {
|
|
||||||
ElMessage.success('打印功能待完善')
|
|
||||||
visible.value = false
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@ -1,95 +0,0 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
import WelcomeItem from './WelcomeItem.vue'
|
|
||||||
import DocumentationIcon from './icons/IconDocumentation.vue'
|
|
||||||
import ToolingIcon from './icons/IconTooling.vue'
|
|
||||||
import EcosystemIcon from './icons/IconEcosystem.vue'
|
|
||||||
import CommunityIcon from './icons/IconCommunity.vue'
|
|
||||||
import SupportIcon from './icons/IconSupport.vue'
|
|
||||||
|
|
||||||
const openReadmeInEditor = () => fetch('/__open-in-editor?file=README.md')
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<WelcomeItem>
|
|
||||||
<template #icon>
|
|
||||||
<DocumentationIcon />
|
|
||||||
</template>
|
|
||||||
<template #heading>Documentation</template>
|
|
||||||
|
|
||||||
Vue’s
|
|
||||||
<a href="https://vuejs.org/" target="_blank" rel="noopener">official documentation</a>
|
|
||||||
provides you with all information you need to get started.
|
|
||||||
</WelcomeItem>
|
|
||||||
|
|
||||||
<WelcomeItem>
|
|
||||||
<template #icon>
|
|
||||||
<ToolingIcon />
|
|
||||||
</template>
|
|
||||||
<template #heading>Tooling</template>
|
|
||||||
|
|
||||||
This project is served and bundled with
|
|
||||||
<a href="https://vite.dev/guide/features.html" target="_blank" rel="noopener">Vite</a>. The
|
|
||||||
recommended IDE setup is
|
|
||||||
<a href="https://code.visualstudio.com/" target="_blank" rel="noopener">VSCode</a>
|
|
||||||
+
|
|
||||||
<a href="https://github.com/vuejs/language-tools" target="_blank" rel="noopener"
|
|
||||||
>Vue - Official</a
|
|
||||||
>. If you need to test your components and web pages, check out
|
|
||||||
<a href="https://vitest.dev/" target="_blank" rel="noopener">Vitest</a>
|
|
||||||
and
|
|
||||||
<a href="https://www.cypress.io/" target="_blank" rel="noopener">Cypress</a>
|
|
||||||
/
|
|
||||||
<a href="https://playwright.dev/" target="_blank" rel="noopener">Playwright</a>.
|
|
||||||
|
|
||||||
<br />
|
|
||||||
|
|
||||||
More instructions are available in
|
|
||||||
<a href="javascript:void(0)" @click="openReadmeInEditor"><code>README.md</code></a
|
|
||||||
>.
|
|
||||||
</WelcomeItem>
|
|
||||||
|
|
||||||
<WelcomeItem>
|
|
||||||
<template #icon>
|
|
||||||
<EcosystemIcon />
|
|
||||||
</template>
|
|
||||||
<template #heading>Ecosystem</template>
|
|
||||||
|
|
||||||
Get official tools and libraries for your project:
|
|
||||||
<a href="https://pinia.vuejs.org/" target="_blank" rel="noopener">Pinia</a>,
|
|
||||||
<a href="https://router.vuejs.org/" target="_blank" rel="noopener">Vue Router</a>,
|
|
||||||
<a href="https://test-utils.vuejs.org/" target="_blank" rel="noopener">Vue Test Utils</a>, and
|
|
||||||
<a href="https://github.com/vuejs/devtools" target="_blank" rel="noopener">Vue Dev Tools</a>. If
|
|
||||||
you need more resources, we suggest paying
|
|
||||||
<a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">Awesome Vue</a>
|
|
||||||
a visit.
|
|
||||||
</WelcomeItem>
|
|
||||||
|
|
||||||
<WelcomeItem>
|
|
||||||
<template #icon>
|
|
||||||
<CommunityIcon />
|
|
||||||
</template>
|
|
||||||
<template #heading>Community</template>
|
|
||||||
|
|
||||||
Got stuck? Ask your question on
|
|
||||||
<a href="https://chat.vuejs.org" target="_blank" rel="noopener">Vue Land</a>
|
|
||||||
(our official Discord server), or
|
|
||||||
<a href="https://stackoverflow.com/questions/tagged/vue.js" target="_blank" rel="noopener"
|
|
||||||
>StackOverflow</a
|
|
||||||
>. You should also follow the official
|
|
||||||
<a href="https://bsky.app/profile/vuejs.org" target="_blank" rel="noopener">@vuejs.org</a>
|
|
||||||
Bluesky account or the
|
|
||||||
<a href="https://x.com/vuejs" target="_blank" rel="noopener">@vuejs</a>
|
|
||||||
X account for latest news in the Vue world.
|
|
||||||
</WelcomeItem>
|
|
||||||
|
|
||||||
<WelcomeItem>
|
|
||||||
<template #icon>
|
|
||||||
<SupportIcon />
|
|
||||||
</template>
|
|
||||||
<template #heading>Support Vue</template>
|
|
||||||
|
|
||||||
As an independent project, Vue relies on community backing for its sustainability. You can help
|
|
||||||
us by
|
|
||||||
<a href="https://vuejs.org/sponsor/" target="_blank" rel="noopener">becoming a sponsor</a>.
|
|
||||||
</WelcomeItem>
|
|
||||||
</template>
|
|
||||||
@ -1,87 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="item">
|
|
||||||
<i>
|
|
||||||
<slot name="icon"></slot>
|
|
||||||
</i>
|
|
||||||
<div class="details">
|
|
||||||
<h3>
|
|
||||||
<slot name="heading"></slot>
|
|
||||||
</h3>
|
|
||||||
<slot></slot>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.item {
|
|
||||||
margin-top: 2rem;
|
|
||||||
display: flex;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.details {
|
|
||||||
flex: 1;
|
|
||||||
margin-left: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
i {
|
|
||||||
display: flex;
|
|
||||||
place-items: center;
|
|
||||||
place-content: center;
|
|
||||||
width: 32px;
|
|
||||||
height: 32px;
|
|
||||||
|
|
||||||
color: var(--color-text);
|
|
||||||
}
|
|
||||||
|
|
||||||
h3 {
|
|
||||||
font-size: 1.2rem;
|
|
||||||
font-weight: 500;
|
|
||||||
margin-bottom: 0.4rem;
|
|
||||||
color: var(--color-heading);
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 1024px) {
|
|
||||||
.item {
|
|
||||||
margin-top: 0;
|
|
||||||
padding: 0.4rem 0 1rem calc(var(--section-gap) / 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
i {
|
|
||||||
top: calc(50% - 25px);
|
|
||||||
left: -26px;
|
|
||||||
position: absolute;
|
|
||||||
border: 1px solid var(--color-border);
|
|
||||||
background: var(--color-background);
|
|
||||||
border-radius: 8px;
|
|
||||||
width: 50px;
|
|
||||||
height: 50px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.item:before {
|
|
||||||
content: ' ';
|
|
||||||
border-left: 1px solid var(--color-border);
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
bottom: calc(50% + 25px);
|
|
||||||
height: calc(50% - 25px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.item:after {
|
|
||||||
content: ' ';
|
|
||||||
border-left: 1px solid var(--color-border);
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: calc(50% + 25px);
|
|
||||||
height: calc(50% - 25px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.item:first-of-type:before {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.item:last-of-type:after {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@ -1,11 +0,0 @@
|
|||||||
import { describe, it, expect } from 'vitest'
|
|
||||||
|
|
||||||
import { mount } from '@vue/test-utils'
|
|
||||||
import HelloWorld from '../HelloWorld.vue'
|
|
||||||
|
|
||||||
describe('HelloWorld', () => {
|
|
||||||
it('renders properly', () => {
|
|
||||||
const wrapper = mount(HelloWorld, { props: { msg: 'Hello Vitest' } })
|
|
||||||
expect(wrapper.text()).toContain('Hello Vitest')
|
|
||||||
})
|
|
||||||
})
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
<template>
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor">
|
|
||||||
<path
|
|
||||||
d="M15 4a1 1 0 1 0 0 2V4zm0 11v-1a1 1 0 0 0-1 1h1zm0 4l-.707.707A1 1 0 0 0 16 19h-1zm-4-4l.707-.707A1 1 0 0 0 11 14v1zm-4.707-1.293a1 1 0 0 0-1.414 1.414l1.414-1.414zm-.707.707l-.707-.707.707.707zM9 11v-1a1 1 0 0 0-.707.293L9 11zm-4 0h1a1 1 0 0 0-1-1v1zm0 4H4a1 1 0 0 0 1.707.707L5 15zm10-9h2V4h-2v2zm2 0a1 1 0 0 1 1 1h2a3 3 0 0 0-3-3v2zm1 1v6h2V7h-2zm0 6a1 1 0 0 1-1 1v2a3 3 0 0 0 3-3h-2zm-1 1h-2v2h2v-2zm-3 1v4h2v-4h-2zm1.707 3.293l-4-4-1.414 1.414 4 4 1.414-1.414zM11 14H7v2h4v-2zm-4 0c-.276 0-.525-.111-.707-.293l-1.414 1.414C5.42 15.663 6.172 16 7 16v-2zm-.707 1.121l3.414-3.414-1.414-1.414-3.414 3.414 1.414 1.414zM9 12h4v-2H9v2zm4 0a3 3 0 0 0 3-3h-2a1 1 0 0 1-1 1v2zm3-3V3h-2v6h2zm0-6a3 3 0 0 0-3-3v2a1 1 0 0 1 1 1h2zm-3-3H3v2h10V0zM3 0a3 3 0 0 0-3 3h2a1 1 0 0 1 1-1V0zM0 3v6h2V3H0zm0 6a3 3 0 0 0 3 3v-2a1 1 0 0 1-1-1H0zm3 3h2v-2H3v2zm1-1v4h2v-4H4zm1.707 4.707l.586-.586-1.414-1.414-.586.586 1.414 1.414z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</template>
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
<template>
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="17" fill="currentColor">
|
|
||||||
<path
|
|
||||||
d="M11 2.253a1 1 0 1 0-2 0h2zm-2 13a1 1 0 1 0 2 0H9zm.447-12.167a1 1 0 1 0 1.107-1.666L9.447 3.086zM1 2.253L.447 1.42A1 1 0 0 0 0 2.253h1zm0 13H0a1 1 0 0 0 1.553.833L1 15.253zm8.447.833a1 1 0 1 0 1.107-1.666l-1.107 1.666zm0-14.666a1 1 0 1 0 1.107 1.666L9.447 1.42zM19 2.253h1a1 1 0 0 0-.447-.833L19 2.253zm0 13l-.553.833A1 1 0 0 0 20 15.253h-1zm-9.553-.833a1 1 0 1 0 1.107 1.666L9.447 14.42zM9 2.253v13h2v-13H9zm1.553-.833C9.203.523 7.42 0 5.5 0v2c1.572 0 2.961.431 3.947 1.086l1.107-1.666zM5.5 0C3.58 0 1.797.523.447 1.42l1.107 1.666C2.539 2.431 3.928 2 5.5 2V0zM0 2.253v13h2v-13H0zm1.553 13.833C2.539 15.431 3.928 15 5.5 15v-2c-1.92 0-3.703.523-5.053 1.42l1.107 1.666zM5.5 15c1.572 0 2.961.431 3.947 1.086l1.107-1.666C9.203 13.523 7.42 13 5.5 13v2zm5.053-11.914C11.539 2.431 12.928 2 14.5 2V0c-1.92 0-3.703.523-5.053 1.42l1.107 1.666zM14.5 2c1.573 0 2.961.431 3.947 1.086l1.107-1.666C18.203.523 16.421 0 14.5 0v2zm3.5.253v13h2v-13h-2zm1.553 12.167C18.203 13.523 16.421 13 14.5 13v2c1.573 0 2.961.431 3.947 1.086l1.107-1.666zM14.5 13c-1.92 0-3.703.523-5.053 1.42l1.107 1.666C11.539 15.431 12.928 15 14.5 15v-2z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</template>
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
<template>
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="20" fill="currentColor">
|
|
||||||
<path
|
|
||||||
d="M11.447 8.894a1 1 0 1 0-.894-1.789l.894 1.789zm-2.894-.789a1 1 0 1 0 .894 1.789l-.894-1.789zm0 1.789a1 1 0 1 0 .894-1.789l-.894 1.789zM7.447 7.106a1 1 0 1 0-.894 1.789l.894-1.789zM10 9a1 1 0 1 0-2 0h2zm-2 2.5a1 1 0 1 0 2 0H8zm9.447-5.606a1 1 0 1 0-.894-1.789l.894 1.789zm-2.894-.789a1 1 0 1 0 .894 1.789l-.894-1.789zm2 .789a1 1 0 1 0 .894-1.789l-.894 1.789zm-1.106-2.789a1 1 0 1 0-.894 1.789l.894-1.789zM18 5a1 1 0 1 0-2 0h2zm-2 2.5a1 1 0 1 0 2 0h-2zm-5.447-4.606a1 1 0 1 0 .894-1.789l-.894 1.789zM9 1l.447-.894a1 1 0 0 0-.894 0L9 1zm-2.447.106a1 1 0 1 0 .894 1.789l-.894-1.789zm-6 3a1 1 0 1 0 .894 1.789L.553 4.106zm2.894.789a1 1 0 1 0-.894-1.789l.894 1.789zm-2-.789a1 1 0 1 0-.894 1.789l.894-1.789zm1.106 2.789a1 1 0 1 0 .894-1.789l-.894 1.789zM2 5a1 1 0 1 0-2 0h2zM0 7.5a1 1 0 1 0 2 0H0zm8.553 12.394a1 1 0 1 0 .894-1.789l-.894 1.789zm-1.106-2.789a1 1 0 1 0-.894 1.789l.894-1.789zm1.106 1a1 1 0 1 0 .894 1.789l-.894-1.789zm2.894.789a1 1 0 1 0-.894-1.789l.894 1.789zM8 19a1 1 0 1 0 2 0H8zm2-2.5a1 1 0 1 0-2 0h2zm-7.447.394a1 1 0 1 0 .894-1.789l-.894 1.789zM1 15H0a1 1 0 0 0 .553.894L1 15zm1-2.5a1 1 0 1 0-2 0h2zm12.553 2.606a1 1 0 1 0 .894 1.789l-.894-1.789zM17 15l.447.894A1 1 0 0 0 18 15h-1zm1-2.5a1 1 0 1 0-2 0h2zm-7.447-5.394l-2 1 .894 1.789 2-1-.894-1.789zm-1.106 1l-2-1-.894 1.789 2 1 .894-1.789zM8 9v2.5h2V9H8zm8.553-4.894l-2 1 .894 1.789 2-1-.894-1.789zm.894 0l-2-1-.894 1.789 2 1 .894-1.789zM16 5v2.5h2V5h-2zm-4.553-3.894l-2-1-.894 1.789 2 1 .894-1.789zm-2.894-1l-2 1 .894 1.789 2-1L8.553.106zM1.447 5.894l2-1-.894-1.789-2 1 .894 1.789zm-.894 0l2 1 .894-1.789-2-1-.894 1.789zM0 5v2.5h2V5H0zm9.447 13.106l-2-1-.894 1.789 2 1 .894-1.789zm0 1.789l2-1-.894-1.789-2 1 .894 1.789zM10 19v-2.5H8V19h2zm-6.553-3.894l-2-1-.894 1.789 2 1 .894-1.789zM2 15v-2.5H0V15h2zm13.447 1.894l2-1-.894-1.789-2 1 .894 1.789zM18 15v-2.5h-2V15h2z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</template>
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
<template>
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor">
|
|
||||||
<path
|
|
||||||
d="M10 3.22l-.61-.6a5.5 5.5 0 0 0-7.666.105 5.5 5.5 0 0 0-.114 7.665L10 18.78l8.39-8.4a5.5 5.5 0 0 0-.114-7.665 5.5 5.5 0 0 0-7.666-.105l-.61.61z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</template>
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
<!-- This icon is from <https://github.com/Templarian/MaterialDesign>, distributed under Apache 2.0 (https://www.apache.org/licenses/LICENSE-2.0) license-->
|
|
||||||
<template>
|
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
||||||
aria-hidden="true"
|
|
||||||
role="img"
|
|
||||||
class="iconify iconify--mdi"
|
|
||||||
width="24"
|
|
||||||
height="24"
|
|
||||||
preserveAspectRatio="xMidYMid meet"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M20 18v-4h-3v1h-2v-1H9v1H7v-1H4v4h16M6.33 8l-1.74 4H7v-1h2v1h6v-1h2v1h2.41l-1.74-4H6.33M9 5v1h6V5H9m12.84 7.61c.1.22.16.48.16.8V18c0 .53-.21 1-.6 1.41c-.4.4-.85.59-1.4.59H4c-.55 0-1-.19-1.4-.59C2.21 19 2 18.53 2 18v-4.59c0-.32.06-.58.16-.8L4.5 7.22C4.84 6.41 5.45 6 6.33 6H7V5c0-.55.18-1 .57-1.41C7.96 3.2 8.44 3 9 3h6c.56 0 1.04.2 1.43.59c.39.41.57.86.57 1.41v1h.67c.88 0 1.49.41 1.83 1.22l2.34 5.39z"
|
|
||||||
fill="currentColor"
|
|
||||||
></path>
|
|
||||||
</svg>
|
|
||||||
</template>
|
|
||||||
@ -1,40 +0,0 @@
|
|||||||
<template>
|
|
||||||
<el-tag :type="tagType">
|
|
||||||
{{ statusText }}
|
|
||||||
</el-tag>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { computed } from 'vue'
|
|
||||||
|
|
||||||
const props = defineProps({
|
|
||||||
status: {
|
|
||||||
type: Number,
|
|
||||||
required: true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const statusText = computed(() => {
|
|
||||||
const statusMap = {
|
|
||||||
1: '待审核',
|
|
||||||
2: '已审核',
|
|
||||||
3: '待发货',
|
|
||||||
4: '已发货',
|
|
||||||
5: '已完成',
|
|
||||||
6: '已关闭'
|
|
||||||
}
|
|
||||||
return statusMap[props.status] || '未知状态'
|
|
||||||
})
|
|
||||||
|
|
||||||
const tagType = computed(() => {
|
|
||||||
const typeMap = {
|
|
||||||
1: 'warning',
|
|
||||||
2: 'success',
|
|
||||||
3: 'info',
|
|
||||||
4: 'primary',
|
|
||||||
5: 'success',
|
|
||||||
6: 'danger'
|
|
||||||
}
|
|
||||||
return typeMap[props.status] || 'info'
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user