feat:增加换货单的逻辑,已发货短信模板更改

This commit is contained in:
一休哥哥6666
2026-06-15 13:42:52 +08:00
parent dfef98814b
commit 2991dd88bb
28 changed files with 575 additions and 628 deletions

View File

@@ -114,23 +114,6 @@ export function rejectExchangeOrder(data) {
}) })
} }
// 拒绝换货申请订单完成
export function completeExchangeRejectedOrder(data) {
return request({
url: '/jysystem/order/exchangeRejectedComplete',
method: 'put',
data: data
})
}
// 批量将拒绝换货申请订单更新为已完成
export function completeAllExchangeRejectedOrder() {
return request({
url: '/jysystem/order/exchangeRejectedCompleteAll',
method: 'put'
})
}
// 变更订单状态 // 变更订单状态
export function changeOrderStatus(data) { export function changeOrderStatus(data) {
return request({ return request({

View File

@@ -172,15 +172,6 @@
@click="handleQuickFilter('exchangeRejected')" @click="handleQuickFilter('exchangeRejected')"
>拒绝换货申请</el-button> >拒绝换货申请</el-button>
</el-col> </el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
size="mini"
@click="handleBatchCompleteExchangeRejected"
v-hasPermi="['jysystem:order:edit']"
>更新拒绝换货申请为已完成</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row> </el-row>
@@ -200,17 +191,22 @@
</el-table-column> </el-table-column>
<el-table-column label="B价格" align="center" width="90"> <el-table-column label="B价格" align="center" width="90">
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{ formatPriceB(scope.row) }}</span> <span>{{ formatPriceAmount(formatPriceB(scope.row)) }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="C价格" align="center" width="90"> <el-table-column label="C价格" align="center" width="90">
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{ formatPriceC(scope.row) }}</span> <span>{{ formatPriceAmount(formatPriceC(scope.row)) }}</span>
</template>
</el-table-column>
<el-table-column label="物流费用" align="center" width="90">
<template slot-scope="scope">
<span>{{ formatPriceAmount(formatLogisticsFee(scope.row)) }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="渐进多焦点价格" align="center" width="120"> <el-table-column label="渐进多焦点价格" align="center" width="120">
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{ formatProgressiveMultifocalPrice(scope.row) }}</span> <span>{{ formatPriceAmount(formatProgressiveMultifocalPrice(scope.row)) }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="订单状态" align="center" prop="orderStatus" width="130"> <el-table-column label="订单状态" align="center" prop="orderStatus" width="130">
@@ -850,21 +846,21 @@
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="B合计"> <el-descriptions-item label="B合计">
<el-tag <el-tag
v-if="isPendingTagText(formatPriceAmount(formatPriceTotal(detail, 'priceB')))" v-if="isPendingTagText(formatPriceAmount(formatDetailPriceTotal(detail, 'priceB')))"
type="danger" type="danger"
size="small" size="small"
:disable-transitions="true" :disable-transitions="true"
>{{ formatPriceAmount(formatPriceTotal(detail, 'priceB')) }}</el-tag> >{{ formatPriceAmount(formatDetailPriceTotal(detail, 'priceB')) }}</el-tag>
<span v-else class="price-total-value">{{ formatPriceAmount(formatPriceTotal(detail, 'priceB')) }}</span> <span v-else class="price-total-value">{{ formatPriceAmount(formatDetailPriceTotal(detail, 'priceB')) }}</span>
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="C合计"> <el-descriptions-item label="C合计">
<el-tag <el-tag
v-if="isPendingTagText(formatPriceAmount(formatPriceTotal(detail, 'priceC')))" v-if="isPendingTagText(formatPriceAmount(formatDetailPriceTotal(detail, 'priceC')))"
type="danger" type="danger"
size="small" size="small"
:disable-transitions="true" :disable-transitions="true"
>{{ formatPriceAmount(formatPriceTotal(detail, 'priceC')) }}</el-tag> >{{ formatPriceAmount(formatDetailPriceTotal(detail, 'priceC')) }}</el-tag>
<span v-else class="price-total-value">{{ formatPriceAmount(formatPriceTotal(detail, 'priceC')) }}</span> <span v-else class="price-total-value">{{ formatPriceAmount(formatDetailPriceTotal(detail, 'priceC')) }}</span>
</el-descriptions-item> </el-descriptions-item>
</el-descriptions> </el-descriptions>
<div class="detail-logistics-fee-block"> <div class="detail-logistics-fee-block">
@@ -876,26 +872,6 @@
<span>{{ formatPriceAmount(formatLogisticsLogFee(scope.row, detail)) }}</span> <span>{{ formatPriceAmount(formatLogisticsLogFee(scope.row, detail)) }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="应收结算" align="center" width="100">
<template slot-scope="scope">
<dict-tag
v-if="formatLogSaleSettleStatus(scope.row) != null"
:options="dict.type.jy_sale_settle_status"
:value="formatLogSaleSettleStatus(scope.row)"
/>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="应付结算" align="center" width="100">
<template slot-scope="scope">
<dict-tag
v-if="formatLogPurchaseSettleStatus(scope.row) != null"
:options="dict.type.jy_purchase_settle_status"
:value="formatLogPurchaseSettleStatus(scope.row)"
/>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="发货日期" align="center" width="120"> <el-table-column label="发货日期" align="center" width="120">
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{ formatShipDate(scope.row.operateTime) }}</span> <span>{{ formatShipDate(scope.row.operateTime) }}</span>
@@ -1021,26 +997,6 @@
<dict-tag :options="dict.type.jy_order_status" :value="scope.row.orderStatus" /> <dict-tag :options="dict.type.jy_order_status" :value="scope.row.orderStatus" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="应收结算" align="center" width="100">
<template slot-scope="scope">
<dict-tag
v-if="formatLogSaleSettleStatus(scope.row) != null"
:options="dict.type.jy_sale_settle_status"
:value="formatLogSaleSettleStatus(scope.row)"
/>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="应付结算" align="center" width="100">
<template slot-scope="scope">
<dict-tag
v-if="formatLogPurchaseSettleStatus(scope.row) != null"
:options="dict.type.jy_purchase_settle_status"
:value="formatLogPurchaseSettleStatus(scope.row)"
/>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="remark" min-width="160" show-overflow-tooltip /> <el-table-column label="备注" align="center" prop="remark" min-width="160" show-overflow-tooltip />
<el-table-column label="操作人" align="center" prop="operator" width="100" /> <el-table-column label="操作人" align="center" prop="operator" width="100" />
<el-table-column label="操作时间" align="center" prop="operateTime" width="160" /> <el-table-column label="操作时间" align="center" prop="operateTime" width="160" />
@@ -1124,7 +1080,7 @@
/> />
</el-form-item> </el-form-item>
<el-alert <el-alert
title="仅汇总所选年月内已完成状态的订单品牌方生成应收(AR)镜片厂生成应付(AP)" title="仅汇总所选年月内已完成或换货完成状态的订单品牌方生成应收(AR)镜片厂生成应付(AP)"
type="info" type="info"
:closable="false" :closable="false"
show-icon show-icon
@@ -1142,7 +1098,7 @@
import axios from 'axios' import axios from 'axios'
import { getToken } from '@/utils/auth' import { getToken } from '@/utils/auth'
import { isExternal } from '@/utils/validate' import { isExternal } from '@/utils/validate'
import { listOrder, getOrder, getOrderLogistics, delOrder, addOrder, updateOrder, previewAssignPrice, assignOrder, rejectOrder, closeOrder, completeOrder, agreeExchangeOrder, rejectExchangeOrder, completeExchangeRejectedOrder, completeAllExchangeRejectedOrder, changeOrderStatus } from "@/api/jysystem/order"; import { listOrder, getOrder, getOrderLogistics, delOrder, addOrder, updateOrder, previewAssignPrice, assignOrder, rejectOrder, closeOrder, completeOrder, agreeExchangeOrder, rejectExchangeOrder, changeOrderStatus } from "@/api/jysystem/order";
import { checkPermi } from "@/utils/permission"; import { checkPermi } from "@/utils/permission";
import { listBrandTenant, listLensFactoryTenant } from "@/api/jysystem/tenant"; import { listBrandTenant, listLensFactoryTenant } from "@/api/jysystem/tenant";
import { listLensOptions } from "@/api/jysystem/lens"; import { listLensOptions } from "@/api/jysystem/lens";
@@ -1216,6 +1172,9 @@ export default {
ORDER_STATUS_SHIPPED: '8', ORDER_STATUS_SHIPPED: '8',
ORDER_STATUS_COMPLETED: '9', ORDER_STATUS_COMPLETED: '9',
ORDER_STATUS_EXCHANGE_APPLY: '12', ORDER_STATUS_EXCHANGE_APPLY: '12',
ORDER_STATUS_EXCHANGE_AGREED: '13',
ORDER_STATUS_EXCHANGE_LOGISTICS: '15',
ORDER_STATUS_EXCHANGE_COMPLETED: '17',
ORDER_STATUS_EXCHANGE_REJECTED: '21', ORDER_STATUS_EXCHANGE_REJECTED: '21',
logisticsDialogVisible: false, logisticsDialogVisible: false,
logisticsBasic: null, logisticsBasic: null,
@@ -1368,20 +1327,42 @@ export default {
}, },
formatPriceB(row) { formatPriceB(row) {
if (!row) return '-'; if (!row) return '-';
if (this.isExchangeOrder(row)) return '-';
if (this.isPendingAssign(row)) return '未核算'; if (this.isPendingAssign(row)) return '未核算';
return row.priceB != null ? row.priceB : '-'; return row.priceB != null ? row.priceB : '-';
}, },
formatPriceC(row) { formatPriceC(row) {
if (!row) return '-'; if (!row) return '-';
if (this.isExchangeOrder(row)) return '-';
if (this.isPendingAssign(row)) return '未核算'; if (this.isPendingAssign(row)) return '未核算';
return row.priceC != null ? row.priceC : '-'; return row.priceC != null ? row.priceC : '-';
}, },
formatProgressiveMultifocalPrice(row) { formatProgressiveMultifocalPrice(row) {
if (!row) return '-'; if (!row) return '-';
if (this.isExchangeOrder(row)) return '-';
if (Number(row.progressiveMultifocal) !== 1) return '-'; if (Number(row.progressiveMultifocal) !== 1) return '-';
if (this.isPendingAssign(row)) return '未核算'; if (this.isPendingAssign(row)) return '未核算';
return row.progressiveMultifocalPrice != null ? row.progressiveMultifocalPrice : '-'; return row.progressiveMultifocalPrice != null ? row.progressiveMultifocalPrice : '-';
}, },
isExchangeOrder(row) {
if (!row) return false;
if (row.orderNo && String(row.orderNo).startsWith('HH')) return true;
const status = row.orderStatus != null ? String(row.orderStatus) : '';
return status === this.ORDER_STATUS_EXCHANGE_APPLY
|| status === this.ORDER_STATUS_EXCHANGE_AGREED
|| status === this.ORDER_STATUS_EXCHANGE_LOGISTICS
|| status === this.ORDER_STATUS_EXCHANGE_COMPLETED;
},
formatDetailPriceTotal(detail, priceKey) {
if (this.isExchangeOrder(detail)) return this.formatDetailLogisticsFee(detail);
return this.formatPriceTotal(detail, priceKey);
},
formatLogisticsFee(row) {
if (!row) return '-';
if (!this.isExchangeOrder(row)) return '-';
const fee = this.parseLogisticsFeeValue(row.logisticsFee);
return fee != null ? fee : '-';
},
formatPriceBC(row) { formatPriceBC(row) {
return `${this.formatPriceB(row)} / ${this.formatPriceC(row)}`; return `${this.formatPriceB(row)} / ${this.formatPriceC(row)}`;
}, },
@@ -1430,7 +1411,7 @@ export default {
hasFee = true; hasFee = true;
} }
}); });
if (!hasFee && logs.length > 0 && detail.logisticsFee != null) { if (!hasFee && detail.logisticsFee != null) {
const legacyFee = this.parseLogisticsFeeValue(detail.logisticsFee); const legacyFee = this.parseLogisticsFeeValue(detail.logisticsFee);
if (legacyFee != null) return legacyFee; if (legacyFee != null) return legacyFee;
} }
@@ -1440,24 +1421,6 @@ export default {
formatDetailLogisticsFee(detail) { formatDetailLogisticsFee(detail) {
return this.sumDetailLogisticsFee(detail); return this.sumDetailLogisticsFee(detail);
}, },
formatLogSaleSettleStatus(log) {
if (!log || log.expressNo == null || String(log.expressNo).trim() === '') {
return null;
}
if (log.saleSettleStatus != null && log.saleSettleStatus !== '') {
return log.saleSettleStatus;
}
return '0';
},
formatLogPurchaseSettleStatus(log) {
if (!log || log.expressNo == null || String(log.expressNo).trim() === '') {
return null;
}
if (log.purchaseSettleStatus != null && log.purchaseSettleStatus !== '') {
return log.purchaseSettleStatus;
}
return '0';
},
formatShipDate(time) { formatShipDate(time) {
if (!time) { if (!time) {
return '-'; return '-';
@@ -1730,13 +1693,17 @@ export default {
}, },
canViewLogistics(row) { canViewLogistics(row) {
if (!row || row.orderStatus == null) return false; if (!row || row.orderStatus == null) return false;
const status = Number(row.orderStatus); const status = String(row.orderStatus);
return status === Number(this.ORDER_STATUS_SHIPPED) || status === 9; return status === this.ORDER_STATUS_SHIPPED
|| status === this.ORDER_STATUS_EXCHANGE_LOGISTICS
|| status === this.ORDER_STATUS_COMPLETED
|| status === this.ORDER_STATUS_EXCHANGE_COMPLETED;
}, },
canCompleteOrder(row) { canCompleteOrder(row) {
if (!row || row.orderStatus == null) return false; if (!row || row.orderStatus == null) return false;
const status = String(row.orderStatus); const status = String(row.orderStatus);
return status === this.ORDER_STATUS_SHIPPED || status === this.ORDER_STATUS_EXCHANGE_REJECTED; return status === this.ORDER_STATUS_SHIPPED
|| status === this.ORDER_STATUS_EXCHANGE_LOGISTICS;
}, },
handleViewLogistics(row) { handleViewLogistics(row) {
if (!row || !row.id) return; if (!row || !row.id) return;
@@ -1864,28 +1831,13 @@ export default {
if (!row || !row.id) { if (!row || !row.id) {
return; return;
} }
const isExchangeRejected = String(row.orderStatus) === this.ORDER_STATUS_EXCHANGE_REJECTED; this.$modal.confirm(`确认完成订单"${row.orderNo}"吗?`).then(() => {
const confirmMsg = isExchangeRejected return completeOrder({ orderId: row.id });
? `确认将拒绝换货申请订单"${row.orderNo}"标记为已完成吗?`
: `确认完成订单"${row.orderNo}"吗?`;
const requestFn = isExchangeRejected
? () => completeExchangeRejectedOrder({ orderId: row.id })
: () => completeOrder({ orderId: row.id });
this.$modal.confirm(confirmMsg).then(() => {
return requestFn();
}).then(() => { }).then(() => {
this.$modal.msgSuccess('操作成功'); this.$modal.msgSuccess('操作成功');
this.getList(); this.getList();
}).catch(() => {}); }).catch(() => {});
}, },
handleBatchCompleteExchangeRejected() {
this.$modal.confirm('确认将所有拒绝换货申请状态的订单更新为已完成吗?').then(() => {
return completeAllExchangeRejectedOrder();
}).then((res) => {
this.$modal.msgSuccess((res && res.msg) || '操作成功');
this.getList();
}).catch(() => {});
},
handleAgreeExchange(row) { handleAgreeExchange(row) {
if (!row || !row.id) { if (!row || !row.id) {
return; return;

View File

@@ -55,7 +55,7 @@ public class ExpressQueryUtils {
HttpHeaders headers = new HttpHeaders(); HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", "APPCODE " + appCode); headers.set("Authorization", "APPCODE " + appCode);
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); headers.setContentType(MediaType.parseMediaType("application/x-www-form-urlencoded; charset=UTF-8"));
MultiValueMap<String, String> body = new LinkedMultiValueMap<>(); MultiValueMap<String, String> body = new LinkedMultiValueMap<>();
body.add("expressNo", expressNo); body.add("expressNo", expressNo);
@@ -75,21 +75,46 @@ public class ExpressQueryUtils {
return result; return result;
} catch (HttpStatusCodeException e) { } catch (HttpStatusCodeException e) {
int status = e.getRawStatusCode(); int status = e.getRawStatusCode();
log.error("调用阿里云物流查询失败 expressNo={} status={}", expressNo, status, e); String caError = e.getResponseHeaders() != null
? e.getResponseHeaders().getFirst("X-Ca-Error-Message") : null;
log.warn("调用阿里云物流查询失败 expressNo={} status={} caError={}", expressNo, status, caError);
result.put("errorCode", "HTTP_" + status); result.put("errorCode", "HTTP_" + status);
if (status == 403) { if (status == 403)
result.put("errorMsg", "物流查询服务授权失效HTTP 403请在阿里云 API 市场续费快递查询接口并更新 express.ali.app-code"); {
} else { result.put("errorMsg", buildExpress403Message(caError));
}
else
{
String errorBody = e.getResponseBodyAsString(); String errorBody = e.getResponseBodyAsString();
result.put("errorMsg", StringUtils.isNotEmpty(errorBody) ? errorBody : ("物流查询请求失败HTTP状态码" + status)); result.put("errorMsg", StringUtils.isNotEmpty(errorBody) ? errorBody : ("物流查询请求失败HTTP状态码" + status));
} }
return result; return result;
} catch (Exception e) { }
catch (Exception e)
{
log.error("调用阿里云物流查询失败 expressNo={}", expressNo, e); log.error("调用阿里云物流查询失败 expressNo={}", expressNo, e);
result.put("errorCode", "EXCEPTION"); result.put("errorCode", "EXCEPTION");
result.put("errorMsg", e.getMessage()); result.put("errorMsg", e.getMessage());
return result; return result;
} }
} }
private String buildExpress403Message(String caError)
{
if (StringUtils.isEmpty(caError))
{
return "物流查询未授权HTTP 403请在阿里云 API 市场购买「快递物流查询」接口,"
+ "并使用该商品对应的 AppCode 配置 express.ali.app-code不能与实名认证等其它 API 混用)";
}
if (caError.contains("Quota") || caError.contains("quota") || caError.contains("exhausted"))
{
return "物流查询套餐次数已用完HTTP 403请在阿里云 API 市场续费快递查询接口";
}
if (caError.contains("Unauthorized") || caError.contains("Invalid AppCode") || caError.contains("not exists"))
{
return "物流查询 AppCode 无效或未订阅该 APIHTTP 403请更新 express.ali.app-code 为快递查询商品的 AppCode";
}
return "物流查询未授权HTTP 403" + caError;
}
} }

View File

@@ -3,21 +3,6 @@ import store from '@/store'
import DataDict from '@/utils/dict' import DataDict from '@/utils/dict'
import { getDicts as getDicts } from '@/api/system/dict/data' import { getDicts as getDicts } from '@/api/system/dict/data'
function searchDictByKey(dict, key) {
if (key == null && key == "") {
return null
}
try {
for (let i = 0; i < dict.length; i++) {
if (dict[i].key == key) {
return dict[i].value
}
}
} catch (e) {
return null
}
}
function install() { function install() {
Vue.use(DataDict, { Vue.use(DataDict, {
metas: { metas: {
@@ -25,19 +10,14 @@ function install() {
labelField: 'dictLabel', labelField: 'dictLabel',
valueField: 'dictValue', valueField: 'dictValue',
request(dictMeta) { request(dictMeta) {
const storeDict = searchDictByKey(store.getters.dict, dictMeta.type) return new Promise((resolve, reject) => {
if (storeDict) { getDicts(dictMeta.type).then(res => {
return new Promise(resolve => { resolve(storeDict) }) store.dispatch('dict/setDict', { key: dictMeta.type, value: res.data })
} else { resolve(res.data)
return new Promise((resolve, reject) => { }).catch(error => {
getDicts(dictMeta.type).then(res => { reject(error)
store.dispatch('dict/setDict', { key: dictMeta.type, value: res.data })
resolve(res.data)
}).catch(error => {
reject(error)
})
}) })
} })
}, },
}, },
}, },

View File

@@ -1,7 +1,7 @@
<template> <template>
<div> <div>
<template v-for="(item, index) in options"> <template v-for="(item, index) in options">
<template v-if="values.includes(item.value)"> <template v-if="values.includes(String(item.value))">
<span <span
v-if="(item.raw.listClass == 'default' || item.raw.listClass == '') && (item.raw.cssClass == '' || item.raw.cssClass == null)" v-if="(item.raw.listClass == 'default' || item.raw.listClass == '') && (item.raw.cssClass == '' || item.raw.cssClass == null)"
:key="item.value" :key="item.value"
@@ -63,7 +63,7 @@ export default {
// 传入值为数组 // 传入值为数组
let unmatch = false // 添加一个标志来判断是否有未匹配项 let unmatch = false // 添加一个标志来判断是否有未匹配项
this.values.forEach(item => { this.values.forEach(item => {
if (!this.options.some(v => v.value === item)) { if (!this.options.some(v => String(v.value) === String(item))) {
this.unmatchArray.push(item) this.unmatchArray.push(item)
unmatch = true // 如果有未匹配项将标志设置为true unmatch = true // 如果有未匹配项将标志设置为true
} }

View File

@@ -4,10 +4,15 @@ const state = {
const mutations = { const mutations = {
SET_DICT: (state, { key, value }) => { SET_DICT: (state, { key, value }) => {
if (key !== null && key !== "") { if (key !== null && key !== "") {
state.dict.push({ const index = state.dict.findIndex(item => item.key === key)
key: key, if (index >= 0) {
value: value state.dict.splice(index, 1, { key: key, value: value })
}) } else {
state.dict.push({
key: key,
value: value
})
}
} }
}, },
REMOVE_DICT: (state, key) => { REMOVE_DICT: (state, key) => {

View File

@@ -30,7 +30,16 @@
<span>{{ formatLens(scope.row) }}</span> <span>{{ formatLens(scope.row) }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="C价格" align="center" prop="priceC" width="80" /> <el-table-column label="C价格" align="center" width="80">
<template slot-scope="scope">
<span>{{ formatPriceAmount(formatPriceC(scope.row)) }}</span>
</template>
</el-table-column>
<el-table-column label="物流费用" align="center" width="90">
<template slot-scope="scope">
<span>{{ formatPriceAmount(formatLogisticsFee(scope.row)) }}</span>
</template>
</el-table-column>
<el-table-column label="渐进多焦点价格" align="center" min-width="100"> <el-table-column label="渐进多焦点价格" align="center" min-width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{ formatProgressiveMultifocalPrice(scope.row) }}</span> <span>{{ formatProgressiveMultifocalPrice(scope.row) }}</span>
@@ -187,11 +196,11 @@
</div> </div>
<div class="section-body"> <div class="section-body">
<el-descriptions :column="2" border size="small" class="detail-descriptions detail-descriptions--price"> <el-descriptions :column="2" border size="small" class="detail-descriptions detail-descriptions--price">
<el-descriptions-item label="C价格">{{ formatPriceAmount(detail.priceC) }}</el-descriptions-item> <el-descriptions-item label="C价格">{{ formatPriceAmount(formatPriceC(detail)) }}</el-descriptions-item>
<el-descriptions-item label="物流费用">{{ formatPriceAmount(formatDetailLogisticsFee(detail)) }}</el-descriptions-item> <el-descriptions-item label="物流费用">{{ formatPriceAmount(formatDetailLogisticsFee(detail)) }}</el-descriptions-item>
<el-descriptions-item label="渐进多焦点价格">{{ formatPriceAmount(formatProgressiveMultifocalPrice(detail)) }}</el-descriptions-item> <el-descriptions-item label="渐进多焦点价格">{{ formatPriceAmount(formatProgressiveMultifocalPrice(detail)) }}</el-descriptions-item>
<el-descriptions-item label="合计"> <el-descriptions-item label="合计">
<span class="price-total-value">{{ formatPriceAmount(formatPriceTotal(detail, 'priceC')) }}</span> <span class="price-total-value">{{ formatPriceAmount(formatDetailPriceTotal(detail, 'priceC')) }}</span>
</el-descriptions-item> </el-descriptions-item>
</el-descriptions> </el-descriptions>
<div class="detail-logistics-fee-block"> <div class="detail-logistics-fee-block">
@@ -203,26 +212,6 @@
<span>{{ formatPriceAmount(formatLogisticsLogFee(scope.row, detail)) }}</span> <span>{{ formatPriceAmount(formatLogisticsLogFee(scope.row, detail)) }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="应收结算" align="center" width="100">
<template slot-scope="scope">
<dict-tag
v-if="formatLogSaleSettleStatus(scope.row) != null"
:options="dict.type.jy_sale_settle_status"
:value="formatLogSaleSettleStatus(scope.row)"
/>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="应付结算" align="center" width="100">
<template slot-scope="scope">
<dict-tag
v-if="formatLogPurchaseSettleStatus(scope.row) != null"
:options="dict.type.jy_purchase_settle_status"
:value="formatLogPurchaseSettleStatus(scope.row)"
/>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="发货日期" align="center" width="120"> <el-table-column label="发货日期" align="center" width="120">
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{ formatShipDate(scope.row.operateTime) }}</span> <span>{{ formatShipDate(scope.row.operateTime) }}</span>
@@ -311,26 +300,6 @@
<dict-tag :options="dict.type.jy_order_status" :value="scope.row.orderStatus" /> <dict-tag :options="dict.type.jy_order_status" :value="scope.row.orderStatus" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="应收结算" align="center" width="100">
<template slot-scope="scope">
<dict-tag
v-if="formatLogSaleSettleStatus(scope.row) != null"
:options="dict.type.jy_sale_settle_status"
:value="formatLogSaleSettleStatus(scope.row)"
/>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="应付结算" align="center" width="100">
<template slot-scope="scope">
<dict-tag
v-if="formatLogPurchaseSettleStatus(scope.row) != null"
:options="dict.type.jy_purchase_settle_status"
:value="formatLogPurchaseSettleStatus(scope.row)"
/>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="remark" min-width="160" show-overflow-tooltip /> <el-table-column label="备注" align="center" prop="remark" min-width="160" show-overflow-tooltip />
<el-table-column label="操作人" align="center" prop="operator" width="100" /> <el-table-column label="操作人" align="center" prop="operator" width="100" />
<el-table-column label="操作时间" align="center" prop="operateTime" width="160" /> <el-table-column label="操作时间" align="center" prop="operateTime" width="160" />
@@ -574,7 +543,10 @@ export default {
ORDER_STATUS_PRODUCING: '7', ORDER_STATUS_PRODUCING: '7',
ORDER_STATUS_SHIPPED: '8', ORDER_STATUS_SHIPPED: '8',
ORDER_STATUS_COMPLETED: '9', ORDER_STATUS_COMPLETED: '9',
ORDER_STATUS_EXCHANGE_APPLY: '12',
ORDER_STATUS_EXCHANGE_AGREED: '13', ORDER_STATUS_EXCHANGE_AGREED: '13',
ORDER_STATUS_EXCHANGE_LOGISTICS: '15',
ORDER_STATUS_EXCHANGE_COMPLETED: '17',
ORDER_STATUS_WITHDRAWN: '20', ORDER_STATUS_WITHDRAWN: '20',
ORDER_STATUS_SUPPLEMENTED: '19', ORDER_STATUS_SUPPLEMENTED: '19',
logisticsDialogVisible: false, logisticsDialogVisible: false,
@@ -703,8 +675,32 @@ export default {
}, },
formatProgressiveMultifocalPrice(row) { formatProgressiveMultifocalPrice(row) {
if (!row) return '-' if (!row) return '-'
if (this.isExchangeOrder(row)) return '-'
return row.progressiveMultifocalPrice != null ? row.progressiveMultifocalPrice : '-' return row.progressiveMultifocalPrice != null ? row.progressiveMultifocalPrice : '-'
}, },
isExchangeOrder(row) {
if (!row) return false
if (row.orderNo && String(row.orderNo).startsWith('HH')) return true
const status = row.orderStatus != null ? String(row.orderStatus) : ''
return status === this.ORDER_STATUS_EXCHANGE_APPLY || status === this.ORDER_STATUS_EXCHANGE_AGREED
|| status === this.ORDER_STATUS_EXCHANGE_LOGISTICS
|| status === this.ORDER_STATUS_EXCHANGE_COMPLETED
},
formatLogisticsFee(row) {
if (!row) return '-'
if (!this.isExchangeOrder(row)) return '-'
const fee = this.parseLogisticsFeeValue(row.logisticsFee)
return fee != null ? fee : '-'
},
formatPriceC(row) {
if (!row) return '-'
if (this.isExchangeOrder(row)) return '-'
return row.priceC != null ? row.priceC : '-'
},
formatDetailPriceTotal(detail, priceKey) {
if (this.isExchangeOrder(detail)) return this.formatDetailLogisticsFee(detail)
return this.formatPriceTotal(detail, priceKey)
},
formatPriceAmount(value) { formatPriceAmount(value) {
if (value == null || value === '' || value === '-') return '-' if (value == null || value === '' || value === '-') return '-'
if (value === '未核算') return '未核算' if (value === '未核算') return '未核算'
@@ -750,7 +746,7 @@ export default {
hasFee = true hasFee = true
} }
}) })
if (!hasFee && logs.length > 0 && detail.logisticsFee != null) { if (!hasFee && detail.logisticsFee != null) {
const legacyFee = this.parseLogisticsFeeValue(detail.logisticsFee) const legacyFee = this.parseLogisticsFeeValue(detail.logisticsFee)
if (legacyFee != null) return legacyFee if (legacyFee != null) return legacyFee
} }
@@ -760,24 +756,6 @@ export default {
formatDetailLogisticsFee(detail) { formatDetailLogisticsFee(detail) {
return this.sumDetailLogisticsFee(detail) return this.sumDetailLogisticsFee(detail)
}, },
formatLogSaleSettleStatus(log) {
if (!log || log.expressNo == null || String(log.expressNo).trim() === '') {
return null
}
if (log.saleSettleStatus != null && log.saleSettleStatus !== '') {
return log.saleSettleStatus
}
return '0'
},
formatLogPurchaseSettleStatus(log) {
if (!log || log.expressNo == null || String(log.expressNo).trim() === '') {
return null
}
if (log.purchaseSettleStatus != null && log.purchaseSettleStatus !== '') {
return log.purchaseSettleStatus
}
return '0'
},
formatShipDate(time) { formatShipDate(time) {
if (!time) { if (!time) {
return '-' return '-'
@@ -915,12 +893,17 @@ export default {
}, },
canCompleteOrder(row) { canCompleteOrder(row) {
if (!row || row.orderStatus == null) return false if (!row || row.orderStatus == null) return false
return String(row.orderStatus) === this.ORDER_STATUS_SHIPPED const status = String(row.orderStatus)
return status === this.ORDER_STATUS_SHIPPED
|| status === this.ORDER_STATUS_EXCHANGE_LOGISTICS
}, },
canViewLogistics(row) { canViewLogistics(row) {
if (!row || row.orderStatus == null) return false if (!row || row.orderStatus == null) return false
const status = Number(row.orderStatus) const status = String(row.orderStatus)
return status === Number(this.ORDER_STATUS_SHIPPED) || status === 9 return status === this.ORDER_STATUS_SHIPPED
|| status === this.ORDER_STATUS_EXCHANGE_LOGISTICS
|| status === this.ORDER_STATUS_COMPLETED
|| status === this.ORDER_STATUS_EXCHANGE_COMPLETED
}, },
handleViewLogistics(row) { handleViewLogistics(row) {
if (!row || !row.id) return if (!row || !row.id) return

View File

@@ -73,6 +73,11 @@
<span v-else>{{ formatPriceB(scope.row) }}</span> <span v-else>{{ formatPriceB(scope.row) }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="物流费用" align="center" width="90">
<template slot-scope="scope">
<span>{{ formatPriceAmount(formatLogisticsFee(scope.row)) }}</span>
</template>
</el-table-column>
<el-table-column label="渐进多焦点价格" align="center" min-width="100"> <el-table-column label="渐进多焦点价格" align="center" min-width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<el-tag <el-tag
@@ -671,12 +676,12 @@
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="合计"> <el-descriptions-item label="合计">
<el-tag <el-tag
v-if="isPendingTagText(formatPriceAmount(formatPriceTotal(detail, 'priceB')))" v-if="isPendingTagText(formatPriceAmount(formatDetailPriceTotal(detail, 'priceB')))"
type="danger" type="danger"
size="small" size="small"
:disable-transitions="true" :disable-transitions="true"
>{{ formatPriceAmount(formatPriceTotal(detail, 'priceB')) }}</el-tag> >{{ formatPriceAmount(formatDetailPriceTotal(detail, 'priceB')) }}</el-tag>
<span v-else class="price-total-value">{{ formatPriceAmount(formatPriceTotal(detail, 'priceB')) }}</span> <span v-else class="price-total-value">{{ formatPriceAmount(formatDetailPriceTotal(detail, 'priceB')) }}</span>
</el-descriptions-item> </el-descriptions-item>
</el-descriptions> </el-descriptions>
<div class="detail-logistics-fee-block"> <div class="detail-logistics-fee-block">
@@ -688,26 +693,6 @@
<span>{{ formatPriceAmount(formatLogisticsLogFee(scope.row, detail)) }}</span> <span>{{ formatPriceAmount(formatLogisticsLogFee(scope.row, detail)) }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="应收结算" align="center" width="100">
<template slot-scope="scope">
<dict-tag
v-if="formatLogSaleSettleStatus(scope.row) != null"
:options="dict.type.jy_sale_settle_status"
:value="formatLogSaleSettleStatus(scope.row)"
/>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="应付结算" align="center" width="100">
<template slot-scope="scope">
<dict-tag
v-if="formatLogPurchaseSettleStatus(scope.row) != null"
:options="dict.type.jy_purchase_settle_status"
:value="formatLogPurchaseSettleStatus(scope.row)"
/>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="发货日期" align="center" width="120"> <el-table-column label="发货日期" align="center" width="120">
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{ formatShipDate(scope.row.operateTime) }}</span> <span>{{ formatShipDate(scope.row.operateTime) }}</span>
@@ -796,26 +781,6 @@
<dict-tag :options="dict.type.jy_order_status" :value="scope.row.orderStatus" /> <dict-tag :options="dict.type.jy_order_status" :value="scope.row.orderStatus" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="应收结算" align="center" width="100">
<template slot-scope="scope">
<dict-tag
v-if="formatLogSaleSettleStatus(scope.row) != null"
:options="dict.type.jy_sale_settle_status"
:value="formatLogSaleSettleStatus(scope.row)"
/>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="应付结算" align="center" width="100">
<template slot-scope="scope">
<dict-tag
v-if="formatLogPurchaseSettleStatus(scope.row) != null"
:options="dict.type.jy_purchase_settle_status"
:value="formatLogPurchaseSettleStatus(scope.row)"
/>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="remark" min-width="160" show-overflow-tooltip /> <el-table-column label="备注" align="center" prop="remark" min-width="160" show-overflow-tooltip />
<el-table-column label="操作人" align="center" prop="operator" width="100" /> <el-table-column label="操作人" align="center" prop="operator" width="100" />
<el-table-column label="操作时间" align="center" prop="operateTime" width="160" /> <el-table-column label="操作时间" align="center" prop="operateTime" width="160" />
@@ -890,7 +855,7 @@
<span class="section-index">01</span> <span class="section-index">01</span>
<div class="section-text"> <div class="section-text">
<h4>换货申请说明</h4> <h4>换货申请说明</h4>
<p>填写换货申请原因订单将进入换货申请状态</p> <p>填写换货申请原因系统将复制当前订单生成新换货申请单原订单状态不变</p>
</div> </div>
</div> </div>
<div class="section-body"> <div class="section-body">
@@ -1053,6 +1018,9 @@ export default {
ORDER_STATUS_SHIPPED: '8', ORDER_STATUS_SHIPPED: '8',
ORDER_STATUS_COMPLETED: '9', ORDER_STATUS_COMPLETED: '9',
ORDER_STATUS_EXCHANGE_APPLY: '12', ORDER_STATUS_EXCHANGE_APPLY: '12',
ORDER_STATUS_EXCHANGE_AGREED: '13',
ORDER_STATUS_EXCHANGE_LOGISTICS: '15',
ORDER_STATUS_EXCHANGE_COMPLETED: '17',
ORDER_STATUS_EXCHANGE_REJECTED: '21', ORDER_STATUS_EXCHANGE_REJECTED: '21',
logisticsDialogVisible: false, logisticsDialogVisible: false,
logisticsBasic: null, logisticsBasic: null,
@@ -1162,7 +1130,7 @@ export default {
}, },
exchangeApplyDialogSubtitle() { exchangeApplyDialogSubtitle() {
if (this.exchangeApplyForm && this.exchangeApplyForm.orderNo) { if (this.exchangeApplyForm && this.exchangeApplyForm.orderNo) {
return `订单编号 ${this.exchangeApplyForm.orderNo} · 填写原因后提交换货申请` return `订单编号 ${this.exchangeApplyForm.orderNo} · 提交后将生成 HH 前缀的新换货申请`
} }
return '填写原因后提交换货申请' return '填写原因后提交换货申请'
}, },
@@ -1315,14 +1283,35 @@ export default {
const status = String(row.orderStatus) const status = String(row.orderStatus)
return status === this.ORDER_STATUS_DRAFT || status === this.ORDER_STATUS_REJECTED return status === this.ORDER_STATUS_DRAFT || status === this.ORDER_STATUS_REJECTED
}, },
isExchangeOrder(row) {
if (!row) return false
if (row.orderNo && String(row.orderNo).startsWith('HH')) return true
const status = row.orderStatus != null ? String(row.orderStatus) : ''
return status === this.ORDER_STATUS_EXCHANGE_APPLY
|| status === this.ORDER_STATUS_EXCHANGE_AGREED
|| status === this.ORDER_STATUS_EXCHANGE_LOGISTICS
|| status === this.ORDER_STATUS_EXCHANGE_COMPLETED
},
formatDetailPriceTotal(detail, priceKey) {
if (this.isExchangeOrder(detail)) return this.formatDetailLogisticsFee(detail)
return this.formatPriceTotal(detail, priceKey)
},
formatLogisticsFee(row) {
if (!row) return '-'
if (!this.isExchangeOrder(row)) return '-'
const fee = this.parseLogisticsFeeValue(row.logisticsFee)
return fee != null ? fee : '-'
},
formatPriceB(row) { formatPriceB(row) {
if (!row) return '-' if (!row) return '-'
if (this.isExchangeOrder(row)) return '-'
if (this.isUnsetPriceStatus(row)) return '-' if (this.isUnsetPriceStatus(row)) return '-'
if (String(row.orderStatus) === this.ORDER_STATUS_SUBMIT) return '未核算' if (String(row.orderStatus) === this.ORDER_STATUS_SUBMIT) return '未核算'
return row.priceB != null ? row.priceB : '-' return row.priceB != null ? row.priceB : '-'
}, },
formatProgressiveMultifocalPrice(row) { formatProgressiveMultifocalPrice(row) {
if (!row) return '-' if (!row) return '-'
if (this.isExchangeOrder(row)) return '-'
if (Number(row.progressiveMultifocal) !== 1) return '-' if (Number(row.progressiveMultifocal) !== 1) return '-'
if (this.isUnsetPriceStatus(row)) return '-' if (this.isUnsetPriceStatus(row)) return '-'
if (String(row.orderStatus) === this.ORDER_STATUS_SUBMIT) return '未核算' if (String(row.orderStatus) === this.ORDER_STATUS_SUBMIT) return '未核算'
@@ -1373,7 +1362,7 @@ export default {
hasFee = true hasFee = true
} }
}) })
if (!hasFee && logs.length > 0 && detail.logisticsFee != null) { if (!hasFee && detail.logisticsFee != null) {
const legacyFee = this.parseLogisticsFeeValue(detail.logisticsFee) const legacyFee = this.parseLogisticsFeeValue(detail.logisticsFee)
if (legacyFee != null) return legacyFee if (legacyFee != null) return legacyFee
} }
@@ -1383,24 +1372,6 @@ export default {
formatDetailLogisticsFee(detail) { formatDetailLogisticsFee(detail) {
return this.sumDetailLogisticsFee(detail) return this.sumDetailLogisticsFee(detail)
}, },
formatLogSaleSettleStatus(log) {
if (!log || log.expressNo == null || String(log.expressNo).trim() === '') {
return null
}
if (log.saleSettleStatus != null && log.saleSettleStatus !== '') {
return log.saleSettleStatus
}
return '0'
},
formatLogPurchaseSettleStatus(log) {
if (!log || log.expressNo == null || String(log.expressNo).trim() === '') {
return null
}
if (log.purchaseSettleStatus != null && log.purchaseSettleStatus !== '') {
return log.purchaseSettleStatus
}
return '0'
},
formatShipDate(time) { formatShipDate(time) {
if (!time) { if (!time) {
return '-' return '-'
@@ -1932,17 +1903,24 @@ export default {
}, },
canViewLogistics(row) { canViewLogistics(row) {
if (!row || row.orderStatus == null) return false if (!row || row.orderStatus == null) return false
const status = Number(row.orderStatus) const status = String(row.orderStatus)
return status === Number(this.ORDER_STATUS_SHIPPED) || status === 9 return status === this.ORDER_STATUS_SHIPPED
|| status === this.ORDER_STATUS_EXCHANGE_LOGISTICS
|| status === this.ORDER_STATUS_COMPLETED
|| status === this.ORDER_STATUS_EXCHANGE_COMPLETED
}, },
canCompleteOrder(row) { canCompleteOrder(row) {
if (!row || row.orderStatus == null) return false if (!row || row.orderStatus == null) return false
return String(row.orderStatus) === this.ORDER_STATUS_SHIPPED const status = String(row.orderStatus)
return status === this.ORDER_STATUS_SHIPPED
|| status === this.ORDER_STATUS_EXCHANGE_LOGISTICS
}, },
canExchangeApplyOrder(row) { canExchangeApplyOrder(row) {
if (!row || row.orderStatus == null) return false if (!row || row.orderStatus == null) return false
const status = String(row.orderStatus) const status = String(row.orderStatus)
return status === this.ORDER_STATUS_COMPLETED || status === this.ORDER_STATUS_EXCHANGE_REJECTED return status === this.ORDER_STATUS_COMPLETED
|| status === this.ORDER_STATUS_EXCHANGE_COMPLETED
|| status === this.ORDER_STATUS_EXCHANGE_REJECTED
}, },
canReceiveOrder(row) { canReceiveOrder(row) {
if (!row || row.orderStatus == null) return false if (!row || row.orderStatus == null) return false
@@ -2037,7 +2015,7 @@ export default {
}, },
handleExchangeApply(row) { handleExchangeApply(row) {
if (!row || !row.id || !this.canExchangeApplyOrder(row)) { if (!row || !row.id || !this.canExchangeApplyOrder(row)) {
this.$message.warning('仅已完成或拒绝换货申请状态订单可申请换货') this.$message.warning('仅已完成、换货完成或拒绝换货申请状态订单可申请换货')
return return
} }
this.exchangeApplyForm = { this.exchangeApplyForm = {
@@ -2061,8 +2039,10 @@ export default {
exchangeApplyPortalOrder({ exchangeApplyPortalOrder({
orderId: this.exchangeApplyForm.orderId, orderId: this.exchangeApplyForm.orderId,
reason: this.exchangeApplyForm.reason reason: this.exchangeApplyForm.reason
}).then(() => { }).then((res) => {
this.$modal.msgSuccess('换货申请已提交') const newOrder = res && res.data
const newOrderNo = newOrder && newOrder.orderNo ? newOrder.orderNo : ''
this.$modal.msgSuccess(newOrderNo ? `换货申请已提交,新订单号:${newOrderNo}` : '换货申请已提交')
this.exchangeApplyOpen = false this.exchangeApplyOpen = false
this.getList() this.getList()
if (this.detailOpen && this.detail.id === this.exchangeApplyForm.orderId) { if (this.detailOpen && this.detail.id === this.exchangeApplyForm.orderId) {

View File

@@ -16,7 +16,7 @@ public class SmsProperties
/** 配片订单分配至镜片厂(模板变量 code=订单号) */ /** 配片订单分配至镜片厂(模板变量 code=订单号) */
private SceneConfig assignOrder = new SceneConfig(); private SceneConfig assignOrder = new SceneConfig();
/** 配片订单发货通知(模板变量 code、expressCompany、expressNo */ /** 配片订单发货通知(模板变量 code、expressCompany */
private SceneConfig shipOrder = new SceneConfig(); private SceneConfig shipOrder = new SceneConfig();
public String getSignName() public String getSignName()

View File

@@ -199,32 +199,6 @@ public class JySysOrderController extends BaseController
rejectDTO.getOrderId(), rejectDTO.getReason().trim(), getUsername())); rejectDTO.getOrderId(), rejectDTO.getReason().trim(), getUsername()));
} }
@PreAuthorize("@ss.hasPermi('jysystem:order:edit')")
@Log(title = "拒绝换货申请订单完成", businessType = BusinessType.UPDATE)
@PutMapping("/exchangeRejectedComplete")
public AjaxResult exchangeRejectedComplete(@RequestBody OrderCloseDTO completeDTO)
{
if (completeDTO == null || completeDTO.getOrderId() == null)
{
return error("订单ID不能为空");
}
return toAjax(jySysOrderService.adminCompleteExchangeRejectedOrder(
completeDTO.getOrderId(), getUsername()));
}
@PreAuthorize("@ss.hasPermi('jysystem:order:edit')")
@Log(title = "批量完成拒绝换货申请订单", businessType = BusinessType.UPDATE)
@PutMapping("/exchangeRejectedCompleteAll")
public AjaxResult exchangeRejectedCompleteAll()
{
int rows = jySysOrderService.adminCompleteAllExchangeRejectedOrders(getUsername());
if (rows <= 0)
{
return success("没有需要更新的订单");
}
return success("已成功更新 " + rows + " 条订单");
}
@PreAuthorize("@ss.hasPermi('jysystem:order:edit')") @PreAuthorize("@ss.hasPermi('jysystem:order:edit')")
@Log(title = "订单状态变更", businessType = BusinessType.UPDATE) @Log(title = "订单状态变更", businessType = BusinessType.UPDATE)
@PutMapping("/changeStatus") @PutMapping("/changeStatus")

View File

@@ -210,7 +210,7 @@ public class JySysOrderPortalController extends BaseController
{ {
return error("换货申请原因不能为空"); return error("换货申请原因不能为空");
} }
return toAjax(jySysOrderPortalService.exchangeApplyPortalOrder( return success(jySysOrderPortalService.exchangeApplyPortalOrder(
exchangeDTO.getOrderId(), exchangeDTO.getReason().trim())); exchangeDTO.getOrderId(), exchangeDTO.getReason().trim()));
} }

View File

@@ -25,12 +25,6 @@ public class JySysOrderStatusLog
private BigDecimal logisticsFee; private BigDecimal logisticsFee;
/** 应收结算状态0未结算 1已结算 */
private String saleSettleStatus;
/** 应付结算状态0未结算 1已结算 */
private String purchaseSettleStatus;
private String remark; private String remark;
private String operator; private String operator;
@@ -98,26 +92,6 @@ public class JySysOrderStatusLog
this.logisticsFee = logisticsFee; this.logisticsFee = logisticsFee;
} }
public String getSaleSettleStatus()
{
return saleSettleStatus;
}
public void setSaleSettleStatus(String saleSettleStatus)
{
this.saleSettleStatus = saleSettleStatus;
}
public String getPurchaseSettleStatus()
{
return purchaseSettleStatus;
}
public void setPurchaseSettleStatus(String purchaseSettleStatus)
{
this.purchaseSettleStatus = purchaseSettleStatus;
}
public String getRemark() public String getRemark()
{ {
return remark; return remark;
@@ -158,8 +132,6 @@ public class JySysOrderStatusLog
.append("expressCompany", getExpressCompany()) .append("expressCompany", getExpressCompany())
.append("expressNo", getExpressNo()) .append("expressNo", getExpressNo())
.append("logisticsFee", getLogisticsFee()) .append("logisticsFee", getLogisticsFee())
.append("saleSettleStatus", getSaleSettleStatus())
.append("purchaseSettleStatus", getPurchaseSettleStatus())
.append("remark", getRemark()) .append("remark", getRemark())
.append("operator", getOperator()) .append("operator", getOperator())
.append("operateTime", getOperateTime()) .append("operateTime", getOperateTime())

View File

@@ -28,6 +28,8 @@ public interface JySysOrderMapper extends BaseMapper<JySysOrder>
int countByTenantId(@Param("tenantId") Long tenantId); int countByTenantId(@Param("tenantId") Long tenantId);
int countByOrderNo(@Param("orderNo") String orderNo);
List<JySysOrder> selectCompletedOrdersByYearMonth(@Param("settleYearMonth") String settleYearMonth); List<JySysOrder> selectCompletedOrdersByYearMonth(@Param("settleYearMonth") String settleYearMonth);
int updatePurchaseSettleStatusByOrderIds(@Param("orderIds") List<Long> orderIds, int updatePurchaseSettleStatusByOrderIds(@Param("orderIds") List<Long> orderIds,

View File

@@ -17,10 +17,4 @@ public interface JySysOrderStatusLogMapper
List<JySysOrderStatusLog> selectUnsettledShipLogsByOrderIdAndType(@Param("orderId") Long orderId, List<JySysOrderStatusLog> selectUnsettledShipLogsByOrderIdAndType(@Param("orderId") Long orderId,
@Param("settlementType") String settlementType); @Param("settlementType") String settlementType);
int updateSaleSettleStatusByIds(@Param("ids") List<Long> ids, @Param("settleStatus") String settleStatus);
int updatePurchaseSettleStatusByIds(@Param("ids") List<Long> ids, @Param("settleStatus") String settleStatus);
int resetShipLogSettleStatusByOrderIds(@Param("orderIds") List<Long> orderIds);
} }

View File

@@ -46,7 +46,7 @@ public interface IJySysOrderPortalService
int completePortalOrder(Long orderId); int completePortalOrder(Long orderId);
int exchangeApplyPortalOrder(Long orderId, String reason); JySysOrder exchangeApplyPortalOrder(Long orderId, String reason);
int receivePortalOrder(Long orderId); int receivePortalOrder(Long orderId);

View File

@@ -52,7 +52,7 @@ public interface IJySysOrderService extends IService<JySysOrder>
int brandReceiveExchangeRejectedOrder(Long orderId, Long brandTenantId, String operator); int brandReceiveExchangeRejectedOrder(Long orderId, Long brandTenantId, String operator);
int brandExchangeApplyOrder(Long orderId, Long brandTenantId, String reason, String operator); JySysOrder brandExchangeApplyOrder(Long orderId, Long brandTenantId, String reason, String operator);
int adminRejectOrder(Long orderId, String reason, String operator); int adminRejectOrder(Long orderId, String reason, String operator);
@@ -64,10 +64,6 @@ public interface IJySysOrderService extends IService<JySysOrder>
int adminRejectExchangeOrder(Long orderId, String reason, String operator); int adminRejectExchangeOrder(Long orderId, String reason, String operator);
int adminCompleteExchangeRejectedOrder(Long orderId, String operator);
int adminCompleteAllExchangeRejectedOrders(String operator);
int brandResubmitOrder(Long orderId, Long brandTenantId, String reason, String operator); int brandResubmitOrder(Long orderId, Long brandTenantId, String reason, String operator);
int changeOrderStatus(Long orderId, String orderStatus, String operator); int changeOrderStatus(Long orderId, String orderStatus, String operator);

View File

@@ -19,7 +19,6 @@ public interface SmsNotificationService
* @param phone 手机号(品牌方租户手机号,或收货人手机号) * @param phone 手机号(品牌方租户手机号,或收货人手机号)
* @param orderNo 订单号,对应模板变量 code * @param orderNo 订单号,对应模板变量 code
* @param expressCompany 快递公司,对应模板变量 expressCompany * @param expressCompany 快递公司,对应模板变量 expressCompany
* @param expressNo 快递单号,对应模板变量 expressNo
*/ */
void trySendOrderShippedNotify(String phone, String orderNo, String expressCompany, String expressNo); void trySendOrderShippedNotify(String phone, String orderNo, String expressCompany);
} }

View File

@@ -37,6 +37,14 @@ import com.ruoyi.jysystem.vo.FeeSettlementDetailVO;
@Service @Service
public class JySysFeeSettlementServiceImpl implements IJySysFeeSettlementService public class JySysFeeSettlementServiceImpl implements IJySysFeeSettlementService
{ {
private static final String ORDER_STATUS_EXCHANGE_APPLY = "12";
private static final String ORDER_STATUS_EXCHANGE_AGREED = "13";
private static final String ORDER_STATUS_EXCHANGE_LOGISTICS = "15";
private static final String ORDER_STATUS_EXCHANGE_COMPLETED = "17";
@Resource @Resource
private JySysFeeSettlementMapper feeSettlementMapper; private JySysFeeSettlementMapper feeSettlementMapper;
@@ -130,10 +138,6 @@ public class JySysFeeSettlementServiceImpl implements IJySysFeeSettlementService
{ {
throw new ServiceException("该年月没有已完成状态的订单,无法生成结算单"); throw new ServiceException("该年月没有已完成状态的订单,无法生成结算单");
} }
if (forceRegenerate && exists)
{
resetShipLogSettleStatusForOrders(orders);
}
Map<Long, List<JySysOrder>> brandGroups = new LinkedHashMap<>(); Map<Long, List<JySysOrder>> brandGroups = new LinkedHashMap<>();
Map<Long, List<JySysOrder>> factoryGroups = new LinkedHashMap<>(); Map<Long, List<JySysOrder>> factoryGroups = new LinkedHashMap<>();
@@ -210,27 +214,9 @@ public class JySysFeeSettlementServiceImpl implements IJySysFeeSettlementService
update.setUpdateTime(DateUtils.getNowDate()); update.setUpdateTime(DateUtils.getNowDate());
int rows = feeSettlementMapper.updateSettleStatus(update); int rows = feeSettlementMapper.updateSettleStatus(update);
updateOrderSettleStatusBySettlement(settlement, operator); updateOrderSettleStatusBySettlement(settlement, operator);
updateStatusLogSettleStatusBySettlement(settlement);
return rows; return rows;
} }
private void updateStatusLogSettleStatusBySettlement(JySysFeeSettlement settlement)
{
List<Long> statusLogIds = collectStatusLogIdsBySettlement(settlement.getId());
if (statusLogIds.isEmpty())
{
return;
}
if (JySysFeeSettlement.TYPE_AP.equals(settlement.getSettlementType()))
{
jySysOrderStatusLogMapper.updatePurchaseSettleStatusByIds(statusLogIds, "1");
}
else if (JySysFeeSettlement.TYPE_AR.equals(settlement.getSettlementType()))
{
jySysOrderStatusLogMapper.updateSaleSettleStatusByIds(statusLogIds, "1");
}
}
private void updateOrderSettleStatusBySettlement(JySysFeeSettlement settlement, String operator) private void updateOrderSettleStatusBySettlement(JySysFeeSettlement settlement, String operator)
{ {
List<JySysFeeSettlementItem> items = feeSettlementItemMapper.selectBySettlementId(settlement.getId()); List<JySysFeeSettlementItem> items = feeSettlementItemMapper.selectBySettlementId(settlement.getId());
@@ -314,10 +300,13 @@ public class JySysFeeSettlementServiceImpl implements IJySysFeeSettlementService
private JySysFeeSettlementItem buildSettlementItem(Long settlementId, String type, JySysOrder order) private JySysFeeSettlementItem buildSettlementItem(Long settlementId, String type, JySysOrder order)
{ {
BigDecimal lensPrice = JySysFeeSettlement.TYPE_AR.equals(type) boolean exchangeOrder = isExchangeOrder(order);
? defaultAmount(order.getPriceC()) : defaultAmount(order.getPriceB()); BigDecimal lensPrice = exchangeOrder ? BigDecimal.ZERO
BigDecimal progressivePrice = Integer.valueOf(1).equals(order.getProgressiveMultifocal()) : (JySysFeeSettlement.TYPE_AR.equals(type)
? defaultAmount(order.getProgressiveMultifocalPrice()) : BigDecimal.ZERO; ? defaultAmount(order.getPriceC()) : defaultAmount(order.getPriceB()));
BigDecimal progressivePrice = exchangeOrder ? BigDecimal.ZERO
: (Integer.valueOf(1).equals(order.getProgressiveMultifocal())
? defaultAmount(order.getProgressiveMultifocalPrice()) : BigDecimal.ZERO);
List<JySysOrderStatusLog> shipLogs = jySysOrderStatusLogMapper List<JySysOrderStatusLog> shipLogs = jySysOrderStatusLogMapper
.selectUnsettledShipLogsByOrderIdAndType(order.getId(), type); .selectUnsettledShipLogsByOrderIdAndType(order.getId(), type);
@@ -374,7 +363,6 @@ public class JySysFeeSettlementServiceImpl implements IJySysFeeSettlementService
{ {
continue; continue;
} }
revertLogSettleStatusBySettlement(settlement);
if ("1".equals(settlement.getSettleStatus())) if ("1".equals(settlement.getSettleStatus()))
{ {
revertOrderSettleStatusBySettlement(settlement); revertOrderSettleStatusBySettlement(settlement);
@@ -392,24 +380,6 @@ public class JySysFeeSettlementServiceImpl implements IJySysFeeSettlementService
} }
} }
/** 删除结算单时回滚关联发货日志的结算状态,便于重新生成时再次纳入物流费用 */
private void revertLogSettleStatusBySettlement(JySysFeeSettlement settlement)
{
List<Long> statusLogIds = collectStatusLogIdsBySettlement(settlement.getId());
if (statusLogIds.isEmpty())
{
return;
}
if (JySysFeeSettlement.TYPE_AP.equals(settlement.getSettlementType()))
{
jySysOrderStatusLogMapper.updatePurchaseSettleStatusByIds(statusLogIds, "0");
}
else if (JySysFeeSettlement.TYPE_AR.equals(settlement.getSettlementType()))
{
jySysOrderStatusLogMapper.updateSaleSettleStatusByIds(statusLogIds, "0");
}
}
private void revertOrderSettleStatusBySettlement(JySysFeeSettlement settlement) private void revertOrderSettleStatusBySettlement(JySysFeeSettlement settlement)
{ {
List<JySysFeeSettlementItem> items = feeSettlementItemMapper.selectBySettlementId(settlement.getId()); List<JySysFeeSettlementItem> items = feeSettlementItemMapper.selectBySettlementId(settlement.getId());
@@ -433,38 +403,6 @@ public class JySysFeeSettlementServiceImpl implements IJySysFeeSettlementService
} }
} }
private void resetShipLogSettleStatusForOrders(List<JySysOrder> orders)
{
if (orders == null || orders.isEmpty())
{
return;
}
List<Long> orderIds = orders.stream()
.map(JySysOrder::getId)
.filter(orderId -> orderId != null)
.distinct()
.collect(Collectors.toList());
if (!orderIds.isEmpty())
{
jySysOrderStatusLogMapper.resetShipLogSettleStatusByOrderIds(orderIds);
}
}
private List<Long> collectStatusLogIdsBySettlement(Long settlementId)
{
List<JySysFeeSettlementItem> items = feeSettlementItemMapper.selectBySettlementId(settlementId);
if (items == null || items.isEmpty())
{
return new ArrayList<>();
}
List<Long> itemIds = items.stream().map(JySysFeeSettlementItem::getId).collect(Collectors.toList());
return feeSettlementLogisticsMapper.selectBySettlementItemIds(itemIds).stream()
.map(JySysFeeSettlementLogistics::getStatusLogId)
.filter(statusLogId -> statusLogId != null)
.distinct()
.collect(Collectors.toList());
}
private String nextSettlementNo(String type) private String nextSettlementNo(String type)
{ {
String datePart = new SimpleDateFormat("yyyyMMdd").format(new Date()); String datePart = new SimpleDateFormat("yyyyMMdd").format(new Date());
@@ -496,6 +434,23 @@ public class JySysFeeSettlementServiceImpl implements IJySysFeeSettlementService
return value != null ? value : BigDecimal.ZERO; return value != null ? value : BigDecimal.ZERO;
} }
private boolean isExchangeOrder(JySysOrder order)
{
if (order == null)
{
return false;
}
if (StringUtils.isNotEmpty(order.getOrderNo()) && order.getOrderNo().startsWith("HH"))
{
return true;
}
String status = order.getOrderStatus();
return ORDER_STATUS_EXCHANGE_APPLY.equals(status)
|| ORDER_STATUS_EXCHANGE_AGREED.equals(status)
|| ORDER_STATUS_EXCHANGE_LOGISTICS.equals(status)
|| ORDER_STATUS_EXCHANGE_COMPLETED.equals(status);
}
@Override @Override
public byte[] exportPdf(Long id) public byte[] exportPdf(Long id)
{ {

View File

@@ -229,7 +229,7 @@ public class JySysOrderPortalServiceImpl implements IJySysOrderPortalService
} }
@Override @Override
public int exchangeApplyPortalOrder(Long orderId, String reason) public JySysOrder exchangeApplyPortalOrder(Long orderId, String reason)
{ {
JySysTenant tenant = requireBrandTenant(); JySysTenant tenant = requireBrandTenant();
return jySysOrderService.brandExchangeApplyOrder( return jySysOrderService.brandExchangeApplyOrder(

View File

@@ -59,6 +59,10 @@ public class JySysOrderServiceImpl extends ServiceImpl<JySysOrderMapper, JySysOr
private static final String ORDER_STATUS_EXCHANGE_AGREED = "13"; private static final String ORDER_STATUS_EXCHANGE_AGREED = "13";
private static final String ORDER_STATUS_EXCHANGE_LOGISTICS = "15";
private static final String ORDER_STATUS_EXCHANGE_COMPLETED = "17";
private static final String ORDER_STATUS_EXCHANGE_REJECTED = "21"; private static final String ORDER_STATUS_EXCHANGE_REJECTED = "21";
private static final String ORDER_STATUS_CANCELLED = "18"; private static final String ORDER_STATUS_CANCELLED = "18";
@@ -347,7 +351,7 @@ public class JySysOrderServiceImpl extends ServiceImpl<JySysOrderMapper, JySysOr
throw new ServiceException("物流费用不能小于0"); throw new ServiceException("物流费用不能小于0");
} }
saveStatusLog(orderId, ORDER_STATUS_SHIPPED, operator, expressCompany, expressNo, null, logisticsFee); saveStatusLog(orderId, resolveShipStatus(order), operator, expressCompany, expressNo, null, logisticsFee);
BigDecimal totalLogisticsFee = jySysOrderStatusLogMapper.sumLogisticsFeeByOrderId(orderId); BigDecimal totalLogisticsFee = jySysOrderStatusLogMapper.sumLogisticsFeeByOrderId(orderId);
if (totalLogisticsFee == null) if (totalLogisticsFee == null)
{ {
@@ -362,7 +366,7 @@ public class JySysOrderServiceImpl extends ServiceImpl<JySysOrderMapper, JySysOr
update.setAttachment(order.getAttachment()); update.setAttachment(order.getAttachment());
update.setLensFactoryTenantId(order.getLensFactoryTenantId()); update.setLensFactoryTenantId(order.getLensFactoryTenantId());
update.setLogisticsFee(totalLogisticsFee); update.setLogisticsFee(totalLogisticsFee);
update.setOrderStatus(ORDER_STATUS_SHIPPED); update.setOrderStatus(resolveShipStatus(order));
update.setUpdateBy(operator); update.setUpdateBy(operator);
update.setUpdateTime(DateUtils.getNowDate()); update.setUpdateTime(DateUtils.getNowDate());
@@ -383,12 +387,13 @@ public class JySysOrderServiceImpl extends ServiceImpl<JySysOrderMapper, JySysOr
update.setAttachment(order.getAttachment()); update.setAttachment(order.getAttachment());
update.setLensFactoryTenantId(order.getLensFactoryTenantId()); update.setLensFactoryTenantId(order.getLensFactoryTenantId());
update.setLogisticsFee(order.getLogisticsFee()); update.setLogisticsFee(order.getLogisticsFee());
update.setOrderStatus(ORDER_STATUS_COMPLETED); String completeStatus = resolveCompleteStatus(order);
update.setOrderStatus(completeStatus);
update.setUpdateBy(operator); update.setUpdateBy(operator);
update.setUpdateTime(DateUtils.getNowDate()); update.setUpdateTime(DateUtils.getNowDate());
int rows = jySysOrderMapper.updateJySysOrder(update); int rows = jySysOrderMapper.updateJySysOrder(update);
saveStatusLog(orderId, ORDER_STATUS_COMPLETED, operator, null, null, null); saveStatusLog(orderId, completeStatus, operator, null, null, null);
return rows; return rows;
} }
@@ -406,12 +411,13 @@ public class JySysOrderServiceImpl extends ServiceImpl<JySysOrderMapper, JySysOr
update.setAttachment(order.getAttachment()); update.setAttachment(order.getAttachment());
update.setLensFactoryTenantId(order.getLensFactoryTenantId()); update.setLensFactoryTenantId(order.getLensFactoryTenantId());
update.setLogisticsFee(order.getLogisticsFee()); update.setLogisticsFee(order.getLogisticsFee());
update.setOrderStatus(ORDER_STATUS_COMPLETED); String completeStatus = resolveCompleteStatus(order);
update.setOrderStatus(completeStatus);
update.setUpdateBy(operator); update.setUpdateBy(operator);
update.setUpdateTime(DateUtils.getNowDate()); update.setUpdateTime(DateUtils.getNowDate());
int rows = jySysOrderMapper.updateJySysOrder(update); int rows = jySysOrderMapper.updateJySysOrder(update);
saveStatusLog(orderId, ORDER_STATUS_COMPLETED, operator, null, null, null); saveStatusLog(orderId, completeStatus, operator, null, null, null);
return rows; return rows;
} }
@@ -440,29 +446,19 @@ public class JySysOrderServiceImpl extends ServiceImpl<JySysOrderMapper, JySysOr
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public int brandExchangeApplyOrder(Long orderId, Long brandTenantId, String reason, String operator) public JySysOrder brandExchangeApplyOrder(Long orderId, Long brandTenantId, String reason, String operator)
{ {
JySysOrder order = requireBrandExchangeAppliableOrder(orderId, brandTenantId); requireBrandExchangeAppliableOrder(orderId, brandTenantId);
if (StringUtils.isEmpty(reason)) if (StringUtils.isEmpty(reason))
{ {
throw new ServiceException("换货申请原因不能为空"); throw new ServiceException("换货申请原因不能为空");
} }
JySysOrder source = selectJySysOrderById(orderId);
JySysOrder update = new JySysOrder(); if (source == null)
update.setId(orderId); {
update.setBrandTenantId(order.getBrandTenantId()); throw new ServiceException("订单不存在");
update.setLensId(order.getLensId()); }
update.setProductId(order.getProductId()); return copyOrderForExchangeApply(source, reason, operator);
update.setAttachment(order.getAttachment());
update.setLensFactoryTenantId(order.getLensFactoryTenantId());
update.setLogisticsFee(order.getLogisticsFee());
update.setOrderStatus(ORDER_STATUS_EXCHANGE_APPLY);
update.setUpdateBy(operator);
update.setUpdateTime(DateUtils.getNowDate());
int rows = jySysOrderMapper.updateJySysOrder(update);
saveStatusLog(orderId, ORDER_STATUS_EXCHANGE_APPLY, operator, null, null, reason);
return rows;
} }
@Override @Override
@@ -557,11 +553,13 @@ public class JySysOrderServiceImpl extends ServiceImpl<JySysOrderMapper, JySysOr
{ {
throw new ServiceException("订单不存在"); throw new ServiceException("订单不存在");
} }
if (!ORDER_STATUS_SHIPPED.equals(order.getOrderStatus())) if (!ORDER_STATUS_SHIPPED.equals(order.getOrderStatus())
&& !ORDER_STATUS_EXCHANGE_LOGISTICS.equals(order.getOrderStatus()))
{ {
throw new ServiceException("仅已发货状态的订单可完成"); throw new ServiceException("仅已发货或换货物流状态的订单可完成");
} }
String completeStatus = resolveCompleteStatus(order);
JySysOrder update = new JySysOrder(); JySysOrder update = new JySysOrder();
update.setId(orderId); update.setId(orderId);
update.setBrandTenantId(order.getBrandTenantId()); update.setBrandTenantId(order.getBrandTenantId());
@@ -570,12 +568,12 @@ public class JySysOrderServiceImpl extends ServiceImpl<JySysOrderMapper, JySysOr
update.setAttachment(order.getAttachment()); update.setAttachment(order.getAttachment());
update.setLensFactoryTenantId(order.getLensFactoryTenantId()); update.setLensFactoryTenantId(order.getLensFactoryTenantId());
update.setLogisticsFee(order.getLogisticsFee()); update.setLogisticsFee(order.getLogisticsFee());
update.setOrderStatus(ORDER_STATUS_COMPLETED); update.setOrderStatus(completeStatus);
update.setUpdateBy(operator); update.setUpdateBy(operator);
update.setUpdateTime(DateUtils.getNowDate()); update.setUpdateTime(DateUtils.getNowDate());
int rows = jySysOrderMapper.updateJySysOrder(update); int rows = jySysOrderMapper.updateJySysOrder(update);
saveStatusLog(orderId, ORDER_STATUS_COMPLETED, operator, null, null, null); saveStatusLog(orderId, completeStatus, operator, null, null, null);
return rows; return rows;
} }
@@ -629,33 +627,6 @@ public class JySysOrderServiceImpl extends ServiceImpl<JySysOrderMapper, JySysOr
return rows; return rows;
} }
@Override
@Transactional(rollbackFor = Exception.class)
public int adminCompleteExchangeRejectedOrder(Long orderId, String operator)
{
return completeExchangeRejectedToCompleted(orderId, operator);
}
@Override
@Transactional(rollbackFor = Exception.class)
public int adminCompleteAllExchangeRejectedOrders(String operator)
{
JySysOrder query = new JySysOrder();
query.setOrderStatus(ORDER_STATUS_EXCHANGE_REJECTED);
List<JySysOrder> orderList = jySysOrderMapper.selectJySysOrderList(query);
if (orderList == null || orderList.isEmpty())
{
return 0;
}
int count = 0;
for (JySysOrder order : orderList)
{
completeExchangeRejectedToCompleted(order.getId(), operator);
count++;
}
return count;
}
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public int brandResubmitOrder(Long orderId, Long brandTenantId, String reason, String operator) public int brandResubmitOrder(Long orderId, Long brandTenantId, String reason, String operator)
@@ -801,9 +772,10 @@ public class JySysOrderServiceImpl extends ServiceImpl<JySysOrderMapper, JySysOr
private JySysOrder requireFactoryCompletableOrder(Long orderId, Long lensFactoryTenantId) private JySysOrder requireFactoryCompletableOrder(Long orderId, Long lensFactoryTenantId)
{ {
JySysOrder order = requireFactoryOwnedOrder(orderId, lensFactoryTenantId); JySysOrder order = requireFactoryOwnedOrder(orderId, lensFactoryTenantId);
if (!ORDER_STATUS_SHIPPED.equals(order.getOrderStatus())) if (!ORDER_STATUS_SHIPPED.equals(order.getOrderStatus())
&& !ORDER_STATUS_EXCHANGE_LOGISTICS.equals(order.getOrderStatus()))
{ {
throw new ServiceException("仅已发货状态的订单可完成"); throw new ServiceException("仅已发货或换货物流状态的订单可完成");
} }
return order; return order;
} }
@@ -827,9 +799,10 @@ public class JySysOrderServiceImpl extends ServiceImpl<JySysOrderMapper, JySysOr
{ {
throw new ServiceException("无权操作该订单"); throw new ServiceException("无权操作该订单");
} }
if (!ORDER_STATUS_SHIPPED.equals(order.getOrderStatus())) if (!ORDER_STATUS_SHIPPED.equals(order.getOrderStatus())
&& !ORDER_STATUS_EXCHANGE_LOGISTICS.equals(order.getOrderStatus()))
{ {
throw new ServiceException("仅已发货状态的订单可完成"); throw new ServiceException("仅已发货或换货物流状态的订单可完成");
} }
return order; return order;
} }
@@ -880,46 +853,14 @@ public class JySysOrderServiceImpl extends ServiceImpl<JySysOrderMapper, JySysOr
throw new ServiceException("无权操作该订单"); throw new ServiceException("无权操作该订单");
} }
if (!ORDER_STATUS_COMPLETED.equals(order.getOrderStatus()) if (!ORDER_STATUS_COMPLETED.equals(order.getOrderStatus())
&& !ORDER_STATUS_EXCHANGE_COMPLETED.equals(order.getOrderStatus())
&& !ORDER_STATUS_EXCHANGE_REJECTED.equals(order.getOrderStatus())) && !ORDER_STATUS_EXCHANGE_REJECTED.equals(order.getOrderStatus()))
{ {
throw new ServiceException("仅已完成或拒绝换货申请状态的订单可申请换货"); throw new ServiceException("仅已完成、换货完成或拒绝换货申请状态的订单可申请换货");
} }
return order; return order;
} }
private int completeExchangeRejectedToCompleted(Long orderId, String operator)
{
if (orderId == null)
{
throw new ServiceException("订单ID不能为空");
}
JySysOrder order = jySysOrderMapper.selectJySysOrderById(orderId);
if (order == null)
{
throw new ServiceException("订单不存在");
}
if (!ORDER_STATUS_EXCHANGE_REJECTED.equals(order.getOrderStatus()))
{
throw new ServiceException("仅拒绝换货申请状态的订单可完成");
}
JySysOrder update = new JySysOrder();
update.setId(orderId);
update.setBrandTenantId(order.getBrandTenantId());
update.setLensId(order.getLensId());
update.setProductId(order.getProductId());
update.setAttachment(order.getAttachment());
update.setLensFactoryTenantId(order.getLensFactoryTenantId());
update.setLogisticsFee(order.getLogisticsFee());
update.setOrderStatus(ORDER_STATUS_COMPLETED);
update.setUpdateBy(operator);
update.setUpdateTime(DateUtils.getNowDate());
int rows = jySysOrderMapper.updateJySysOrder(update);
saveStatusLog(orderId, ORDER_STATUS_COMPLETED, operator, null, null, null);
return rows;
}
private JySysOrder requireAdminExchangeAppliableOrder(Long orderId) private JySysOrder requireAdminExchangeAppliableOrder(Long orderId)
{ {
if (orderId == null) if (orderId == null)
@@ -1126,6 +1067,45 @@ public class JySysOrderServiceImpl extends ServiceImpl<JySysOrderMapper, JySysOr
} }
} }
private String resolveShipStatus(JySysOrder order)
{
if (order != null && isExchangeOrder(order.getId()))
{
return ORDER_STATUS_EXCHANGE_LOGISTICS;
}
return ORDER_STATUS_SHIPPED;
}
private String resolveCompleteStatus(JySysOrder order)
{
if (order != null && ORDER_STATUS_EXCHANGE_LOGISTICS.equals(order.getOrderStatus()))
{
return ORDER_STATUS_EXCHANGE_COMPLETED;
}
return ORDER_STATUS_COMPLETED;
}
private boolean isExchangeOrder(Long orderId)
{
if (orderId == null)
{
return false;
}
List<JySysOrderStatusLog> logs = jySysOrderStatusLogMapper.selectJySysOrderStatusLogByOrderId(orderId);
if (logs == null || logs.isEmpty())
{
return false;
}
for (JySysOrderStatusLog log : logs)
{
if (log != null && ORDER_STATUS_EXCHANGE_APPLY.equals(log.getOrderStatus()))
{
return true;
}
}
return false;
}
private void saveOptometryList(JySysOrder jySysOrder) private void saveOptometryList(JySysOrder jySysOrder)
{ {
if (jySysOrder.getId() == null) if (jySysOrder.getId() == null)
@@ -1200,12 +1180,6 @@ public class JySysOrderServiceImpl extends ServiceImpl<JySysOrderMapper, JySysOr
statusLog.setExpressCompany(expressCompany); statusLog.setExpressCompany(expressCompany);
statusLog.setExpressNo(expressNo); statusLog.setExpressNo(expressNo);
statusLog.setLogisticsFee(logisticsFee); statusLog.setLogisticsFee(logisticsFee);
if (ORDER_STATUS_SHIPPED.equals(orderStatus)
&& StringUtils.isNotEmpty(expressNo))
{
statusLog.setSaleSettleStatus("0");
statusLog.setPurchaseSettleStatus("0");
}
statusLog.setRemark(remark); statusLog.setRemark(remark);
statusLog.setOperator(operator); statusLog.setOperator(operator);
statusLog.setOperateTime(DateUtils.getNowDate()); statusLog.setOperateTime(DateUtils.getNowDate());
@@ -1219,4 +1193,94 @@ public class JySysOrderServiceImpl extends ServiceImpl<JySysOrderMapper, JySysOr
int randomPart = ThreadLocalRandom.current().nextInt(1000, 10000); int randomPart = ThreadLocalRandom.current().nextInt(1000, 10000);
return "JY" + timePart + randomPart; return "JY" + timePart + randomPart;
} }
private JySysOrder copyOrderForExchangeApply(JySysOrder source, String reason, String operator)
{
Date now = DateUtils.getNowDate();
JySysOrder newOrder = new JySysOrder();
newOrder.setOrderNo(buildExchangeOrderNo(source.getOrderNo()));
newOrder.setBrandTenantId(source.getBrandTenantId());
newOrder.setLensFactoryTenantId(source.getLensFactoryTenantId());
newOrder.setProductId(source.getProductId());
newOrder.setLensId(source.getLensId());
newOrder.setPriceB(source.getPriceB());
newOrder.setPriceC(source.getPriceC());
newOrder.setLogisticsFee(BigDecimal.ZERO);
newOrder.setProgressiveMultifocal(source.getProgressiveMultifocal());
newOrder.setProgressiveMultifocalPrice(source.getProgressiveMultifocalPrice());
newOrder.setOrderStatus(ORDER_STATUS_EXCHANGE_APPLY);
newOrder.setPurchaseSettleStatus("0");
newOrder.setSaleSettleStatus("0");
newOrder.setReceiverName(source.getReceiverName());
newOrder.setReceiverPhone(source.getReceiverPhone());
newOrder.setReceiverAddress(source.getReceiverAddress());
newOrder.setAttachment(source.getAttachment());
newOrder.setRemark(source.getRemark());
newOrder.setDelFlag(0);
newOrder.setCreateBy(operator);
newOrder.setUpdateBy(operator);
newOrder.setCreateTime(now);
newOrder.setUpdateTime(now);
newOrder.setOptometryList(copyOptometryList(source.getOptometryList()));
fillDefaultValue(newOrder);
jySysOrderMapper.insertJySysOrder(newOrder);
saveOptometryList(newOrder);
saveStatusLog(newOrder.getId(), ORDER_STATUS_EXCHANGE_APPLY, operator, null, null, reason);
return selectJySysOrderById(newOrder.getId());
}
private List<JySysOrderOptometry> copyOptometryList(List<JySysOrderOptometry> sourceList)
{
List<JySysOrderOptometry> copiedList = new ArrayList<>();
if (sourceList == null || sourceList.isEmpty())
{
return copiedList;
}
for (JySysOrderOptometry source : sourceList)
{
if (source == null || StringUtils.isEmpty(source.getEyeSide()))
{
continue;
}
JySysOrderOptometry copy = new JySysOrderOptometry();
copy.setEyeSide(source.getEyeSide());
copy.setSphereS(source.getSphereS());
copy.setCylinderC(source.getCylinderC());
copy.setAxisA(source.getAxisA());
copy.setPd(source.getPd());
copy.setDualPd(source.getDualPd());
copy.setPdType(source.getPdType());
copy.setPupilHeight(source.getPupilHeight());
copy.setDistanceVa(source.getDistanceVa());
copy.setNearAdd(source.getNearAdd());
copiedList.add(copy);
}
return copiedList;
}
private String buildExchangeOrderNo(String sourceOrderNo)
{
String numericPart = StringUtils.isEmpty(sourceOrderNo)
? new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())
+ ThreadLocalRandom.current().nextInt(1000, 10000)
: sourceOrderNo.replaceAll("\\D", "");
if (StringUtils.isEmpty(numericPart))
{
numericPart = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())
+ ThreadLocalRandom.current().nextInt(1000, 10000);
}
String orderNo = "HH" + numericPart;
int retry = 0;
while (jySysOrderMapper.countByOrderNo(orderNo) > 0 && retry < 10)
{
orderNo = "HH" + numericPart + ThreadLocalRandom.current().nextInt(1000, 10000);
retry++;
}
if (jySysOrderMapper.countByOrderNo(orderNo) > 0)
{
throw new ServiceException("生成换货订单号失败,请稍后重试");
}
return orderNo;
}
} }

View File

@@ -2,6 +2,8 @@ package com.ruoyi.jysystem.service.impl;
import java.util.List; import java.util.List;
import javax.annotation.Resource; import javax.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.DateUtils;
@@ -23,12 +25,16 @@ import com.ruoyi.jysystem.utils.TenantTypeHelper;
@Service @Service
public class JySysTenantMessageServiceImpl implements IJySysTenantMessageService public class JySysTenantMessageServiceImpl implements IJySysTenantMessageService
{ {
private static final Logger log = LoggerFactory.getLogger(JySysTenantMessageServiceImpl.class);
private static final String ORDER_STATUS_DRAFT = "1"; private static final String ORDER_STATUS_DRAFT = "1";
private static final String ORDER_STATUS_ASSIGNED = "3"; private static final String ORDER_STATUS_ASSIGNED = "3";
private static final String ORDER_STATUS_SHIPPED = "8"; private static final String ORDER_STATUS_SHIPPED = "8";
private static final String ORDER_STATUS_EXCHANGE_LOGISTICS = "15";
@Resource @Resource
private JySysTenantMessageMapper jySysTenantMessageMapper; private JySysTenantMessageMapper jySysTenantMessageMapper;
@@ -102,18 +108,30 @@ public class JySysTenantMessageServiceImpl implements IJySysTenantMessageService
} }
insertMessage(order.getBrandTenantId(), order.getId(), orderNo, insertMessage(order.getBrandTenantId(), order.getId(), orderNo,
JySysTenantMessage.TYPE_STATUS_CHANGE, "订单状态变更", content, orderStatus); JySysTenantMessage.TYPE_STATUS_CHANGE, "订单状态变更", content, orderStatus);
if (ORDER_STATUS_SHIPPED.equals(orderStatus)) if (ORDER_STATUS_SHIPPED.equals(orderStatus)
|| ORDER_STATUS_EXCHANGE_LOGISTICS.equals(orderStatus))
{ {
// 模板「您的配片单…」通知配片单所属品牌方;无租户手机号时回退收货人手机号 log.info("[发货短信] 触发检查: orderId={}, orderNo={}, orderStatus={}, expressCompany={}, brandTenantId={}, brandPhone={}, receiverPhone={}",
String smsPhone = StringUtils.isNotEmpty(brandTenant.getPhone()) orderId, orderNo, orderStatus, expressCompany, brandTenant.getId(), brandTenant.getPhone(), order.getReceiverPhone());
? brandTenant.getPhone() String smsPhone = resolveShipNotifyPhone(brandTenant.getPhone(), order.getReceiverPhone());
: order.getReceiverPhone();
if (StringUtils.isNotEmpty(smsPhone)) if (StringUtils.isNotEmpty(smsPhone))
{ {
smsNotificationService.trySendOrderShippedNotify(smsPhone, orderNo, expressCompany, expressNo); log.info("[发货短信] 准备发送: orderNo={}, smsPhone={}, expressCompany={}", orderNo, smsPhone, expressCompany);
smsNotificationService.trySendOrderShippedNotify(
smsPhone, orderNo, expressCompany);
}
else
{
log.warn("[发货短信] 跳过: 无有效手机号, orderNo={}, brandPhone={}, receiverPhone={}",
orderNo, brandTenant.getPhone(), order.getReceiverPhone());
} }
} }
} }
else
{
log.warn("[发货短信] 跳过: 品牌方租户无效, orderId={}, brandTenantId={}, tenantType={}",
orderId, order.getBrandTenantId(), brandTenant != null ? brandTenant.getTenantType() : null);
}
} }
if (order.getLensFactoryTenantId() != null) if (order.getLensFactoryTenantId() != null)
@@ -171,4 +189,41 @@ public class JySysTenantMessageServiceImpl implements IJySysTenantMessageService
} }
return tenant; return tenant;
} }
private String resolveShipNotifyPhone(String brandPhone, String receiverPhone)
{
if (isValidMobile(brandPhone))
{
return normalizeMobile(brandPhone);
}
if (isValidMobile(receiverPhone))
{
return normalizeMobile(receiverPhone);
}
return null;
}
private boolean isValidMobile(String phone)
{
return normalizeMobile(phone) != null;
}
private String normalizeMobile(String phone)
{
if (StringUtils.isEmpty(phone))
{
return null;
}
String digits = phone.replaceAll("\\D", "");
if (digits.length() >= 11)
{
String mobile = digits.substring(digits.length() - 11);
if (mobile.matches("^1[3-9]\\d{9}$"))
{
return mobile;
}
}
String trimmed = phone.trim();
return trimmed.matches("^1[3-9]\\d{9}$") ? trimmed : null;
}
} }

