ts-glitter 16.2.0 → 16.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/lowcode/Entry.js +1 -1
  2. package/lowcode/Entry.ts +1 -1
  3. package/lowcode/backend-manager/bg-widget.js +1 -1
  4. package/lowcode/backend-manager/bg-widget.ts +1 -1
  5. package/lowcode/cms-plugin/module/order-setting.js +20 -30
  6. package/lowcode/cms-plugin/module/order-setting.ts +19 -29
  7. package/lowcode/cms-plugin/shopping-order-manager.js +16 -32
  8. package/lowcode/cms-plugin/shopping-order-manager.ts +17 -32
  9. package/lowcode/jspage/function-page/setting_editor.js +8 -0
  10. package/lowcode/jspage/function-page/setting_editor.ts +8 -8
  11. package/package.json +1 -1
  12. package/src/api-public/controllers/ai-chat.js.map +1 -1
  13. package/src/api-public/controllers/app-release.js.map +1 -1
  14. package/src/api-public/controllers/article.js.map +1 -1
  15. package/src/api-public/controllers/post.js.map +1 -1
  16. package/src/api-public/controllers/shop.js +0 -14
  17. package/src/api-public/controllers/shop.js.map +1 -1
  18. package/src/api-public/controllers/shop.ts +11 -11
  19. package/src/api-public/controllers/user.js.map +1 -1
  20. package/src/api-public/services/ai-robot.js.map +1 -1
  21. package/src/api-public/services/delivery.js.map +1 -1
  22. package/src/api-public/services/post.js.map +1 -1
  23. package/src/api-public/services/public-table-check.js.map +1 -1
  24. package/src/api-public/services/recommend.js.map +1 -1
  25. package/src/api-public/services/schedule.js.map +1 -1
  26. package/src/api-public/services/shopping.d.ts +1 -0
  27. package/src/api-public/services/shopping.js +72 -16
  28. package/src/api-public/services/shopping.js.map +1 -1
  29. package/src/api-public/services/shopping.ts +118 -56
  30. package/tyn2etd9zq.json +1 -0
