feat: 工作流支持自定义颜色

This commit is contained in:
kuaifan 2025-08-01 11:27:00 +08:00
parent 02544d29fd
commit e792ab7b4d
27 changed files with 397 additions and 243 deletions

View File

@ -2367,7 +2367,7 @@ class ProjectController extends AbstractController
$task->updateTask($data, $updateMarking);
//
$data = ProjectTask::oneTask($task->id)->toArray();
$data["flow_item_name"] = $newFlowItem->status . "|" . $newFlowItem->name;
$data["flow_item_name"] = $newFlowItem->status . "|" . $newFlowItem->name . "|" . $newFlowItem->color;
$data['update_marking'] = $updateMarking ?: json_decode('{}');
$task->pushMsg('update', $data);
//
@ -2424,7 +2424,7 @@ class ProjectController extends AbstractController
]);
}
//
$turns = ProjectFlowItem::select(['id', 'name', 'status', 'turns'])->whereFlowId($projectFlow->id)->orderBy('sort')->get();
$turns = ProjectFlowItem::select(['id', 'name', 'status', 'turns', 'color'])->whereFlowId($projectFlow->id)->orderBy('sort')->get();
if (empty($projectFlowItem)) {
$data = [
'task_id' => $projectTask->id,

View File

@ -423,24 +423,25 @@ class Project extends AbstractModel
$projectUserids = $this->relationUserids();
foreach ($flows as $item) {
$id = intval($item['id']);
$name = trim(str_replace('|', '·', $item['name']));
$turns = Base::arrayRetainInt($item['turns'] ?: [], true);
$userids = Base::arrayRetainInt($item['userids'] ?: [], true);
$usertype = trim($item['usertype']);
$userlimit = intval($item['userlimit']);
$columnid = intval($item['columnid']);
if ($usertype == 'replace' && empty($userids)) {
throw new ApiException("状态[{$item['name']}]设置错误,设置流转模式时必须填写状态负责人");
throw new ApiException("状态[{$name}]设置错误,设置流转模式时必须填写状态负责人");
}
if ($usertype == 'merge' && empty($userids)) {
throw new ApiException("状态[{$item['name']}]设置错误,设置剔除模式时必须填写状态负责人");
throw new ApiException("状态[{$name}]设置错误,设置剔除模式时必须填写状态负责人");
}
if ($userlimit && empty($userids)) {
throw new ApiException("状态[{$item['name']}]设置错误,设置限制负责人时必须填写状态负责人");
throw new ApiException("状态[{$name}]设置错误,设置限制负责人时必须填写状态负责人");
}
foreach ($userids as $userid) {
if (!in_array($userid, $projectUserids)) {
$nickname = User::userid2nickname($userid);
throw new ApiException("状态[{$item['name']}]设置错误,状态负责人[{$nickname}]不在项目成员内");
throw new ApiException("状态[{$name}]设置错误,状态负责人[{$nickname}]不在项目成员内");
}
}
$flow = ProjectFlowItem::updateInsert([
@ -448,8 +449,9 @@ class Project extends AbstractModel
'project_id' => $this->id,
'flow_id' => $projectFlow->id,
], [
'name' => trim($item['name']),
'name' => $name,
'status' => trim($item['status']),
'color' => trim($item['color']),
'sort' => intval($item['sort']),
'turns' => $turns,
'userids' => $userids,
@ -469,7 +471,7 @@ class Project extends AbstractModel
$hasEnd = true;
}
if (!$isInsert) {
$upTaskList[$flow->id] = $flow->status . "|" . $flow->name;
$upTaskList[$flow->id] = $flow->status . "|" . $flow->name . "|" . $flow->color;
}
}
}

View File

@ -12,6 +12,7 @@ use App\Module\Base;
* @property int|null $flow_id 流程ID
* @property string|null $name 名称
* @property string|null $status 状态
* @property string|null $color 自定义颜色
* @property array $turns 可流转
* @property array $userids 状态负责人ID
* @property string|null $usertype 流转模式
@ -38,6 +39,7 @@ use App\Module\Base;
* @method static \Illuminate\Database\Eloquent\Builder|ProjectFlowItem whereProjectId($value)
* @method static \Illuminate\Database\Eloquent\Builder|ProjectFlowItem whereSort($value)
* @method static \Illuminate\Database\Eloquent\Builder|ProjectFlowItem whereStatus($value)
* @method static \Illuminate\Database\Eloquent\Builder|ProjectFlowItem whereColor($value)
* @method static \Illuminate\Database\Eloquent\Builder|ProjectFlowItem whereTurns($value)
* @method static \Illuminate\Database\Eloquent\Builder|ProjectFlowItem whereUpdatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|ProjectFlowItem whereUserids($value)

View File

@ -485,7 +485,7 @@ class ProjectTask extends AbstractModel
foreach ($projectFlowItem as $item) {
if ($item->status == 'start') {
$task->flow_item_id = $item->id;
$task->flow_item_name = $item->status . "|" . $item->name;
$task->flow_item_name = $item->status . "|" . $item->name . "|" . $item->color;
$owner = array_merge($owner, $item->userids);
break;
}
@ -649,7 +649,7 @@ class ProjectTask extends AbstractModel
$data['column_id'] = $newFlowItem->columnid;
}
$this->flow_item_id = $newFlowItem->id;
$this->flow_item_name = $newFlowItem->status . "|" . $newFlowItem->name;
$this->flow_item_name = $newFlowItem->status . "|" . $newFlowItem->name . "|" . $newFlowItem->color;
$this->addLog("修改{任务}状态", [
'flow' => $flowData,
'change' => [$currentFlowItem?->name, $newFlowItem->name]
@ -1907,7 +1907,7 @@ class ProjectTask extends AbstractModel
// 更新任务流程
$flowItem = projectFlowItem::whereProjectId($projectId)->whereId($flowItemId)->first();
$this->flow_item_id = $flowItemId;
$this->flow_item_name = $flowItem->status . "|" . $flowItem->name;
$this->flow_item_name = $flowItem->status . "|" . $flowItem->name . "|" . $flowItem->color;
if ($flowItem->status == 'end') {
$this->completeTask(Carbon::now(), $flowItem->name);
} else {

View File

@ -40,7 +40,7 @@ class LoopTask extends AbstractTask
foreach ($projectFlowItem as $flowItem) {
if ($flowItem->status == 'start') {
$task->flow_item_id = $flowItem->id;
$task->flow_item_name = $flowItem->status . "|" . $flowItem->name;
$task->flow_item_name = $flowItem->status . "|" . $flowItem->name . "|" . $flowItem->color;
if ($flowItem->userids) {
$userids = array_values(array_unique($flowItem->userids));
foreach ($userids as $uid) {

View File

@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddColorToProjectFlowItemsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('project_flow_items', function (Blueprint $table) {
if (!Schema::hasColumn('project_flow_items', 'color')) {
$table->string('color', 20)->nullable()->default('')->after('status')->comment('自定义颜色');
}
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('project_flow_items', function (Blueprint $table) {
$table->dropColumn('color');
});
}
}

View File

@ -692,6 +692,71 @@ import {convertLocalResourcePath} from "../components/Replace/utils";
return secondLast;
}
return "";
},
/**
* 根据十六进制颜色生成通用 CSS 变量样式
* @param {string} hexColor - 颜色值格式如 "#RRGGBB"
* @param {number[]} levels - 需要生成的透明度等级数组 [10, 20, 70]代表 10%20%70%
* @param {string} prefix - 生成的 CSS 变量前缀默认为 'custom-color'
* @param {Object|null} styles - 可选的样式对象如果未传入则会创建一个新的对象
* @returns {Object|null} 返回包含 CSS 变量的对象若未传入颜色则返回 null
*/
generateColorVarStyle(hexColor, levels = [], prefix = 'custom-color', styles = null) {
if (typeof hexColor !== 'string' || !/^#([0-9a-fA-F]{6})$/.test(hexColor)) {
return styles;
}
// 解析十六进制颜色为 RGB
const r = parseInt(hexColor.substring(1, 3), 16);
const g = parseInt(hexColor.substring(3, 5), 16);
const b = parseInt(hexColor.substring(5, 7), 16);
// 初始化样式对象
if (!$A.isJson(styles)) {
styles = {};
}
// 遍历 levels生成对应透明度的 rgba 变量
levels.forEach(level => {
// 只处理有效的数字
if (typeof level === 'number' && level >= 0 && level <= 100) {
const alpha = Math.round((level / 100) * 100) / 100; // 保留两位小数
styles[`--${prefix}-${level}`] = `rgba(${r}, ${g}, ${b}, ${alpha})`;
}
});
// 加上 100% 不透明度直接用 hexColor
styles[`--${prefix}-100`] = hexColor
return styles;
},
/**
* 转换工作流状态
* @param {string|{flow_item_name, complete_at}} item
* @returns {{status: null, name: string, color: null}}
*/
convertWorkflow(item) {
let status = null,
name = item,
color = null;
if ($A.isJson(item)) {
name = item.flow_item_name
if (name.indexOf("|") === -1) {
if (name.complete_at) {
name = $A.L('已完成');
} else {
name = $A.L('未完成');
}
}
}
if (name && name.indexOf("|") !== -1) {
const arr = `${name}||`.split("|")
status = arr[0]
name = arr[1]
color = arr[2]
}
return {status, name, color}
}
});

View File

@ -36,6 +36,7 @@
v-for="(item, key) in taskBrowseLists"
v-if="item.id > 0 && key < 10"
:key="key"
:style="$A.generateColorVarStyle(item.flow_item_color, [10], 'flow-item-custom-color')"
class="task-title"
@click.native="openTask(item)"
:name="item.name">

View File

@ -128,7 +128,6 @@
<EDropdown
v-else
trigger="click"
size="small"
@command="dropColumn(column, $event)">
<Icon type="ios-more" />
<EDropdownMenu slot="dropdown" class="project-panel-more-dropdown-menu">
@ -181,9 +180,10 @@
@remove="sortUpdate">
<div
v-for="item in column.tasks"
:key="`${column.id}_${item.id}`"
:data-id="item.id"
:class="['task-item task-draggable', item.complete_at ? 'complete' : '', taskIsHidden(item) ? 'hidden' : '']"
:style="taskItemStyle(item)"
:style="$A.generateColorVarStyle(item.flow_item_color, [10], 'flow-item-custom-color', taskItemStyle(item))"
@click="openTask(item)">
<template v-if="taskItemVisible(item)">
<div :class="['task-head', item.desc ? 'has-desc' : '']">
@ -973,7 +973,8 @@ export default {
value: item2.id,
label: `${item2.name} (${length})`,
status: item2.status,
class: item2.status
class: item2.status,
style: $A.generateColorVarStyle(item2.color, [10], 'flow-item-custom-color'),
}
})
}

View File

@ -13,7 +13,13 @@
<div class="workflow-item">
<div class="workflow-name">{{data.name}}</div>
<div class="workflow-status">
<div v-for="item in data.project_flow_item" :class="item.status">{{item.name}}</div>
<div
v-for="item in data.project_flow_item"
:key="item.id"
:class="item.status"
:style="$A.generateColorVarStyle(item.color, [10], 'flow-item-custom-color')">
{{item.name}}
</div>
</div>
<div class="workflow-save" @click.stop="">
<template v-if="contrast(data.project_flow_item, data.project_flow_bak)">
@ -57,7 +63,7 @@
</div>
<div class="taskflow-config-table-block hr">
<div class="taskflow-config-table-block-title">{{$L('可流转到')}}</div>
<div v-for="item in data.project_flow_item" class="taskflow-config-table-block-item">
<div v-for="item in data.project_flow_item" :key="item.id" class="taskflow-config-table-block-item">
<span class="transform-status-name">{{item.name}}</span>
</div>
</div>
@ -71,8 +77,13 @@
class="taskflow-config-table-list-wrapper"
tag="div"
draggable=".column-border"
@sort="">
<div v-for="item in data.project_flow_item" class="taskflow-config-table-status-column column-border" :class="item.status">
@sort="() => {}">
<div
v-for="(item, index) in data.project_flow_item"
:key="index"
:style="$A.generateColorVarStyle(item.color, [10, 20, 70], 'flow-item-custom-color')"
class="taskflow-config-table-status-column column-border"
:class="item.status">
<div
class="taskflow-config-table-status-item taskflow-config-table-column-header">
<div class="status-label-with-menu" :class="item.status">
@ -88,29 +99,38 @@
</Badge>
</div>
<EDropdownMenu slot="dropdown" class="taskflow-config-more-dropdown-menu">
<EDropdownItem v-if="item.userids.length > 0" command="user">
<div class="users">
<UserAvatar v-for="(uid, ukey) in item.userids" :key="ukey" :userid="uid" :size="28" :borderWidth="1" :showName="item.userids.length === 1"/>
</div>
</EDropdownItem>
<EDropdownItem command="user">
<div class="item">
<Icon type="md-settings" />
<Badge :dot="item.userids.length > 0 || item.columnid > 0">
{{$L('状态设置')}}
</Badge>
</div>
</EDropdownItem>
<EDropdownItem command="name">
<div class="item">
<Icon type="md-create" />{{$L('修改名称')}}
</div>
</EDropdownItem>
<EDropdownItem command="remove">
<div class="item delete">
<Icon type="md-trash" />{{$L('删除')}}
</div>
</EDropdownItem>
<li class="taskflow-config-more-dropdown-warp">
<ul>
<EDropdownItem v-if="item.userids.length > 0" command="user">
<div class="users">
<UserAvatar v-for="(uid, ukey) in item.userids" :key="ukey" :userid="uid" :size="28" :borderWidth="1" :showName="item.userids.length === 1"/>
</div>
</EDropdownItem>
<EDropdownItem command="user">
<div class="item">
<Icon type="md-settings" />
<Badge :dot="item.userids.length > 0 || item.columnid > 0">
{{$L('状态设置')}}
</Badge>
</div>
</EDropdownItem>
<EDropdownItem command="name">
<div class="item">
<Icon type="md-create" />{{$L('修改名称')}}
</div>
</EDropdownItem>
<EDropdownItem command="remove">
<div class="item delete">
<Icon type="md-trash" />{{$L('删除')}}
</div>
</EDropdownItem>
<EDropdownItem v-for="(c, k) in $store.state.columnColorList" :key="k" :divided="k==0" :command="c">
<div class="item">
<i class="taskfont" :style="{color:c.color||'#ddd'}" v-html="c.color == item.color ? '&#xe61d;' : '&#xe61c;'"></i>{{$L(c.name)}}
</div>
</EDropdownItem>
</ul>
</li>
</EDropdownMenu>
</EDropdown>
</div>
@ -415,8 +435,8 @@ export default {
});
},
onMore(name, item) {
switch (name) {
onMore(command, item) {
switch (command) {
case "user":
this.$set(this.settingData, 'id', item.id);
this.$set(this.settingData, 'name', item.name);
@ -434,6 +454,11 @@ export default {
case "remove":
this.onRemove(item);
break;
default:
if (command.name) {
this.$set(item, 'color', command.color);
}
}
},

View File

@ -26,13 +26,19 @@
<template v-if="flows.type==='group'">
<OptionGroup v-for="(group, index) in flows.groups" :key="index" :label="group.label">
<Option v-for="(item, key) in group.items" :key="key" :value="item.id" :label="item.name">
<div class="tag-dot" :class="item.status">{{item.name}}</div>
<div
class="tag-dot"
:style="$A.generateColorVarStyle(item.color, [], 'flow-item-custom-color')"
:class="item.status">{{item.name}}</div>
</Option>
</OptionGroup>
</template>
<template v-else>
<Option v-for="(item, key) in flows.items" :key="key" :value="item.id" :label="item.name">
<div class="tag-dot" :class="item.status">{{item.name}}</div>
<div
class="tag-dot"
:style="$A.generateColorVarStyle(item.color, [], 'flow-item-custom-color')"
:class="item.status">{{item.name}}</div>
</Option>
</template>
</Select>

View File

@ -26,13 +26,19 @@
<template v-if="flows.type==='group'">
<OptionGroup v-for="(group, index) in flows.groups" :key="index" :label="group.label">
<Option v-for="(item, key) in group.items" :key="key" :value="item.id" :label="item.name">
<div class="tag-dot" :class="item.status">{{item.name}}</div>
<div
class="tag-dot"
:style="$A.generateColorVarStyle(item.color, [], 'flow-item-custom-color')"
:class="item.status">{{item.name}}</div>
</Option>
</OptionGroup>
</template>
<template v-else>
<Option v-for="(item, key) in flows.items" :key="key" :value="item.id" :label="item.name">
<div class="tag-dot" :class="item.status">{{item.name}}</div>
<div
class="tag-dot"
:style="$A.generateColorVarStyle(item.color, [], 'flow-item-custom-color')"
:class="item.status">{{item.name}}</div>
</Option>
</template>
</Select>

View File

@ -9,7 +9,10 @@
:load-status="taskDetail.loading === true"
@on-update="getLogLists"/>
</div>
<div v-if="taskDetail.flow_item_name" class="subtask-flow">
<div
v-if="taskDetail.flow_item_name"
class="subtask-flow"
:style="$A.generateColorVarStyle(taskDetail.flow_item_color, [10], 'flow-item-custom-color')">
<span :class="taskDetail.flow_item_status" @click.stop="openMenu($event, taskDetail)">{{taskDetail.flow_item_name}}</span>
</div>
<div class="subtask-name">
@ -69,7 +72,10 @@
size="medium"
:color-show="false"
@on-update="getLogLists"/>
<div v-if="taskDetail.flow_item_name" class="flow">
<div
v-if="taskDetail.flow_item_name"
class="flow"
:style="$A.generateColorVarStyle(taskDetail.flow_item_color, [10], 'flow-item-custom-color')">
<span :class="taskDetail.flow_item_status" @click.stop="openMenu($event, taskDetail)">{{taskDetail.flow_item_name}}</span>
</div>
<div v-if="taskDetail.archived_at" class="flow">

View File

@ -1,5 +1,5 @@
<template>
<div class="task-move">
<div class="task-move" :style="$A.generateColorVarStyle(task.flow_item_color, [10], 'flow-item-custom-color')">
<Cascader
v-model="cascader"

View File

@ -20,7 +20,11 @@
</div>
</EDropdownItem>
<template v-else-if="turns.length > 0">
<EDropdownItem v-for="item in turns" :key="item.id" :command="`turn::${item.id}`">
<EDropdownItem
v-for="item in turns"
:key="item.id"
:command="`turn::${item.id}`"
:style="$A.generateColorVarStyle(item.color, [10], 'flow-item-custom-color')">
<div class="item flow">
<Icon v-if="item.id == task.flow_item_id && flow.auto_assign !== true" class="check" type="md-checkmark-circle-outline" />
<Icon v-else type="md-radio-button-off" />

View File

@ -8,7 +8,7 @@
class="task-item">
<Row
class="task-row"
:style="taskItemStyle(item)">
:style="$A.generateColorVarStyle(item.flow_item_color, [10], 'flow-item-custom-color', taskItemStyle(item))">
<template v-if="taskItemVisible(`${openKey}_${item.id}`)">
<em v-if="item.p_name" class="priority-color" :style="{backgroundColor:item.p_color}"></em>
<Col span="12" :class="['row-name', item.complete_at ? 'complete' : '']">

View File

@ -64,7 +64,7 @@
v-for="(item, index) in column.list"
:key="index"
:class="{complete: item.complete_at}"
:style="item.color ? {backgroundColor: item.color} : {}"
:style="$A.generateColorVarStyle(item.flow_item_color, [10], 'flow-item-custom-color', item.color ? {backgroundColor: item.color} : {})"
@click="openTask(item)">
<em
v-if="item.p_name"

View File

@ -1868,8 +1868,12 @@ export default {
});
} else if ($A.isJson(data)) {
data._time = $A.dayjs().unix();
//
if (data.flow_item_name && data.flow_item_name.indexOf("|") !== -1) {
[data.flow_item_status, data.flow_item_name] = data.flow_item_name.split("|")
const flowInfo = $A.convertWorkflow(data.flow_item_name)
data.flow_item_status = flowInfo.status;
data.flow_item_name = flowInfo.name;
data.flow_item_color = flowInfo.color;
}
//
if (typeof data.archived_at !== "undefined") {
@ -2652,7 +2656,7 @@ export default {
state.cacheTasks.filter(({flow_item_id})=> flow_item_id == item.id).some(task => {
dispatch("saveTask", {
id: task.id,
flow_item_name: `${item.status}|${item.name}`,
flow_item_name: `${item.status}|${item.name}|${item.color}`,
})
})
}

View File

@ -193,15 +193,20 @@ export default {
// 列表背景色
columnColorList: [
{name: '默认', color: ''},
{name: '灰色', color: '#999999'},
{name: '棕色', color: '#947364'},
{name: '橘色', color: '#faaa6c'},
{name: '黄色', color: '#f2d86d'},
{name: '绿色', color: '#73b45c'},
{name: '蓝色', color: '#51abea'},
{name: '绿色', color: '#73b45c'},
{name: '黄色', color: '#f2d86d'},
{name: '橙色', color: '#faaa6c'},
{name: '红色', color: '#ff7070'},
{name: '紫色', color: '#b583e3'},
{name: '粉色', color: '#ff819c'},
{name: '红色', color: '#ff7070'},
{name: '青色', color: '#3ad1c8'},
{name: '棕色', color: '#947364'},
{name: '灰色', color: '#999999'},
{name: '深蓝', color: '#2b5caa'},
{name: '深绿', color: '#1a7f5a'},
{name: '金色', color: '#ffd700'},
{name: '湖蓝', color: '#00bcd4'},
],
// 任务背景色

View File

@ -974,19 +974,22 @@ body.window-portrait {
transform: translateY(-50%);
}
&.start:after {
background-color: $flow-status-start-color;
background-color: var(--flow-item-custom-color-100, $flow-status-start-color);
}
&.progress:after {
background-color: $flow-status-progress-color;
background-color: var(--flow-item-custom-color-100, $flow-status-progress-color);
}
&.test:after {
background-color: $flow-status-test-color;
background-color: var(--flow-item-custom-color-100, $flow-status-test-color);
}
&.completed:after,
&.end:after {
background-color: var(--flow-item-custom-color-100, $flow-status-end-color);
}
&.completed:after {
background-color: $flow-status-end-color;
}

View File

@ -113,27 +113,27 @@
color: #595959;
&.start {
background-color: rgba($flow-status-start-color, 0.1);
border-color: rgba($flow-status-start-color, 0.1);
color: $flow-status-start-color;
background-color: var(--flow-item-custom-color-10, rgba($flow-status-start-color, 0.1));
border-color: var(--flow-item-custom-color-10, rgba($flow-status-start-color, 0.1));
color: var(--flow-item-custom-color-100, $flow-status-start-color);
}
&.progress {
background-color: rgba($flow-status-progress-color, 0.1);
border-color: rgba($flow-status-progress-color, 0.1);
color: $flow-status-progress-color;
background-color: var(--flow-item-custom-color-10, rgba($flow-status-progress-color, 0.1));
border-color: var(--flow-item-custom-color-10, rgba($flow-status-progress-color, 0.1));
color: var(--flow-item-custom-color-100, $flow-status-progress-color);
}
&.test {
background-color: rgba($flow-status-test-color, 0.1);
border-color: rgba($flow-status-test-color, 0.1);
color: $flow-status-test-color;
background-color: var(--flow-item-custom-color-10, rgba($flow-status-test-color, 0.1));
border-color: var(--flow-item-custom-color-10, rgba($flow-status-test-color, 0.1));
color: var(--flow-item-custom-color-100, $flow-status-test-color);
}
&.end {
background-color: rgba($flow-status-end-color, 0.1);
border-color: rgba($flow-status-end-color, 0.1);
color: $flow-status-end-color;
background-color: var(--flow-item-custom-color-10, rgba($flow-status-end-color, 0.1));
border-color: var(--flow-item-custom-color-10, rgba($flow-status-end-color, 0.1));
color: var(--flow-item-custom-color-100, $flow-status-end-color);
}
}
}

View File

@ -173,24 +173,24 @@
white-space: nowrap;
text-overflow: ellipsis;
&.start {
background-color: rgba($flow-status-start-color, 0.1);
border-color: rgba($flow-status-start-color, 0.1);
color: $flow-status-start-color;
background-color: var(--flow-item-custom-color-10, rgba($flow-status-start-color, 0.1));
border-color: var(--flow-item-custom-color-10, rgba($flow-status-start-color, 0.1));
color: var(--flow-item-custom-color-100, $flow-status-start-color);
}
&.progress {
background-color: rgba($flow-status-progress-color, 0.1);
border-color: rgba($flow-status-progress-color, 0.1);
color: $flow-status-progress-color;
background-color: var(--flow-item-custom-color-10, rgba($flow-status-progress-color, 0.1));
border-color: var(--flow-item-custom-color-10, rgba($flow-status-progress-color, 0.1));
color: var(--flow-item-custom-color-100, $flow-status-progress-color);
}
&.test {
background-color: rgba($flow-status-test-color, 0.1);
border-color: rgba($flow-status-test-color, 0.1);
color: $flow-status-test-color;
background-color: var(--flow-item-custom-color-10, rgba($flow-status-test-color, 0.1));
border-color: var(--flow-item-custom-color-10, rgba($flow-status-test-color, 0.1));
color: var(--flow-item-custom-color-100, $flow-status-test-color);
}
&.end {
background-color: rgba($flow-status-end-color, 0.1);
border-color: rgba($flow-status-end-color, 0.1);
color: $flow-status-end-color;
background-color: var(--flow-item-custom-color-10, rgba($flow-status-end-color, 0.1));
border-color: var(--flow-item-custom-color-10, rgba($flow-status-end-color, 0.1));
color: var(--flow-item-custom-color-100, $flow-status-end-color);
}
&.tag-dot {
position: relative;
@ -420,24 +420,24 @@
text-align: center;
overflow: hidden;
&.start {
background-color: rgba($flow-status-start-color, 0.1);
border-color: rgba($flow-status-start-color, 0.1);
color: $flow-status-start-color;
background-color: var(--flow-item-custom-color-10, rgba($flow-status-start-color, 0.1));
border-color: var(--flow-item-custom-color-10, rgba($flow-status-start-color, 0.1));
color: var(--flow-item-custom-color-100, $flow-status-start-color);
}
&.progress {
background-color: rgba($flow-status-progress-color, 0.1);
border-color: rgba($flow-status-progress-color, 0.1);
color: $flow-status-progress-color;
background-color: var(--flow-item-custom-color-10, rgba($flow-status-progress-color, 0.1));
border-color: var(--flow-item-custom-color-10, rgba($flow-status-progress-color, 0.1));
color: var(--flow-item-custom-color-100, $flow-status-progress-color);
}
&.test {
background-color: rgba($flow-status-test-color, 0.1);
border-color: rgba($flow-status-test-color, 0.1);
color: $flow-status-test-color;
background-color: var(--flow-item-custom-color-10, rgba($flow-status-test-color, 0.1));
border-color: var(--flow-item-custom-color-10, rgba($flow-status-test-color, 0.1));
color: var(--flow-item-custom-color-100, $flow-status-test-color);
}
&.end {
background-color: rgba($flow-status-end-color, 0.1);
border-color: rgba($flow-status-end-color, 0.1);
color: $flow-status-end-color;
background-color: var(--flow-item-custom-color-10, rgba($flow-status-end-color, 0.1));
border-color: var(--flow-item-custom-color-10, rgba($flow-status-end-color, 0.1));
color: var(--flow-item-custom-color-100, $flow-status-end-color);
}
}
> pre {
@ -788,24 +788,24 @@
margin-right: 3px;
text-align: center;
&.start {
background-color: rgba($flow-status-start-color, 0.1);
border-color: rgba($flow-status-start-color, 0.1);
color: $flow-status-start-color;
background-color: var(--flow-item-custom-color-10, rgba($flow-status-start-color, 0.1));
border-color: var(--flow-item-custom-color-10, rgba($flow-status-start-color, 0.1));
color: var(--flow-item-custom-color-100, $flow-status-start-color);
}
&.progress {
background-color: rgba($flow-status-progress-color, 0.1);
border-color: rgba($flow-status-progress-color, 0.1);
color: $flow-status-progress-color;
background-color: var(--flow-item-custom-color-10, rgba($flow-status-progress-color, 0.1));
border-color: var(--flow-item-custom-color-10, rgba($flow-status-progress-color, 0.1));
color: var(--flow-item-custom-color-100, $flow-status-progress-color);
}
&.test {
background-color: rgba($flow-status-test-color, 0.1);
border-color: rgba($flow-status-test-color, 0.1);
color: $flow-status-test-color;
background-color: var(--flow-item-custom-color-10, rgba($flow-status-test-color, 0.1));
border-color: var(--flow-item-custom-color-10, rgba($flow-status-test-color, 0.1));
color: var(--flow-item-custom-color-100, $flow-status-test-color);
}
&.end {
background-color: rgba($flow-status-end-color, 0.1);
border-color: rgba($flow-status-end-color, 0.1);
color: $flow-status-end-color;
background-color: var(--flow-item-custom-color-10, rgba($flow-status-end-color, 0.1));
border-color: var(--flow-item-custom-color-10, rgba($flow-status-end-color, 0.1));
color: var(--flow-item-custom-color-100, $flow-status-end-color);
}
}
}
@ -961,6 +961,7 @@
.project-panel-more-dropdown-menu {
.project-panel-more-dropdown-warp {
height: 400px;
min-height: 120px;
max-height: calc(100vh - 250px);
overflow-y: auto;
@ -1008,16 +1009,16 @@
color: $primary-text-color !important;
&.start {
color: $flow-status-start-color !important;
color: var(--flow-item-custom-color-100, $flow-status-start-color) !important;
}
&.progress {
color: $flow-status-progress-color !important;
color: var(--flow-item-custom-color-100, $flow-status-progress-color) !important;
}
&.test {
color: $flow-status-test-color !important;
color: var(--flow-item-custom-color-100, $flow-status-test-color) !important;
}
&.end {
color: $flow-status-end-color !important;
color: var(--flow-item-custom-color-100, $flow-status-end-color) !important;
}
&.tag-dot {
@ -1041,24 +1042,6 @@
border-top: 1px solid #EBEEF5;
}
}
&:hover,
&.ivu-cascader-menu-item-active {
&.project-panel-flow-cascader-item {
&.start {
background-color: rgba($flow-status-start-color, 0.1);
}
&.progress {
background-color: rgba($flow-status-progress-color, 0.1);
}
&.test {
background-color: rgba($flow-status-test-color, 0.1);
}
&.end {
background-color: rgba($flow-status-end-color, 0.1);
}
}
}
}
}