View File

@@ -35,56 +35,67 @@ public class SmsNotificationServiceImpl implements SmsNotificationService
} }
@Override @Override
public void trySendOrderShippedNotify(String phone, String orderNo, String expressCompany, String expressNo) public void trySendOrderShippedNotify(String phone, String orderNo, String expressCompany)
{ {
Map<String, String> params = new HashMap<>(3); Map<String, String> params = new HashMap<>(2);
params.put("code", nullToEmpty(orderNo)); params.put("code", nullToEmpty(orderNo));
params.put("expressCompany", nullToEmpty(expressCompany)); params.put("expressCompany", nullToEmpty(expressCompany));
params.put("expressNo", nullToEmpty(expressNo));
trySendScene("配片订单发货", smsProperties.getShipOrder(), phone, params); trySendScene("配片订单发货", smsProperties.getShipOrder(), phone, params);
} }
private void trySendScene(String sceneLabel, SmsProperties.SceneConfig scene, String phone, Map<String, String> templateParams) private void trySendScene(String sceneLabel, SmsProperties.SceneConfig scene, String phone, Map<String, String> templateParams)
{ {
if (scene == null || !scene.isEnabled()) if (scene == null)
{ {
log.warn("[发货短信] 跳过: {}场景配置为空", sceneLabel);
return;
}
if (!scene.isEnabled())
{
log.warn("[发货短信] 跳过: {}短信未启用, enabled=false", sceneLabel);
return; return;
} }
if (StringUtils.isEmpty(phone)) if (StringUtils.isEmpty(phone))
{ {
log.warn("[发货短信] 跳过: {}手机号为空", sceneLabel);
return; return;
} }
String templateCode = StringUtils.isNotEmpty(scene.getTemplate()) ? scene.getTemplate().trim() : null; String templateCode = StringUtils.isNotEmpty(scene.getTemplate()) ? scene.getTemplate().trim() : null;
if (StringUtils.isEmpty(templateCode)) if (StringUtils.isEmpty(templateCode))
{ {
log.warn("未配置{}短信模板请在 application.yml 的 sms.{} 中填写 template", log.warn("[发货短信] 跳过: 未配置{}短信模板, 请在 application.yml 的 sms.{} 中填写 template",
sceneLabel, sceneLabel.contains("分配") ? "assign-order" : "ship-order"); sceneLabel, sceneLabel.contains("分配") ? "assign-order" : "ship-order");
return; return;
} }
String mobile = phone.trim(); String mobile = normalizeMobile(phone);
if (!MOBILE_PATTERN.matcher(mobile).matches()) if (mobile == null)
{ {
log.warn("{}短信手机号格式无效,跳过通知: {}", sceneLabel, phone); log.warn("[发货短信] 跳过: {}手机号格式无效, rawPhone={}", sceneLabel, phone);
return; return;
} }
String signName = smsProperties.getSignName();
String templateParam = JSON.toJSONString(templateParams);
log.info("[发货短信] 调用阿里云: scene={}, phone={}, signName={}, template={}, params={}",
sceneLabel, mobile, signName, templateCode, templateParam);
try try
{ {
String templateParam = JSON.toJSONString(templateParams); Map<String, Object> result = SmsUtils.sendNotifyMsg(mobile, signName, templateCode, templateParam);
Map<String, Object> result = SmsUtils.sendNotifyMsg(mobile, smsProperties.getSignName(),
templateCode, templateParam);
Integer statusCode = (Integer) result.get("statusCode"); Integer statusCode = (Integer) result.get("statusCode");
String bodyCode = (String) result.get("bodyCode"); String bodyCode = (String) result.get("bodyCode");
String bodyMessage = (String) result.get("bodyMessage");
String bizId = (String) result.get("bizId");
String requestId = (String) result.get("requestId");
if (statusCode == null || statusCode != 200 || !"OK".equalsIgnoreCase(bodyCode)) if (statusCode == null || statusCode != 200 || !"OK".equalsIgnoreCase(bodyCode))
{ {
log.warn("{}短信发送失败: phone={}, template={}, params={}, statusCode={}, bodyCode={}", log.warn("[发货短信] 发送失败: scene={}, phone={}, template={}, params={}, statusCode={}, bodyCode={}, bodyMessage={}, bizId={}, requestId={}",
sceneLabel, mobile, templateCode, templateParam, statusCode, bodyCode); sceneLabel, mobile, templateCode, templateParam, statusCode, bodyCode, bodyMessage, bizId, requestId);
return; return;
} }
log.info("{}短信已发送: {}", sceneLabel, mobile); log.info("[发货短信] 发送成功: scene={}, phone={}, bizId={}, requestId={}", sceneLabel, mobile, bizId, requestId);
} }
catch (Exception e) catch (Exception e)
{ {
log.warn("{}短信发送异常: phone={}, err={}", sceneLabel, mobile, e.getMessage()); log.warn("[发货短信] 发送异常: scene={}, phone={}, err={}", sceneLabel, mobile, e.getMessage(), e);
} }
} }
@@ -92,4 +103,22 @@ public class SmsNotificationServiceImpl implements SmsNotificationService
{ {
return value != null ? value : ""; return value != null ? value : "";
} }
private String normalizeMobile(String phone)
{
if (StringUtils.isEmpty(phone))
{
return null;
}
String digits = phone.replaceAll("\\D", "");
if (digits.length() >= 11)
{
String mobile = digits.substring(digits.length() - 11);
if (MOBILE_PATTERN.matcher(mobile).matches())
{
return mobile;
}
}
return MOBILE_PATTERN.matcher(phone.trim()).matches() ? phone.trim() : null;
}
} }