@@ -295,7 +295,7 @@ export class Shopping {
295
295
  if (`${query.id || ''}`) {
296
296
  if (`${query.id}`.includes(',')) {
297
297
  querySql.push(`id in (${query.id})`);
298
- console.log("query.id -- " , query.id)
298
+ console.log("query.id -- ", query.id)
299
299
  } else {
300
300
  querySql.push(`id = ${query.id}`);
301
301
  }
@@ -317,7 +317,7 @@ export class Shopping {
317
317
  query.productType.split(',').map((dd) => {
318
318
  if (dd === 'hidden') {
319
319
  querySql.push(`(content->>'$.visible' = "false")`);
320
- } else if (dd !== 'all'){
320
+ } else if (dd !== 'all') {
321
321
  querySql.push(`(content->>'$.productType.${dd}' = "true")`);
322
322
  }
323
323
  });
@@ -525,8 +525,8 @@ export class Shopping {
525
525
  dd.content.preview_image = dd.content.language_data[`${query.language}`].preview_image || dd.content.preview_image;
526
526
  (dd.content.variants || []).map((variant: any) => {
527
527
  variant.preview_image = variant[`preview_image_${query.language}`] || variant.preview_image;
528
- if(variant.preview_image==='https://d3jnmi1tfjgtti.cloudfront.net/file/234285319/1722936949034-default_image.jpg'){
529
- variant.preview_image=dd.content.preview_image[0];
528
+ if (variant.preview_image === 'https://d3jnmi1tfjgtti.cloudfront.net/file/234285319/1722936949034-default_image.jpg') {
529
+ variant.preview_image = dd.content.preview_image[0];
530
530
  }
531
531
  });
532
532
  }
@@ -638,8 +638,8 @@ export class Shopping {
638
638
  ) {
639
639
  let sql = `SELECT v.id,
640
640
  v.product_id,
641
- v.content as variant_content,
642
- p.content as product_content,
641
+ v.content as variant_content,
642
+ p.content as product_content,
643
643
  CAST(JSON_EXTRACT(v.content, '$.stock') AS UNSIGNED) as stock
644
644
  FROM \`${this.app}\`.t_variants AS v
645
645
  JOIN
@@ -1134,7 +1134,7 @@ export class Shopping {
1134
1134
  variant.stock = countless > 0 ? countless : 0;
1135
1135
  variant.deduction_log = returnData.deductionLog;
1136
1136
  b.deduction_log = returnData.deductionLog;
1137
- await this.updateVariantsWithSpec(variant , b.id , b.spec)
1137
+ await this.updateVariantsWithSpec(variant, b.id, b.spec)
1138
1138
  //這裡更新資訊
1139
1139
  await db.query(
1140
1140
  `UPDATE \`${this.app}\`.\`t_manager_post\`
@@ -2156,7 +2156,7 @@ export class Shopping {
2156
2156
  if (data.orderData) {
2157
2157
  update.orderData = JSON.stringify(data.orderData);
2158
2158
  }
2159
-
2159
+ const store_config = await new User(this.app).getConfigV2({key: 'store_manager', user_id: 'manager'});
2160
2160
  const origin = await db.query(
2161
2161
  `SELECT *
2162
2162
  FROM \`${this.app}\`.t_checkout
@@ -2171,8 +2171,32 @@ export class Shopping {
2171
2171
  let sns = new SMS(this.app);
2172
2172
  const updateProgress = JSON.parse(update.orderData).progress;
2173
2173
 
2174
- if (origin[0].orderData.progress !== 'shipping' && updateProgress === 'shipping') {
2174
+ //Migrate舊版和新版訂單
2175
+ function migrateOrder(lineItems: any) {
2176
+ for (const lineItem of lineItems) {
2177
+ lineItem.stockList = undefined;
2178
+ lineItem.deduction_log = lineItem.deduction_log || {}
2179
+ if (Object.keys(lineItem.deduction_log).length === 0) {
2180
+ //將舊版回填migrate成新版本
2181
+ lineItem.deduction_log[store_config.list[0].id] = {count: lineItem.count}
2182
+ }
2183
+ }
2184
+ }
2185
+
2186
+ console.log(`update.orderData=>`, update.orderData)
2187
+ migrateOrder(data.orderData.lineItems)
2188
+ migrateOrder(origin[0].orderData.lineItems)
2175
2189
 
2190
+ //當訂單變成已取消的當下去執行
2191
+ if (origin[0].orderData.orderStatus !== '-1' && update.orderData.orderStatus === '-1') {
2192
+ for (const lineItem of origin[0].orderData.lineItems) {
2193
+ //回填所有庫存點數量
2194
+ for (const b of Object.keys(lineItem.deduction_log)) {
2195
+ await new Shopping(this.app, this.token).calcVariantsStock(lineItem.deduction_log[b] || 0, b, lineItem.id, lineItem.spec);
2196
+ }
2197
+ }
2198
+ await AutoSendEmail.customerOrder(this.app, 'auto-email-order-cancel-success', data.orderData.orderID, data.orderData.email, data.orderData.language);
2199
+ } else if (origin[0].orderData.progress !== 'shipping' && updateProgress === 'shipping') {
2176
2200
  if (data.orderData.customer_info.phone) {
2177
2201
  await sns.sendCustomerSns('auto-sns-shipment', data.orderData.orderID, data.orderData.customer_info.phone);
2178
2202
  console.log('出貨簡訊寄送成功');
@@ -2182,25 +2206,9 @@ export class Shopping {
2182
2206
  await line.sendCustomerLine('auto-line-shipment', data.orderData.orderID, data.orderData.customer_info.lineID);
2183
2207
  console.log('付款成功line訊息寄送成功');
2184
2208
  }
2185
- //出貨庫存修改
2186
- for (const lineItem of origin[0].orderData.lineItems) {
2187
- let variant = data.orderData.lineItems.find((lineItem2:any)=>{
2188
- return lineItem2.id == lineItem.id && JSON.stringify(lineItem.spec) == JSON.stringify(lineItem2.spec);
2189
- })
2190
- //把原本庫存扣的補回去
2191
- await new Stock(this.app, this.token).recoverStock(lineItem)
2192
- //扣掉這次更改後訂單扣的
2193
- await new Stock(this.app, this.token).shippingStock(variant);
2194
- }
2195
-
2196
-
2197
- // console.log("origin.orderData.progress -- " , data.orderData.lineItems);
2198
2209
 
2199
2210
  await AutoSendEmail.customerOrder(this.app, 'auto-email-shipment', data.orderData.orderID, data.orderData.email, data.orderData.language);
2200
- }
2201
-
2202
- // 商品到貨信件通知(消費者)
2203
- if (origin[0].orderData.progress !== 'arrived' && updateProgress === 'arrived') {
2211
+ } else if (origin[0].orderData.progress !== 'arrived' && updateProgress === 'arrived') {
2204
2212
  if (data.orderData.customer_info.phone) {
2205
2213
  await sns.sendCustomerSns('auto-sns-shipment-arrival', data.orderData.orderID, data.orderData.customer_info.phone);
2206
2214
  console.log('到貨簡訊寄送成功');
@@ -2211,8 +2219,21 @@ export class Shopping {
2211
2219
  console.log('付款成功line訊息寄送成功');
2212
2220
  }
2213
2221
  await AutoSendEmail.customerOrder(this.app, 'auto-email-shipment-arrival', data.orderData.orderID, data.orderData.email, data.orderData.language);
2222
+ } else {
2223
+ for (const new_line_item of data.orderData.lineItems) {
2224
+ const og_line_items = origin[0].orderData.lineItems.find((dd: any) => {
2225
+ return (dd.id === new_line_item.id) && (dd.spec.join('') === new_line_item.spec.join(''))
2226
+ });
2227
+ for (const key of Object.keys(new_line_item.deduction_log)) {
2228
+ const u_: number = new_line_item.deduction_log[key];
2229
+ const o_: number = og_line_items.deduction_log[key];
2230
+ console.log(`key->`,key)
2231
+ await new Shopping(this.app, this.token).calcVariantsStock((u_ - o_) * -1, key, new_line_item.id, new_line_item.spec);
2232
+ }
2233
+ }
2214
2234
  }
2215
2235
 
2236
+
2216
2237
  if (origin[0].status !== 1 && update.status === 1) {
2217
2238
  await this.releaseCheckout(1, data.orderData.orderID);
2218
2239
  }
@@ -2231,6 +2252,7 @@ export class Shopping {
2231
2252
  orderData: data.orderData,
2232
2253
  };
2233
2254
  } catch (e) {
2255
+ console.error(e)
2234
2256
  throw exception.BadRequestError('BAD_REQUEST', 'putOrder Error:' + e, null);
2235
2257
  }
2236
2258
  }
@@ -2757,7 +2779,7 @@ OR JSON_UNQUOTE(JSON_EXTRACT(orderData, '$.orderStatus')) NOT IN (-99)) `);
2757
2779
  []
2758
2780
  );
2759
2781
  }
2760
- const store_config=await new User(this.app).getConfigV2({key:'store_manager',user_id:'manager'});
2782
+ const store_config = await new User(this.app).getConfigV2({key: 'store_manager', user_id: 'manager'});
2761
2783
  await Promise.all(content.variants.map((a: any) => {
2762
2784
  content.min_price = content.min_price ?? a.sale_price;
2763
2785
  content.max_price = content.max_price ?? a.sale_price;
@@ -2769,13 +2791,13 @@ OR JSON_UNQUOTE(JSON_EXTRACT(orderData, '$.orderStatus')) NOT IN (-99)) `);
2769
2791
  }
2770
2792
  a.type = 'variants';
2771
2793
  a.product_id = content.id;
2772
- a.stockList=a.stockList || {}
2794
+ a.stockList = a.stockList || {}
2773
2795
  if (a.show_understocking === 'false') {
2774
2796
  a.stock = 0
2775
2797
  a.stockList = {}
2776
- }else if(Object.keys(a.stockList).length===0){
2798
+ } else if (Object.keys(a.stockList).length === 0) {
2777
2799
  //適應舊版庫存更新
2778
- a.stockList[store_config.list[0].id]={count:a.stock}
2800
+ a.stockList[store_config.list[0].id] = {count: a.stock}
2779
2801
  }
2780
2802
  return new Promise(async (resolve, reject) => {
2781
2803
  await db.query(`INSERT INTO \`${this.app}\`.t_variants
@@ -2806,8 +2828,10 @@ OR JSON_UNQUOTE(JSON_EXTRACT(orderData, '$.orderStatus')) NOT IN (-99)) `);
2806
2828
  }
2807
2829
  }
2808
2830
 
2809
- public async updateVariantsWithSpec(data: any , product_id: string , spec:string[]) {
2810
- const sql = (spec.length > 0) ?`AND JSON_CONTAINS(content->'$.spec', JSON_ARRAY(${spec.map((data:string)=>{return `\"${data}\"`}).join(',')}));`:''
2831
+ public async updateVariantsWithSpec(data: any, product_id: string, spec: string[]) {
2832
+ const sql = (spec.length > 0) ? `AND JSON_CONTAINS(content->'$.spec', JSON_ARRAY(${spec.map((data: string) => {
2833
+ return `\"${data}\"`
2834
+ }).join(',')}));` : ''
2811
2835
 
2812
2836
  try {
2813
2837
  await db.query(
@@ -2822,14 +2846,41 @@ OR JSON_UNQUOTE(JSON_EXTRACT(orderData, '$.orderStatus')) NOT IN (-99)) `);
2822
2846
  product_id,