View File

@ -75,24 +75,24 @@
vertical-align: middle;
overflow: hidden;
&.start {
background-color: rgba($flow-status-start-color, 0.1);
border-color: rgba($flow-status-start-color, 0.1);
color: $flow-status-start-color;
background-color: var(--flow-item-custom-color-10, rgba($flow-status-start-color, 0.1));
border-color: var(--flow-item-custom-color-10, rgba($flow-status-start-color, 0.1));
color: var(--flow-item-custom-color-100, $flow-status-start-color);
}
&.progress {
background-color: rgba($flow-status-progress-color, 0.1);
border-color: rgba($flow-status-progress-color, 0.1);
color: $flow-status-progress-color;
background-color: var(--flow-item-custom-color-10, rgba($flow-status-progress-color, 0.1));
border-color: var(--flow-item-custom-color-10, rgba($flow-status-progress-color, 0.1));
color: var(--flow-item-custom-color-100, $flow-status-progress-color);
}
&.test {
background-color: rgba($flow-status-test-color, 0.1);
border-color: rgba($flow-status-test-color, 0.1);
color: $flow-status-test-color;
background-color: var(--flow-item-custom-color-10, rgba($flow-status-test-color, 0.1));
border-color: var(--flow-item-custom-color-10, rgba($flow-status-test-color, 0.1));
color: var(--flow-item-custom-color-100, $flow-status-test-color);
}
&.end {
background-color: rgba($flow-status-end-color, 0.1);
border-color: rgba($flow-status-end-color, 0.1);
color: $flow-status-end-color;
background-color: var(--flow-item-custom-color-10, rgba($flow-status-end-color, 0.1));
border-color: var(--flow-item-custom-color-10, rgba($flow-status-end-color, 0.1));
color: var(--flow-item-custom-color-100, $flow-status-end-color);
}
}
}
@ -337,74 +337,74 @@
}
&.start {
border-color:rgba($flow-status-start-color, 0.2);
border-color: var(--flow-item-custom-color-20, rgba($flow-status-start-color, 0.2));
&:hover {
border-color: rgba($flow-status-start-color, 0.7);
border-color: var(--flow-item-custom-color-70, rgba($flow-status-start-color, 0.7));
}
.ivu-radio-checked .ivu-radio-inner {
border-color: $flow-status-start-color;
border-color: var(--flow-item-custom-color-100, $flow-status-start-color);
box-shadow: none;
}
.ivu-radio-inner::after {
background-color: $flow-status-start-color;
background-color: var(--flow-item-custom-color-100, $flow-status-start-color);
}
.ivu-checkbox-checked .ivu-checkbox-inner {
border-color: $flow-status-start-color;
background-color: $flow-status-start-color;
border-color: var(--flow-item-custom-color-100, $flow-status-start-color);
background-color: var(--flow-item-custom-color-100, $flow-status-start-color);
}
}
&.progress {
border-color: rgba($flow-status-progress-color, 0.2);
border-color: var(--flow-item-custom-color-20, rgba($flow-status-progress-color, 0.2));
&:hover {
border-color: rgba($flow-status-progress-color, 0.7);
border-color: var(--flow-item-custom-color-70, rgba($flow-status-progress-color, 0.7));
}
.ivu-radio-checked .ivu-radio-inner {
border-color: $flow-status-progress-color;
border-color: var(--flow-item-custom-color-100, $flow-status-progress-color);
box-shadow: none;
}
.ivu-radio-inner::after {
background-color: $flow-status-progress-color;
background-color: var(--flow-item-custom-color-100, $flow-status-progress-color);
}
.ivu-checkbox-checked .ivu-checkbox-inner {
border-color: $flow-status-progress-color;
background-color: $flow-status-progress-color;
border-color: var(--flow-item-custom-color-100, $flow-status-progress-color);
background-color: var(--flow-item-custom-color-100, $flow-status-progress-color);
}
}
&.test {
border-color: rgba($flow-status-test-color, 0.2);
border-color: var(--flow-item-custom-color-20, rgba($flow-status-test-color, 0.2));
&:hover {
border-color: rgba($flow-status-test-color, 0.7);
border-color: var(--flow-item-custom-color-70, rgba($flow-status-test-color, 0.7));
}
.ivu-radio-checked .ivu-radio-inner {
border-color: $flow-status-test-color;
border-color: var(--flow-item-custom-color-100, $flow-status-test-color);
box-shadow: none;
}
.ivu-radio-inner::after {
background-color: $flow-status-test-color;
background-color: var(--flow-item-custom-color-100, $flow-status-test-color);
}
.ivu-checkbox-checked .ivu-checkbox-inner {
border-color: $flow-status-test-color;
background-color: $flow-status-test-color;
border-color: var(--flow-item-custom-color-100, $flow-status-test-color);
background-color: var(--flow-item-custom-color-100, $flow-status-test-color);
}
}
&.end {
border-color: rgba($flow-status-end-color, 0.2);
border-color: var(--flow-item-custom-color-20, rgba($flow-status-end-color, 0.2));
&:hover {
border-color: rgba($flow-status-end-color, 0.7);
border-color: var(--flow-item-custom-color-70, rgba($flow-status-end-color, 0.7));
}
.ivu-radio-checked .ivu-radio-inner {
border-color: $flow-status-end-color;
border-color: var(--flow-item-custom-color-100, $flow-status-end-color);
box-shadow: none;
}
.ivu-radio-inner::after {
background-color: $flow-status-end-color;
background-color: var(--flow-item-custom-color-100, $flow-status-end-color);
}
.ivu-checkbox-checked .ivu-checkbox-inner {
border-color: $flow-status-end-color;
background-color: $flow-status-end-color;
border-color: var(--flow-item-custom-color-100, $flow-status-end-color);
background-color: var(--flow-item-custom-color-100, $flow-status-end-color);
}
}
@ -445,20 +445,20 @@
}
&.start {
background-color: rgba($flow-status-start-color, 0.1);
color: $flow-status-start-color;
background-color: var(--flow-item-custom-color-10, rgba($flow-status-start-color, 0.1));
color: var(--flow-item-custom-color-100, $flow-status-start-color);
}
&.progress {
background-color: rgba($flow-status-progress-color, 0.1);
color: $flow-status-progress-color;
background-color: var(--flow-item-custom-color-10, rgba($flow-status-progress-color, 0.1));
color: var(--flow-item-custom-color-100, $flow-status-progress-color);
}
&.test {
background-color: rgba($flow-status-test-color, 0.1);
color: $flow-status-test-color;
background-color: var(--flow-item-custom-color-10, rgba($flow-status-test-color, 0.1));
color: var(--flow-item-custom-color-100, $flow-status-test-color);
}
&.end {
background-color: rgba($flow-status-end-color, 0.1);
color: $flow-status-end-color;
background-color: var(--flow-item-custom-color-10, rgba($flow-status-end-color, 0.1));
color: var(--flow-item-custom-color-100, $flow-status-end-color);
}
.name {
@ -545,6 +545,13 @@
}
}
.taskflow-config-more-dropdown-menu {
.taskflow-config-more-dropdown-warp {
height: 400px;
min-height: 180px;
max-height: calc(100vh - 250px);
overflow-y: auto;
list-style: none;
}
.users {
display: flex;
padding: 6px 0;

View File

@ -129,29 +129,29 @@
white-space: nowrap;
overflow: hidden;
&.archived {
background-color: rgba($flow-status-archived-color, 0.1);
border-color: rgba($flow-status-archived-color, 0.1);
color: $flow-status-archived-color;
background-color: var(--flow-item-custom-color-10, rgba($flow-status-archived-color, 0.1));
border-color: var(--flow-item-custom-color-10, rgba($flow-status-archived-color, 0.1));
color: var(--flow-item-custom-color-100, $flow-status-archived-color);
}
&.start {
background-color: rgba($flow-status-start-color, 0.1);
border-color: rgba($flow-status-start-color, 0.1);
color: $flow-status-start-color;
background-color: var(--flow-item-custom-color-10, rgba($flow-status-start-color, 0.1));
border-color: var(--flow-item-custom-color-10, rgba($flow-status-start-color, 0.1));
color: var(--flow-item-custom-color-100, $flow-status-start-color);
}
&.progress {
background-color: rgba($flow-status-progress-color, 0.1);
border-color: rgba($flow-status-progress-color, 0.1);
color: $flow-status-progress-color;
background-color: var(--flow-item-custom-color-10, rgba($flow-status-progress-color, 0.1));
border-color: var(--flow-item-custom-color-10, rgba($flow-status-progress-color, 0.1));
color: var(--flow-item-custom-color-100, $flow-status-progress-color);
}
&.test {
background-color: rgba($flow-status-test-color, 0.1);
border-color: rgba($flow-status-test-color, 0.1);
color: $flow-status-test-color;
background-color: var(--flow-item-custom-color-10, rgba($flow-status-test-color, 0.1));
border-color: var(--flow-item-custom-color-10, rgba($flow-status-test-color, 0.1));
color: var(--flow-item-custom-color-100, $flow-status-test-color);
}
&.end {
background-color: rgba($flow-status-end-color, 0.1);
border-color: rgba($flow-status-end-color, 0.1);
color: $flow-status-end-color;
background-color: var(--flow-item-custom-color-10, rgba($flow-status-end-color, 0.1));
border-color: var(--flow-item-custom-color-10, rgba($flow-status-end-color, 0.1));
color: var(--flow-item-custom-color-100, $flow-status-end-color);
}
}
}
@ -445,24 +445,24 @@
text-align: center;
cursor: pointer;
&.start {
background-color: rgba($flow-status-start-color, 0.1);
border-color: rgba($flow-status-start-color, 0.1);
color: $flow-status-start-color;
background-color: var(--flow-item-custom-color-10, rgba($flow-status-start-color, 0.1));
border-color: var(--flow-item-custom-color-10, rgba($flow-status-start-color, 0.1));
color: var(--flow-item-custom-color-100, $flow-status-start-color);
}
&.progress {
background-color: rgba($flow-status-progress-color, 0.1);
border-color: rgba($flow-status-progress-color, 0.1);
color: $flow-status-progress-color;
background-color: var(--flow-item-custom-color-10, rgba($flow-status-progress-color, 0.1));
border-color: var(--flow-item-custom-color-10, rgba($flow-status-progress-color, 0.1));
color: var(--flow-item-custom-color-100, $flow-status-progress-color);
}
&.test {
background-color: rgba($flow-status-test-color, 0.1);
border-color: rgba($flow-status-test-color, 0.1);
color: $flow-status-test-color;
background-color: var(--flow-item-custom-color-10, rgba($flow-status-test-color, 0.1));
border-color: var(--flow-item-custom-color-10, rgba($flow-status-test-color, 0.1));
color: var(--flow-item-custom-color-100, $flow-status-test-color);
}
&.end {
background-color: rgba($flow-status-end-color, 0.1);
border-color: rgba($flow-status-end-color, 0.1);
color: $flow-status-end-color;
background-color: var(--flow-item-custom-color-10, rgba($flow-status-end-color, 0.1));
border-color: var(--flow-item-custom-color-10, rgba($flow-status-end-color, 0.1));
color: var(--flow-item-custom-color-100, $flow-status-end-color);
}
}
}

