Commit 9b310b89a277c5fa53e6f05e4a8732cd4b43564d

Authored by guzijian
1 parent 9aeb947a

feat: 新增灵活跟班设置

src/api/expand/expand.js
... ... @@ -42,3 +42,29 @@ export function delExpand(id) {
42 42 method: 'delete'
43 43 })
44 44 }
  45 +
  46 +export function addSmartExpand(data) {
  47 + return request({
  48 + url: '/expand/expand/addSmartExpand',
  49 + method: 'post',
  50 + data
  51 + })
  52 +}
  53 +
  54 +
  55 +export function querySmartExpand(params) {
  56 + return request({
  57 + url: '/expand/expand/querySmartExpand',
  58 + method: 'get',
  59 + params
  60 + })
  61 +}
  62 +
  63 +
  64 +export function updateSmartExpand(data) {
  65 + return request({
  66 + url: '/expand/expand/updateSmartExpand',
  67 + method: 'put',
  68 + data
  69 + })
  70 +}
... ...
src/views/expand/expand/index.vue
... ... @@ -18,33 +18,31 @@
18 18 <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['expand:expand:add']">新增</el-button>
19 19 </el-col>
20 20 <el-col :span="1.5">
21   - <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate"
22   - v-hasPermi="['expand:expand:edit']">修改</el-button>
23   - </el-col>
24   - <el-col :span="1.5">
25   - <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete"
26   - v-hasPermi="['expand:expand:remove']">删除</el-button>
  21 + <el-button type="primary" plain icon="Plus" @click="handleSmartAdd"
  22 + v-hasPermi="['expand:expand:smart:add']">灵活跟班</el-button>
27 23 </el-col>
28 24 <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
29 25 </el-row>
30 26  
31   - <el-table v-loading="loading" border :data="expandList" @selection-change="handleSelectionChange">
  27 + <el-table v-loading="loading" max-height="600" border :data="expandList" @selection-change="handleSelectionChange">
32 28 <el-table-column type="selection" width="55" align="center" />
33 29 <el-table-column label="驾驶员" align="center" prop="master" width="120" />
34 30 <el-table-column label="跟班人" align="center" prop="slave" width="120" />
35   - <el-table-column label="开始日期" align="center" prop="startDate" width="180">
  31 + <el-table-column label="时间范围" align="center" width="260">
36 32 <template #default="scope">
37   - <span>{{ parseTime(scope.row.startDate, '{y}-{m}-{d}') }}</span>
  33 + <span>
  34 + {{ parseTime(scope.row.startDate, '{y}-{m}-{d}') + "到"
  35 + + parseTime(scope.row.endDate, '{y}-{m}-{d}') }}</span>
38 36 </template>
39 37 </el-table-column>
40   - <el-table-column label="结束日期" align="center" prop="endDate" width="180">
  38 + <el-table-column label="状态" align="center" prop="status">
41 39 <template #default="scope">
42   - <span>{{ parseTime(scope.row.endDate, '{y}-{m}-{d}') }}</span>
  40 + <dict-tag :options="sys_normal_disable" :value="scope.row.status" />
43 41 </template>
44 42 </el-table-column>
45   - <el-table-column label="状态" align="center" prop="status">
  43 + <el-table-column label="类型" align="center" prop="type" width="180">
46 44 <template #default="scope">
47   - <dict-tag :options="sys_normal_disable" :value="scope.row.status" />
  45 + <dict-tag :options="expand_type" :value="scope.row.type" />
48 46 </template>
49 47 </el-table-column>
50 48 <el-table-column label="备注" align="center" prop="remark" />
... ... @@ -58,8 +56,8 @@
58 56 </el-table-column>
59 57 </el-table>
60 58  
61   - <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize"
62   - @pagination="getList" />
  59 + <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum"
  60 + v-model:limit="queryParams.pageSize" @pagination="getList" />