2823
2847
  ]
2824
2848
  );
2825
- }catch (e:any){
2826
- console.log("error -- " , e)
2849
+ } catch (e: any) {
2850
+ console.log("error -- ", e)
2827
2851
  }
2828
2852
 
2829
2853
  }
2830
2854
 
2855
+ //更新庫存數量
2856
+ public async calcVariantsStock(calc: number, stock_id: string, product_id: string, spec: string[]) {
2857
+ const pd_data = (await db.query(`select *
2858
+ from \`${this.app}\`.t_manager_post
2859
+ where id = ?`, [product_id]))[0]['content'];
2860
+ const store_config = await new User(this.app).getConfigV2({key: 'store_manager', user_id: 'manager'});
2861
+ const variant_s: any = pd_data.variants.find((dd: any) => {
2862
+ return dd.spec.join('-') === spec.join('-')
2863
+ });
2864
+ if (Object.keys(variant_s.stockList).length === 0) {
2865
+ //適應舊版庫存更新
2866
+ variant_s.stockList[store_config.list[0].id] = {count: variant_s.stock}
2867
+ }
2868
+ if (variant_s.stockList[stock_id] ) {
2869
+ console.log(`find-vas`,variant_s.stockList[stock_id] )
2870
+ variant_s.stockList[stock_id].count=variant_s.stockList[stock_id].count ||0
2871
+ variant_s.stockList[stock_id].count = variant_s.stockList[stock_id].count + calc;
2872
+ if (variant_s.stockList[stock_id].count < 0) {
2873
+ variant_s.stockList[stock_id].count = 0
2874
+ }
2831
2875
 
2832
- async getDataAnalyze(tags: string[],query?:any) {
2876
+ }
2877
+
2878
+ console.log(`variant_s_${stock_id}=>`,variant_s)
2879
+ await this.postVariantsAndPriceValue(pd_data)
2880
+ }
2881
+
2882
+
2883
+ async getDataAnalyze(tags: string[], query?: any) {
2833
2884
  try {
2834
2885
  console.log('AnalyzeTimer Start');
2835
2886
  const timer: any = {};
@@ -2856,7 +2907,7 @@ OR JSON_UNQUOTE(JSON_EXTRACT(orderData, '$.orderStatus')) NOT IN (-99)) `);
2856
2907
  result[tag] = await this.getHotProducts('month');
2857
2908
  break;
2858
2909
  case 'hot_products_all':
2859
- result[tag] = await this.getHotProducts('all',query);
2910
+ result[tag] = await this.getHotProducts('all', query);
2860
2911
  break;
2861
2912
  case 'hot_products_today':
2862
2913
  result[tag] = await this.getHotProducts('day');
@@ -3273,22 +3324,22 @@ OR JSON_UNQUOTE(JSON_EXTRACT(orderData, '$.orderStatus')) NOT IN (-99)) `);
3273
3324
  }