View File

@ -47,24 +47,24 @@
margin-top: 8px;
text-align: center;
&.start {
background-color: rgba($flow-status-start-color, 0.1);
border-color: rgba($flow-status-start-color, 0.1);
color: $flow-status-start-color;
background-color: var(--flow-item-custom-color-10, rgba($flow-status-start-color, 0.1));
border-color: var(--flow-item-custom-color-10, rgba($flow-status-start-color, 0.1));
color: var(--flow-item-custom-color-100, $flow-status-start-color);
}
&.progress {
background-color: rgba($flow-status-progress-color, 0.1);
border-color: rgba($flow-status-progress-color, 0.1);
color: $flow-status-progress-color;
background-color: var(--flow-item-custom-color-10, rgba($flow-status-progress-color, 0.1));
border-color: var(--flow-item-custom-color-10, rgba($flow-status-progress-color, 0.1));
color: var(--flow-item-custom-color-100, $flow-status-progress-color);
}
&.test {
background-color: rgba($flow-status-test-color, 0.1);
border-color: rgba($flow-status-test-color, 0.1);
color: $flow-status-test-color;
background-color: var(--flow-item-custom-color-10, rgba($flow-status-test-color, 0.1));
border-color: var(--flow-item-custom-color-10, rgba($flow-status-test-color, 0.1));
color: var(--flow-item-custom-color-100, $flow-status-test-color);
}
&.end {
background-color: rgba($flow-status-end-color, 0.1);
border-color: rgba($flow-status-end-color, 0.1);
color: $flow-status-end-color;
background-color: var(--flow-item-custom-color-10, rgba($flow-status-end-color, 0.1));
border-color: var(--flow-item-custom-color-10, rgba($flow-status-end-color, 0.1));
color: var(--flow-item-custom-color-100, $flow-status-end-color);
}
}
}

