This commit is contained in:
2026-04-13 21:29:51 +08:00
parent 4b3b9e83cf
commit 503b6ddd4f
7 changed files with 202 additions and 141 deletions
+1 -1
View File
@@ -13,5 +13,5 @@
} }
] ]
}, },
"lastUpdated": 1776083682738 "lastUpdated": 1776086663736
} }
+102 -94
View File
@@ -8,28 +8,33 @@ import (
"time" "time"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/mitchellh/mapstructure"
"gorm.io/gorm" "gorm.io/gorm"
) )
// decodeJSON 将 map 通过 JSON 中转解码到目标结构体,绕过 mapstructure 的字段名匹配问题
func decodeJSON(data map[string]interface{}, out interface{}) error {
jsonBytes, err := json.Marshal(data)
if err != nil {
return err
}
return json.Unmarshal(jsonBytes, out)
}
type CostItem struct { type CostItem struct {
Cost int `json:"cost"` // 费用(分) Cost int `json:"cost"` // 费用(分)
CostT int `json:"costt"` // 总价 CostT int `json:"costt"` // 总价
CurrencyType int `json:"currencytype"` // 货币类型: 1-CNY 2-MOP 3-HKD 4-USD CurrencyType int `json:"currencytype"` // 货币类型: 1-CNY 2-MOP 3-HKD 4-USD
Int int `json:"int"` // 数量 Int int `json:"int"` // 数量
Type int `json:"type"` // 费用类型: 1-单价 2-运费 Type int `json:"type"` // 费用类型: 1-单价 2-运费
} }
type From_purchase_addorder struct { type From_purchase_addorder struct {
Costs []CostItem `json:"costs"` // 成本 Costs []CostItem `json:"costs"` // 成本
Link string `json:"link"` // 链接 Link string `json:"link"` // 链接
OrderStatus string `json:"order_status"` // 订单状态 OrderStatus string `json:"order_status"` // 订单状态
//PartName string `json:"partname"` // 物件名称 Photos []string `json:"photos"` // 图片备注
Photos []string `json:"photos"` // 图片备注 Remark string `json:"remark"` // 备注
Remark string `json:"remark"` // 备注 Styles string `json:"styles"` // 样式备注
Styles string `json:"styles"` // 样式备注 Title string `json:"title"` // 标题
Title string `json:"title"` // 标题
//TrackingNumber string `json:"tracking_number"` // 快递单号
//UpdateTime string `json:"update_time"` // 更新时间
} }
type TabPurchaseOrder struct { type TabPurchaseOrder struct {
@@ -39,21 +44,21 @@ type TabPurchaseOrder struct {
Remark string `gorm:"type:text;comment:备注"` Remark string `gorm:"type:text;comment:备注"`
Link string `gorm:"size:1000;comment:链接"` Link string `gorm:"size:1000;comment:链接"`
Styles string `gorm:"type:text;comment:样式数组"` Styles string `gorm:"type:text;comment:样式数组"`
OrderStatus string `gorm:"size:50;default:pending;comment:订单状态: pending-待处理 ordered-已下单 arrived-已到达 received-已收件"` OrderStatus string `gorm:"size:50;default:pending;comment:订单状态: pending-待处理 ordered-已下单 arrived-已到达 received-已收件 lost-丢件 returned-退件"`
CreatedAt *time.Time `gorm:"type:datetime;autoCreateTime"` CreatedAt *time.Time `gorm:"type:datetime;autoCreateTime"`
UpdatedAt *time.Time `gorm:"type:datetime;autoUpdateTime"` UpdatedAt *time.Time `gorm:"type:datetime;autoUpdateTime"`
DeletedAt gorm.DeletedAt `gorm:"index"` DeletedAt gorm.DeletedAt `gorm:"index"`
} }
type TabPurchaseCosts struct { type TabPurchaseCosts struct {
ID uint `gorm:"primarykey"` ID uint `gorm:"primarykey"`
OrderID uint `gorm:"not null"` OrderID uint `gorm:"not null"`
UserID uint `gorm:"not null"` UserID uint `gorm:"not null"`
Price int `gorm:"not null"` Price int `gorm:"not null"`
Quantity int `gorm:"not null"` Quantity int `gorm:"not null"`
CurrencyType int `gorm:"default:1;comment:货币类型: 1-CNY 2-MOP 3-HKD 4-USD"` CurrencyType int `gorm:"default:1;comment:货币类型: 1-CNY 2-MOP 3-HKD 4-USD"`
CostType int `gorm:"default:1;comment:费用类型: 1-单价 2-运费"` CostType int `gorm:"default:1;comment:费用类型: 1-单价 2-运费"`
CreatedAt *time.Time `gorm:"type:datetime;autoCreateTime"` CreatedAt *time.Time `gorm:"type:datetime;autoCreateTime"`
} }
type TabPurchaseFileBind struct { type TabPurchaseFileBind struct {
@@ -113,7 +118,7 @@ func ApiPurchase(r *gin.RouterGroup) {
ID uint `json:"id"` ID uint `json:"id"`
} }
var from FromGetOrder var from FromGetOrder
if err := mapstructure.Decode(data, &from); err != nil || from.ID == 0 { if err := decodeJSON(data, &from); err != nil || from.ID == 0 {
ReturnJson(ctx, "jsonErr", nil) ReturnJson(ctx, "jsonErr", nil)
return return
} }
@@ -212,7 +217,7 @@ func ApiPurchase(r *gin.RouterGroup) {
Photos []string `json:"photos"` // 变更附带的图片哈希 Photos []string `json:"photos"` // 变更附带的图片哈希
} }
var from FromUpdateStatus var from FromUpdateStatus
if err := mapstructure.Decode(data, &from); err != nil || from.ID == 0 { if err := decodeJSON(data, &from); err != nil || from.ID == 0 {
ReturnJson(ctx, "jsonErr", nil) ReturnJson(ctx, "jsonErr", nil)
return return
} }
@@ -231,6 +236,8 @@ func ApiPurchase(r *gin.RouterGroup) {
"ordered": true, "ordered": true,
"arrived": true, "arrived": true,
"received": true, "received": true,
"lost": true,
"returned": true,
} }
if !validStatuses[from.Status] { if !validStatuses[from.Status] {
ReturnJson(ctx, "invalid_status", nil) ReturnJson(ctx, "invalid_status", nil)
@@ -283,7 +290,7 @@ func ApiPurchase(r *gin.RouterGroup) {
// 写操作日志 // 写操作日志
newContent, _ := json.Marshal(map[string]string{ newContent, _ := json.Marshal(map[string]string{
"status": from.Status, "status": from.Status,
"comment": comment, "comment": comment,
}) })
oldContent, _ := json.Marshal(map[string]string{ oldContent, _ := json.Marshal(map[string]string{
@@ -316,7 +323,7 @@ func ApiPurchase(r *gin.RouterGroup) {
} }
var jsondata From_purchase_getorders var jsondata From_purchase_getorders
if err := mapstructure.Decode(data, &jsondata); err == nil { if err := decodeJSON(data, &jsondata); err == nil {
fmt.Println(jsondata) fmt.Println(jsondata)
is_data_ok := true is_data_ok := true
@@ -366,7 +373,8 @@ func ApiPurchase(r *gin.RouterGroup) {
//fmt.Println(user) //fmt.Println(user)
//DebugPrintJson(data) //DebugPrintJson(data)
var jsondata From_purchase_addorder var jsondata From_purchase_addorder
if err := mapstructure.Decode(data, &jsondata); err == nil { fmt.Println(data)
if err := decodeJSON(data, &jsondata); err == nil {
//jsonStr, _ := json.MarshalIndent(jsondata, "", " ") //jsonStr, _ := json.MarshalIndent(jsondata, "", " ")
//fmt.Println("转换后数据:\n", string(jsonStr)) //fmt.Println("转换后数据:\n", string(jsonStr))
@@ -406,79 +414,79 @@ func ApiPurchase(r *gin.RouterGroup) {
// fmt.Println("err5") // fmt.Println("err5")
// } // }
if is_data_ok { if is_data_ok {
//校验通过 //校验通过
//photos, _ := json.Marshal(jsondata.Photos) //photos, _ := json.Marshal(jsondata.Photos)
new_data := TabPurchaseOrder{ new_data := TabPurchaseOrder{
UserID: user.ID, UserID: user.ID,
Title: jsondata.Title, Title: jsondata.Title,
Remark: jsondata.Remark, Remark: jsondata.Remark,
Link: jsondata.Link, Link: jsondata.Link,
Styles: jsondata.Styles, Styles: jsondata.Styles,
OrderStatus: "pending", // 默认待处理 OrderStatus: "pending", // 默认待处理
} }
models.DB.Create(&new_data) models.DB.Create(&new_data)
for i := 0; i < len(jsondata.Costs); i++ { for i := 0; i < len(jsondata.Costs); i++ {
currencyType := jsondata.Costs[i].CurrencyType currencyType := jsondata.Costs[i].CurrencyType
if currencyType <= 0 { if currencyType <= 0 {
currencyType = 1 // 默认 CNY currencyType = 1 // 默认 CNY
}
costType := jsondata.Costs[i].Type
if costType <= 0 {
costType = 1 // 默认单价
}
new_cost_data := TabPurchaseCosts{
Price: jsondata.Costs[i].Cost,
Quantity: jsondata.Costs[i].Int,
UserID: user.ID,
OrderID: new_data.ID,
CurrencyType: currencyType,
CostType: costType,
}
models.DB.Create(&new_cost_data)
}
//绑定文件
for i := 0; i < len(jsondata.Photos); i++ {
findFile := models.TabFileInfo_{
Sha256: jsondata.Photos[i],
Type: "image",
}
if models.DB.Where(&findFile).First(&findFile).Error == nil {
bind := TabPurchaseFileBind{
OrderID: new_data.ID,
FileID: findFile.ID,
} }
models.DB.Create(&bind) costType := jsondata.Costs[i].Type
if costType <= 0 {
costType = 1 // 默认单价
}
new_cost_data := TabPurchaseCosts{
Price: jsondata.Costs[i].Cost,
Quantity: jsondata.Costs[i].Int,
UserID: user.ID,
OrderID: new_data.ID,
CurrencyType: currencyType,
CostType: costType,
}
models.DB.Create(&new_cost_data)
} }
}
// 写创建日志 //绑定文件
newContent, _ := json.Marshal(jsondata) for i := 0; i < len(jsondata.Photos); i++ {
tosqllog := TabPurchaseLog{ findFile := models.TabFileInfo_{
UserID: user.ID, Sha256: jsondata.Photos[i],
OrderID: new_data.ID, Type: "image",
ActionType: "create", }
NewContent: string(newContent), if models.DB.Where(&findFile).First(&findFile).Error == nil {
OldContent: "", bind := TabPurchaseFileBind{
IP: ctx.ClientIP(), OrderID: new_data.ID,
} FileID: findFile.ID,
models.DB.Create(&tosqllog) }
models.DB.Create(&bind)
}
}
// 写状态创建 commit // 写创建日志
commitLog := TabPurchaseCommit{ newContent, _ := json.Marshal(jsondata)
OrderID: new_data.ID, tosqllog := TabPurchaseLog{
UserID: user.ID, UserID: user.ID,
Action: "create", OrderID: new_data.ID,
Status: "pending", ActionType: "create",
OldStatus: "", NewContent: string(newContent),
Comment: "订单创建", OldContent: "",
IP: ctx.ClientIP(), IP: ctx.ClientIP(),
} }
models.DB.Create(&commitLog) models.DB.Create(&tosqllog)
ReturnJson(ctx, "apiOK", nil) // 写状态创建 commit
commitLog := TabPurchaseCommit{
OrderID: new_data.ID,
UserID: user.ID,
Action: "create",
Status: "pending",
OldStatus: "",
Comment: "订单创建",
IP: ctx.ClientIP(),
}
models.DB.Create(&commitLog)
ReturnJson(ctx, "apiOK", nil)
} else { } else {
ReturnJson(ctx, "jsonErr_1", nil) ReturnJson(ctx, "jsonErr_1", nil)
+4 -1
View File
@@ -70,6 +70,8 @@
"status_ordered": "Ordered", "status_ordered": "Ordered",
"status_arrived": "Arrived", "status_arrived": "Arrived",
"status_received": "Received", "status_received": "Received",
"status_lost": "Lost",
"status_returned": "Returned",
"completed": "Completed", "completed": "Completed",
"pending": "Pending", "pending": "Pending",
"show": "Show", "show": "Show",
@@ -226,7 +228,8 @@
"type_cof_pass": "Confirm new password", "type_cof_pass": "Confirm new password",
"old_pass_incorrect": "Old password is incorrect", "old_pass_incorrect": "Old password is incorrect",
"confirm_password_incorrect": "Confirm password is incorrect", "confirm_password_incorrect": "Confirm password is incorrect",
"save_success": "Saved successfully" "save_success": "Saved successfully",
"submit": "Submit"
}, },
"settings": { "settings": {
"cancel": "Cancel", "cancel": "Cancel",
+4 -1
View File
@@ -70,6 +70,8 @@
"status_ordered": "已下单", "status_ordered": "已下单",
"status_arrived": "已到达", "status_arrived": "已到达",
"status_received": "已收件", "status_received": "已收件",
"status_lost": "丢件",
"status_returned": "退件",
"completed": "已完成", "completed": "已完成",
"pending": "待处理", "pending": "待处理",
"show": "显示", "show": "显示",
@@ -226,7 +228,8 @@
"type_cof_pass": "确认新密码", "type_cof_pass": "确认新密码",
"old_pass_incorrect": "旧密码不正确", "old_pass_incorrect": "旧密码不正确",
"confirm_password_incorrect": "确认密码不正确", "confirm_password_incorrect": "确认密码不正确",
"save_success": "保存成功" "save_success": "保存成功",
"submit": "提交"
}, },
"settings": { "settings": {
"cancel": "取消", "cancel": "取消",
+22 -23
View File
@@ -7,34 +7,33 @@ import { usersApi } from '@/api/users';
export const useUsersStore = defineStore('users', () => { export const useUsersStore = defineStore('users', () => {
const usersInfo =ref([]); const usersInfo =ref([]);
function getUsernameFromUserID(userID){ function getUserFromUserID(userID){
//console.log(userID) return usersInfo.value?.find(item => item.UserID === userID) ?? null
//先在usersInfo找找有没有 }
const target = usersInfo.value?.find(item => item.UserID === userID)
if(target){
return target.Username //有的话直接返回
}else{
//没有的话 询问后端
usersApi.getUserInfoFromUserID(userID).then((r)=>{
//console.log(r)
if(r.errCode==0)
{
switch(r.raw.err_code){
case 0:
if(r.raw.return.userinfo){
usersInfo.value.push(r.raw.return.userinfo)
}
break;
}
}
})
return "..." // 第一次返回这个,不会空白/报错 function getUsernameFromUserID(userID){
const target = getUserFromUserID(userID)
if (target) {
return target.Username
} }
usersApi.getUserInfoFromUserID(userID).then((r) => {
if (r.errCode == 0 && r.raw.err_code == 0 && r.raw.return.userinfo) {
usersInfo.value.push(r.raw.return.userinfo)
}
})
return "..."
}
function getAvatarUrlFromUserID(userID) {
const target = getUserFromUserID(userID)
if (target?.AvatarPath) {
return `/api/static/avatar/${target.AvatarPath}`
}
return `/ava.svg`
} }
return{ return{
usersInfo,getUsernameFromUserID, usersInfo,getUsernameFromUserID,getAvatarUrlFromUserID,
} }
}) })
@@ -6,6 +6,7 @@ import { useToastStore } from "@/stores/toast";
import { usePageTitle } from "@/composables/usePageTitle"; import { usePageTitle } from "@/composables/usePageTitle";
import { purchaseApi } from "@/api/purchase"; import { purchaseApi } from "@/api/purchase";
import { useUserStore } from "@/stores/user"; import { useUserStore } from "@/stores/user";
import { useUsersStore } from "@/stores/users";
import { import {
IconChevronLeft, IconChevronLeft,
IconExternalLink, IconExternalLink,
@@ -22,6 +23,7 @@ const { t, locale } = useI18n();
const route = useRoute(); const route = useRoute();
const router = useRouter(); const router = useRouter();
const toast = useToastStore(); const toast = useToastStore();
const usersStore = useUsersStore();
const userStore = useUserStore(); const userStore = useUserStore();
const orderId = computed(() => parseInt(route.params.id)); const orderId = computed(() => parseInt(route.params.id));
@@ -47,6 +49,8 @@ const statusOptions = [
{ value: "ordered", labelKey: "status_ordered", color: "blue" }, { value: "ordered", labelKey: "status_ordered", color: "blue" },
{ value: "arrived", labelKey: "status_arrived", color: "purple" }, { value: "arrived", labelKey: "status_arrived", color: "purple" },
{ value: "received", labelKey: "status_received", color: "green" }, { value: "received", labelKey: "status_received", color: "green" },
{ value: "lost", labelKey: "status_lost", color: "red" },
{ value: "returned", labelKey: "status_returned", color: "gray" },
]; ];
// 状态颜色映射 // 状态颜色映射
@@ -58,6 +62,10 @@ const statusColorClass = computed(() => ({
"bg-purple-100 text-purple-700 dark:bg-purple-900/40 dark:text-purple-400", "bg-purple-100 text-purple-700 dark:bg-purple-900/40 dark:text-purple-400",
received: received:
"bg-green-100 text-green-700 dark:bg-green-900/40 dark:text-green-400", "bg-green-100 text-green-700 dark:bg-green-900/40 dark:text-green-400",
lost:
"bg-red-100 text-red-700 dark:bg-red-900/40 dark:text-red-400",
returned:
"bg-gray-200 text-gray-600 dark:bg-gray-700 dark:text-gray-300",
})); }));
// 货币选项 // 货币选项
@@ -278,6 +286,7 @@ onMounted(fetchOrder);
</script> </script>
<template> <template>
<div class="mx-auto max-w-6xl px-6 py-6"> <div class="mx-auto max-w-6xl px-6 py-6">
<!-- 返回按钮 --> <!-- 返回按钮 -->
<div class="mb-4"> <div class="mb-4">
@@ -349,6 +358,18 @@ onMounted(fetchOrder);
</span> </span>
{{ getStatusLabel(order.OrderStatus) }} {{ getStatusLabel(order.OrderStatus) }}
</span> </span>
<!-- 创建者 -->
<span
v-if="order?.UserID"
class="ml-1 flex items-center gap-1.5 rounded-full border border-gray-200 bg-gray-50 px-2 py-0.5 text-xs text-gray-500 dark:border-dk-muted dark:bg-dk-base dark:text-gray-400"
>
<img
:src="usersStore.getAvatarUrlFromUserID(order.UserID)"
class="rounded-full object-cover"
style="width:18px;height:18px;"
/>
{{ usersStore.getUsernameFromUserID(order.UserID) }}
</span>
</div> </div>
<span class="text-sm text-gray-400">{{ <span class="text-sm text-gray-400">{{
formatDate(order?.CreatedAt) formatDate(order?.CreatedAt)
@@ -363,7 +384,24 @@ onMounted(fetchOrder);
>{{ t("purchase.change_status") }}:</span >{{ t("purchase.change_status") }}:</span
> >
<button <button
v-for="opt in statusOptions" v-for="opt in statusOptions.slice(0, 4)"
:key="opt.value"
class="inline-flex items-center gap-1 rounded-full border px-3 py-1 text-xs font-medium transition-all"
:class="
order?.OrderStatus === opt.value
? [getStatusColorClass(opt.value), 'border-transparent']
: 'border-gray-200 text-gray-500 hover:border-gray-300 hover:bg-gray-50 dark:border-dk-muted dark:text-gray-400 dark:hover:bg-dk-base'
"
:disabled="updatingStatus"
@click="openStatusDialog(opt.value)"
>
<IconCheck v-if="order?.OrderStatus === opt.value" :size="12" />
{{ t("purchase." + opt.labelKey) }}
</button>
<!-- 异常状态右对齐 -->
<span class="flex-1" />
<button
v-for="opt in statusOptions.slice(4)"
:key="opt.value" :key="opt.value"
class="inline-flex items-center gap-1 rounded-full border px-3 py-1 text-xs font-medium transition-all" class="inline-flex items-center gap-1 rounded-full border px-3 py-1 text-xs font-medium transition-all"
:class=" :class="
@@ -574,22 +612,33 @@ onMounted(fetchOrder);
<div <div
v-for="commit in commits" v-for="commit in commits"
:key="commit.id" :key="commit.id"
class="flex items-start gap-4 py-3" class="flex items-start gap-3 py-3"
> >
<!-- 时间线点 --> <!-- 左侧头像 + 用户名 -->
<div class="mt-1 flex-shrink-0"> <div class="flex w-20 flex-shrink-0 flex-col items-center gap-1">
<img
:src="usersStore.getAvatarUrlFromUserID(commit.userId)"
class="rounded-full border border-gray-200 object-cover dark:border-dk-muted"
style="width:32px;height:32px;"
/>
<span
class="w-full truncate text-center"
style="font-size:11px;color:var(--text-secondary,#6b7280);"
:title="usersStore.getUsernameFromUserID(commit.userId)"
>
{{ usersStore.getUsernameFromUserID(commit.userId) }}
</span>
</div>
<!-- 中间时间线点 -->
<div class="flex flex-shrink-0 flex-col items-center pt-1">
<div <div
class="h-2.5 w-2.5 rounded-full" class="h-3 w-3 rounded-full border-2 border-white dark:border-dk-base"
:class="{ :class="getStatusColorClass(commit.status)"
'bg-yellow-400': commit.status === 'pending',
'bg-blue-400': commit.status === 'ordered',
'bg-purple-400': commit.status === 'arrived',
'bg-green-400': commit.status === 'received',
}"
/> />
</div> </div>
<!-- 内容 --> <!-- 右侧状态 + 备注 + 图片 -->
<div class="flex-1 min-w-0"> <div class="flex-1 min-w-0">
<div class="flex flex-wrap items-center gap-2"> <div class="flex flex-wrap items-center gap-2">
<span <span
@@ -611,7 +660,7 @@ onMounted(fetchOrder);
: "" : ""
}}{{ getStatusLabel(commit.status) }} }}{{ getStatusLabel(commit.status) }}
</span> </span>
<span class="text-xs text-gray-400">{{ <span class="ml-auto text-xs text-gray-400">{{
formatDate(commit.createdAt) formatDate(commit.createdAt)
}}</span> }}</span>
</div> </div>
@@ -621,7 +670,6 @@ onMounted(fetchOrder);
> >
{{ commit.comment }} {{ commit.comment }}
</p> </p>
<!-- 变更图片 -->
<div <div
v-if="commit.photos?.length" v-if="commit.photos?.length"
class="mt-2 flex flex-wrap gap-1.5" class="mt-2 flex flex-wrap gap-1.5"
@@ -632,7 +680,7 @@ onMounted(fetchOrder);
:href="`/api/files/get/${hash}`" :href="`/api/files/get/${hash}`"
target="_blank" target="_blank"
class="block overflow-hidden rounded border border-gray-200 dark:border-dk-muted transition-transform hover:scale-105" class="block overflow-hidden rounded border border-gray-200 dark:border-dk-muted transition-transform hover:scale-105"
style="width: 48px; height: 48px" style="width:48px;height:48px;"
> >
<img <img
:src="`/api/files/get/${hash}`" :src="`/api/files/get/${hash}`"
@@ -810,7 +858,7 @@ onMounted(fetchOrder);
:size="14" :size="14"
class="animate-spin" class="animate-spin"
/> />
{{ t("message.save_ok") }} {{ t("message.submit") }}
</button> </button>
</div> </div>
</div> </div>
@@ -113,10 +113,10 @@ const costEntries = reactive([]);
* 用户填写完表单后点击"添加"按钮加入 costEntries * 用户填写完表单后点击"添加"按钮加入 costEntries
*/ */
const newCost = reactive({ const newCost = reactive({
type: "1", // 费用类型:默认"单价" type: 1, // 费用类型:默认"单价"
int: 1, // 数量:默认1 int: 1, // 数量:默认1
cost: 0, // 单价:默认0 cost: 0, // 单价:默认0
currencyType: "1", // 货币类型:默认人民币 currencyType: 1, // 货币类型:默认人民币
}); });
// 费用验证错误状态:点击添加按钮后发现费用为0时触发 // 费用验证错误状态:点击添加按钮后发现费用为0时触发
@@ -166,10 +166,10 @@ function addCostEntry() {
currencytype: newCost.currencyType, currencytype: newCost.currencyType,
}); });
// 添加后重置表单,以便继续添加下一条 // 添加后重置表单,以便继续添加下一条
newCost.type = "1"; newCost.type = 1;
newCost.int = 1; newCost.int = 1;
newCost.cost = 0; newCost.cost = 0;
newCost.currencyType = "1"; newCost.currencyType = 1;
} }
/** /**