View File

@@ -185,6 +185,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
and (brand_tenant_id = #{tenantId} or lens_factory_tenant_id = #{tenantId}) and (brand_tenant_id = #{tenantId} or lens_factory_tenant_id = #{tenantId})
</select> </select>
<select id="countByOrderNo" resultType="int">
select count(1)
from jy_sys_order
where del_flag = '0'
and order_no = #{orderNo}
</select>
<select id="selectCompletedOrdersByYearMonth" resultMap="JySysOrderResult"> <select id="selectCompletedOrdersByYearMonth" resultMap="JySysOrderResult">
select o.id, o.order_no, o.brand_tenant_id, bt.name as brand_tenant_name, select o.id, o.order_no, o.brand_tenant_id, bt.name as brand_tenant_name,
o.lens_factory_tenant_id, lf.name as lens_factory_tenant_name, o.lens_factory_tenant_id, lf.name as lens_factory_tenant_name,
@@ -197,11 +204,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
left join jy_sys_tenant bt on o.brand_tenant_id = bt.id left join jy_sys_tenant bt on o.brand_tenant_id = bt.id
left join jy_sys_tenant lf on o.lens_factory_tenant_id = lf.id left join jy_sys_tenant lf on o.lens_factory_tenant_id = lf.id
where o.del_flag = '0' where o.del_flag = '0'
and o.order_status = '9' and o.order_status in ('9', '17')
and exists ( and exists (
select 1 from jy_sys_order_status_log sl select 1 from jy_sys_order_status_log sl
where sl.order_id = o.id where sl.order_id = o.id
and sl.order_status = '9' and sl.order_status in ('9', '17')
and DATE_FORMAT(sl.operate_time, '%Y-%m') = #{settleYearMonth} and DATE_FORMAT(sl.operate_time, '%Y-%m') = #{settleYearMonth}
) )
order by o.id asc order by o.id asc

View File

@@ -11,8 +11,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="expressCompany" column="express_company" /> <result property="expressCompany" column="express_company" />
<result property="expressNo" column="express_no" /> <result property="expressNo" column="express_no" />
<result property="logisticsFee" column="logistics_fee" /> <result property="logisticsFee" column="logistics_fee" />
<result property="saleSettleStatus" column="sale_settle_status" />
<result property="purchaseSettleStatus" column="purchase_settle_status" />
<result property="remark" column="remark" /> <result property="remark" column="remark" />
<result property="operator" column="operator" /> <result property="operator" column="operator" />
<result property="operateTime" column="operate_time" /> <result property="operateTime" column="operate_time" />
@@ -20,7 +18,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<select id="selectJySysOrderStatusLogByOrderId" parameterType="Long" resultMap="JySysOrderStatusLogResult"> <select id="selectJySysOrderStatusLogByOrderId" parameterType="Long" resultMap="JySysOrderStatusLogResult">
select id, order_id, order_status, express_company, express_no, logistics_fee, select id, order_id, order_status, express_company, express_no, logistics_fee,
sale_settle_status, purchase_settle_status, remark, operator, operate_time remark, operator, operate_time
from jy_sys_order_status_log from jy_sys_order_status_log
where order_id = #{orderId} where order_id = #{orderId}
order by operate_time desc, id desc order by operate_time desc, id desc
@@ -43,8 +41,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="expressCompany != null">express_company,</if> <if test="expressCompany != null">express_company,</if>
<if test="expressNo != null">express_no,</if> <if test="expressNo != null">express_no,</if>
<if test="logisticsFee != null">logistics_fee,</if> <if test="logisticsFee != null">logistics_fee,</if>
<if test="saleSettleStatus != null">sale_settle_status,</if>
<if test="purchaseSettleStatus != null">purchase_settle_status,</if>
<if test="remark != null">remark,</if> <if test="remark != null">remark,</if>
<if test="operator != null">operator,</if> <if test="operator != null">operator,</if>
<if test="operateTime != null">operate_time,</if> <if test="operateTime != null">operate_time,</if>
@@ -55,8 +51,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="expressCompany != null">#{expressCompany},</if> <if test="expressCompany != null">#{expressCompany},</if>
<if test="expressNo != null">#{expressNo},</if> <if test="expressNo != null">#{expressNo},</if>
<if test="logisticsFee != null">#{logisticsFee},</if> <if test="logisticsFee != null">#{logisticsFee},</if>
<if test="saleSettleStatus != null">#{saleSettleStatus},</if>
<if test="purchaseSettleStatus != null">#{purchaseSettleStatus},</if>
<if test="remark != null">#{remark},</if> <if test="remark != null">#{remark},</if>
<if test="operator != null">#{operator},</if> <if test="operator != null">#{operator},</if>
<if test="operateTime != null">#{operateTime},</if> <if test="operateTime != null">#{operateTime},</if>
@@ -64,52 +58,21 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</insert> </insert>
<select id="selectUnsettledShipLogsByOrderIdAndType" resultMap="JySysOrderStatusLogResult"> <select id="selectUnsettledShipLogsByOrderIdAndType" resultMap="JySysOrderStatusLogResult">
select id, order_id, order_status, express_company, express_no, logistics_fee, select l.id, l.order_id, l.order_status, l.express_company, l.express_no, l.logistics_fee,
sale_settle_status, purchase_settle_status, remark, operator, operate_time l.remark, l.operator, l.operate_time
from jy_sys_order_status_log from jy_sys_order_status_log l
where order_id = #{orderId} where l.order_id = #{orderId}
and order_status = '8' and l.order_status in ('8', '15')
and express_no is not null and l.express_no is not null
and TRIM(express_no) != '' and TRIM(l.express_no) != ''
<choose> and l.id not in (
<when test="settlementType == 'AR'"> select fl.status_log_id
and (sale_settle_status is null or sale_settle_status = '0') from jy_sys_fee_settlement_logistics fl
</when> inner join jy_sys_fee_settlement_item fi on fl.settlement_item_id = fi.id
<when test="settlementType == 'AP'"> inner join jy_sys_fee_settlement fs on fi.settlement_id = fs.id
and (purchase_settle_status is null or purchase_settle_status = '0') where fl.status_log_id is not null
</when> and fs.settlement_type = #{settlementType}
</choose> )
order by operate_time asc, id asc order by l.operate_time asc, l.id asc
</select> </select>
<update id="updateSaleSettleStatusByIds">
update jy_sys_order_status_log
set sale_settle_status = #{settleStatus}
where id in
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</update>
<update id="updatePurchaseSettleStatusByIds">
update jy_sys_order_status_log
set purchase_settle_status = #{settleStatus}
where id in
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</update>
<update id="resetShipLogSettleStatusByOrderIds">
update jy_sys_order_status_log
set sale_settle_status = '0',
purchase_settle_status = '0'
where order_id in
<foreach collection="orderIds" item="orderId" open="(" separator="," close=")">
#{orderId}
</foreach>
and order_status = '8'
and express_no is not null
and TRIM(express_no) != ''
</update>
</mapper> </mapper>

View File

@@ -51,7 +51,7 @@ INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value
SELECT 166, 14, '退货物流', '14', 'jy_order_status', NULL, 'primary', 'N', '0', 'admin', NOW(), NULL SELECT 166, 14, '退货物流', '14', 'jy_order_status', NULL, 'primary', 'N', '0', 'admin', NOW(), NULL
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_dict_data` WHERE `dict_type` = 'jy_order_status' AND `dict_value` = '14'); FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_dict_data` WHERE `dict_type` = 'jy_order_status' AND `dict_value` = '14');
INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `remark`) INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `remark`)
SELECT 167, 15, '换货已发货', '15', 'jy_order_status', NULL, 'primary', 'N', '0', 'admin', NOW(), NULL SELECT 167, 15, '换货物流', '15', 'jy_order_status', NULL, 'primary', 'N', '0', 'admin', NOW(), NULL
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_dict_data` WHERE `dict_type` = 'jy_order_status' AND `dict_value` = '15'); FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_dict_data` WHERE `dict_type` = 'jy_order_status' AND `dict_value` = '15');
INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `remark`) INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `remark`)
SELECT 168, 16, '退货完成', '16', 'jy_order_status', NULL, 'success', 'N', '0', 'admin', NOW(), NULL SELECT 168, 16, '退货完成', '16', 'jy_order_status', NULL, 'success', 'N', '0', 'admin', NOW(), NULL