View File

@ -279,24 +279,24 @@
margin-right: 3px;
text-align: center;
&.start {
background-color: rgba($flow-status-start-color, 0.1);
border-color: rgba($flow-status-start-color, 0.1);
color: $flow-status-start-color;
background-color: var(--flow-item-custom-color-10, rgba($flow-status-start-color, 0.1));
border-color: var(--flow-item-custom-color-10, rgba($flow-status-start-color, 0.1));
color: var(--flow-item-custom-color-100, $flow-status-start-color);
}
&.progress {
background-color: rgba($flow-status-progress-color, 0.1);
border-color: rgba($flow-status-progress-color, 0.1);
color: $flow-status-progress-color;
background-color: var(--flow-item-custom-color-10, rgba($flow-status-progress-color, 0.1));
border-color: var(--flow-item-custom-color-10, rgba($flow-status-progress-color, 0.1));
color: var(--flow-item-custom-color-100, $flow-status-progress-color);
}
&.test {
background-color: rgba($flow-status-test-color, 0.1);
border-color: rgba($flow-status-test-color, 0.1);
color: $flow-status-test-color;
background-color: var(--flow-item-custom-color-10, rgba($flow-status-test-color, 0.1));
border-color: var(--flow-item-custom-color-10, rgba($flow-status-test-color, 0.1));
color: var(--flow-item-custom-color-100, $flow-status-test-color);
}
&.end {
background-color: rgba($flow-status-end-color, 0.1);
border-color: rgba($flow-status-end-color, 0.1);
color: $flow-status-end-color;
background-color: var(--flow-item-custom-color-10, rgba($flow-status-end-color, 0.1));
border-color: var(--flow-item-custom-color-10, rgba($flow-status-end-color, 0.1));
color: var(--flow-item-custom-color-100, $flow-status-end-color);
}
}
}