3274
3325
  }
3275
3326
 
3276
- async getHotProducts(duration: 'month' | 'day' | 'all',date?:string) {
3327
+ async getHotProducts(duration: 'month' | 'day' | 'all', date?: string) {
3277
3328
  try {
3278
- console.log(`date`,date)
3329
+ console.log(`date`, date)
3279
3330
  const checkoutSQL = `
3280
3331
  SELECT *
3281
3332
  FROM \`${this.app}\`.t_checkout
3282
3333
  WHERE status = 1
3283
3334
  AND ${
3284
- (()=>{
3285
- switch (duration){
3335
+ (() => {
3336
+ switch (duration) {
3286
3337
  case 'day':
3287
3338
  return `created_time BETWEEN CURDATE() AND CURDATE() + INTERVAL 1 DAY - INTERVAL 1 SECOND`
3288
3339
  case 'month':
3289
3340
  return `(created_time BETWEEN DATE_SUB(NOW(), INTERVAL 1 MONTH) AND NOW())`
3290
3341
  case 'all':
3291
- return `1=1`
3342
+ return `1=1`
3292
3343
  }
3293
3344
  })()
3294
3345
  };
@@ -3296,7 +3347,13 @@ OR JSON_UNQUOTE(JSON_EXTRACT(orderData, '$.orderStatus')) NOT IN (-99)) `);
3296
3347
  const checkouts = await db.query(checkoutSQL, []);
3297
3348
  const series = [];
3298
3349
  const categories = [];
3299
- const product_list: { title: string; count: number,preview_image:string,sale_price:number,pos_info:any }[] = [];
3350
+ const product_list: {
3351
+ title: string;
3352
+ count: number,
3353
+ preview_image: string,
3354
+ sale_price: number,
3355
+ pos_info: any
3356
+ }[] = [];
3300
3357
 
3301
3358
  for (const checkout of checkouts) {
3302
3359
 
@@ -3304,8 +3361,10 @@ OR JSON_UNQUOTE(JSON_EXTRACT(orderData, '$.orderStatus')) NOT IN (-99)) `);
3304
3361
  for (const item1 of checkout.orderData.lineItems) {
3305
3362
  const index = product_list.findIndex((item2) => item1.title === item2.title);
3306
3363
  if (index === -1) {
3307
- product_list.push({title: item1.title, count: item1.count,preview_image:(item1 as any).preview_image,
3308
- sale_price:item1.sale_price,pos_info:checkout.orderData.pos_info});
3364
+ product_list.push({
3365
+ title: item1.title, count: item1.count, preview_image: (item1 as any).preview_image,
3366
+ sale_price: item1.sale_price, pos_info: checkout.orderData.pos_info
3367
+ });
3309
3368
  } else {
3310
3369
  product_list[index].count += item1.count;
3311
3370
  product_list[index].sale_price += item1.sale_price;
@@ -3323,7 +3382,7 @@ OR JSON_UNQUOTE(JSON_EXTRACT(orderData, '$.orderStatus')) NOT IN (-99)) `);
3323
3382
  }
3324
3383
  }
3325
3384
 
3326
- return {series, categories,product_list:final_product_list};
3385
+ return {series, categories, product_list: final_product_list};
3327
3386
  } catch (e) {
3328
3387
  throw exception.BadRequestError('BAD_REQUEST', 'getRecentActiveUser Error:' + e, null);
3329
3388
  }
@@ -4183,33 +4242,36 @@ OR JSON_UNQUOTE(JSON_EXTRACT(orderData, '$.orderStatus')) NOT IN (-99)) `);
4183
4242
  //有新類別要處理
4184
4243
  await this.updateCollectionFromUpdateProduct(content.collection);
4185
4244
  }
4186
- let productArray:any = content.data;
4187
- await (Promise.all(productArray.map((product:any,index:number)=>{
4188
- return new Promise(async (resolve, reject)=>{
4245
+ let productArray: any = content.data;
4246
+ await (Promise.all(productArray.map((product: any, index: number) => {
4247
+ return new Promise(async (resolve, reject) => {
4189
4248
  product.type = 'product';
4190
4249
  //判斷是更新時
4191
- if(product.id){
4192
- const og_data=(await db.query(`select * from \`${this.app}\`.\`t_manager_post\` where id=?`,[product.id]))[0];
4193
- if(og_data){
4250
+ if (product.id) {
4251
+ const og_data = (await db.query(`select *
4252
+ from \`${this.app}\`.\`t_manager_post\`
4253
+ where id = ?`, [product.id]))[0];
4254
+ if (og_data) {
4194
4255
  delete product['preview_image'];
4195
- product={
4256
+ product = {
4196
4257
  ...og_data['content'],
4197
4258
  ...product
4198
4259
  }
4199
- product.preview_image=og_data['content'].preview_image || [];
4200
- productArray[index]=product;
4260
+ product.preview_image = og_data['content'].preview_image || [];
4261
+ productArray[index] = product;
4201
4262
  }
4202
4263
  }
4203
4264
  resolve(true)
4204
4265
  })