63 61  
64 62 <!-- 添加或修改跟班设置对话框 -->
65 63 <el-dialog :title="title" v-loading="openLoading" v-model="open" width="500px" append-to-body>
... ... @@ -67,7 +65,7 @@
67 65 <el-form-item label="状态" prop="status">
68 66 <el-radio-group v-model="form.status">
69 67 <el-radio v-for="dict in sys_normal_disable" :key="dict.value" :label="parseInt(dict.value)">{{ dict.label
70   - }}</el-radio>
  68 + }}</el-radio>
71 69 </el-radio-group>
72 70 </el-form-item>
73 71 <el-form-item label="驾驶员" prop="masterJobCode">
... ... @@ -101,18 +99,106 @@
101 99 </div>
102 100 </template>
103 101 </el-dialog>
  102 +
  103 + <!-- 添加或修改跟班设置对话框 -->
  104 + <el-dialog v-loading="openLoading" v-model="smartOpen" width="800px" append-to-body draggable>
  105 + <div style="display: flex; justify-content: space-between;">
  106 + <!-- el-timeline 时间线控制 -->
  107 + <div>
  108 + <div>
  109 + <h3> 跟班计划 </h3>
  110 + </div>
  111 + <div
  112 + style="height: 600px;padding-right: 20px;padding-top: 20px; width: 400px; overflow: auto; border: 2px solid #dcdfe6;">
  113 + <el-timeline style="max-width: 400px">
  114 + <el-timeline-item v-for="(activity) in smartFrom.activities" placement="top" :key="activity.uuId"
  115 + :timestamp="activity.timestamp">
  116 + <el-card style="max-width: 260px">
  117 + <template #header>
  118 + <div style="display: flex; justify-content: flex-end; align-items: center;">
  119 + <el-icon @click="deleteActivity(activity)" style="cursor: pointer">
  120 + <CloseBold />
  121 + </el-icon>
  122 + </div>
  123 + </template>
  124 + <p>工号:{{ activity.masterJobCode }}</p>
  125 + <h4>驾驶员:{{ activity.name }}</h4>
  126 + </el-card>
  127 + </el-timeline-item>
  128 + </el-timeline>
  129 + </div>
  130 + </div>
  131 + <!-- 新增时间线 -->
  132 + <div style="flex: 1; padding-left: 20px;">
  133 + <!-- 选着驾驶员 -->
  134 + <div style="width: 190px;display: flex; align-items: center; ">
  135 + <p style="white-space: nowrap; margin-right: 5px; ">驾驶员</p>
  136 + <el-select v-model="masterTimeLine.master" filterable placeholder="选择驾驶员">
  137 + <el-option v-for="(item, index) in options" :key="index" :label="item.label" :value="item.label" />
  138 + </el-select>
  139 + </div>
  140 + <!-- 新增时间线 -->
  141 + <div style="margin:20px 0;">
  142 + <el-date-picker value-format="YYYY-MM-DD" clearable v-model="masterTimeLine.dateRange" type="daterange"
  143 + range-separator="至" start-placeholder="开始时间" end-placeholder="结束时间" />
  144 + </div>
  145 + <div style="margin-bottom: 20px;">
  146 + <el-text class="mx-1" size="small" type="info">设置好的时间线点击新增,该时间线的驾驶员会在左边时间线显示,对应时间段的跟班人员会切换驾驶员进行跟班。</el-text>
  147 + </div>
  148 +
  149 + <el-button type="primary" @click="addSmartTimeLine">新增时间线</el-button>
  150 + <!-- 备注 -->
  151 + <div style="margin-top: 20px;">
  152 + <el-input v-model="smartFrom.remark" clearable type="textarea" placeholder="备注" />
  153 + </div>
  154 + </div>
  155 +
  156 + </div>
  157 + <template #header>
  158 + <div class="dialog-header" style="display: flex;justify-content: space-around;align-items: center;">
  159 + <div style="max-width: 190px; display: flex; align-items: center;">
  160 + <!-- 不换行 -->
  161 + <p style=" white-space: nowrap;margin-right: 5px;">跟班人</p>
  162 + <el-select v-model="smartFrom.slaveJobCode" filterable placeholder="选择跟班人员">
  163 + <el-option v-for="(item, index) in options" :key="index" :label="item.label" :value="item.value" />
  164 + </el-select>
  165 + </div>
  166 + <div>
  167 + <p>{{ smartTitle }}</p>
  168 + </div>
  169 + </div>
  170 + </template>
  171 + <template #footer>
  172 + <div class="dialog-footer">
  173 + <el-button type="primary" @click="submitSmartExpand">确 定</el-button>
  174 + <el-button @click="cancelSmart">取 消</el-button>
  175 + </div>
  176 + </template>
  177 + </el-dialog>
