完善字符串类型的体验
This commit is contained in:
@@ -7,5 +7,5 @@ ktor:
|
|||||||
|
|
||||||
traceability:
|
traceability:
|
||||||
# 访问主服务的地址
|
# 访问主服务的地址
|
||||||
core-base-url: "http://127.0.0.1:8089" # 开发
|
# core-base-url: "http://127.0.0.1:8089" # 开发
|
||||||
# core-base-url: "https://ai.ronsunny.cn:8090/api" # 生产
|
core-base-url: "https://ai.ronsunny.cn:8090/api" # 生产
|
||||||
|
|||||||
@@ -85,6 +85,11 @@ a {
|
|||||||
line-height: 1.75;
|
line-height: 1.75;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.timeline-item__body strong {
|
||||||
|
white-space: pre-wrap;
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
.hero p {
|
.hero p {
|
||||||
margin: 12px 0 0;
|
margin: 12px 0 0;
|
||||||
}
|
}
|
||||||
@@ -135,6 +140,7 @@ a {
|
|||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
line-height: 1.6;
|
line-height: 1.6;
|
||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
|
white-space: pre-wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hero__aside {
|
.hero__aside {
|
||||||
|
|||||||
@@ -288,6 +288,19 @@ fun Application.Traceability(config: AppConfig) {
|
|||||||
}
|
}
|
||||||
call.respond(BaseResponse(message = "批次已发布", data = data))
|
call.respond(BaseResponse(message = "批次已发布", data = data))
|
||||||
}
|
}
|
||||||
|
post("/{id}/scan-count/reset") {
|
||||||
|
val id = parseUuidOrNull(call.parameters["id"])
|
||||||
|
if (id == null) {
|
||||||
|
call.respond(HttpStatusCode.BadRequest, BaseResponse(status = false, message = "批次ID无效", data = null))
|
||||||
|
return@post
|
||||||
|
}
|
||||||
|
val data = TraceabilityDao.resetBatchScanCount(id)
|
||||||
|
if (data == null) {
|
||||||
|
call.respond(HttpStatusCode.NotFound, BaseResponse(status = false, message = "批次不存在", data = null))
|
||||||
|
return@post
|
||||||
|
}
|
||||||
|
call.respond(BaseResponse(message = "扫码次数已重置", data = data))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
route("/feedback") {
|
route("/feedback") {
|
||||||
|
|||||||
@@ -764,6 +764,16 @@ object TraceabilityDao {
|
|||||||
getBatch(batchId)
|
getBatch(batchId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun resetBatchScanCount(batchId: UUID): TraceBatchDetailResponse? = transaction {
|
||||||
|
val now = timestampLiteral(nowInstant())
|
||||||
|
val updated = TraceabilityBatchesTable.update({ TraceabilityBatchesTable.id eq batchId }) {
|
||||||
|
it[scanCount] = 0
|
||||||
|
it[updatedAt] = now
|
||||||
|
}
|
||||||
|
if (updated == 0) return@transaction null
|
||||||
|
getBatch(batchId)
|
||||||
|
}
|
||||||
|
|
||||||
fun getPublicDetailByCode(
|
fun getPublicDetailByCode(
|
||||||
batchCode: String,
|
batchCode: String,
|
||||||
increaseScan: Boolean = false,
|
increaseScan: Boolean = false,
|
||||||
|
|||||||
@@ -341,6 +341,10 @@ export function publishTraceabilityBatch(id: string) {
|
|||||||
return requestClient.post(`/traceability/batches/${id}/publish`);
|
return requestClient.post(`/traceability/batches/${id}/publish`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function resetTraceabilityBatchScanCount(id: string) {
|
||||||
|
return requestClient.post(`/traceability/batches/${id}/scan-count/reset`);
|
||||||
|
}
|
||||||
|
|
||||||
export function getTraceabilityPublicDetail(code: string) {
|
export function getTraceabilityPublicDetail(code: string) {
|
||||||
return requestClient.get<TraceabilityApi.PublicDetail>(
|
return requestClient.get<TraceabilityApi.PublicDetail>(
|
||||||
`/traceability/public/by-code/${code}`,
|
`/traceability/public/by-code/${code}`,
|
||||||
|
|||||||
@@ -275,7 +275,10 @@ onMounted(loadBatches);
|
|||||||
>打开地图</a
|
>打开地图</a
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<strong v-else :style="getFieldDisplayStyle(entry.field)">
|
<strong
|
||||||
|
v-else
|
||||||
|
:style="getFieldDisplayStyle(entry.field)"
|
||||||
|
>
|
||||||
{{ formatFieldValue(entry.value) }}
|
{{ formatFieldValue(entry.value) }}
|
||||||
</strong>
|
</strong>
|
||||||
</div>
|
</div>
|
||||||
@@ -349,10 +352,7 @@ onMounted(loadBatches);
|
|||||||
>打开地图</a
|
>打开地图</a
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<strong
|
<strong v-else :style="getFieldDisplayStyle(entry.field)">
|
||||||
v-else
|
|
||||||
:style="getFieldDisplayStyle(entry.field)"
|
|
||||||
>
|
|
||||||
{{ formatFieldValue(entry.value) }}
|
{{ formatFieldValue(entry.value) }}
|
||||||
</strong>
|
</strong>
|
||||||
</div>
|
</div>
|
||||||
@@ -549,6 +549,7 @@ onMounted(loadBatches);
|
|||||||
.access-card strong {
|
.access-card strong {
|
||||||
line-height: 1.6;
|
line-height: 1.6;
|
||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
|
white-space: pre-wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.section-stack {
|
.section-stack {
|
||||||
@@ -578,6 +579,11 @@ onMounted(loadBatches);
|
|||||||
color: #6b7280;
|
color: #6b7280;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.timeline-card strong {
|
||||||
|
white-space: pre-wrap;
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
.kv-grid {
|
.kv-grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import {
|
|||||||
getTraceabilityBatches,
|
getTraceabilityBatches,
|
||||||
getTraceabilityTemplates,
|
getTraceabilityTemplates,
|
||||||
publishTraceabilityBatch,
|
publishTraceabilityBatch,
|
||||||
|
resetTraceabilityBatchScanCount,
|
||||||
updateTraceabilityBatchStep,
|
updateTraceabilityBatchStep,
|
||||||
uploadTraceabilityImage,
|
uploadTraceabilityImage,
|
||||||
} from '#/api';
|
} from '#/api';
|
||||||
@@ -435,6 +436,29 @@ async function saveStep() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function resetBatchScanCount() {
|
||||||
|
if (!batchDetail.value?.id) return;
|
||||||
|
Modal.confirm({
|
||||||
|
title: '重置扫码次数',
|
||||||
|
content: `确认将批次“${batchDetail.value.batchName || batchDetail.value.batchCode}”的扫码次数重置为 0 吗?`,
|
||||||
|
okText: '重置',
|
||||||
|
cancelText: '取消',
|
||||||
|
async onOk() {
|
||||||
|
saving.value = true;
|
||||||
|
try {
|
||||||
|
const detail = await resetTraceabilityBatchScanCount(batchDetail.value!.id);
|
||||||
|
if (detail) {
|
||||||
|
applyBatch(detail);
|
||||||
|
message.success('扫码次数已重置');
|
||||||
|
await loadLists();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
saving.value = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await loadLists();
|
await loadLists();
|
||||||
});
|
});
|
||||||
@@ -509,14 +533,23 @@ onMounted(async () => {
|
|||||||
title="发布信息"
|
title="发布信息"
|
||||||
>
|
>
|
||||||
<template #extra>
|
<template #extra>
|
||||||
<Button
|
<Space>
|
||||||
v-if="batchDetail.publicUrl"
|
<Button
|
||||||
size="small"
|
v-if="batchDetail.publicUrl"
|
||||||
type="primary"
|
size="small"
|
||||||
@click="downloadBatchQrCode"
|
type="primary"
|
||||||
>
|
@click="downloadBatchQrCode"
|
||||||
保存二维码
|
>
|
||||||
</Button>
|
保存二维码
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
v-if="batchDetail.publicUrl"
|
||||||
|
size="small"
|
||||||
|
@click="resetBatchScanCount"
|
||||||
|
>
|
||||||
|
重置扫码次数
|
||||||
|
</Button>
|
||||||
|
</Space>
|
||||||
</template>
|
</template>
|
||||||
<div class="publish-panel">
|
<div class="publish-panel">
|
||||||
<div>
|
<div>
|
||||||
@@ -755,11 +788,12 @@ onMounted(async () => {
|
|||||||
(value) => updateFieldValue(field, value)
|
(value) => updateFieldValue(field, value)
|
||||||
"
|
"
|
||||||
/>
|
/>
|
||||||
<Input
|
<Input.TextArea
|
||||||
v-else-if="field.type === 'string'"
|
v-else-if="field.type === 'string'"
|
||||||
:disabled="isFieldValueLocked(field)"
|
:disabled="isFieldValueLocked(field)"
|
||||||
:placeholder="field.placeholder || '请输入内容'"
|
:placeholder="field.placeholder || '请输入内容'"
|
||||||
:value="currentStep.values[field.key]"
|
:value="currentStep.values[field.key]"
|
||||||
|
:auto-size="{ minRows: 2, maxRows: 6 }"
|
||||||
@update:value="
|
@update:value="
|
||||||
(value) => updateFieldValue(field, value)
|
(value) => updateFieldValue(field, value)
|
||||||
"
|
"
|
||||||
@@ -1261,6 +1295,8 @@ onMounted(async () => {
|
|||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
border-top: 1px dashed #e4e9f2;
|
border-top: 1px dashed #e4e9f2;
|
||||||
padding-top: 10px;
|
padding-top: 10px;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
word-break: break-word;
|
||||||
}
|
}
|
||||||
|
|
||||||
.field-fixed-tip {
|
.field-fixed-tip {
|
||||||
|
|||||||
@@ -638,6 +638,7 @@ onMounted(loadPreviews);
|
|||||||
<Select v-else-if="currentField.type === 'select'" :options="(currentField.options ?? []).map((item) => ({ label: item, value: item }))" :value="getPreviewFieldValue(currentNode, currentField)" style="width: 100%" @update:value="(value) => updateFieldValue(currentNode!, currentField!, value)" />
|
<Select v-else-if="currentField.type === 'select'" :options="(currentField.options ?? []).map((item) => ({ label: item, value: item }))" :value="getPreviewFieldValue(currentNode, currentField)" style="width: 100%" @update:value="(value) => updateFieldValue(currentNode!, currentField!, value)" />
|
||||||
<Select v-else-if="currentField.type === 'multi_select'" mode="multiple" :options="(currentField.options ?? []).map((item) => ({ label: item, value: item }))" :value="getPreviewFieldValue(currentNode, currentField) ?? []" style="width: 100%" @update:value="(value) => updateFieldValue(currentNode!, currentField!, value)" />
|
<Select v-else-if="currentField.type === 'multi_select'" mode="multiple" :options="(currentField.options ?? []).map((item) => ({ label: item, value: item }))" :value="getPreviewFieldValue(currentNode, currentField) ?? []" style="width: 100%" @update:value="(value) => updateFieldValue(currentNode!, currentField!, value)" />
|
||||||
<Input.TextArea v-else-if="currentField.type === 'json'" :value="typeof getPreviewFieldValue(currentNode, currentField) === 'string' ? getPreviewFieldValue(currentNode, currentField) : JSON.stringify(getPreviewFieldValue(currentNode, currentField) ?? {}, null, 2)" :auto-size="{ minRows: 3, maxRows: 6 }" @update:value="(value) => updateFieldValue(currentNode!, currentField!, value)" />
|
<Input.TextArea v-else-if="currentField.type === 'json'" :value="typeof getPreviewFieldValue(currentNode, currentField) === 'string' ? getPreviewFieldValue(currentNode, currentField) : JSON.stringify(getPreviewFieldValue(currentNode, currentField) ?? {}, null, 2)" :auto-size="{ minRows: 3, maxRows: 6 }" @update:value="(value) => updateFieldValue(currentNode!, currentField!, value)" />
|
||||||
|
<Input.TextArea v-else-if="currentField.type === 'string'" :value="getPreviewFieldValue(currentNode, currentField)" :auto-size="{ minRows: 2, maxRows: 6 }" @update:value="(value) => updateFieldValue(currentNode!, currentField!, value)" />
|
||||||
<Input v-else :value="getPreviewFieldValue(currentNode, currentField)" @update:value="(value) => updateFieldValue(currentNode!, currentField!, value)" />
|
<Input v-else :value="getPreviewFieldValue(currentNode, currentField)" @update:value="(value) => updateFieldValue(currentNode!, currentField!, value)" />
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
|
|||||||
Reference in New Issue
Block a user