1367 lines
42 KiB
Vue
1367 lines
42 KiB
Vue
<template>
|
|
<div v-if="islogin == '1'" class="conten">
|
|
<!-- <template v-if="tablet">
|
|
平板
|
|
</template> -->
|
|
|
|
<div class="head">
|
|
<div style="box-sizing: border-box;padding: 5px;">
|
|
<div class="mbx">
|
|
<div>{{mbxone}}</div>
|
|
<n-icon :component="ArrowRedoOutline" size="20" />
|
|
<div>{{ mbtwo }}</div>
|
|
<n-icon :component="ArrowRedoOutline" size="20" />
|
|
<div>{{mbthree}}</div>
|
|
</div>
|
|
<n-icon :component="BuildSharp" size="20" color="#ccc" />
|
|
|
|
<div style="display: flex;align-items: center;padding-left: 10px;">
|
|
<img v-if="userStore.avatar" :src="userStore.avatar" width="40" height="40" style="border-radius: 50%;" />
|
|
<n-icon v-else :component="PersonCircleSharp" size="35" color="#ccc" />
|
|
<div style="padding: 0 10px;font-size: 16px;">{{userStore.nickname}}</div>
|
|
<div style="padding: 2px 5px;border-radius: 5px;font-size: 12px;background: #bd6d07;">{{userStore.postNames}}</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<!-- <n-button v-if="isfullscr" ghost style="margin-right: 20px;color: #fff;" @click="exitFullscreen">
|
|
<template #icon>
|
|
<n-icon>
|
|
<Contract />
|
|
</n-icon>
|
|
</template>
|
|
退出全屏
|
|
</n-button>
|
|
<n-button v-else ghost style="margin-right: 20px;color: #fff;" @click="requestFullscreen">
|
|
<template #icon>
|
|
<n-icon>
|
|
<Contract />
|
|
</n-icon>
|
|
</template>
|
|
全屏
|
|
</n-button> -->
|
|
<n-button @click="refresh" ghost style="margin-right: 20px;color: #fff;">
|
|
<template #icon>
|
|
<n-icon>
|
|
<Sync />
|
|
</n-icon>
|
|
</template>
|
|
|
|
刷新
|
|
</n-button>
|
|
<!--switchworks-->
|
|
<n-button ghost style="margin-right: 20px;color: #fff;" @click="handover">
|
|
<template #icon>
|
|
<n-icon>
|
|
<SwapHorizontalOutline />
|
|
</n-icon>
|
|
</template>
|
|
工位交接
|
|
</n-button>
|
|
<n-button ghost style="color: #fff;" @click="handover">
|
|
<template #icon>
|
|
<n-icon>
|
|
<LogOutOutline />
|
|
</n-icon>
|
|
</template>
|
|
退出登录
|
|
</n-button>
|
|
</div>
|
|
</div>
|
|
<div class="total" style="display: none;">
|
|
<div>
|
|
<div style="display: flex;align-items: center;font-size: 18px;color:#dfdfdf;">
|
|
<n-icon size="20">
|
|
<BarChartOutline />
|
|
</n-icon>
|
|
<div style="padding-left: 8px;">工单数</div>
|
|
</div>
|
|
<div style="font-size: 34px;line-height: 45px;color:#f3f3f3;">50</div>
|
|
</div>
|
|
<div>
|
|
<div style="display: flex;align-items: center;font-size: 18px;color:#dfdfdf;">
|
|
<n-icon size="25">
|
|
<ShapesOutline />
|
|
</n-icon>
|
|
<div style="padding-left: 8px;">计划/已报</div>
|
|
</div>
|
|
<div style="font-size: 34px;line-height: 45px;color:#f3f3f3;">50/20</div>
|
|
</div>
|
|
<div>
|
|
<div style="display: flex;align-items: center;font-size: 18px;color:#dfdfdf;">
|
|
<n-icon size="22">
|
|
<TimerSharp />
|
|
</n-icon>
|
|
<div style="padding-left: 8px;">合格数</div>
|
|
</div>
|
|
<div style="font-size: 34px;color: #bd6d07;line-height: 45px;color:#f3f3f3;">40</div>
|
|
</div>
|
|
<div>
|
|
<div style="display: flex;align-items: center;font-size: 18px;color:#dfdfdf;">
|
|
<n-icon size="22">
|
|
<LogoWebComponent />
|
|
</n-icon>
|
|
<div style="padding-left: 8px;">不良品</div>
|
|
</div>
|
|
<div style="font-size: 34px;line-height: 45px;color:#f3f3f3;">10</div>
|
|
</div>
|
|
|
|
<div>
|
|
<div style="display: flex;align-items: center;font-size: 18px;color:#dfdfdf;">
|
|
<n-icon size="22">
|
|
<LayersOutline />
|
|
</n-icon>
|
|
<div style="padding-left: 8px;">合格率</div>
|
|
</div>
|
|
<div style="font-size: 34px;line-height: 45px;color:#f3f3f3;">80%</div>
|
|
</div>
|
|
</div>
|
|
<n-grid x-gap="20" style="padding:50px 20px 20px;">
|
|
<n-gi :span="5" class="mocz">
|
|
<div style="display: flex;align-items: center;justify-content: space-between;padding:8px 12px;">
|
|
<div style="display: flex;align-items: center;font-size: 18px;color:#dfdfdf;">
|
|
<n-icon size="22">
|
|
<DiceOutline />
|
|
</n-icon>
|
|
<div style="padding-left: 8px;">工单列表</div>
|
|
</div>
|
|
<div style="font-size: 14px;color:#b7b7b7;">共 {{ taskdata.length }} 项</div>
|
|
</div>
|
|
<div style="padding: 20px;border: 2px dashed #afafaf;border-left: none;border-right: none;">
|
|
<n-grid x-gap="10">
|
|
<!-- <n-gi :span="10">
|
|
<n-select
|
|
v-model:value="queryparam.type"
|
|
:options="typeopt"
|
|
remote
|
|
@update:value=""
|
|
/>
|
|
</n-gi> -->
|
|
<n-gi :span="24">
|
|
<n-input-group>
|
|
<n-input
|
|
:style="{ width: '100%' }"
|
|
placeholder="请输入编号或产品"
|
|
v-model:value="pgcode"
|
|
@keyup.enter="queryhand"
|
|
/>
|
|
<n-button style="color:#dfdfdf;" @click="queryhand">
|
|
<template #icon>
|
|
<n-icon size="22">
|
|
<Search />
|
|
</n-icon>
|
|
</template>
|
|
</n-button>
|
|
</n-input-group>
|
|
</n-gi>
|
|
</n-grid>
|
|
</div>
|
|
<div style="height: 450px;padding: 20px;overflow-y: auto;">
|
|
<div v-for="(n,i) in taskdata" @click="getgd(i,n)" class="gditem" :class="{gdactv:gdindex == i}">
|
|
<div style="display: flex;align-items: center;justify-content: space-between;font-size: 22px;">
|
|
<div>{{ n.assingCode }}</div>
|
|
<div style="margin-left: 10px;padding: 4px 10px;border-radius: 10px;font-size: 12px;background: #bd6d07;">{{ticketStatus[n.assingStatus]}}</div>
|
|
</div>
|
|
<div style="font-size: 16px;color: #b7b7b7;">{{n.processName}}</div>
|
|
<div style="display: flex;color: #b7b7b7;">
|
|
<div style="padding-right: 30px;">派工数量 : {{n.quantity}}</div>
|
|
<div>完成数量 : {{n.completedQuantity}}</div>
|
|
</div>
|
|
<div style="color: #b7b7b7;">{{n.beginTime}} 至 {{ n.endTime }}</div>
|
|
<div style="display: flex;width: 100%;align-items: center;">
|
|
<div style="flex: 1;position: relative;margin-right: 10px;height: 6px;background: #afafaf;">
|
|
<div :style="{
|
|
position:'absolute',
|
|
width:setw(n.completedQuantity,n.quantity),
|
|
height:'6px',
|
|
background:'#007f5b'
|
|
}"></div>
|
|
</div>
|
|
<!--completedQuantity 已完成数; quantity 派工总数 Math.floor()-->
|
|
<div>{{toFixed2(n.completedQuantity,n.quantity)}} %</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</n-gi>
|
|
<n-gi :span="14" class="mocz" style="padding:5px 15px;">
|
|
<n-tabs
|
|
type="line"
|
|
tab-style="color: #ccc;"
|
|
default-value="gdcz"
|
|
size="large"
|
|
animated
|
|
pane-wrapper-style="margin: 0 -4px"
|
|
pane-style="color:#fff;padding-left: 4px; padding-right: 4px; box-sizing: border-box;"
|
|
>
|
|
<n-tab-pane name="gdcz">
|
|
<template #tab>
|
|
<n-icon size="22">
|
|
<PrismSharp />
|
|
</n-icon>
|
|
<div style="padding-left: 4px;">工单操作</div>
|
|
</template>
|
|
<div style="padding: 15px;border: 2px solid #186170;border-radius: 10px;background: #244962;">
|
|
<div style="display: flex;align-items: center;padding-bottom: 10px;">
|
|
<div style="font-size: 30px;">{{gdinfo.assingCode}}</div>
|
|
<!-- <div style="margin-left: 8px;padding: 2px 6px;border-radius: 8px;background: #896024;">{{ticketStatus[gdinfo.assingStatus]}}</div> -->
|
|
</div>
|
|
<div style="display: flex;align-items: center;justify-content: space-between;">
|
|
<div style="width: 15%;height: 100px;text-align: center;border: 4px double #ccc;border-radius: 10px;">
|
|
<div style="height: 40px;line-height: 40px;font-size: 16px;background: #177a7b;border-radius: 10px 10px 0 0;">生产总数</div>
|
|
<div style="height: 80px;line-height: 40px;font-size: 30px;">{{gddetail.processPlanTotalNum}}</div>
|
|
</div>
|
|
|
|
<div style="width: 15%;height: 100px;text-align: center;border: 4px double #ccc;border-radius: 10px;">
|
|
<div style="height: 40px;line-height: 40px;font-size: 16px;background: #177a7b;border-radius: 10px 10px 0 0;">转入数量</div>
|
|
<div style="height: 80px;line-height: 40px;font-size: 30px;">{{gddetail.processPlanTransferNum}}</div>
|
|
</div>
|
|
<div style="width: 15%;height: 100px;text-align: center;border: 4px double #ccc;border-radius: 10px;">
|
|
<div style="height: 40px;line-height: 40px;font-size: 16px;background: #177a7b;border-radius: 10px 10px 0 0;">转出数量</div>
|
|
<div style="height: 80px;line-height: 40px;font-size: 30px;">{{gddetail.processPlanTransferOutNum}}</div>
|
|
</div>
|
|
<div style="width: 15%;height: 100px;text-align: center;border: 4px double #ccc;border-radius: 10px;">
|
|
<div style="height: 40px;line-height: 40px;font-size: 16px;color: #e3e3e3;background: #70560c;border-radius: 10px 10px 0 0;">当前任务生产总数</div>
|
|
<div style="height: 80px;line-height: 40px;font-size: 30px;">{{gddetail.assingWorkTotalNum}}</div>
|
|
</div>
|
|
<div style="width: 15%;height: 100px;text-align: center;border: 4px double #ccc;border-radius: 10px;">
|
|
<div style="height: 40px;line-height: 40px;font-size: 16px;color: #e3e3e3;background: #70560c;border-radius: 10px 10px 0 0;">当前任务己生产数</div>
|
|
<div style="height: 80px;line-height: 40px;font-size: 30px;">{{ gddetail.assingWorkProductionTotalNum }}</div>
|
|
</div>
|
|
<div style="width: 15%;height: 100px;text-align: center;border: 4px double #ccc;border-radius: 10px;">
|
|
<div style="height: 40px;line-height: 40px;font-size: 16px;color: #e3e3e3;background: #70560c;border-radius: 10px 10px 0 0;">我的生产数量</div>
|
|
<div style="height: 80px;line-height: 40px;font-size: 30px;">{{ gddetail.assingWorkPersonTotalNum }}</div>
|
|
</div>
|
|
</div>
|
|
<!-- <div style="display: flex;align-items: center;overflow-x: auto;">
|
|
<div @click="gxtab(1)" :class="{gonxactv:gonxindex == 1}" style="box-sizing: border-box;width: 120px;padding: 10px 0;text-align: center;">
|
|
<circlebom :percent="100" />
|
|
<div>饮水机外壳加工</div>
|
|
</div>
|
|
<div @click="gxtab(2)" :class="{gonxactv:gonxindex == 2}" style="width: 120px;padding: 10px 0;text-align: center;">
|
|
<circlebom :percent="20" />
|
|
<div>进检</div>
|
|
</div>
|
|
<div @click="gxtab(3)" :class="{gonxactv:gonxindex == 3}" style="width: 120px;padding: 10px 0;text-align: center;">
|
|
<div class="progress-container">
|
|
<svg viewBox="0 0 120 120">
|
|
<circle class="bg" cx="60" cy="60" r="54" fill="none" stroke-width="6" />
|
|
<circle class="progress" cx="60" cy="60" r="54" fill="none" stroke-width="6"
|
|
stroke-dasharray="339.292" stroke-dashoffset="339.292" />
|
|
</svg>
|
|
<span class="label" id="label">0%</span>
|
|
</div>
|
|
<div>进检</div>
|
|
</div>
|
|
</div> -->
|
|
<div style="display: flex;align-items: center;justify-content: space-between;margin-top: 20px;padding: 20px;border: 1px solid #ccc;border-radius: 10px;">
|
|
<div style="display: flex;align-items: center;">
|
|
<!-- <div style="display: flex;align-items: center;">
|
|
<div style="padding: 2px 4px;font-size: 18px;color:#b7b7b7;border: 1px solid #ccc;">工序名称</div>
|
|
<div style="padding: 2px 4px;font-size: 20px;background: #ccc;color: #1e2a40;">拆解</div>
|
|
</div> -->
|
|
<div style="display: flex;align-items: center;">
|
|
<div style="padding: 2px 4px;font-size: 18px;color:#b7b7b7;border: 1px solid #ccc;">状态</div>
|
|
<div style="padding: 2px 4px;font-size: 20px;background: #ccc;color: #1e2a40;">待执行</div>
|
|
</div>
|
|
<div style="display: flex;align-items: center;margin-left: 30px;">
|
|
<div style="padding: 2px 4px;font-size: 18px;color:#b7b7b7;border: 1px solid #ccc;">完成进度</div>
|
|
<div style="padding: 2px 4px;font-size: 20px;background: #ccc;color: #1e2a40;">30%</div>
|
|
</div>
|
|
<div style="display: flex;align-items: center;margin-left: 30px;">
|
|
<div style="padding: 2px 4px;font-size: 18px;color:#b7b7b7;border: 1px solid #ccc;">质检</div>
|
|
<div style="padding: 2px 4px;font-size: 20px;background: #ccc;color: #1e2a40;">15</div>
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<n-button
|
|
ghost
|
|
style="margin-right: 20px;color: #fff;"
|
|
size="large"
|
|
@click="guizds"
|
|
>
|
|
<template #icon>
|
|
<n-icon>
|
|
<DocumentTextOutline />
|
|
</n-icon>
|
|
</template>
|
|
作业指导书
|
|
</n-button>
|
|
<!-- <n-button ghost style="margin-right: 20px;color: #fff;" size="large">
|
|
<template #icon>
|
|
<n-icon>
|
|
<PricetagsOutline />
|
|
</n-icon>
|
|
</template>
|
|
报工参数
|
|
</n-button> -->
|
|
<n-button ghost style="color: #fff;" size="large">
|
|
<template #icon>
|
|
<n-icon>
|
|
<ScanCircleOutline />
|
|
</n-icon>
|
|
</template>
|
|
工序检验
|
|
</n-button>
|
|
</div>
|
|
</div>
|
|
<div style="margin-top: 20px;padding: 20px;border: 1px solid #ccc;border-radius: 10px;">
|
|
<div style="display: flex;font-size: 16px;">
|
|
<div style="color:#ccc">可报工数量</div>
|
|
<div style="padding-left: 5px;font-weight:bold;">{{gddetail.assingWorkTotalNum - gddetail.assingWorkProductionTotalNum}} </div>
|
|
</div>
|
|
<n-form
|
|
ref="baogformRef"
|
|
:model="baogdata"
|
|
:rules="baogrules"
|
|
label-placement="left"
|
|
label-width="auto"
|
|
:inline="true"
|
|
size="large"
|
|
:style="{
|
|
marginTop:'20px'
|
|
}"
|
|
>
|
|
<n-form-item label="合格数" label-style="color:#fff;">
|
|
<n-input v-model:value="baogdata.okData.qty" placeholder="请输入合格数" />
|
|
</n-form-item>
|
|
<n-form-item label="不合格数" label-style="color:#fff;">
|
|
<n-input v-model:value="baogdata.scrapData.qty" placeholder="请输入不合格数" />
|
|
</n-form-item>
|
|
<n-form-item label="总数" label-style="color:#fff;">
|
|
<n-input v-model:value="baogdata.qcNum" disabled placeholder="" />
|
|
</n-form-item>
|
|
<n-button
|
|
type="success"
|
|
size="large"
|
|
@click="confireport"
|
|
>
|
|
确认报工
|
|
</n-button>
|
|
</n-form>
|
|
</div>
|
|
</div>
|
|
|
|
</n-tab-pane>
|
|
<n-tab-pane name="wend">
|
|
<template #tab>
|
|
<n-icon size="22">
|
|
<ReaderSharp />
|
|
</n-icon>
|
|
<div style="padding-left: 4px;">文档</div>
|
|
</template>
|
|
|
|
<n-tabs
|
|
type="bar"
|
|
tab-style="color: #ccc;"
|
|
default-value="zyzds"
|
|
size="large"
|
|
animated
|
|
pane-wrapper-style="margin: 0 -4px"
|
|
pane-style="color:#fff;padding-left: 4px; padding-right: 4px; box-sizing: border-box;"
|
|
>
|
|
<n-tab-pane name="zyzds" tab="作业指导书">
|
|
<!-- <template #tab>
|
|
<n-icon size="22">
|
|
<Planet />
|
|
</n-icon>
|
|
<div style="padding-left: 4px;">在制品跟踪</div>
|
|
</template> -->
|
|
作业指导书
|
|
</n-tab-pane>
|
|
<n-tab-pane name="tuzhi" tab="图纸">
|
|
<div style="display: flex;width:100%;height: 450px;flex-wrap: wrap;overflow-y: auto;">
|
|
<div v-for="n in 4" style="margin: 0 7px 15px;">
|
|
<n-image
|
|
src="https://07akioni.oss-cn-beijing.aliyuncs.com/07akioni.jpeg" width="160" height="180px" style="border-radius: 10px 10px 0 0;"
|
|
/>
|
|
<!-- <img src="../../assets/images/qiyelogo.png" width="160" height="180px" style="border-radius: 10px 10px 0 0;" /> -->
|
|
<div style="width: 160px;height: 40px;margin-top: -8px;line-height: 40px;border-radius: 0 0 10px 10px;text-align: center;background: #186170;">机械图纸.png</div>
|
|
</div>
|
|
|
|
<!-- <n-image-group show-toolbar-tooltip>
|
|
<n-space>
|
|
<n-image
|
|
width="100"
|
|
src="https://07akioni.oss-cn-beijing.aliyuncs.com/07akioni.jpeg"
|
|
/>
|
|
<n-image
|
|
width="100"
|
|
src="https://gw.alipayobjects.com/zos/antfincdn/aPkFc8Sj7n/method-draw-image.svg"
|
|
/>
|
|
</n-space>
|
|
</n-image-group> -->
|
|
|
|
</div>
|
|
|
|
</n-tab-pane>
|
|
<n-tab-pane name="code" tab="代码">
|
|
<!-- <template #tab>
|
|
<n-icon size="22">
|
|
<Planet />
|
|
</n-icon>
|
|
<div style="padding-left: 4px;">在制品跟踪</div>
|
|
</template> -->
|
|
代码
|
|
</n-tab-pane>
|
|
</n-tabs>
|
|
</n-tab-pane>
|
|
<!-- <n-tab-pane name="zzpgz" tab="在制品跟踪">
|
|
<template #tab>
|
|
<n-icon size="22">
|
|
<Planet />
|
|
</n-icon>
|
|
<div style="padding-left: 4px;">在制品跟踪</div>
|
|
</template>
|
|
在制品跟踪
|
|
</n-tab-pane> -->
|
|
</n-tabs>
|
|
</n-gi>
|
|
<n-gi :span="5" class="mocz">
|
|
<div style="display: flex;align-items: center;justify-content: space-between;padding:8px 12px;border-bottom: 2px dashed #afafaf;">
|
|
<div style="display: flex;align-items: center;font-size: 18px;color:#dfdfdf;">
|
|
<n-icon size="22">
|
|
<HourglassOutline />
|
|
</n-icon>
|
|
<div style="padding-left: 8px;">操作日志</div>
|
|
</div>
|
|
<!-- <div style="font-size: 14px;color:#b7b7b7;">共 40 项</div> -->
|
|
</div>
|
|
<div style="height: 520px;padding:20px;overflow-y: auto;">
|
|
<template v-if="loglist.length > 0">
|
|
<div v-for="n in loglist" style="margin-bottom: 18px;padding: 12px;border:1px solid #afafaf;border-radius:10px;background:#2d475c;">
|
|
<div style="display: flex;align-items: center;justify-content: space-between;font-size: 16px;">
|
|
<div>{{n.userName}}</div>
|
|
<div>{{n.createTime}}</div>
|
|
</div>
|
|
<div style="font-size: 20px;">{{operationType[n.operationType+'']}}</div>
|
|
</div>
|
|
</template>
|
|
<template v-else>
|
|
<n-empty size="huge" style="margin-top: 80px;" description="暂无记录" />
|
|
</template>
|
|
</div>
|
|
|
|
</n-gi>
|
|
</n-grid>
|
|
<div style="display: flex;align-items: center;justify-content: center;">
|
|
<div class="mybtn" style="background: #797b21;">
|
|
<n-icon size="26">
|
|
<CompassOutline />
|
|
</n-icon>
|
|
<div style="padding-left: 2px;">叫料</div>
|
|
</div>
|
|
<div class="mybtn" style="margin-left: 20px;background:#177a7b">
|
|
<n-icon size="26">
|
|
<NavigateCircle />
|
|
</n-icon>
|
|
<div style="padding-left: 2px;">调车</div>
|
|
</div>
|
|
<div class="mybtn" style="margin-left: 20px;">
|
|
<n-icon size="26">
|
|
<PlayCircleOutline />
|
|
</n-icon>
|
|
<div style="padding-left: 2px;">开工</div>
|
|
</div>
|
|
<div class="mybtn" style="margin-left: 20px;background: #1e2a40;border: 1px solid #afafaf;">
|
|
<n-icon size="26">
|
|
<StopCircleOutline />
|
|
</n-icon>
|
|
<div style="padding-left: 2px;">暂停</div>
|
|
</div>
|
|
<!-- <n-button ghost size="large" style="color: #fff;">
|
|
<template #icon size="100">
|
|
<n-icon>
|
|
<Contract />
|
|
</n-icon>
|
|
</template>
|
|
开始
|
|
</n-button>
|
|
<n-button ghost style="margin-right: 20px;color: #fff;">
|
|
<template #icon>
|
|
<n-icon>
|
|
<Sync />
|
|
</n-icon>
|
|
</template>
|
|
暂停
|
|
</n-button> -->
|
|
</div>
|
|
</div>
|
|
<div v-else class="conten">
|
|
<!-- <div class="head">
|
|
<div style="box-sizing: border-box;padding: 5px;">
|
|
|
|
|
|
<div style="display: flex;align-items: center;padding-left: 10px;">
|
|
<n-icon :component="PersonOutline" size="25" color="#ccc" />
|
|
<div style="padding: 0 10px;">{{userStore.nickname}}</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<n-button v-if="isfullscr" ghost style="margin-right: 20px;color: #fff;" @click="exitFullscreen">
|
|
<template #icon>
|
|
<n-icon>
|
|
<Contract />
|
|
</n-icon>
|
|
</template>
|
|
退出全屏
|
|
</n-button>
|
|
<n-button v-else ghost style="margin-right: 20px;color: #fff;" @click="requestFullscreen">
|
|
<template #icon>
|
|
<n-icon>
|
|
<Contract />
|
|
</n-icon>
|
|
</template>
|
|
全屏
|
|
</n-button>
|
|
</div>
|
|
</div> -->
|
|
<!-- <div style="position: absolute;top: 50%;left: 50%;width: 400px;height: 580px;padding: 20px;transform: translate(-50%,-50%);border-radius: 20px;border: 1px #b7b7b7 solid;background: #1e2a40;">
|
|
<div style="width: 100%;padding:10px 20px;text-align: center;">
|
|
<n-icon size="40" color="#00a2ff">
|
|
<EarthOutline />
|
|
</n-icon>
|
|
<div>
|
|
<div style="font-size: 21px;">请绑定当前终端所属工位</div>
|
|
<div style="font-size: 12px;color: #b7b7b7;">绑定后,终端将自动显示该工位的生产任务</div>
|
|
</div>
|
|
</div>
|
|
<n-form
|
|
ref="loginformRef"
|
|
:model="logindata"
|
|
:rules="loginrules"
|
|
label-placement="top"
|
|
label-width="auto"
|
|
size="large"
|
|
:style="{
|
|
marginTop:'20px'
|
|
}"
|
|
>
|
|
|
|
<n-form-item label="所属车间" label-style="color:#fff;" path="workshop">
|
|
<n-select
|
|
v-model:value="logindata.workshopId"
|
|
:render-label="renderlabel"
|
|
remote
|
|
placeholder="请选择车间"
|
|
@update:value="wkupdate"
|
|
:options="workshoplist"
|
|
/>
|
|
</n-form-item>
|
|
<n-form-item label="所属工段" label-style="color:#fff;" path="section">
|
|
<n-select
|
|
:disabled="logindata.workshopId?false:true"
|
|
:render-label="renderlabeltwo"
|
|
v-model:value="logindata.sectionId"
|
|
placeholder="请选择工段"
|
|
@update:value="secupdate"
|
|
:options="sectionlist"
|
|
/>
|
|
</n-form-item>
|
|
<n-form-item label="所属工位" label-style="color:#fff;" path="workstation">
|
|
<n-select
|
|
:disabled="logindata.sectionId?false:true"
|
|
:render-label="renderlabelthree"
|
|
v-model:value="logindata.deviceId"
|
|
placeholder="请选择工位"
|
|
:options="workstationlist"
|
|
/>
|
|
</n-form-item>
|
|
<n-button
|
|
:disabled="logindata.deviceId?false:true"
|
|
type="info"
|
|
style="width: 100%;margin-top: 20px;"
|
|
size="large"
|
|
@click="loginhand"
|
|
>
|
|
确 认 绑 定
|
|
</n-button>
|
|
</n-form>
|
|
</div> -->
|
|
|
|
<div style="position: absolute;top: 50%;left: 50%;width: 400px;height: 500px;padding: 20px;transform: translate(-50%,-50%);border-radius: 20px;border: 1px #b7b7b7 solid;background: #1e2a40;">
|
|
<div style="width: 100%;padding:10px 20px;text-align: center;">
|
|
<n-icon size="40" color="#00a2ff">
|
|
<EarthOutline />
|
|
</n-icon>
|
|
<div>
|
|
<div style="font-size: 21px;">登录终端</div>
|
|
<div style="font-size: 12px;color: #b7b7b7;">登录后,终端将自动显示该工位的生产任务</div>
|
|
</div>
|
|
</div>
|
|
<n-form
|
|
ref="loginformRef"
|
|
:model="formData"
|
|
:rules="loginrules"
|
|
label-placement="top"
|
|
label-width="auto"
|
|
size="large"
|
|
:style="{
|
|
marginTop:'20px'
|
|
}"
|
|
>
|
|
<n-form-item path="username" label-style="color:#fff;" label="用户名">
|
|
<n-input v-model:value="formData.username" placeholder="请输入用户名" :maxlength="50" @keyup.enter="handleLogin">
|
|
<template #prefix><n-icon :component="PersonOutline" /></template>
|
|
</n-input>
|
|
</n-form-item>
|
|
<n-form-item path="password" label-style="color:#fff;" label="密码">
|
|
<n-input v-model:value="formData.password" type="password" placeholder="请输入密码" show-password-on="click" :maxlength="50" @keyup.enter="handleLogin">
|
|
<template #prefix><n-icon :component="LockClosedOutline" /></template>
|
|
</n-input>
|
|
</n-form-item>
|
|
|
|
<n-button
|
|
type="info"
|
|
style="width: 100%;margin-top: 20px;"
|
|
size="large"
|
|
@click="handleLogin"
|
|
>
|
|
登 录
|
|
</n-button>
|
|
</n-form>
|
|
</div>
|
|
</div>
|
|
|
|
<!--工位交接-->
|
|
<n-modal
|
|
v-model:show="handoverpop"
|
|
title="工位交接"
|
|
preset="card"
|
|
style="width: 500px;"
|
|
:mask-closable="false"
|
|
>
|
|
<n-form
|
|
ref="loginformRef"
|
|
:model="formData"
|
|
:rules="loginrules"
|
|
label-placement="top"
|
|
label-width="auto"
|
|
size="large"
|
|
>
|
|
<n-form-item path="" label="交接人">
|
|
<n-input v-model:value="formData.username" placeholder="请输入交接人" />
|
|
</n-form-item>
|
|
<n-button
|
|
type="info"
|
|
style="width: 100%;margin-top: 20px;background: #296791;"
|
|
size="large"
|
|
@click="handleLogin"
|
|
>
|
|
确定交接
|
|
</n-button>
|
|
</n-form>
|
|
|
|
</n-modal>
|
|
|
|
<!--作业指导书-->
|
|
<n-modal
|
|
v-model:show="guidanpop"
|
|
title="作业指导书"
|
|
preset="card"
|
|
style="width: 500px"
|
|
:mask-closable="false"
|
|
>
|
|
<div style="min-height: 400px;">作业指导书</div>
|
|
<!-- <template #footer>
|
|
<n-space justify="end">
|
|
<n-button @click="guidanpop = false">取消</n-button>
|
|
</n-space>
|
|
</template> -->
|
|
</n-modal>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import {
|
|
ref,
|
|
reactive,
|
|
h,
|
|
onMounted,
|
|
render,
|
|
watch,
|
|
} from 'vue'
|
|
|
|
|
|
import {
|
|
NButton,
|
|
NDropdown,
|
|
NIcon,
|
|
NSpace,
|
|
NPagination,
|
|
NGrid,
|
|
NGi,
|
|
NTag,
|
|
useMessage,
|
|
//useDialog,
|
|
type FormInst,
|
|
} from 'naive-ui'
|
|
import {
|
|
CompassOutline,
|
|
NavigateCircle,
|
|
NuclearSharp,
|
|
StopOutline,
|
|
Navigate,
|
|
PlayCircleOutline,
|
|
LockClosedOutline,
|
|
ArrowRedoOutline,
|
|
PersonCircleSharp,
|
|
BuildSharp,
|
|
Contract,
|
|
Sync,
|
|
SwapHorizontalOutline,
|
|
BarChartOutline,
|
|
LayersOutline,
|
|
DiceOutline,
|
|
Search,
|
|
PrismSharp,
|
|
ReaderSharp,
|
|
Planet,
|
|
PersonOutline,
|
|
EarthOutline,
|
|
DocumentTextOutline,
|
|
PricetagsOutline,
|
|
ScanCircleOutline,
|
|
HourglassOutline,
|
|
Power,
|
|
StopCircleOutline,
|
|
ShapesOutline,
|
|
LogoWebComponent,
|
|
TimerSharp,
|
|
LogOutOutline
|
|
} from '@vicons/ionicons5'
|
|
|
|
import Circlebom from './circle.vue'
|
|
|
|
import { useUserStore } from '@/stores/user'
|
|
|
|
import {
|
|
tasklist,
|
|
workstation,
|
|
taskdetail,
|
|
operationlist,
|
|
reportingwork,
|
|
terlogout
|
|
} from '@/api/proterminal'
|
|
|
|
|
|
//import { dictDataApi } from '@/api/org'
|
|
|
|
|
|
// import { submitLogApi } from '@/api/submitLog'
|
|
|
|
// import { SysUser, userApi } from '@/api/system'
|
|
// import { label } from 'three/tsl'
|
|
|
|
//const dialog = useDialog()
|
|
const message = useMessage()
|
|
|
|
const userStore = useUserStore()
|
|
|
|
//刷新
|
|
function refresh() {
|
|
location.reload()
|
|
}
|
|
|
|
//是否平板
|
|
let tablet = ref(false)
|
|
|
|
|
|
//全屏
|
|
let isfullscr = ref(false)
|
|
|
|
//浏览器全屏
|
|
function requestFullscreen() {
|
|
document.documentElement.requestFullscreen()
|
|
isfullscr.value = true
|
|
}
|
|
|
|
//退出全屏
|
|
function exitFullscreen() {
|
|
document.exitFullscreen()
|
|
isfullscr.value = false
|
|
}
|
|
|
|
function toFixed2(m:number,d:number) {
|
|
if(m == 0){
|
|
return '0.00'
|
|
}
|
|
return ((m/d)*100).toFixed(2)
|
|
}
|
|
|
|
function setw(m:number,d:number) {
|
|
if((m/d*100) < 1 && (m/d*100) > 0){
|
|
return '1%'
|
|
}
|
|
return (m/d*100).toFixed(2)+'%'
|
|
}
|
|
|
|
//工单状态
|
|
const ticketStatus :any = {
|
|
1:'待执行',
|
|
2:'执行中',
|
|
3:'质检中',
|
|
4:'流转中',
|
|
5:'已完成',
|
|
6:'部分质检中',
|
|
7:'部分流转中',
|
|
8:'部分完成'
|
|
}
|
|
|
|
//日志类型
|
|
const operationType :any = {
|
|
'-1':'登出',
|
|
'0':'登入',
|
|
'1':'开始',
|
|
'2':'暂停',
|
|
'3':'报工',
|
|
'4':'撤回',
|
|
'5':'叫料',
|
|
'6':'调车',
|
|
'7':'工位交接',
|
|
'8':'工位交接确认'
|
|
}
|
|
|
|
|
|
let queryparam = reactive<any>({
|
|
type:1,
|
|
id:''
|
|
})
|
|
|
|
const typeopt = reactive<any>([
|
|
{
|
|
label: '全部',
|
|
value: 1
|
|
},
|
|
{
|
|
label: '只看本机台',
|
|
value: 2
|
|
},
|
|
{
|
|
label: '只看当前用户',
|
|
value: 3
|
|
}
|
|
])
|
|
|
|
//报工
|
|
let baogformRef = ref()
|
|
let baogdata = reactive<any>({
|
|
id:'', //派工单id
|
|
qcNum:'', //质检数量
|
|
okData:{
|
|
qty:'' //合格数
|
|
},
|
|
scrapData:{
|
|
qty:'' //不合格数
|
|
}
|
|
|
|
// qualified:'', //合格数
|
|
// unqualified:'', //不合格数
|
|
// total:'' //总数
|
|
})
|
|
let baogrules = {
|
|
'okData.qty': [
|
|
{
|
|
required: true,
|
|
trigger: ['blur', 'input'],
|
|
message: '请输入合格数'
|
|
}
|
|
],
|
|
'scrapData.qty':[
|
|
{
|
|
required: true,
|
|
trigger: ['blur', 'input'],
|
|
message: '请输入不合格数'
|
|
}
|
|
]
|
|
}
|
|
|
|
watch(() => baogdata.okData.qty,(v:any) => {
|
|
baogdata.okData.qty = v.replace(/[^\d]/g,'').replace(/^0+(?=\d)/, '')
|
|
baogdata.qcNum = baogdata.okData.qty*1 + baogdata.scrapData.qty*1
|
|
})
|
|
watch(() => baogdata.scrapData.qty,(v:any) => {
|
|
baogdata.scrapData.qty = v.replace(/[^\d]/g,'').replace(/^0+(?=\d)/, '')
|
|
baogdata.qcNum = baogdata.okData.qty*1 + baogdata.scrapData.qty*1
|
|
})
|
|
|
|
//确认报工
|
|
function confireport() {
|
|
if(baogdata.qcNum == 0){
|
|
message.warning('请输入报工数量')
|
|
}else if(baogdata.qcNum > (gddetail.value.assingWorkTotalNum - gddetail.value.assingWorkProductionTotalNum)){
|
|
message.warning('报工总数大于可报工数量')
|
|
}else{
|
|
reportingwork(baogdata).then(() => {
|
|
message.success('操作成功')
|
|
})
|
|
}
|
|
// baogformRef.value?.validate((e:any) => {
|
|
// if (!e) {
|
|
// reportingwork(baogdata)
|
|
// message.success('操作成功')
|
|
// }
|
|
// })
|
|
}
|
|
|
|
|
|
//工单切换
|
|
|
|
let gdinfo = ref<any>({})
|
|
let gdindex = ref<any>(0)
|
|
let gddetail = ref<any>({})
|
|
|
|
function getgd(i:any,n:any){
|
|
|
|
baogdata.okData.qty = ''
|
|
baogdata.scrapData.qty = ''
|
|
|
|
gdinfo.value = n
|
|
let wsdinfo = JSON.parse(sessionStorage.getItem('gwdata') as string)
|
|
baogdata.id = n.id
|
|
gdindex.value = i
|
|
taskdetail({
|
|
userId: userStore.userid,
|
|
assingWorkId: n.id,
|
|
...wsdinfo
|
|
//code: "string"
|
|
}).then(rps => {
|
|
gddetail.value = rps
|
|
})
|
|
}
|
|
|
|
//工序切换
|
|
let gonxindex = ref<any>(0)
|
|
function gxtab(i:any) {
|
|
gonxindex.value = i
|
|
}
|
|
|
|
//工位交接
|
|
let handoverpop = ref(false)
|
|
function handover() {
|
|
handoverpop.value = true
|
|
}
|
|
|
|
//作业指导书
|
|
let guidanpop = ref(false)
|
|
|
|
function guizds() {
|
|
guidanpop.value = true
|
|
}
|
|
|
|
//绑定
|
|
let islogin = ref<any>(sessionStorage.getItem('gwlogin'))
|
|
|
|
let logindata = reactive<any>({
|
|
workshopId: null, //所属车间id
|
|
sectionId: null, //所属工段id
|
|
deviceId: null, //所属工位id
|
|
|
|
// workshop:'', //所属车间
|
|
// section:'', //所属工段
|
|
// workstation:'' //所属工位
|
|
})
|
|
let loginrules = {
|
|
// workshop: [
|
|
// {
|
|
// required: true,
|
|
// trigger: ['blur', 'input'],
|
|
// message: '请选择所属车间'
|
|
// }
|
|
// ],
|
|
// section: [
|
|
// {
|
|
// required: true,
|
|
// trigger: ['blur', 'input'],
|
|
// message: '请选择所属工段'
|
|
// }
|
|
// ],
|
|
// workstation: [
|
|
// {
|
|
// required: true,
|
|
// trigger: ['blur', 'input'],
|
|
// message: '请选择所属工位'
|
|
// }
|
|
// ]
|
|
}
|
|
const loginformRef =ref()
|
|
|
|
//所属车间
|
|
let workshoplist = ref<any>([])
|
|
|
|
//所属工段
|
|
let sectionlist =ref<any>([])
|
|
|
|
//所属工位
|
|
let workstationlist = ref<any>([])
|
|
|
|
//所属工段集合
|
|
let secobj = ref<any>({})
|
|
|
|
//所属工位集合
|
|
let wkstobj = ref<any>({})
|
|
|
|
//日志列表
|
|
let loglist = ref<any>([])
|
|
|
|
let wkdata = JSON.parse(sessionStorage.getItem('gwdata') as string)
|
|
|
|
let pgcode = ref<any>('')
|
|
|
|
function getrwlist(data:any) {
|
|
tasklist(data).then(rps => {
|
|
if(rps && rps.length > 0){
|
|
taskdata.value = rps
|
|
getgd(0,taskdata.value[0])
|
|
}
|
|
})
|
|
}
|
|
|
|
function queryhand() {
|
|
getrwlist({
|
|
userId: userStore.userid,
|
|
...wkdata,
|
|
code:pgcode.value
|
|
})
|
|
}
|
|
|
|
function init() {
|
|
if(islogin.value == '1'){
|
|
getrwlist({
|
|
userId: userStore.userid,
|
|
...wkdata,
|
|
code:''
|
|
})
|
|
|
|
|
|
|
|
operationlist({
|
|
userId: userStore.userid,
|
|
//...logindata,
|
|
}).then(rps => {
|
|
if(rps && rps){
|
|
loglist.value = rps
|
|
}
|
|
})
|
|
|
|
}else{
|
|
//工位选项
|
|
workstation(userStore.userid).then((rps:any) => {
|
|
if(rps && rps.length > 0){
|
|
workshoplist.value = rps.map((n:any) => {
|
|
return {
|
|
label: n.value,
|
|
value:n.key
|
|
}
|
|
})
|
|
rps.forEach((n:any) => {
|
|
let list = n.childList.map((m:any) => {
|
|
return {
|
|
label:m.value,
|
|
value:m.key,
|
|
childList:m.childList
|
|
}
|
|
})
|
|
secobj.value[n.key] = list
|
|
})
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
|
|
function wkupdate(v:any,n:any) {
|
|
//let arr = secobj.value[n.value]
|
|
sectionlist.value = secobj.value[n.value]
|
|
sectionlist.value.forEach((j:any) => {
|
|
let list = j.childList.map((m:any) => {
|
|
return {
|
|
label:m.value,
|
|
value:m.key
|
|
}
|
|
})
|
|
wkstobj.value[j.key] = list
|
|
// return {
|
|
// label:j.value,
|
|
// Value:j.key
|
|
// }
|
|
})
|
|
|
|
console.log(sectionlist.value)
|
|
|
|
}
|
|
|
|
function secupdate(v:any,n:any) {
|
|
workstationlist.value = n.childList.map((n:any) => {
|
|
return {
|
|
label:n.value,
|
|
value:n.key
|
|
}
|
|
})
|
|
}
|
|
|
|
|
|
let mbxone = ref(sessionStorage.getItem('mbxone'))
|
|
let mbtwo = ref(sessionStorage.getItem('mbtwo'))
|
|
let mbthree = ref(sessionStorage.getItem('mbthree'))
|
|
|
|
function renderlabel(n:any) {
|
|
mbxone.value = n.label
|
|
sessionStorage.setItem('mbxone',n.label)
|
|
return n.label
|
|
}
|
|
|
|
function renderlabeltwo(n:any) {
|
|
mbtwo.value = n.label
|
|
sessionStorage.setItem('mbtwo',n.label)
|
|
return n.label
|
|
}
|
|
|
|
function renderlabelthree(n:any) {
|
|
mbthree.value = n.label
|
|
sessionStorage.setItem('mbthree',n.label)
|
|
return n.label
|
|
}
|
|
|
|
//任务列表
|
|
let taskdata = ref<any>([])
|
|
|
|
//登录绑定
|
|
function loginhand() {
|
|
loginformRef.value?.validate((e:any) => {
|
|
if (!e) {
|
|
message.success('绑定成功')
|
|
//tasklist()
|
|
sessionStorage.setItem('gwlogin','1')
|
|
sessionStorage.setItem('gwdata',JSON.stringify(logindata))
|
|
|
|
islogin.value = '1'
|
|
|
|
getrwlist({
|
|
userId: userStore.userid,
|
|
...logindata,
|
|
code:''
|
|
})
|
|
}
|
|
})
|
|
}
|
|
|
|
|
|
//登录
|
|
//登录
|
|
let formData = reactive({
|
|
username:'',
|
|
password:''
|
|
})
|
|
|
|
|
|
function handleLogin() {
|
|
formData.username = formData.username.trim()
|
|
formData.password = formData.password.trim()
|
|
if(formData.username == ''){
|
|
message.warning('请输入用户名')
|
|
}else if(formData.password == ''){
|
|
message.warning('请输入密码')
|
|
}else {
|
|
userStore.login(formData).then(() => {
|
|
message.success('登录成功')
|
|
sessionStorage.setItem('gwlogin','1')
|
|
islogin.value = '1'
|
|
getrwlist({
|
|
userId: userStore.userid,
|
|
...logindata,
|
|
code:''
|
|
})
|
|
|
|
operationlist({
|
|
userId: userStore.userid,
|
|
//...logindata,
|
|
}).then(rps => {
|
|
loglist.value = rps
|
|
})
|
|
})
|
|
}
|
|
|
|
}
|
|
|
|
|
|
//切换工位
|
|
function switchworks() {
|
|
sessionStorage.setItem('gwlogin','0')
|
|
islogin.value = '0'
|
|
}
|
|
|
|
init()
|
|
|
|
onMounted(() => {
|
|
|
|
// getlist()
|
|
// getUserList()
|
|
// loadDictOptions()
|
|
//workload()
|
|
|
|
|
|
|
|
// 初始显示 0%
|
|
//setProgress(50)
|
|
|
|
window.addEventListener('resize', () => {
|
|
const width = window.innerWidth
|
|
if(width < 1024){
|
|
tablet.value = true
|
|
}else{
|
|
tablet.value = false
|
|
}
|
|
// if (width < 768) {
|
|
// console.log('手机模式')
|
|
// } else if (width < 1024) {
|
|
// console.log('平板模式')
|
|
// } else {
|
|
// console.log('桌面模式')
|
|
// }
|
|
})
|
|
|
|
//监听是否全屏 fullscreenchange
|
|
window.addEventListener('resize', () => {
|
|
if(window.innerHeight === screen.height){
|
|
isfullscr.value = true
|
|
}else{
|
|
isfullscr.value = false
|
|
}
|
|
})
|
|
|
|
})
|
|
</script>
|
|
|
|
<style scoped>
|
|
/deep/.n-base-selection .n-base-selection__border, .n-base-selection .n-base-selection__state-border{
|
|
/* background-color:#1b3752; */
|
|
border:1px solid #817e7e;
|
|
/* color: #fff; */
|
|
}
|
|
</style>
|
|
|
|
<style scoped lang="scss">
|
|
|
|
.conten{
|
|
/* width: 100vw; */
|
|
height: 100vh;
|
|
|
|
color: #fff;
|
|
background: linear-gradient(45deg, #010b1a 0%, #45679b 100%);
|
|
.head{
|
|
display: flex;
|
|
height: 70px;
|
|
padding-right:10px;
|
|
justify-content: space-between;
|
|
background:#041b3f; //linear-gradient(0deg, #31558f 0%, #152d52 100%);
|
|
>div{
|
|
display: flex;
|
|
align-items: center;
|
|
.mbx{
|
|
display: flex;
|
|
align-items: center;
|
|
font-size: 18px;
|
|
>div{
|
|
//margin-right: 20px;
|
|
padding:5px 10px;
|
|
//border: 1px dashed #ccc;
|
|
|
|
//background: #2c4970;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.total{
|
|
padding: 20px;
|
|
display: flex;
|
|
justify-content:space-between;
|
|
>div{
|
|
box-sizing: border-box;
|
|
width: 19%;
|
|
height: 100px;
|
|
padding:10px 15px;
|
|
border: 4px double #d4d4d4;
|
|
// border: 4px solid;
|
|
// border-image: linear-gradient(
|
|
// 135deg,
|
|
// #f0f0f0,
|
|
// #8a8a8a,
|
|
// #595959,
|
|
// #b6b4b4
|
|
// ) 1;
|
|
border-radius: 10px;
|
|
}
|
|
}
|
|
.mocz{
|
|
width: 100%;
|
|
height: 600px;
|
|
//border-radius: 30px;
|
|
border: 3px solid;
|
|
border-image: linear-gradient(
|
|
135deg,
|
|
#d3d2d2,
|
|
#8a8a8a,
|
|
#868686,
|
|
#b6b4b4
|
|
) 1;
|
|
.gditem{
|
|
box-sizing: border-box;
|
|
width: 100%;
|
|
margin-bottom: 15px;
|
|
padding: 10px;
|
|
background: #2d475c;
|
|
border-radius: 10px;
|
|
cursor: pointer;
|
|
}
|
|
.gdactv{
|
|
background: #0c5207;
|
|
}
|
|
// box-shadow: 0 0 20px -5px rgba(84, 151, 232, 0.5);
|
|
}
|
|
.gonxactv{
|
|
border: 2px solid #d18610;border-radius: 10px;
|
|
}
|
|
.mybtn{
|
|
box-sizing:border-box;
|
|
display: flex;
|
|
width: 120px;
|
|
height: 60px;
|
|
align-items: center;
|
|
justify-content: center;
|
|
line-height: 60px;
|
|
border-radius: 10px;
|
|
font-size: 20px;
|
|
background: #007f5b;
|
|
cursor: pointer;
|
|
}
|
|
}
|
|
.progress-container {
|
|
display: inline-block;
|
|
position: relative;
|
|
width: 90px;
|
|
height: 90px;
|
|
}
|
|
.progress-container svg {
|
|
transform: rotate(-90deg);
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
.progress-container .bg {
|
|
stroke: #e6e6e6;
|
|
}
|
|
.progress-container .progress {
|
|
stroke: #4caf50;
|
|
stroke-linecap: round;
|
|
transition: stroke-dashoffset 0.6s ease;
|
|
}
|
|
.progress-container .label {
|
|
position: absolute;
|
|
top: 50%;
|
|
left: 50%;
|
|
transform: translate(-50%, -50%);
|
|
font-size: 18px;
|
|
font-weight: bold;
|
|
color: #c5c5c5;
|
|
}
|
|
</style>
|