104 178 </div>
105 179 </template>
106 180  
107 181 <script setup name="Expand">
108 182 import { getPeopleInfo } from '@/api/attendance/attendance';
109   -import { addExpand, delExpand, getExpand, listExpand, updateExpand } from "@/api/expand/expand";
  183 +import { addExpand, addSmartExpand, delExpand, getExpand, listExpand, querySmartExpand, updateExpand, updateSmartExpand } from "@/api/expand/expand";
110 184 import moment from 'moment';
  185 +import { v4 as uuidv4 } from 'uuid';
111 186 import { ref, watch } from "vue";
112 187  
113 188 const { proxy } = getCurrentInstance();
114   -const { sys_normal_disable } = proxy.useDict('sys_normal_disable');
115   -
  189 +const { sys_normal_disable, expand_type } = proxy.useDict('sys_normal_disable', 'expand_type');
  190 +const smartFrom = ref({
  191 + slaveJobCode: null,
  192 + type: 1,
  193 + remark: null,
  194 + activities: []
  195 +});
  196 +const masterTimeLine = ref({
  197 + master: null,
  198 + dateRange: null
  199 +});
  200 +const smartOpen = ref(false);
  201 +const smartTitle = ref('')
116 202 const expandList = ref([]);
117 203 const openLoading = ref(false)
118 204 const open = ref(false);
... ... @@ -142,6 +228,10 @@ const data = reactive({
142 228  
143 229 const { queryParams, form, rules } = toRefs(data);
144 230  
  231 +function cancelSmart() {
  232 + smartOpen.value = false;
  233 + resetSmartFrom();
  234 +}
145 235 /** 查询跟班设置列表 */
146 236 function getList() {
147 237 loading.value = true;
... ... @@ -184,8 +274,6 @@ function handleQuery() {
184 274  
185 275 const disabledDate = (date) => {
186 276 const today = new Date()
187   - const lastDayOfMonth = new Date(today.getFullYear(), today.getMonth() + 1, 0);
188   -
189 277 return date < today;
190 278 }
191 279  
... ... @@ -216,16 +304,104 @@ function handleAdd() {
216 304 open.value = true;
217 305 title.value = "添加跟班设置";
218 306 }
  307 +/** 处理时间线 */
  308 +function addSmartTimeLine() {
  309 + let split = masterTimeLine.value.master.split('/');
  310 + if (!masterTimeLine.value.master || masterTimeLine.value.dateRange == null) {
  311 + proxy.$modal.msgError("驾驶员及其时间范围不能为空");
  312 + return
  313 + }
  314 + smartFrom.value.activities.push({
  315 + name: split[1],
  316 + masterJobCode: split[0],
  317 + timestamp: masterTimeLine.value.dateRange[0] + '至' + masterTimeLine.value.dateRange[1],
  318 + startDate: masterTimeLine.value.dateRange[0] + " 00:00:00",
  319 + endDate: masterTimeLine.value.dateRange[1] + " 00:00:00",
  320 + uuId: uuidv4().toString().replaceAll("-", "")
  321 + })
  322 + smartFrom.value.activities.sort((a, b) => new Date(a.startDate) - new Date(b.startDate));
  323 + console.log(smartFrom.value);
  324 + resetMasterTimeLine();
  325 +}
  326 +
  327 +function deleteActivity(activity) {
  328 + let index = smartFrom.value.activities.findIndex(item => item.uuId === activity.uuId);
  329 + if (index !== -1) {
  330 + smartFrom.value.activities.splice(index, 1);
  331 + }
  332 +}
  333 +
  334 +function resetMasterTimeLine() {
  335 + masterTimeLine.value = {
  336 + master: null,
  337 + dateRange: null
  338 + }
  339 +}
  340 +
  341 +
  342 +function resetSmartFrom() {
  343 + smartFrom.value = {
  344 + slaveJobCode: null,
  345 + activities: [],
  346 + type: 1,
  347 + remark: null
  348 + }
  349 +}
  350 +
  351 +function submitSmartExpand() {
  352 + // 修改
  353 + if (smartFrom.value.id) {
  354 + updateSmartExpand(smartFrom.value).then(response => {
  355 + console.log(smartFrom.value);
  356 + proxy.$modal.msgSuccess("修改成功");
  357 + smartOpen.value = false;
  358 + resetSmartFrom();
  359 + }).catch(error => {
  360 + proxy.$modal.msgError(error.message);
  361 + })
  362 + }
  363 + // 新增
  364 + else {
  365 + addSmartExpand(smartFrom.value).then(response => {
  366 + proxy.$modal.msgSuccess("新增成功");
  367 + smartOpen.value = false;
  368 + resetSmartFrom();
  369 + }).catch(error => {
  370 + proxy.$modal.msgError(error.message);
  371 + })
  372 + }
  373 +
  374 +}
  375 +
  376 +
  377 +/** 灵活跟班新增 */
  378 +function handleSmartAdd() {
  379 + // resetSmart();
  380 + smartOpen.value = true;
  381 + smartTitle.value = "添加灵活跟班";
  382 +}
219 383  
220 384 /** 修改按钮操作 */
221 385 function handleUpdate(row) {
222 386 reset();
223 387 const _id = row.id || ids.value
224   - getExpand(_id).then(response => {
225   - form.value = response.data;
226   - open.value = true;
227   - title.value = "修改跟班设置";
228   - });
  388 + if (row.type == 0) {
  389 + getExpand(_id).then(response => {
  390 + form.value = response.data;
  391 + open.value = true;
  392 + title.value = "修改跟班设置";
  393 + });
  394 + } else {
  395 + querySmartExpand({ id: _id }).then(response => {
  396 + setTimeout(() => {
  397 + response.data.activities.forEach(item => {
  398 + item.timestamp = item.startDate.split(" ")[0] + '至' + item.endDate.split(" ")[0]
  399 + })
  400 + smartFrom.value = { ...response.data };
  401 + }, 0);
  402 + smartOpen.value = true;
  403 + })
  404 + }
229 405 }
230 406  
231 407 /** 提交按钮 */
... ... @@ -250,6 +426,7 @@ function submitForm() {
250 426 }
251 427  
252 428  
  429 +
253 430 watch(open, (val1, val2) => {
254 431 if (open.value) {
255 432 openLoading.value = true
... ... @@ -265,6 +442,23 @@ watch(open, (val1, val2) =&gt; {
265 442 })
266 443 }
267 444 })
  445 +watch(smartOpen, (val1, val2) => {
  446 + if (smartOpen.value) {
  447 + resetSmartFrom()
  448 + openLoading.value = true
  449 + options.value = [];
  450 + getPeopleInfo({ id: null }).then((res) => {
  451 + res.data.forEach(element => {
  452 + options.value.push({
  453 + label: element.jobCode + "/" + element.name,
  454 + value: element.jobCode
  455 + })
  456 + });
  457 + openLoading.value = false;
  458 + })
  459 + }
  460 +})
  461 +
268 462  
269 463 /** 删除按钮操作 */
270 464 function handleDelete(row) {
... ...