View File

@@ -0,0 +1,16 @@
-- 订单状态字典:恢复/确保换货物流、换货完成标签
UPDATE `sys_dict_data`
SET `dict_label` = '换货物流'
WHERE `dict_type` = 'jy_order_status' AND `dict_value` = '15';
UPDATE `sys_dict_data`
SET `dict_label` = '换货完成'
WHERE `dict_type` = 'jy_order_status' AND `dict_value` = '17';
INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `remark`)
SELECT 167, 15, '换货物流', '15', 'jy_order_status', NULL, 'primary', 'N', '0', 'admin', NOW(), NULL
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_dict_data` WHERE `dict_type` = 'jy_order_status' AND `dict_value` = '15');
INSERT INTO `sys_dict_data` (`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `remark`)
SELECT 169, 17, '换货完成', '17', 'jy_order_status', NULL, 'success', 'N', '0', 'admin', NOW(), NULL
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_dict_data` WHERE `dict_type` = 'jy_order_status' AND `dict_value` = '17');

View File

@@ -0,0 +1,4 @@
-- 订单状态日志:移除物流应收/应付结算状态字段(改由费用结算单物流明细关联发货日志)
ALTER TABLE `jy_sys_order_status_log`
DROP COLUMN `sale_settle_status`,
DROP COLUMN `purchase_settle_status`;

View File

@@ -3,16 +3,16 @@ package com.ruoyi.common.utils;
import com.aliyun.dysmsapi20170525.Client; import com.aliyun.dysmsapi20170525.Client;
import com.aliyun.dysmsapi20170525.models.SendSmsRequest; import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.dysmsapi20170525.models.SendSmsResponse; import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import com.aliyun.tea.*;
import com.aliyun.teaopenapi.models.Config; import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.models.RuntimeOptions; import com.aliyun.teautil.models.RuntimeOptions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import static com.aliyun.teautil.Common.assertAsString;
public class SmsUtils { public class SmsUtils {
private static final Logger log = LoggerFactory.getLogger(SmsUtils.class);
public static Client createClient() throws Exception { public static Client createClient() throws Exception {
Config config = new Config() Config config = new Config()
// 配置 AccessKey ID请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID。 // 配置 AccessKey ID请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID。
@@ -43,6 +43,8 @@ public class SmsUtils {
*/ */
public static Map<String, Object> sendNotifyMsg(String phone, String signName, String templateCode, String templateParam) throws Exception { public static Map<String, Object> sendNotifyMsg(String phone, String signName, String templateCode, String templateParam) throws Exception {
HashMap<String, Object> sendSmsResponseMap = new HashMap<>(); HashMap<String, Object> sendSmsResponseMap = new HashMap<>();
log.info("[发货短信] SmsUtils 请求: phone={}, signName={}, templateCode={}, templateParam={}",
phone, signName, templateCode, templateParam);
try { try {
Client client = SmsUtils.createClient(); Client client = SmsUtils.createClient();
SendSmsRequest sendSmsRequest = new SendSmsRequest() SendSmsRequest sendSmsRequest = new SendSmsRequest()
@@ -54,19 +56,26 @@ public class SmsUtils {
SendSmsResponse sendSmsResponse = client.sendSmsWithOptions(sendSmsRequest, new RuntimeOptions()); SendSmsResponse sendSmsResponse = client.sendSmsWithOptions(sendSmsRequest, new RuntimeOptions());
Integer statusCode = sendSmsResponse.getStatusCode(); Integer statusCode = sendSmsResponse.getStatusCode();
String responseCode = sendSmsResponse.getBody().getCode(); String responseCode = sendSmsResponse.getBody() != null ? sendSmsResponse.getBody().getCode() : null;
String responseMessage = sendSmsResponse.getBody() != null ? sendSmsResponse.getBody().getMessage() : null;
String bizId = sendSmsResponse.getBody() != null ? sendSmsResponse.getBody().getBizId() : null;
String requestId = sendSmsResponse.getBody() != null ? sendSmsResponse.getBody().getRequestId() : null;
sendSmsResponseMap.put("statusCode", statusCode); sendSmsResponseMap.put("statusCode", statusCode);
sendSmsResponseMap.put("bodyCode", responseCode); sendSmsResponseMap.put("bodyCode", responseCode);
} catch (TeaException error) { sendSmsResponseMap.put("bodyMessage", responseMessage);
System.out.println(error.getMessage()); sendSmsResponseMap.put("bizId", bizId);
System.out.println(error.getData().get("Recommend")); sendSmsResponseMap.put("requestId", requestId);
assertAsString(error.message); log.info("[发货短信] SmsUtils 响应: phone={}, statusCode={}, bodyCode={}, bodyMessage={}, bizId={}, requestId={}",
phone, statusCode, responseCode, responseMessage, bizId, requestId);
} catch (com.aliyun.tea.TeaException error) {
log.warn("[发货短信] SmsUtils TeaException: phone={}, code={}, message={}",
phone, error.getCode(), error.getMessage());
sendSmsResponseMap.put("bodyCode", error.getCode());
sendSmsResponseMap.put("bodyMessage", error.getMessage());
} catch (Exception _error) { } catch (Exception _error) {
TeaException error = new TeaException(_error.getMessage(), _error); log.warn("[发货短信] SmsUtils 异常: phone={}, err={}", phone, _error.getMessage(), _error);
System.out.println(error.getMessage()); sendSmsResponseMap.put("bodyMessage", _error.getMessage());
System.out.println("诊断地址" + error.getData().get("Recommend"));
assertAsString(error.message);
} }
return sendSmsResponseMap; return sendSmsResponseMap;
} }