| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361 |
- <template>
- <view class="achievement-card" @click="$emit('click')" hover-class="card-hover">
- <!-- 右上角角标状态 - 采用全局统一样式 -->
- <view class="status-tag" :class="statusInfo.type">
- {{ statusInfo.text }}
- </view>
- <view class="card-header">
- <view class="title-box">
- <text class="title">{{ title }}</text>
- </view>
- </view>
-
- <view class="card-content">
- <!-- 创建人 -->
- <view class="info-item" v-if="creator">
- <text class="label">创建人:</text>
- <text class="value">{{ creator }}</text>
- </view>
- <!-- 所属部门 -->
- <view class="info-item" v-if="org">
- <text class="label">所属部门:</text>
- <text class="value">{{ org }}</text>
- </view>
- <!-- 创建时间 -->
- <view class="info-item" v-if="createTime">
- <text class="label">创建时间:</text>
- <text class="value">{{ createTime }}</text>
- </view>
- </view>
-
- <view class="card-footer">
- <view class="type-pill" :class="'type-' + type">
- <uv-icon :name="typeIcon" size="12" :color="typeColor"></uv-icon>
- <text class="type-name" :style="{ color: typeColor }">{{ typeName }}</text>
- </view>
- <view class="click-tip">
- <text>查看详情</text>
- <uv-icon name="arrow-right" size="12" color="#cbd5e1"></uv-icon>
- </view>
- </view>
- </view>
- </template>
- <script setup lang="ts">
- import { computed } from 'vue';
- const props = defineProps<{
- item: any;
- type: string;
- }>();
- defineEmits(['click']);
- const title = computed(() => {
- return props.item.patentName || props.item.softwareName || props.item.achievementName ||
- props.item.standardName || props.item.reportTitle || props.item.workName ||
- props.item.awardCode || props.item.paperName || props.item.codTitle ||
- props.item.activityName || '未命名成果';
- });
- const creator = computed(() => {
- return props.item.createdName || props.item.createBy || '-';
- });
- const createTime = computed(() => {
- const d = props.item.createdTime || props.item.createTime || '';
- if (!d) return '-';
- return d.substring(0, 10);
- });
- const org = computed(() => {
- return props.item.deptName || props.item.organization || props.item.belongUnit ||
- props.item.achievementOwnerUnit || props.item.achievementBelongUnitName || '-';
- });
- const typeName = computed(() => {
- const names: any = {
- patent: '专利',
- software: '软著',
- other: '其他成果',
- standard: '标准',
- decision: '决策咨询',
- work: '学术著作',
- awards: '奖项荣誉',
- paper: '学术论文',
- conference: '学术会议',
- special_activity: '科技专项活动'
- };
- return names[props.type] || '成果';
- });
- const typeIcon = computed(() => {
- const icons: any = {
- patent: 'integral',
- software: 'file-text',
- other: 'grid',
- standard: 'tags',
- decision: 'chat',
- work: 'file-text',
- awards: 'gift',
- paper: 'list',
- conference: 'mic',
- special_activity: 'calendar'
- };
- return icons[props.type] || 'file-text';
- });
- const typeColor = computed(() => {
- const colors: any = {
- patent: '#3b82f6',
- software: '#10b981',
- other: '#f59e0b',
- standard: '#ef4444',
- decision: '#8b5cf6',
- work: '#06b6d4',
- awards: '#f43f5e',
- paper: '#14b8a6',
- conference: '#6366f1',
- special_activity: '#f97316'
- };
- return colors[props.type] || '#3b82f6';
- });
- const statusInfo = computed(() => {
- const type = props.type;
- const item = props.item;
-
- if (type === 'patent') {
- const s = String(item.patentStatus);
- const map: any = {
- '10': { text: '初始', type: 'primary' },
- '20': { text: '待审批', type: 'primary' },
- '30': { text: '专利审批中', type: 'info' },
- '40': { text: '专利审批通过', type: 'success' },
- '50': { text: '专利审批拒绝', type: 'error' },
- '60': { text: '转化审批中', type: 'info' },
- '70': { text: '转化成功', type: 'success' },
- '80': { text: '转化失败', type: 'error' },
- '90': { text: '专利授权审批中', type: 'info' },
- '100': { text: '专利授权审批通过', type: 'success' },
- '110': { text: '专利授权审批不通过', type: 'error' },
- };
- return map[s] || { text: '未知', type: 'info' };
- }
-
- if (type === 'software' || type === 'other') {
- const s = String(item.status);
- const map: any = {
- '10': { text: '初始', type: 'primary' },
- '20': { text: '审批中', type: 'info' },
- '30': { text: '审批通过', type: 'success' },
- '40': { text: '审批拒绝', type: 'error' },
- };
- return map[s] || { text: '未知', type: 'info' };
- }
-
- if (type === 'standard') {
- const s = String(item.approveStatus);
- const map: any = {
- '10': { text: '待提交', type: 'primary' },
- '20': { text: '待审批', type: 'primary' },
- '30': { text: '已通过', type: 'success' },
- '40': { text: '已拒绝', type: 'error' },
- '50': { text: '已取消', type: 'info' },
- '60': { text: '已撤回', type: 'info' },
- };
- return map[s] || { text: '未知', type: 'info' };
- }
-
- if (type === 'decision') {
- const s = String(item.status);
- const map: any = {
- '10': { text: '待提交', type: 'primary' },
- '20': { text: '审批中', type: 'info' },
- '30': { text: '审批通过', type: 'success' },
- '40': { text: '审批驳回', type: 'error' },
- };
- return map[s] || { text: '未知', type: 'info' };
- }
-
- if (type === 'work') {
- const s = String(item.workStatus);
- const map: any = {
- '10': { text: '初始', type: 'primary' },
- '20': { text: '待审批', type: 'primary' },
- '30': { text: '审批中', type: 'info' },
- '40': { text: '审批通过', type: 'success' },
- '50': { text: '审批拒绝', type: 'error' },
- };
- return map[s] || { text: '未知', type: 'info' };
- }
-
- if (type === 'awards') {
- const s = String(item.awardStatus);
- const map: any = {
- '10': { text: '初始', type: 'primary' },
- '20': { text: '待审批', type: 'primary' },
- '30': { text: '奖项荣誉审批中', type: 'info' },
- '40': { text: '奖项荣誉审批通过', type: 'success' },
- '50': { text: '奖项荣誉审批拒绝', type: 'error' },
- '90': { text: '登记审批中', type: 'info' },
- '100': { text: '登记审批通过', type: 'success' },
- '110': { text: '登记审批拒绝', type: 'error' },
- };
- return map[s] || { text: '未知', type: 'info' };
- }
-
- if (type === 'paper') {
- const s = String(item.paperStatus);
- const map: any = {
- '10': { text: '初始', type: 'primary' },
- '20': { text: '待审批', type: 'primary' },
- '30': { text: '审批中', type: 'info' },
- '40': { text: '审批通过', type: 'success' },
- '50': { text: '审批拒绝', type: 'error' },
- };
- return map[s] || { text: '未知', type: 'info' };
- }
- if (type === 'conference') {
- const s = String(item.approvalStatus);
- const map: any = {
- '10': { text: '待提交', type: 'primary' },
- '20': { text: '审批中', type: 'info' },
- '30': { text: '审批通过', type: 'success' },
- '40': { text: '审批退回', type: 'error' },
- };
- return map[s] || { text: '未知', type: 'info' };
- }
- if (type === 'special_activity') {
- const s = Number(item.auditStatus);
- const map: any = {
- 0: { text: '待审核', type: 'primary' },
- 1: { text: '驳回', type: 'error' },
- 2: { text: '再次提交', type: 'primary' },
- 3: { text: '审核通过', type: 'success' },
- };
- return map[s] || { text: '未知', type: 'info' };
- }
- return { text: '未知', type: 'info' };
- });
- </script>
- <style lang="scss" scoped>
- .achievement-card {
- background-color: #ffffff;
- border-radius: 20rpx;
- padding: 40rpx 30rpx 30rpx;
- margin-bottom: 28rpx;
- box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.03);
- position: relative;
- overflow: hidden;
- border: 1rpx solid #f1f5f9;
- }
- .status-tag {
- position: absolute;
- top: 0;
- right: 0;
- padding: 8rpx 24rpx;
- font-size: 22rpx;
- font-weight: bold;
- color: #ffffff;
- border-bottom-left-radius: 20rpx;
- z-index: 5;
-
- &.primary { background-color: #3b82f6; }
- &.success { background-color: #10b981; }
- &.error { background-color: #ef4444; }
- &.warning { background-color: #f59e0b; }
- &.info { background-color: #94a3b8; }
- }
- .card-header {
- margin-bottom: 24rpx;
- padding-right: 140rpx;
-
- .title {
- font-size: 32rpx;
- font-weight: 600;
- color: #1e293b;
- line-height: 1.5;
- display: -webkit-box;
- -webkit-box-orient: vertical;
- -webkit-line-clamp: 2;
- overflow: hidden;
- }
- }
- .card-content {
- .info-item {
- display: flex;
- justify-content: space-between;
- align-items: flex-start;
- margin-bottom: 16rpx;
- font-size: 26rpx;
- line-height: 36rpx;
-
- .label {
- color: #94a3b8;
- width: 140rpx;
- flex-shrink: 0;
- }
-
- .value {
- color: #334155;
- flex: 1;
- text-align: right;
- font-weight: 400;
- word-break: break-all;
-
- &.highlight {
- color: #3b82f6;
- }
- }
- }
- }
- .card-footer {
- margin-top: 24rpx;
- padding-top: 24rpx;
- border-top: 1rpx solid #f1f5f9;
- display: flex;
- justify-content: space-between;
- align-items: center;
-
- .type-pill {
- display: flex;
- align-items: center;
- background-color: #f8fafc;
- padding: 6rpx 20rpx;
- border-radius: 100rpx;
- gap: 8rpx;
- border: 1rpx solid #f1f5f9;
-
- .type-name {
- font-size: 22rpx;
- font-weight: bold;
- }
- }
-
- .click-tip {
- display: flex;
- align-items: center;
- gap: 4rpx;
- text {
- font-size: 24rpx;
- color: #cbd5e1;
- }
- }
- }
- .card-hover {
- background-color: #fafbfc;
- }
- </style>
|