4205
4266
  })));
4206
4267
  const data = await db.query(
4207
- `replace INTO \`${this.app}\`.\`t_manager_post\` (id,userID,content) values ?`,
4268
+ `replace
4269
+ INTO \`${this.app}\`.\`t_manager_post\` (id,userID,content) values ?`,
4208
4270
  [
4209
4271
  productArray.map((product: any) => {
4210
4272
  product.type = 'product';
4211
4273
  this.checkVariantDataType(product.variants);
4212
- return [product.id || null,this.token?.userID,JSON.stringify(product)]
4274
+ return [product.id || null, this.token?.userID, JSON.stringify(product)]
4213
4275
  }),
4214
4276
  ]
4215
4277
  );
@@ -0,0 +1 @@
1
+ [{"request":["請問要如何新增訂單","新增訂單該怎麼做"],"response":"請前往訂單管理的「訂單」,點擊右上角「新增」即可新增訂單"},{"request":["請問要如何編輯訂單","編輯訂單該怎麼做","如何修改訂單"],"response":"請前往訂單管理的「訂單」,點擊一份訂單進行編輯操作"},{"request":["請問要如何封存訂單","封存訂單該怎麼做"],"response":"請前往訂單管理的「訂單」,在列表中勾選想要封存的訂單,即可批量封存"},{"request":["請問要如何解除封存訂單","解除封存訂單該怎麼做"],"response":"請前往訂單管理的「已封存訂單」,在列表中勾選想要解除封存的訂單,即可批量解除封存"},{"request":["請問要如何刪除訂單","刪除訂單該怎麼做"],"response":"目前系統沒有設計訂單刪除的功能,僅可勾選想要封存的訂單,將訂單以封存的方式改變狀態"},{"request":["請問要如何搜尋訂單","搜尋訂單該怎麼做","我想要按照日期排序訂單,該怎麼做","可以只顯示付款狀態已付款的訂單嗎"],"response":"請前往訂單管理的「訂單」,在列表左上方可以根據訂單編號、訂購人姓名、商品名稱等進行關鍵字搜尋,也可以在右上選擇篩選和排序,可以做到更仔細的訂單查詢"},{"request":["請問要如何查看訂單狀態","訂單付款狀態如何得知","訂單出貨狀態如何得知","請問出貨狀態在哪"],"response":"請前往訂單管理的「訂單」,點擊任一訂單,在右上角有出貨狀態、付款狀態、訂單進度的顯示,也可以在詳細訂單中查看更多內容"},{"request":["請問要如何匯出訂單列表","匯出訂單列表要怎麼做","有辦法匯出訂單"],"response":"請前往訂單管理的「訂單」,點擊右上角「匯出」即匯出當前搜尋結果的訂單excel檔案"},{"request":["如何上架商品","如何下架商品","有辦法上架或下架多個商品嗎","上架商品","下架商品"],"response":"請前往商品管理的「商品列表」,可直接在列表上下架商品,或勾選多個商品後,點擊「更多操作」來批量更改"},{"request":["請問要如何新增商品","新增商品該怎麼做","新增商品在哪","新增商品","如何添加商品","添加商品該怎麼做"],"response":"請前往商品管理的「商品列表」,點擊右上角「新增」即可新增商品"},{"request":["請問要如何匯出商品列表","匯出商品列表要怎麼做","有辦法匯出商品列表嗎"],"response":"請前往商品管理的「商品列表」,點擊右上角「匯入」或「匯出」,即可匯入多個商品,或匯出當前搜尋結果的商品excel檔案"},{"request":["如何透過訂單編號查詢商品","如何用商品條碼來搜尋商品","有辦法在商品列表中加入篩選嗎","排序建立時間為最新的商品列表"],"response":"請前往商品管理的「商品列表」,在列表左上方可以根據商品名稱、SKU、商品條碼等進行關鍵字搜尋,也可以在右上選擇篩選和排序,可以做到更仔細的商品查詢"},{"request":["如何新增商品規格","如何編輯商品規格","調整商品規格","能更改商品規格的大小、尺寸、顏色、型號嗎","新增規格","如何修改規格"],"response":"請前往商品管理的「商品列表」,點擊任一商品,往下找到「商品規格」欄位,可以新增與編輯規格種類,下方「規格設定」將會顯示所有商品規格的組合"},{"request":["如何修改商品狀態","如何編輯商品狀態為草稿的商品","啟用商品該如何設定","如何讓商品無法購買"],"response":"請前往商品管理的「商品列表」,點擊任一商品,「商品狀態」在右上角,「啟用」為在前台公布並開放購買,「草稿」則在前台暫時不公布也不可購買"},{"request":["如何設定商品價格","商品的原價該怎麼設定","商品的價格該在哪裡設定"],"response":"請前往商品管理的「商品列表」,點擊任一商品,若有多個規格請點擊任一規格,往下找到「定價」欄位,「售價」為消費者商品購買金額,「原價」為較高價格的售價,可依照銷售策略訂定您想要的價格"},{"request":["如何設定商品運費","如何設定商品重量","如何設定商品材積","商品的重量該怎麼設定","商品的材積該在哪裡設定"],"response":"請前往商品管理的「商品列表」,點擊任一商品,若有多個規格請點擊任一規格,往下找到「運費計算」欄位,可針對商品的運費計算方式選擇依照「材積」、「重量」或不計算,並在下方填入商品的單位值,隨後會依照商店設定中「運費設定」的級距後,計算出消費者購物車的運費總金額"},{"request":["如何新增商品分類","商品分類該怎麼設定","商品分類在哪裡設定"],"response":"請前往商品管理的「商品分類」,點擊右上角「新增」,輸入分類標題與連結網址(唯一),並設定該分類的商品與SEO,即可儲存完成新增"},{"request":["如何編輯商品分類","商品分類在哪裡編輯"],"response":"請前往商品管理的「商品分類」,點擊任一商品分類進行編輯"},{"request":["如何刪除商品分類","商品分類在哪裡刪除"],"response":"請前往商品管理的「商品分類」,點擊任一商品分類,下方功能列中按下「刪除類別」,請注意刪除類別時,若有包含子類別,也將一併刪除"},{"request":["如何調整商品分類的順序","想調整商品分類在前台的順序"],"response":"請前往商品管理的「商品分類」,點擊右上角「編輯順序」,可拖曳父子層的類別,進而改變前台瀏覽商品的分類順序"},{"request":["如何設定商店的基本訊息","如何設定商店的基本資料","設定商店名稱和統一編號,該從哪裡開始"],"response":"請前往商店設定的「商店訊息」,在基本資訊欄位可填寫商家資料,作為對外宣傳與首頁資訊"},{"request":["如何設定商店的SEO","如何設定商店的圖示","設定商店縮圖,該從哪裡開始"],"response":"請前往商店設定的「商店訊息」,在SEO欄位可填寫商家在網頁上的SEO設定與圖片,並自訂網域、Google Analytics(GA4)、代碼管理工具"},{"request":["如何編輯商店金流","商店線上或線下金流該怎麼設定","商店的付款方式","atm或貨到付款在哪裡設定","信用卡付款方式在哪裡設定","如何設定line pay"],"response":"請前往商店設定的「金流設定」,可管理線上與線下金流,無論是指定付款方式、付款告知提醒等,商家皆可自訂"},{"request":["如何編輯商店物流","超商配送該怎麼設定","711店到店如何設定","全家店到店如何設定","ok店到店如何設定","萊爾富店到店如何設定","交貨方式在哪裡設定"],"response":"請前往商店設定的「配送設定」,可設定啟用物流的方式,以及設定給消費者的配送說明,超商店到店請詳閱各大超商配送與價格資訊"},{"request":["如何填寫商店物流追蹤","物流追蹤該怎麼設定","如何新增物流追蹤"],"response":"請前往商店設定的「配送設定」,點擊右上角的「物流追蹤設定」,可設定綠界物流參數,設定完成即可達成物流追蹤與托運單列印功能"},{"request":["如何填寫商店物流運費","運費級距該怎麼設定"],"response":"請前往商店設定的「運費設定」,可以設定訂單「總材積」或「總重量」所在的級距,進而計算該訂單運費金額"},{"request":["如何開啟或關閉購物金功能","新加入會員購物金該怎麼設定","購物金的使用期限","生日禮發放購物金的方式","如何設定購物金折抵上限","如何允許購物金是否可折抵"],"response":"請前往商店設定的「購物金設定」,可以設定消費者在訂單結帳時可使用折抵的購物金,以及新註冊加入會員或會員生日禮的購物金自動發放、訂單折抵上限、購物金使用期限等"},{"request":["線上金流有哪些"],"response":"我們有提供「藍新金流」與「綠界金流」的串接,並提供正式測試區切分與多種付款方式"},{"request":["線下金流有哪些"],"response":"我們有提供「ATM轉帳」、「LINE PAY」與基本的「貨到付款」,在不執行線上付款時,可由店家自行與消費者商議付款方式"},{"request":["訂單重量的運費計算方式","訂單材積的運費計算方式"],"response":"訂單內的商品會設定依「重量」或依「材積」,分別做出總計,再按照總計值找出「運費設定」所設定的區間,算出該訂單的運費金額"},{"request":["購物金的用途是什麼","什麼是購物金"],"response":"購物金是商家發送給消費者的訂單可抵用金額,1點購物金代表1元,並搭配新加入會員、生日禮、優惠券,或是手動給予消費者購物金,來達到行銷作用"},{"request":["如何查看商品庫存","什麼是商品庫存"],"response":"請前往商品管理的「庫存列表」,會顯示商品的每個規格中各自的安全庫存與實際庫存數量,可即時查看與編輯值,點擊則可查看商品規格詳細資料"},{"request":["如何設定商品庫存"],"response":"請前往商品管理的「商品列表」,點擊任一商品,若有多個規格請點擊任一規格,往下找到「庫存政策」欄位,可設定是否追蹤庫存,系統將會記錄購買商品時的增減"},{"request":["什麼是安全庫存"],"response":"安全庫存指的是商品啟用庫存追蹤時,若實際庫存低於安全庫存量,系統將會通知商家,商品低於安全庫存量的提醒"},{"request":["什麼是POS"],"response":"POS是指在零售行業中用於處理交易的硬軟體組合。通常包括一台電腦、POS軟體、條碼掃描儀、收銀機、發票列印機和付款處理等設備"},{"request":["如何查看POS訂單","怎麼篩選POS訂單"],"response":"請前往訂單管理的「訂單」,在列表上方可以點選「POS訂單」的標籤,即可查看所有的POS訂單"},{"request":["什麼是已封存訂單"],"response":"已封存的訂單將不會在所有訂單中顯示,需要到訂單管理的「已封存訂單」中解除封存訂單,才會顯示於所有訂單的列表中"},{"request":["如何新增退貨單"],"response":"請前往訂單管理的「退貨單」,點擊右上角新增,輸入想要退貨的訂單編號,並設定退貨單的詳細內容,即可建立退貨單"},{"request":["如何新增顧客"],"response":"請前往顧客管理的「顧客列表」,點擊右上角新增,輸入顧客基本資料,即可新增"},{"request":["如何加入黑名單","什麼是顧客黑名單"],"response":"請前往顧客管理的「顧客列表」,點擊想要加入黑名單的顧客,在顧客詳細右上角點擊「加入黑名單」即可,黑名單的顧客將無法登入與購物車結帳"},{"request":["什麼是顧客分群"],"response":"顧客分群是將所有的顧客分類,目前有提供「電子郵件訂閱者」、「尚未購買過的顧客」、「已購買多次的顧客」,可透過顧客分群了解到不同客群有哪些會員"},{"request":["什麼是會員等級"],"response":"會員等級是按照顧客訂單消費紀錄來給予不同等級的設定,條件可分為累計蕭累或單次消費,會員等級可以在優惠券、生日禮等活動時,界定不同內容與優惠身份"},{"request":["什麼是優惠券","如何設定優惠券","如何設定優惠促銷活動","優惠券要怎麼新增","如何建立優惠券"],"response":"請前往優惠促銷的「折扣活動」,可以新增一個新的優惠券活動,可指定產品、顧客、設定金額、套用範圍、計算方式等,建立專屬店家的活動"},{"request":["怎樣啟用或關閉優惠券","如何更改優惠券狀態"],"response":"點擊任一優惠券,在設定中有「活動狀態」的按鈕,可以點擊啟用與關閉並儲存"},{"request":["如何設定優惠券代碼","如何指定優惠券可使用的對象","如何指定想要的顧客才可以使用的優惠券","怎麼設定優惠券可使用的來源","如何僅限POS使用優惠券"],"response":"點擊任一優惠券,在設定中有「活動方式」、「活動對象」、「可使用訂單來源」,這些設定可以限制優惠券的使用範圍與來源"},{"request":["如何設定優惠券折扣金額","如何指定優惠券折抵的百分比","怎麼設定優惠券套用的商品分類","指定商品才可以使用優惠券","如何應用優惠券到特定商品"],"response":"點擊任一優惠券,在設定中有「折扣金額」與「套用至」,這些設定可以限制優惠券折扣條件,以及在商品上的套用限制"},{"request":["如何設定優惠券消費條件","如何指定滿額送","怎麼設定優惠券觸發條件","如何設定買幾送幾的優惠券"],"response":"點擊任一優惠券,在設定中有「消費條件」、「計算單位」、「重複觸發」,這些設定可以讓優惠券有其觸發條件、是否重複觸發,以及計算單位的標的"},{"request":["如何設定優惠券使用次數","如何設定全館使用次數","怎麼設定一個人使用優惠券的次數","指定優惠券使用次數"],"response":"點擊任一優惠券,在設定中有「全館總使用次數」與「個人總使用次數」,可以設定在全館或個人,在商店中無限制次數或限制使用次數"},{"request":["如何設定優惠券使用期限","怎麼設定優惠券的開始時間與結束時間","無期限的優惠券要如何設定"],"response":"點擊任一優惠券,在設定中有「有效日期」,可以設定優惠券啟用的開始時間與結束時間"},{"request":["如何刪除優惠券"],"response":"點擊任一優惠券,下方功能列有「刪除優惠券」,或是在列表勾選洗要刪除的優惠券,點擊「批量移除」,即可刪除優惠券"},{"request":["如何新增購物金","如何發放購物金"],"response":"請前往優惠促銷的「購物金紀錄」,點擊右上角新增,輸入欲增加或減少的金額,並設定天數,接著指定顧客,即可完成購物金增減"},{"request":["如何新增隱形賣場"],"response":"請前往行銷推廣的「隱形賣場」,點擊右上角新增,選擇符合您需求的模板,接著設定網頁名稱、連結、SEO,以及賣場內的產品,儲存即可完成隱形賣場"},{"request":["什麼是隱形賣場"],"response":"隱形賣場是指透過專屬的連結,可進入的賣場,只有透過專屬連結進入網站時,才可進入此隱形賣場,進而做到行銷與分流追蹤的目的"},{"request":["如何新增一頁商店"],"response":"請前往行銷推廣的「一頁商店」,點擊右上角新增,選擇符合您需求的模板,接著設定網頁名稱、連結、SEO,以及賣場內的產品,儲存即可完成一頁商店"},{"request":["什麼是一頁商店"],"response":"一頁商店是指透過單一頁面設計,推廣指定商品與類別,讓頁面獨立展現特色,進而做到行銷與分流追蹤的目的"},{"request":["如何設定分銷連結"],"response":"請前往行銷推廣的「分銷連結」,點擊右上角新增,設定分銷代碼、導向的網址、專屬網址,以及分潤條件與類型,並設定推薦人,儲存即可完成分銷連結"},{"request":["什麼是分銷連結"],"response":"分銷連結指的是特別給予推薦人引薦用的商城連結,透過推薦人的廣發與行銷,來達到觸擊連結的效果,讓電商與賣場得到更多關注與曝光率"},{"request":["分銷連結的推薦人是什麼","如何新增推薦人"],"response":"請前往行銷推廣的「推薦人列表」,點擊右上角新增,可新增行銷用的推薦人帳號,並可以在「分銷連結」設定上選取該推薦人"},{"request":["自動寄件是什麼功能","如何使用自動寄件"],"response":"自動寄件是系統在指定事件發生時自動發送的寄信功能,諸如商品出到貨、訂單成立與付款、生日祝福、客服訊息等寄件格式設定,以及是否啟用功能"},{"request":["手動寄件是什麼功能","如何使用手動寄件"],"response":"手動寄件是系統提供商家寄信給消費者的寄信功能,可以指定多個客群或顧客,輸入標題與內文,並指定寄送時間"},{"request":["如何自訂網頁主題","如何設定網站佈景主題","前台網頁要如何設計","什麼是佈景主題","如何修改網站排版","網頁設計該怎麼做"],"response":"請前往品牌官網的「佈景主題」,在第一張卡的右側點擊「自訂」,即可進入頁面編輯系統,在該系統可以自由設定您想要的網站設計與排版"},{"request":["如何新增網誌文章","網誌文章是什麼","如何發佈網誌"],"response":"請前往品牌官網的「網誌文章」,在右上角點擊新增,選定一個模板並設定網誌內容,儲存即建立網誌完成"},{"request":["如何設定分頁","分頁列表是什麼","分頁列表在哪"],"response":"請前往品牌官網的「分頁列表」,列表是自訂新增的連結,可配合「佈景主題」在頁面中自訂添加需要有連結的地方"},{"request":["如何設定選單管理","選單管理是什麼","頁腳連結在哪","導覽列的連結要如何設定","如何設定主選單"],"response":"請前往品牌官網的「選單管理」,選單分為主選單與頁腳,可加入指定的頁面連結與外部連結,系統將自動在每個頁面的頁首頁腳添加超連結"},{"request":["如何切換商店","其他的商城要如何開啟","切換商店的地方在哪","如何新增商店"],"response":"請移動至右上角會員頭像處,點擊「所有商店」,即可查看所有您建立的商店、當前方案與預覽圖"},{"request":["要如何為商品添加圖片和描述","如何新增商品圖片或敘述"],"response":"點擊任一商品編輯,可以在「商品說明」欄位添加商品的敘述,「圖片」則可以新增多張不同角度和種類的圖片"},{"request":["怎樣將商品分類到不同的分類目錄中","可以將商品新增到不同的分類嗎"],"response":"商品可以填加到多個不同的「商品分類」,在父層的商品分類中會同時包含底下的子層商品,讓您的商品有更多方式來分類"},{"request":["如何查看最新的訂單"],"response":"訂單管理的「訂單」列表,預設已按照最新到最舊的方式排列"},{"request":["如何處理待處理的訂單","如何篩選已付款的訂單"],"response":"訂單管理的「訂單」列表右上有篩選器,可以從篩選器中選取訂單裝態處理中、付款狀態已付款等設定"},{"request":["怎樣查看訂單的配送地址","怎樣查看訂購人資料","如何知道訂單的結帳方式"],"response":"訂單管理的「訂單」點選任一訂單,右側有「訂購人資料」、「收件人資料」、「付款方式」、「配送方式」,這些欄位可以讓您清楚知道訂單的消費者資訊"},{"request":["怎樣更新訂單的訂單狀態","如何更新訂單的付款狀態","訂單該怎麼更新出貨狀態"],"response":"訂單管理的「訂單」點選任一訂單,可以查找「訂單狀態」、「付款狀態」、「配送狀態」,這些欄位可以讓您調整訂單的各項狀態"},{"request":["怎樣處理顧客在訂單的疑問","如何回答顧客對訂單的疑問"],"response":"顧客管理的「客服系統」可以針對不同的顧客來專一答覆,顧客在購物車結帳時也可以填寫備註,在訂單詳細裡的「訂單備註」中可以查看"},{"request":["如何查看顧客的訂單紀錄"],"response":"顧客管理的「顧客列表」搜尋顧客後,點擊該顧客,顧客詳細中有「訂單記錄」,可查閱顧客訂單歷史紀錄"},{"request":["怎麼查找顧客的購物金紀錄"],"response":"顧客管理的「顧客列表」搜尋顧客後,點擊該顧客,顧客詳細中有「購物金」,可瞭解到顧客現有購物金餘額,與購物金增減紀錄"},{"request":["怎麼設定免運費"],"response":"請前往優惠促銷的「免運費活動」,可以新增一個免運費優惠券活動,並設定消費條件、觸發方式、使用期限等"}]