View File

@ -433,24 +433,24 @@
border: 1px solid $primary-color;
margin-right: 6px;
&.start {
background-color: rgba($flow-status-start-color, 0.1);
border-color: rgba($flow-status-start-color, 0.1);
color: $flow-status-start-color;
background-color: var(--flow-item-custom-color-10, rgba($flow-status-start-color, 0.1));
border-color: var(--flow-item-custom-color-10, rgba($flow-status-start-color, 0.1));
color: var(--flow-item-custom-color-100, $flow-status-start-color);
}
&.progress {
background-color: rgba($flow-status-progress-color, 0.1);
border-color: rgba($flow-status-progress-color, 0.1);
color: $flow-status-progress-color;
background-color: var(--flow-item-custom-color-10, rgba($flow-status-progress-color, 0.1));
border-color: var(--flow-item-custom-color-10, rgba($flow-status-progress-color, 0.1));
color: var(--flow-item-custom-color-100, $flow-status-progress-color);
}
&.test {
background-color: rgba($flow-status-test-color, 0.1);
border-color: rgba($flow-status-test-color, 0.1);
color: $flow-status-test-color;
background-color: var(--flow-item-custom-color-10, rgba($flow-status-test-color, 0.1));
border-color: var(--flow-item-custom-color-10, rgba($flow-status-test-color, 0.1));
color: var(--flow-item-custom-color-100, $flow-status-test-color);
}
&.end {
background-color: rgba($flow-status-end-color, 0.1);
border-color: rgba($flow-status-end-color, 0.1);
color: $flow-status-end-color;
background-color: var(--flow-item-custom-color-10, rgba($flow-status-end-color, 0.1));
border-color: var(--flow-item-custom-color-10, rgba($flow-status-end-color, 0.1));
color: var(--flow-item-custom-color-100, $flow-status-end-color);
}
}
.task-title-text {